From 391d569a453e8f55bd26d3b2e23039721b6adc61 Mon Sep 17 00:00:00 2001 From: freddygv Date: Sat, 22 Aug 2020 18:05:09 -0600 Subject: [PATCH 01/20] Add LB policy to service-resolver --- agent/structs/config_entry_discoverychain.go | 124 ++++++++ .../config_entry_discoverychain_test.go | 272 ++++++++++++++++++ api/config_entry_discoverychain.go | 65 +++++ api/config_entry_discoverychain_test.go | 102 +++++++ 4 files changed, 563 insertions(+) diff --git a/agent/structs/config_entry_discoverychain.go b/agent/structs/config_entry_discoverychain.go index 04cf32353..c87b46f00 100644 --- a/agent/structs/config_entry_discoverychain.go +++ b/agent/structs/config_entry_discoverychain.go @@ -639,6 +639,10 @@ type ServiceResolverConfigEntry struct { // to this service. ConnectTimeout time.Duration `json:",omitempty" alias:"connect_timeout"` + // LoadBalancer determines the load balancing policy and configuration for services + // issuing requests to this upstream service. + LoadBalancer LoadBalancer `json:",omitempty" alias:"load_balancer"` + EnterpriseMeta `hcl:",squash" mapstructure:",squash"` RaftIndex } @@ -807,6 +811,56 @@ func (e *ServiceResolverConfigEntry) Validate() error { return fmt.Errorf("Bad ConnectTimeout '%s', must be >= 0", e.ConnectTimeout) } + validPolicies := map[string]bool{ + "": true, + "random": true, + "round_robin": true, + "least_request": true, + "ring_hash": true, + "maglev": true, + } + if ok := validPolicies[e.LoadBalancer.Policy]; !ok { + return fmt.Errorf("Bad LoadBalancer policy: %q is not supported", e.LoadBalancer.Policy) + } + + if e.LoadBalancer.Policy != "ring_hash" && e.LoadBalancer.RingHashConfig != (RingHashConfig{}) { + return fmt.Errorf("Bad LoadBalancer configuration. "+ + "RingHashConfig specified for incompatible load balancing policy %q", e.LoadBalancer.Policy) + } + if e.LoadBalancer.Policy != "least_request" && e.LoadBalancer.LeastRequestConfig != (LeastRequestConfig{}) { + return fmt.Errorf("Bad LoadBalancer configuration. "+ + "LeastRequestConfig specified for incompatible load balancing policy %q", e.LoadBalancer.Policy) + } + if !e.LoadBalancer.IsHashBased() && len(e.LoadBalancer.HashPolicies) > 0 { + return fmt.Errorf("Bad LoadBalancer configuration: "+ + "HashPolicies specified for non-hash-based Policy: %q", e.LoadBalancer.Policy) + } + + validFields := map[string]bool{ + "header": true, + "cookie": true, + "query_parameter": true, + } + for i, hp := range e.LoadBalancer.HashPolicies { + if ok := validFields[hp.Field]; hp.Field != "" && !ok { + return fmt.Errorf("Bad LoadBalancer HashPolicy[%d]: %q is not a supported field", i, hp.Field) + } + if hp.SourceAddress && hp.Field != "" { + return fmt.Errorf("Bad LoadBalancer HashPolicy[%d]: "+ + "A single hash policy cannot hash both a source address and a %q", i, hp.Field) + } + if hp.SourceAddress && hp.FieldMatchValue != "" { + return fmt.Errorf("Bad LoadBalancer HashPolicy[%d]: "+ + "A FieldMatchValue cannot be specified when hashing SourceAddress", i) + } + if hp.Field != "" && hp.FieldMatchValue == "" { + return fmt.Errorf("Bad LoadBalancer HashPolicy[%d]: Field %q was specified without a FieldMatchValue", i, hp.Field) + } + if hp.FieldMatchValue != "" && hp.Field == "" { + return fmt.Errorf("Bad LoadBalancer HashPolicy[%d]: FieldMatchValue requires a Field to apply to", i) + } + } + return nil } @@ -943,6 +997,76 @@ type ServiceResolverFailover struct { Datacenters []string `json:",omitempty"` } +// LoadBalancer determines the load balancing policy and configuration for services +// issuing requests to this upstream service. +type LoadBalancer struct { + // Policy is the load balancing policy used to select a host + Policy string `json:",omitempty"` + + // RingHashConfig contains configuration for the "ring_hash" policy type + RingHashConfig RingHashConfig `json:",omitempty" alias:"ring_hash_config"` + + // LeastRequestConfig contains configuration for the "least_request" policy type + LeastRequestConfig LeastRequestConfig `json:",omitempty" alias:"least_request_config"` + + // HashPolicies is a list of hash policies to use for hashing load balancing algorithms. + // Hash policies are evaluated individually and combined such that identical lists + // result in the same hash. + // If no hash policies are present, or none are successfully evaluated, + // then a random backend host will be selected. + HashPolicies []HashPolicy `json:",omitempty" alias:"hash_policies"` +} + +func (l LoadBalancer) IsHashBased() bool { + switch l.Policy { + case "maglev", "ring_hash": + return true + default: + return false + } +} + +// RingHashConfig contains configuration for the "ring_hash" policy type +type RingHashConfig struct { + // MinimumRingSize determines the minimum number of hashes per destination host + MinimumRingSize uint64 `json:",omitempty" alias:"minimum_ring_size"` + + // MaximumRingSize determines the maximum number of hashes per destination host + MaximumRingSize uint64 `json:",omitempty" alias:"maximum_ring_size"` +} + +// LeastRequestConfig contains configuration for the "least_request" policy type +type LeastRequestConfig struct { + // ChoiceCount determines the number of random healthy hosts from which to select the one with the least requests. + ChoiceCount uint32 `json:",omitempty" alias:"choice_count"` +} + +// HashPolicy is a list of hash policies to use for hashing load balancing algorithms. +// Hash policies are evaluated individually and combined such that identical lists +// result in the same hash. +// If no hash policies are present, or none are successfully evaluated, +// then a random backend host will be selected. +type HashPolicy struct { + // Field is the attribute type to hash on. + // Must be one of "header","cookie", or "query_parameter". + // Cannot be specified along with SourceIP. + Field string `json:",omitempty"` + + // FieldMatchValue is the value to hash. + // ie. header name, cookie name, URL query parameter name + // Cannot be specified along with SourceIP. + FieldMatchValue string `json:",omitempty" alias:"field_value"` + + // SourceAddress determines whether the hash should be of the source IP rather than of a field and field value. + // Cannot be specified along with Field and FieldMatchValue. + SourceAddress bool `json:",omitempty" alias:"source_address"` + + // Terminal will short circuit the computation of the hash when multiple hash policies are present. + // If a hash is computed when a Terminal policy is evaluated, + // then that hash will be used and subsequent hash policies will be ignored. + Terminal bool `json:",omitempty"` +} + type discoveryChainConfigEntry interface { ConfigEntry // ListRelatedServices returns a list of other names of services referenced diff --git a/agent/structs/config_entry_discoverychain_test.go b/agent/structs/config_entry_discoverychain_test.go index 5f332e9bb..d5db08ec5 100644 --- a/agent/structs/config_entry_discoverychain_test.go +++ b/agent/structs/config_entry_discoverychain_test.go @@ -536,6 +536,278 @@ func TestServiceResolverConfigEntry(t *testing.T) { } } +func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { + + type testcase struct { + name string + entry *ServiceResolverConfigEntry + normalizeErr string + validateErr string + + // check is called between normalize and validate + check func(t *testing.T, entry *ServiceResolverConfigEntry) + } + + cases := []testcase{ + { + name: "empty policy is valid", + entry: &ServiceResolverConfigEntry{ + Kind: ServiceResolver, + Name: "test", + LoadBalancer: LoadBalancer{Policy: ""}, + }, + }, + { + name: "supported policy", + entry: &ServiceResolverConfigEntry{ + Kind: ServiceResolver, + Name: "test", + LoadBalancer: LoadBalancer{Policy: "random"}, + }, + }, + { + name: "unsupported policy", + entry: &ServiceResolverConfigEntry{ + Kind: ServiceResolver, + Name: "test", + LoadBalancer: LoadBalancer{Policy: "fake-policy"}, + }, + validateErr: `"fake-policy" is not supported`, + }, + { + name: "bad policy for least request config", + entry: &ServiceResolverConfigEntry{ + Kind: ServiceResolver, + Name: "test", + LoadBalancer: LoadBalancer{ + Policy: "ring_hash", + LeastRequestConfig: LeastRequestConfig{ChoiceCount: 2}, + }, + }, + validateErr: `LeastRequestConfig specified for incompatible load balancing policy`, + }, + { + name: "bad policy for ring hash config", + entry: &ServiceResolverConfigEntry{ + Kind: ServiceResolver, + Name: "test", + LoadBalancer: LoadBalancer{ + Policy: "least_request", + RingHashConfig: RingHashConfig{MinimumRingSize: 1024}, + }, + }, + validateErr: `RingHashConfig specified for incompatible load balancing policy`, + }, + { + name: "good policy for ring hash config", + entry: &ServiceResolverConfigEntry{ + Kind: ServiceResolver, + Name: "test", + LoadBalancer: LoadBalancer{ + Policy: "ring_hash", + RingHashConfig: RingHashConfig{MinimumRingSize: 1024}, + }, + }, + }, + { + name: "good policy for least request config", + entry: &ServiceResolverConfigEntry{ + Kind: ServiceResolver, + Name: "test", + LoadBalancer: LoadBalancer{ + Policy: "least_request", + LeastRequestConfig: LeastRequestConfig{ChoiceCount: 2}, + }, + }, + }, + { + name: "empty policy is not defaulted", + entry: &ServiceResolverConfigEntry{ + Kind: ServiceResolver, + Name: "test", + LoadBalancer: LoadBalancer{ + Policy: "", + }, + }, + check: func(t *testing.T, entry *ServiceResolverConfigEntry) { + require.Equal(t, "", entry.LoadBalancer.Policy) + }, + }, + { + name: "empty policy with hash policy", + entry: &ServiceResolverConfigEntry{ + Kind: ServiceResolver, + Name: "test", + LoadBalancer: LoadBalancer{ + Policy: "", + HashPolicies: []HashPolicy{ + { + SourceAddress: true, + }, + }, + }, + }, + validateErr: `HashPolicies specified for non-hash-based Policy`, + }, + { + name: "supported match field", + entry: &ServiceResolverConfigEntry{ + Kind: ServiceResolver, + Name: "test", + LoadBalancer: LoadBalancer{ + Policy: "maglev", + HashPolicies: []HashPolicy{ + { + Field: "header", + FieldMatchValue: "X-Consul-Token", + }, + }, + }, + }, + }, + { + name: "unsupported match field", + entry: &ServiceResolverConfigEntry{ + Kind: ServiceResolver, + Name: "test", + LoadBalancer: LoadBalancer{ + Policy: "maglev", + HashPolicies: []HashPolicy{ + { + Field: "not-header", + }, + }, + }, + }, + validateErr: `"not-header" is not a supported field`, + }, + { + name: "cannot match on source address and custom field", + entry: &ServiceResolverConfigEntry{ + Kind: ServiceResolver, + Name: "test", + LoadBalancer: LoadBalancer{ + Policy: "maglev", + HashPolicies: []HashPolicy{ + { + Field: "header", + SourceAddress: true, + }, + }, + }, + }, + validateErr: `A single hash policy cannot hash both a source address and a "header"`, + }, + { + name: "matchvalue not compatible with source address", + entry: &ServiceResolverConfigEntry{ + Kind: ServiceResolver, + Name: "test", + LoadBalancer: LoadBalancer{ + Policy: "maglev", + HashPolicies: []HashPolicy{ + { + FieldMatchValue: "X-Consul-Token", + SourceAddress: true, + }, + }, + }, + }, + validateErr: `A FieldMatchValue cannot be specified when hashing SourceAddress`, + }, + { + name: "field without match value", + entry: &ServiceResolverConfigEntry{ + Kind: ServiceResolver, + Name: "test", + LoadBalancer: LoadBalancer{ + Policy: "maglev", + HashPolicies: []HashPolicy{ + { + Field: "header", + }, + }, + }, + }, + validateErr: `Field "header" was specified without a FieldMatchValue`, + }, + { + name: "field without match value", + entry: &ServiceResolverConfigEntry{ + Kind: ServiceResolver, + Name: "test", + LoadBalancer: LoadBalancer{ + Policy: "maglev", + HashPolicies: []HashPolicy{ + { + FieldMatchValue: "my-cookie", + }, + }, + }, + }, + validateErr: `FieldMatchValue requires a Field to apply to`, + }, + { + name: "ring hash kitchen sink", + entry: &ServiceResolverConfigEntry{ + Kind: ServiceResolver, + Name: "test", + LoadBalancer: LoadBalancer{ + Policy: "ring_hash", + RingHashConfig: RingHashConfig{MaximumRingSize: 10, MinimumRingSize: 2}, + HashPolicies: []HashPolicy{ + { + Field: "cookie", + FieldMatchValue: "my-cookie", + }, + { + Field: "header", + FieldMatchValue: "alt-header", + Terminal: true, + }, + }, + }, + }, + }, + { + name: "least request kitchen sink", + entry: &ServiceResolverConfigEntry{ + Kind: ServiceResolver, + Name: "test", + LoadBalancer: LoadBalancer{ + Policy: "least_request", + LeastRequestConfig: LeastRequestConfig{ChoiceCount: 20}, + }, + }, + }, + } + + for _, tc := range cases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + err := tc.entry.Normalize() + if tc.normalizeErr != "" { + require.Error(t, err) + require.Contains(t, err.Error(), tc.normalizeErr) + return + } + require.NoError(t, err) + + if tc.check != nil { + tc.check(t, tc.entry) + } + + err = tc.entry.Validate() + if tc.validateErr != "" { + require.Error(t, err) + require.Contains(t, err.Error(), tc.validateErr) + return + } + require.NoError(t, err) + }) + } +} + func TestServiceSplitterConfigEntry(t *testing.T) { makesplitter := func(splits ...ServiceSplit) *ServiceSplitterConfigEntry { diff --git a/api/config_entry_discoverychain.go b/api/config_entry_discoverychain.go index f3994f0dd..0bfd3dde2 100644 --- a/api/config_entry_discoverychain.go +++ b/api/config_entry_discoverychain.go @@ -138,6 +138,10 @@ type ServiceResolverConfigEntry struct { Failover map[string]ServiceResolverFailover `json:",omitempty"` ConnectTimeout time.Duration `json:",omitempty" alias:"connect_timeout"` + // LoadBalancer determines the load balancing policy and configuration for services + // issuing requests to this upstream service. + LoadBalancer LoadBalancer `json:",omitempty" alias:"load_balancer"` + CreateIndex uint64 ModifyIndex uint64 } @@ -201,3 +205,64 @@ type ServiceResolverFailover struct { Namespace string `json:",omitempty"` Datacenters []string `json:",omitempty"` } + +// LoadBalancer determines the load balancing policy and configuration for services +// issuing requests to this upstream service. +type LoadBalancer struct { + // Policy is the load balancing policy used to select a host + Policy string `json:",omitempty"` + + // RingHashConfig contains configuration for the "ring_hash" policy type + RingHashConfig RingHashConfig `json:",omitempty" alias:"ring_hash_config"` + + // LeastRequestConfig contains configuration for the "least_request" policy type + LeastRequestConfig LeastRequestConfig `json:",omitempty" alias:"least_request_config"` + + // HashPolicies is a list of hash policies to use for hashing load balancing algorithms. + // Hash policies are evaluated individually and combined such that identical lists + // result in the same hash. + // If no hash policies are present, or none are successfully evaluated, + // then a random backend host will be selected. + HashPolicies []HashPolicy `json:",omitempty" alias:"hash_policies"` +} + +// RingHashConfig contains configuration for the "ring_hash" policy type +type RingHashConfig struct { + // MinimumRingSize determines the minimum number of hashes per destination host + MinimumRingSize uint64 `json:",omitempty" alias:"minimum_ring_size"` + + // MaximumRingSize determines the maximum number of hashes per destination host + MaximumRingSize uint64 `json:",omitempty" alias:"maximum_ring_size"` +} + +// LeastRequestConfig contains configuration for the "least_request" policy type +type LeastRequestConfig struct { + // ChoiceCount determines the number of random healthy hosts from which to select the one with the least requests. + ChoiceCount uint32 `json:",omitempty" alias:"choice_count"` +} + +// HashPolicy is a list of hash policies to use for hashing load balancing algorithms. +// Hash policies are evaluated individually and combined such that identical lists +// result in the same hash. +// If no hash policies are present, or none are successfully evaluated, +// then a random backend host will be selected. +type HashPolicy struct { + // Field is the attribute type to hash on. + // Must be one of "header","cookie", or "query_parameter". + // Cannot be specified along with SourceIP. + Field string `json:",omitempty"` + + // FieldMatchValue is the value to hash. + // ie. header name, cookie name, URL query parameter name + // Cannot be specified along with SourceIP. + FieldMatchValue string `json:",omitempty" alias:"field_value"` + + // SourceAddress determines whether the hash should be of the source IP rather than of a field and field value. + // Cannot be specified along with Field and FieldMatchValue. + SourceAddress bool `json:",omitempty" alias:"source_address"` + + // Terminal will short circuit the computation of the hash when multiple hash policies are present. + // If a hash is computed when a Terminal policy is evaluated, + // then that hash will be used and subsequent hash policies will be ignored. + Terminal bool `json:",omitempty"` +} diff --git a/api/config_entry_discoverychain_test.go b/api/config_entry_discoverychain_test.go index d01f7b628..0e77429bb 100644 --- a/api/config_entry_discoverychain_test.go +++ b/api/config_entry_discoverychain_test.go @@ -233,3 +233,105 @@ func TestAPI_ConfigEntry_DiscoveryChain(t *testing.T) { require.True(t, ok, "subtest %q failed so aborting remainder", name) } } + +func TestAPI_ConfigEntry_ServiceResolver_LoadBalancer(t *testing.T) { + t.Parallel() + c, s := makeClient(t) + defer s.Stop() + + config_entries := c.ConfigEntries() + + verifyResolver := func(t *testing.T, initial ConfigEntry) { + t.Helper() + require.IsType(t, &ServiceResolverConfigEntry{}, initial) + testEntry := initial.(*ServiceResolverConfigEntry) + + // set it + _, wm, err := config_entries.Set(testEntry, nil) + require.NoError(t, err) + require.NotNil(t, wm) + require.NotEqual(t, 0, wm.RequestTime) + + // get it + entry, qm, err := config_entries.Get(ServiceResolver, testEntry.Name, nil) + require.NoError(t, err) + require.NotNil(t, qm) + require.NotEqual(t, 0, qm.RequestTime) + + // verify it + readResolver, ok := entry.(*ServiceResolverConfigEntry) + require.True(t, ok) + readResolver.ModifyIndex = 0 // reset for Equals() + readResolver.CreateIndex = 0 // reset for Equals() + + require.Equal(t, testEntry, readResolver) + } + + // First set the necessary protocols to allow advanced routing features. + for _, service := range []string{ + "test-least-req", + "test-ring-hash", + } { + serviceDefaults := &ServiceConfigEntry{ + Kind: ServiceDefaults, + Name: service, + Protocol: "http", + } + _, _, err := config_entries.Set(serviceDefaults, nil) + require.NoError(t, err) + } + + // NOTE: Due to service graph validation, these have to happen in a specific order. + for _, tc := range []struct { + name string + entry ConfigEntry + verify func(t *testing.T, initial ConfigEntry) + }{ + { + name: "least-req", + entry: &ServiceResolverConfigEntry{ + Kind: ServiceResolver, + Name: "test-least-req", + Namespace: defaultNamespace, + LoadBalancer: LoadBalancer{ + Policy: "least_request", + LeastRequestConfig: LeastRequestConfig{ChoiceCount: 10}, + }, + }, + verify: verifyResolver, + }, + { + name: "ring-hash-with-policies", + entry: &ServiceResolverConfigEntry{ + Kind: ServiceResolver, + Name: "test-ring-hash", + Namespace: defaultNamespace, + LoadBalancer: LoadBalancer{ + Policy: "ring_hash", + RingHashConfig: RingHashConfig{ + MinimumRingSize: 1024 * 2, + MaximumRingSize: 1024 * 4, + }, + HashPolicies: []HashPolicy{ + { + Field: "header", + FieldMatchValue: "my-session-header", + Terminal: true, + }, + { + SourceAddress: true, + }, + }, + }, + }, + verify: verifyResolver, + }, + } { + tc := tc + name := fmt.Sprintf("%s:%s: %s", tc.entry.GetKind(), tc.entry.GetName(), tc.name) + ok := t.Run(name, func(t *testing.T) { + tc.verify(t, tc.entry) + }) + require.True(t, ok, "subtest %q failed so aborting remainder", name) + } +} From afb14b670564508b995cfecb57a4750356027be4 Mon Sep 17 00:00:00 2001 From: freddygv Date: Fri, 28 Aug 2020 13:11:04 -0600 Subject: [PATCH 02/20] Compile down LB policy to disco chain nodes --- agent/consul/discoverychain/compile.go | 11 ++ agent/consul/discoverychain/compile_test.go | 195 ++++++++++++++++++++ agent/structs/discovery_chain.go | 3 + 3 files changed, 209 insertions(+) diff --git a/agent/consul/discoverychain/compile.go b/agent/consul/discoverychain/compile.go index ca43b4da7..d94667787 100644 --- a/agent/consul/discoverychain/compile.go +++ b/agent/consul/discoverychain/compile.go @@ -707,6 +707,7 @@ func (c *compiler) getSplitterNode(sid structs.ServiceID) (*structs.DiscoveryGra // sanely if there is some sort of graph loop below. c.recordNode(splitNode) + var hasLB bool for _, split := range splitter.Splits { compiledSplit := &structs.DiscoverySplit{ Weight: split.Weight, @@ -739,6 +740,15 @@ func (c *compiler) getSplitterNode(sid structs.ServiceID) (*structs.DiscoveryGra return nil, err } compiledSplit.NextNode = node.MapKey() + + // There exists the possibility that a splitter may split between two distinct service names + // with distinct hash-based load balancer configs specified in their service resolvers. + // We cannot apply multiple hash policies to a splitter node's route action. + // Therefore, we attach the first hash-based load balancer config we encounter. + if !hasLB && node.LoadBalancer.IsHashBased() { + splitNode.LoadBalancer = node.LoadBalancer + hasLB = true + } } c.usesAdvancedRoutingFeatures = true @@ -851,6 +861,7 @@ RESOLVE_AGAIN: Target: target.ID, ConnectTimeout: connectTimeout, }, + LoadBalancer: resolver.LoadBalancer, } target.Subset = resolver.Subsets[target.ServiceSubset] diff --git a/agent/consul/discoverychain/compile_test.go b/agent/consul/discoverychain/compile_test.go index ac77600dc..e5aca02b4 100644 --- a/agent/consul/discoverychain/compile_test.go +++ b/agent/consul/discoverychain/compile_test.go @@ -51,6 +51,7 @@ func TestCompile(t *testing.T) { "default resolver with external sni": testcase_DefaultResolver_ExternalSNI(), "resolver with no entries and inferring defaults": testcase_DefaultResolver(), "default resolver with proxy defaults": testcase_DefaultResolver_WithProxyDefaults(), + "loadbalancer config": testcase_LBConfig(), "service redirect to service with default resolver is not a default chain": testcase_RedirectToDefaultResolverIsNotDefaultChain(), "all the bells and whistles": testcase_AllBellsAndWhistles(), @@ -1760,6 +1761,17 @@ func testcase_AllBellsAndWhistles() compileTestCase { "prod": {Filter: "ServiceMeta.env == prod"}, "qa": {Filter: "ServiceMeta.env == qa"}, }, + LoadBalancer: structs.LoadBalancer{ + Policy: "ring_hash", + RingHashConfig: structs.RingHashConfig{ + MaximumRingSize: 100, + }, + HashPolicies: []structs.HashPolicy{ + { + SourceAddress: true, + }, + }, + }, }, &structs.ServiceResolverConfigEntry{ Kind: "service-resolver", @@ -1821,6 +1833,17 @@ func testcase_AllBellsAndWhistles() compileTestCase { NextNode: "resolver:v3.main.default.dc1", }, }, + LoadBalancer: structs.LoadBalancer{ + Policy: "ring_hash", + RingHashConfig: structs.RingHashConfig{ + MaximumRingSize: 100, + }, + HashPolicies: []structs.HashPolicy{ + { + SourceAddress: true, + }, + }, + }, }, "resolver:prod.redirected.default.dc1": { Type: structs.DiscoveryGraphNodeTypeResolver, @@ -1829,6 +1852,17 @@ func testcase_AllBellsAndWhistles() compileTestCase { ConnectTimeout: 5 * time.Second, Target: "prod.redirected.default.dc1", }, + LoadBalancer: structs.LoadBalancer{ + Policy: "ring_hash", + RingHashConfig: structs.RingHashConfig{ + MaximumRingSize: 100, + }, + HashPolicies: []structs.HashPolicy{ + { + SourceAddress: true, + }, + }, + }, }, "resolver:v1.main.default.dc1": { Type: structs.DiscoveryGraphNodeTypeResolver, @@ -2219,6 +2253,167 @@ func testcase_CircularSplit() compileTestCase { } } +func testcase_LBConfig() compileTestCase { + entries := newEntries() + setServiceProtocol(entries, "foo", "http") + setServiceProtocol(entries, "bar", "http") + setServiceProtocol(entries, "baz", "http") + + entries.AddSplitters( + &structs.ServiceSplitterConfigEntry{ + Kind: "service-splitter", + Name: "main", + Splits: []structs.ServiceSplit{ + {Weight: 60, Service: "foo"}, + {Weight: 20, Service: "bar"}, + {Weight: 20, Service: "baz"}, + }, + }, + ) + + entries.AddResolvers( + &structs.ServiceResolverConfigEntry{ + Kind: "service-resolver", + Name: "foo", + LoadBalancer: structs.LoadBalancer{ + Policy: "least_request", + LeastRequestConfig: structs.LeastRequestConfig{ + ChoiceCount: 3, + }, + }, + }, + &structs.ServiceResolverConfigEntry{ + Kind: "service-resolver", + Name: "bar", + LoadBalancer: structs.LoadBalancer{ + Policy: "ring_hash", + RingHashConfig: structs.RingHashConfig{ + MaximumRingSize: 101, + }, + HashPolicies: []structs.HashPolicy{ + { + SourceAddress: true, + }, + }, + }, + }, + &structs.ServiceResolverConfigEntry{ + Kind: "service-resolver", + Name: "baz", + LoadBalancer: structs.LoadBalancer{ + Policy: "maglev", + HashPolicies: []structs.HashPolicy{ + { + Field: "cookie", + FieldMatchValue: "chocolate-chip", + Terminal: true, + }, + }, + }, + }, + ) + + expect := &structs.CompiledDiscoveryChain{ + Protocol: "http", + StartNode: "splitter:main.default", + Nodes: map[string]*structs.DiscoveryGraphNode{ + "splitter:main.default": { + Type: structs.DiscoveryGraphNodeTypeSplitter, + Name: "main.default", + Splits: []*structs.DiscoverySplit{ + { + Weight: 60, + NextNode: "resolver:foo.default.dc1", + }, + { + Weight: 20, + NextNode: "resolver:bar.default.dc1", + }, + { + Weight: 20, + NextNode: "resolver:baz.default.dc1", + }, + }, + // The LB config from bar is attached because splitters only care about hash-based policies, + // and it's the config from bar not baz because we pick the first one we encounter in the Splits. + LoadBalancer: structs.LoadBalancer{ + Policy: "ring_hash", + RingHashConfig: structs.RingHashConfig{ + MaximumRingSize: 101, + }, + HashPolicies: []structs.HashPolicy{ + { + SourceAddress: true, + }, + }, + }, + }, + // Each service's LB config is passed down from the service-resolver to the resolver node + "resolver:foo.default.dc1": { + Type: structs.DiscoveryGraphNodeTypeResolver, + Name: "foo.default.dc1", + Resolver: &structs.DiscoveryResolver{ + Default: true, + ConnectTimeout: 5 * time.Second, + Target: "foo.default.dc1", + }, + LoadBalancer: structs.LoadBalancer{ + Policy: "least_request", + LeastRequestConfig: structs.LeastRequestConfig{ + ChoiceCount: 3, + }, + }, + }, + "resolver:bar.default.dc1": { + Type: structs.DiscoveryGraphNodeTypeResolver, + Name: "bar.default.dc1", + Resolver: &structs.DiscoveryResolver{ + Default: true, + ConnectTimeout: 5 * time.Second, + Target: "bar.default.dc1", + }, + LoadBalancer: structs.LoadBalancer{ + Policy: "ring_hash", + RingHashConfig: structs.RingHashConfig{ + MaximumRingSize: 101, + }, + HashPolicies: []structs.HashPolicy{ + { + SourceAddress: true, + }, + }, + }, + }, + "resolver:baz.default.dc1": { + Type: structs.DiscoveryGraphNodeTypeResolver, + Name: "baz.default.dc1", + Resolver: &structs.DiscoveryResolver{ + Default: true, + ConnectTimeout: 5 * time.Second, + Target: "baz.default.dc1", + }, + LoadBalancer: structs.LoadBalancer{ + Policy: "maglev", + HashPolicies: []structs.HashPolicy{ + { + Field: "cookie", + FieldMatchValue: "chocolate-chip", + Terminal: true, + }, + }, + }, + }, + }, + Targets: map[string]*structs.DiscoveryTarget{ + "foo.default.dc1": newTarget("foo", "", "default", "dc1", nil), + "bar.default.dc1": newTarget("bar", "", "default", "dc1", nil), + "baz.default.dc1": newTarget("baz", "", "default", "dc1", nil), + }, + } + + return compileTestCase{entries: entries, expect: expect} +} + func newSimpleRoute(name string, muts ...func(*structs.ServiceRoute)) structs.ServiceRoute { r := structs.ServiceRoute{ Match: &structs.ServiceRouteMatch{ diff --git a/agent/structs/discovery_chain.go b/agent/structs/discovery_chain.go index e5a3f7228..85ee5965c 100644 --- a/agent/structs/discovery_chain.go +++ b/agent/structs/discovery_chain.go @@ -107,6 +107,9 @@ type DiscoveryGraphNode struct { // fields for Type==resolver Resolver *DiscoveryResolver `json:",omitempty"` + + // shared by Type==resolver || Type==splitter + LoadBalancer LoadBalancer `json:",omitempty"` } func (s *DiscoveryGraphNode) IsRouter() bool { From 8f470b30d7fa4aef9f7eac08c225af9ebd7ebf4d Mon Sep 17 00:00:00 2001 From: freddygv Date: Fri, 28 Aug 2020 13:11:55 -0600 Subject: [PATCH 03/20] Log error as error --- agent/xds/server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agent/xds/server.go b/agent/xds/server.go index 09f3c1d3f..8eaa299d9 100644 --- a/agent/xds/server.go +++ b/agent/xds/server.go @@ -156,7 +156,7 @@ func (s *Server) StreamAggregatedResources(stream ADSStream) error { err := s.process(stream, reqCh) if err != nil { - s.Logger.Debug("Error handling ADS stream", "error", err) + s.Logger.Error("Error handling ADS stream", "error", err) } // prevents writing to a closed channel if send failed on blocked recv From 194d34b09dc6824e007a53db12216b276f330a78 Mon Sep 17 00:00:00 2001 From: freddygv Date: Fri, 28 Aug 2020 14:27:40 -0600 Subject: [PATCH 04/20] Pass LB config to Envoy via xDS --- agent/proxycfg/testing.go | 55 ++++- agent/xds/clusters.go | 76 +++++- agent/xds/clusters_test.go | 180 +++++++++++++- agent/xds/listeners.go | 9 +- agent/xds/routes.go | 188 ++++++++++++-- agent/xds/routes_test.go | 230 ++++++++++++++++++ ...t-proxy-lb-in-resolver.envoy-1-12-x.golden | 175 +++++++++++++ ...t-proxy-lb-in-resolver.envoy-1-13-x.golden | 175 +++++++++++++ ...t-proxy-lb-in-resolver.envoy-1-14-x.golden | 175 +++++++++++++ ...t-proxy-lb-in-resolver.envoy-1-15-x.golden | 175 +++++++++++++ ...ingress-lb-in-resolver.envoy-1-12-x.golden | 108 ++++++++ ...ingress-lb-in-resolver.envoy-1-13-x.golden | 108 ++++++++ ...ingress-lb-in-resolver.envoy-1-14-x.golden | 108 ++++++++ ...ingress-lb-in-resolver.envoy-1-15-x.golden | 108 ++++++++ ...ateway-hash-lb-ignored.envoy-1-12-x.golden | 151 ++++++++++++ ...ateway-hash-lb-ignored.envoy-1-13-x.golden | 151 ++++++++++++ ...ateway-hash-lb-ignored.envoy-1-14-x.golden | 151 ++++++++++++ ...ateway-hash-lb-ignored.envoy-1-15-x.golden | 151 ++++++++++++ ...y-non-hash-lb-injected.envoy-1-12-x.golden | 163 +++++++++++++ ...y-non-hash-lb-injected.envoy-1-13-x.golden | 163 +++++++++++++ ...y-non-hash-lb-injected.envoy-1-14-x.golden | 163 +++++++++++++ ...y-non-hash-lb-injected.envoy-1-15-x.golden | 163 +++++++++++++ ...ting-gateway-lb-config.envoy-1-12-x.golden | 224 +++++++++++++++++ ...ting-gateway-lb-config.envoy-1-13-x.golden | 224 +++++++++++++++++ ...ting-gateway-lb-config.envoy-1-14-x.golden | 224 +++++++++++++++++ ...ting-gateway-lb-config.envoy-1-15-x.golden | 224 +++++++++++++++++ ...m-and-tagged-addresses.envoy-1-12-x.golden | 70 ++++-- ...m-and-tagged-addresses.envoy-1-13-x.golden | 70 ++++-- ...m-and-tagged-addresses.envoy-1-14-x.golden | 70 ++++-- ...m-and-tagged-addresses.envoy-1-15-x.golden | 70 ++++-- ...ng-gateway-no-api-cert.envoy-1-12-x.golden | 35 ++- ...ng-gateway-no-api-cert.envoy-1-13-x.golden | 35 ++- ...ng-gateway-no-api-cert.envoy-1-14-x.golden | 35 ++- ...ng-gateway-no-api-cert.envoy-1-15-x.golden | 35 ++- ...ateway-service-subsets.envoy-1-12-x.golden | 105 +++++--- ...ateway-service-subsets.envoy-1-13-x.golden | 105 +++++--- ...ateway-service-subsets.envoy-1-14-x.golden | 105 +++++--- ...ateway-service-subsets.envoy-1-15-x.golden | 105 +++++--- .../terminating-gateway.envoy-1-12-x.golden | 35 ++- .../terminating-gateway.envoy-1-13-x.golden | 35 ++- .../terminating-gateway.envoy-1-14-x.golden | 35 ++- .../terminating-gateway.envoy-1-15-x.golden | 35 ++- ...t-proxy-lb-in-resolver.envoy-1-12-x.golden | 61 +++++ ...t-proxy-lb-in-resolver.envoy-1-13-x.golden | 61 +++++ ...t-proxy-lb-in-resolver.envoy-1-14-x.golden | 61 +++++ ...t-proxy-lb-in-resolver.envoy-1-15-x.golden | 61 +++++ ...ingress-lb-in-resolver.envoy-1-12-x.golden | 62 +++++ ...ingress-lb-in-resolver.envoy-1-13-x.golden | 62 +++++ ...ingress-lb-in-resolver.envoy-1-14-x.golden | 62 +++++ ...ingress-lb-in-resolver.envoy-1-15-x.golden | 62 +++++ ...ting-gateway-lb-config.envoy-1-12-x.golden | 133 ++++++++++ ...ting-gateway-lb-config.envoy-1-13-x.golden | 133 ++++++++++ ...ting-gateway-lb-config.envoy-1-14-x.golden | 133 ++++++++++ ...ting-gateway-lb-config.envoy-1-15-x.golden | 133 ++++++++++ 54 files changed, 5719 insertions(+), 307 deletions(-) create mode 100644 agent/xds/testdata/clusters/connect-proxy-lb-in-resolver.envoy-1-12-x.golden create mode 100644 agent/xds/testdata/clusters/connect-proxy-lb-in-resolver.envoy-1-13-x.golden create mode 100644 agent/xds/testdata/clusters/connect-proxy-lb-in-resolver.envoy-1-14-x.golden create mode 100644 agent/xds/testdata/clusters/connect-proxy-lb-in-resolver.envoy-1-15-x.golden create mode 100644 agent/xds/testdata/clusters/ingress-lb-in-resolver.envoy-1-12-x.golden create mode 100644 agent/xds/testdata/clusters/ingress-lb-in-resolver.envoy-1-13-x.golden create mode 100644 agent/xds/testdata/clusters/ingress-lb-in-resolver.envoy-1-14-x.golden create mode 100644 agent/xds/testdata/clusters/ingress-lb-in-resolver.envoy-1-15-x.golden create mode 100644 agent/xds/testdata/clusters/mesh-gateway-hash-lb-ignored.envoy-1-12-x.golden create mode 100644 agent/xds/testdata/clusters/mesh-gateway-hash-lb-ignored.envoy-1-13-x.golden create mode 100644 agent/xds/testdata/clusters/mesh-gateway-hash-lb-ignored.envoy-1-14-x.golden create mode 100644 agent/xds/testdata/clusters/mesh-gateway-hash-lb-ignored.envoy-1-15-x.golden create mode 100644 agent/xds/testdata/clusters/mesh-gateway-non-hash-lb-injected.envoy-1-12-x.golden create mode 100644 agent/xds/testdata/clusters/mesh-gateway-non-hash-lb-injected.envoy-1-13-x.golden create mode 100644 agent/xds/testdata/clusters/mesh-gateway-non-hash-lb-injected.envoy-1-14-x.golden create mode 100644 agent/xds/testdata/clusters/mesh-gateway-non-hash-lb-injected.envoy-1-15-x.golden create mode 100644 agent/xds/testdata/clusters/terminating-gateway-lb-config.envoy-1-12-x.golden create mode 100644 agent/xds/testdata/clusters/terminating-gateway-lb-config.envoy-1-13-x.golden create mode 100644 agent/xds/testdata/clusters/terminating-gateway-lb-config.envoy-1-14-x.golden create mode 100644 agent/xds/testdata/clusters/terminating-gateway-lb-config.envoy-1-15-x.golden create mode 100644 agent/xds/testdata/routes/connect-proxy-lb-in-resolver.envoy-1-12-x.golden create mode 100644 agent/xds/testdata/routes/connect-proxy-lb-in-resolver.envoy-1-13-x.golden create mode 100644 agent/xds/testdata/routes/connect-proxy-lb-in-resolver.envoy-1-14-x.golden create mode 100644 agent/xds/testdata/routes/connect-proxy-lb-in-resolver.envoy-1-15-x.golden create mode 100644 agent/xds/testdata/routes/ingress-lb-in-resolver.envoy-1-12-x.golden create mode 100644 agent/xds/testdata/routes/ingress-lb-in-resolver.envoy-1-13-x.golden create mode 100644 agent/xds/testdata/routes/ingress-lb-in-resolver.envoy-1-14-x.golden create mode 100644 agent/xds/testdata/routes/ingress-lb-in-resolver.envoy-1-15-x.golden create mode 100644 agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-12-x.golden create mode 100644 agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-13-x.golden create mode 100644 agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-14-x.golden create mode 100644 agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-15-x.golden diff --git a/agent/proxycfg/testing.go b/agent/proxycfg/testing.go index a534b3a7c..96a4c8749 100644 --- a/agent/proxycfg/testing.go +++ b/agent/proxycfg/testing.go @@ -765,6 +765,10 @@ func TestConfigSnapshotDiscoveryChainWithRouter(t testing.T) *ConfigSnapshot { return testConfigSnapshotDiscoveryChain(t, "chain-and-router") } +func TestConfigSnapshotDiscoveryChainWithLB(t testing.T) *ConfigSnapshot { + return testConfigSnapshotDiscoveryChain(t, "lb-resolver") +} + func testConfigSnapshotDiscoveryChain(t testing.T, variation string, additionalEntries ...structs.ConfigEntry) *ConfigSnapshot { roots, leaf := TestCerts(t) @@ -1250,6 +1254,50 @@ func setupTestVariationConfigEntriesAndSnapshot( }, }, ) + case "lb-resolver": + entries = append(entries, + &structs.ProxyConfigEntry{ + Kind: structs.ProxyDefaults, + Name: structs.ProxyConfigGlobal, + Config: map[string]interface{}{ + "protocol": "http", + }, + }, + &structs.ServiceSplitterConfigEntry{ + Kind: structs.ServiceSplitter, + Name: "db", + Splits: []structs.ServiceSplit{ + {Weight: 95.5, Service: "something-else"}, + {Weight: 4.5, Service: "db"}, + }, + }, + &structs.ServiceResolverConfigEntry{ + Kind: structs.ServiceResolver, + Name: "db", + LoadBalancer: structs.LoadBalancer{ + Policy: "ring_hash", + RingHashConfig: structs.RingHashConfig{ + MinimumRingSize: 20, + MaximumRingSize: 30, + }, + HashPolicies: []structs.HashPolicy{ + { + Field: "cookie", + FieldMatchValue: "chocolate-chip", + Terminal: true, + }, + { + Field: "header", + FieldMatchValue: "x-user-id", + }, + { + SourceAddress: true, + Terminal: true, + }, + }, + }, + }, + ) case "http-multiple-services": default: t.Fatalf("unexpected variation: %q", variation) @@ -1348,6 +1396,7 @@ func setupTestVariationConfigEntriesAndSnapshot( snap.WatchedUpstreamEndpoints["bar"] = map[string]structs.CheckServiceNodes{ "bar.default.dc1": TestUpstreamNodesAlternate(t), } + case "lb-resolver": default: t.Fatalf("unexpected variation: %q", variation) return ConfigSnapshotUpstreams{} @@ -1558,6 +1607,10 @@ func TestConfigSnapshotIngressGatewayNoServices(t testing.T) *ConfigSnapshot { return testConfigSnapshotIngressGateway(t, false, "tcp", "default") } +func TestConfigSnapshotIngressWithLB(t testing.T) *ConfigSnapshot { + return testConfigSnapshotIngressGateway(t, true, "http", "lb-resolver") +} + func TestConfigSnapshotIngressDiscoveryChainWithEntries(t testing.T, additionalEntries ...structs.ConfigEntry) *ConfigSnapshot { return testConfigSnapshotIngressGateway(t, true, "http", "simple", additionalEntries...) } @@ -1828,7 +1881,7 @@ func testConfigSnapshotTerminatingGateway(t testing.T, populateServices bool) *C snap.TerminatingGateway.ServiceConfigs = map[structs.ServiceName]*structs.ServiceConfigResponse{ web: { - ProxyConfig: map[string]interface{}{"protocol": "tcp"}, + ProxyConfig: map[string]interface{}{"protocol": "http"}, }, api: { ProxyConfig: map[string]interface{}{"protocol": "tcp"}, diff --git a/agent/xds/clusters.go b/agent/xds/clusters.go index 928fe930e..8bad63b63 100644 --- a/agent/xds/clusters.go +++ b/agent/xds/clusters.go @@ -16,6 +16,7 @@ import ( "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" "github.com/golang/protobuf/ptypes/any" + "github.com/golang/protobuf/ptypes/wrappers" "github.com/hashicorp/consul/agent/connect" "github.com/hashicorp/consul/agent/proxycfg" "github.com/hashicorp/consul/agent/structs" @@ -205,9 +206,13 @@ func (s *Server) makeGatewayServiceClusters(cfgSnap *proxycfg.ConfigSnapshot) ([ clusterName := connect.ServiceSNI(svc.Name, "", svc.NamespaceOrDefault(), cfgSnap.Datacenter, cfgSnap.Roots.TrustDomain) resolver, hasResolver := resolvers[svc] + var lb structs.LoadBalancer + if !hasResolver { // Use a zero value resolver with no timeout and no subsets resolver = &structs.ServiceResolverConfigEntry{} + } else { + lb = resolver.LoadBalancer } // When making service clusters we only pass endpoints with hostnames if the kind is a terminating gateway @@ -223,8 +228,23 @@ func (s *Server) makeGatewayServiceClusters(cfgSnap *proxycfg.ConfigSnapshot) ([ } cluster := s.makeGatewayCluster(cfgSnap, opts) - if cfgSnap.Kind == structs.ServiceKindTerminatingGateway { + switch cfgSnap.Kind { + case structs.ServiceKindTerminatingGateway: injectTerminatingGatewayTLSContext(cfgSnap, cluster, svc) + + err := injectLBToCluster(lb, cluster) + if err != nil { + return nil, fmt.Errorf("failed to apply load balancer configuration to cluster %q: %v", clusterName, err) + } + case structs.ServiceKindMeshGateway: + // We can't apply hash based LB config to mesh gateways because they rely on inspecting HTTP attributes + // and mesh gateways do not decrypt traffic + if !lb.IsHashBased() { + err := injectLBToCluster(lb, cluster) + if err != nil { + return nil, fmt.Errorf("failed to apply load balancer configuration to cluster %q: %v", clusterName, err) + } + } } clusters = append(clusters, cluster) @@ -243,8 +263,23 @@ func (s *Server) makeGatewayServiceClusters(cfgSnap *proxycfg.ConfigSnapshot) ([ } cluster := s.makeGatewayCluster(cfgSnap, opts) - if cfgSnap.Kind == structs.ServiceKindTerminatingGateway { + switch cfgSnap.Kind { + case structs.ServiceKindTerminatingGateway: injectTerminatingGatewayTLSContext(cfgSnap, cluster, svc) + + err := injectLBToCluster(lb, cluster) + if err != nil { + return nil, fmt.Errorf("failed to apply load balancer configuration to cluster %q: %v", clusterName, err) + } + case structs.ServiceKindMeshGateway: + // We can't apply hash based LB config to mesh gateways because they rely on inspecting HTTP attributes + // and mesh gateways do not decrypt traffic + if !lb.IsHashBased() { + err := injectLBToCluster(lb, cluster) + if err != nil { + return nil, fmt.Errorf("failed to apply load balancer configuration to cluster %q: %v", clusterName, err) + } + } } clusters = append(clusters, cluster) } @@ -421,7 +456,7 @@ func (s *Server) makeUpstreamClustersForDiscoveryChain( return nil, err } } else { - s.Logger.Warn("ignoring escape hatch setting, because a discovery chain is configued for", + s.Logger.Warn("ignoring escape hatch setting, because a discovery chain is configured for", "discovery chain", chain.ServiceName, "upstream", upstream.Identifier(), "envoy_cluster_json", chain.ServiceName) } @@ -481,6 +516,10 @@ func (s *Server) makeUpstreamClustersForDiscoveryChain( OutlierDetection: cfg.PassiveHealthCheck.AsOutlierDetection(), } + if err := injectLBToCluster(node.LoadBalancer, c); err != nil { + return nil, fmt.Errorf("failed to apply load balancer configuration to cluster %q: %v", sni, err) + } + proto := cfg.Protocol if proto == "" { proto = chain.Protocol @@ -518,6 +557,37 @@ func (s *Server) makeUpstreamClustersForDiscoveryChain( return out, nil } +func injectLBToCluster(l structs.LoadBalancer, c *envoy.Cluster) error { + switch l.Policy { + case "": + return nil + case "least_request": + c.LbPolicy = envoy.Cluster_LEAST_REQUEST + c.LbConfig = &envoy.Cluster_LeastRequestLbConfig_{ + LeastRequestLbConfig: &envoy.Cluster_LeastRequestLbConfig{ + ChoiceCount: &wrappers.UInt32Value{Value: l.LeastRequestConfig.ChoiceCount}, + }, + } + case "round_robin": + c.LbPolicy = envoy.Cluster_ROUND_ROBIN + case "random": + c.LbPolicy = envoy.Cluster_RANDOM + case "ring_hash": + c.LbPolicy = envoy.Cluster_RING_HASH + c.LbConfig = &envoy.Cluster_RingHashLbConfig_{ + RingHashLbConfig: &envoy.Cluster_RingHashLbConfig{ + MinimumRingSize: &wrappers.UInt64Value{Value: l.RingHashConfig.MinimumRingSize}, + MaximumRingSize: &wrappers.UInt64Value{Value: l.RingHashConfig.MaximumRingSize}, + }, + } + case "maglev": + c.LbPolicy = envoy.Cluster_MAGLEV + default: + return fmt.Errorf("unsupported load balancer policy %q for cluster %q", l.Policy, c.Name) + } + return nil +} + // makeClusterFromUserConfig returns the listener config decoded from an // arbitrary proto3 json format string or an error if it's invalid. // diff --git a/agent/xds/clusters_test.go b/agent/xds/clusters_test.go index 856ab6745..14714feb7 100644 --- a/agent/xds/clusters_test.go +++ b/agent/xds/clusters_test.go @@ -2,6 +2,7 @@ package xds import ( "bytes" + "github.com/golang/protobuf/ptypes/wrappers" "path/filepath" "sort" "testing" @@ -230,6 +231,11 @@ func TestClustersFromSnapshot(t *testing.T) { create: proxycfg.TestConfigSnapshotDiscoveryChain_SplitterWithResolverRedirectMultiDC, setup: nil, }, + { + name: "connect-proxy-lb-in-resolver", + create: proxycfg.TestConfigSnapshotDiscoveryChainWithLB, + setup: nil, + }, { name: "expose-paths-local-app-paths", create: proxycfg.TestConfigSnapshotExposeConfig, @@ -344,6 +350,61 @@ func TestClustersFromSnapshot(t *testing.T) { } }, }, + { + name: "mesh-gateway-non-hash-lb-injected", + create: proxycfg.TestConfigSnapshotMeshGateway, + setup: func(snap *proxycfg.ConfigSnapshot) { + snap.MeshGateway.ServiceResolvers = map[structs.ServiceName]*structs.ServiceResolverConfigEntry{ + structs.NewServiceName("bar", nil): { + Kind: structs.ServiceResolver, + Name: "bar", + Subsets: map[string]structs.ServiceResolverSubset{ + "v1": { + Filter: "Service.Meta.Version == 1", + }, + "v2": { + Filter: "Service.Meta.Version == 2", + OnlyPassing: true, + }, + }, + LoadBalancer: structs.LoadBalancer{ + Policy: "least_request", + LeastRequestConfig: structs.LeastRequestConfig{ + ChoiceCount: 5, + }, + }, + }, + } + }, + }, + { + name: "mesh-gateway-hash-lb-ignored", + create: proxycfg.TestConfigSnapshotMeshGateway, + setup: func(snap *proxycfg.ConfigSnapshot) { + snap.MeshGateway.ServiceResolvers = map[structs.ServiceName]*structs.ServiceResolverConfigEntry{ + structs.NewServiceName("bar", nil): { + Kind: structs.ServiceResolver, + Name: "bar", + Subsets: map[string]structs.ServiceResolverSubset{ + "v1": { + Filter: "Service.Meta.Version == 1", + }, + "v2": { + Filter: "Service.Meta.Version == 2", + OnlyPassing: true, + }, + }, + LoadBalancer: structs.LoadBalancer{ + Policy: "ring_hash", + RingHashConfig: structs.RingHashConfig{ + MinimumRingSize: 20, + MaximumRingSize: 50, + }, + }, + }, + } + }, + }, { name: "ingress-gateway", create: proxycfg.TestConfigSnapshotIngressGateway, @@ -419,6 +480,11 @@ func TestClustersFromSnapshot(t *testing.T) { create: proxycfg.TestConfigSnapshotIngress_SplitterWithResolverRedirectMultiDC, setup: nil, }, + { + name: "ingress-lb-in-resolver", + create: proxycfg.TestConfigSnapshotIngressWithLB, + setup: nil, + }, { name: "terminating-gateway", create: proxycfg.TestConfigSnapshotTerminatingGateway, @@ -521,6 +587,35 @@ func TestClustersFromSnapshot(t *testing.T) { } }, }, + { + name: "terminating-gateway-lb-config", + create: proxycfg.TestConfigSnapshotTerminatingGateway, + setup: func(snap *proxycfg.ConfigSnapshot) { + snap.TerminatingGateway.ServiceResolvers = map[structs.ServiceName]*structs.ServiceResolverConfigEntry{ + structs.NewServiceName("web", nil): { + Kind: structs.ServiceResolver, + Name: "web", + DefaultSubset: "v2", + Subsets: map[string]structs.ServiceResolverSubset{ + "v1": { + Filter: "Service.Meta.Version == 1", + }, + "v2": { + Filter: "Service.Meta.Version == 2", + OnlyPassing: true, + }, + }, + LoadBalancer: structs.LoadBalancer{ + Policy: "ring_hash", + RingHashConfig: structs.RingHashConfig{ + MinimumRingSize: 20, + MaximumRingSize: 50, + }, + }, + }, + } + }, + }, { name: "ingress-multiple-listeners-duplicate-service", create: proxycfg.TestConfigSnapshotIngress_MultipleListenersDuplicateService, @@ -707,7 +802,7 @@ var customAppClusterJSONTpl = `{ "hosts": [ { "socketAddress": { - "address": "127.0.0.1", + "address": "127.0.0.1", "portValue": 8080 } } @@ -739,3 +834,86 @@ func setupTLSRootsAndLeaf(t *testing.T, snap *proxycfg.ConfigSnapshot) { snap.Roots.Roots[0].RootCert = golden(t, "test-root-cert", "", "") } } + +func TestLoadBalancer_injectLBToCluster(t *testing.T) { + var tests = []struct { + name string + lb structs.LoadBalancer + expected envoy.Cluster + }{ + { + name: "skip empty", + lb: structs.LoadBalancer{ + Policy: "", + }, + expected: envoy.Cluster{}, + }, + { + name: "round_robin", + lb: structs.LoadBalancer{ + Policy: "round_robin", + }, + expected: envoy.Cluster{LbPolicy: envoy.Cluster_ROUND_ROBIN}, + }, + { + name: "random", + lb: structs.LoadBalancer{ + Policy: "random", + }, + expected: envoy.Cluster{LbPolicy: envoy.Cluster_RANDOM}, + }, + { + name: "maglev", + lb: structs.LoadBalancer{ + Policy: "maglev", + }, + expected: envoy.Cluster{LbPolicy: envoy.Cluster_MAGLEV}, + }, + { + name: "ring_hash", + lb: structs.LoadBalancer{ + Policy: "ring_hash", + RingHashConfig: structs.RingHashConfig{ + MinimumRingSize: 3, + MaximumRingSize: 7, + }, + }, + expected: envoy.Cluster{ + LbPolicy: envoy.Cluster_RING_HASH, + LbConfig: &envoy.Cluster_RingHashLbConfig_{ + RingHashLbConfig: &envoy.Cluster_RingHashLbConfig{ + MinimumRingSize: &wrappers.UInt64Value{Value: 3}, + MaximumRingSize: &wrappers.UInt64Value{Value: 7}, + }, + }, + }, + }, + { + name: "least_request", + lb: structs.LoadBalancer{ + Policy: "least_request", + LeastRequestConfig: structs.LeastRequestConfig{ + ChoiceCount: 3, + }, + }, + expected: envoy.Cluster{ + LbPolicy: envoy.Cluster_LEAST_REQUEST, + LbConfig: &envoy.Cluster_LeastRequestLbConfig_{ + LeastRequestLbConfig: &envoy.Cluster_LeastRequestLbConfig{ + ChoiceCount: &wrappers.UInt32Value{Value: 3}, + }, + }, + }, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + var c envoy.Cluster + err := injectLBToCluster(tc.lb, &c) + require.NoError(t, err) + + require.Equal(t, tc.expected, c) + }) + } +} diff --git a/agent/xds/listeners.go b/agent/xds/listeners.go index ae78ffa9d..cfdfd4d7f 100644 --- a/agent/xds/listeners.go +++ b/agent/xds/listeners.go @@ -820,7 +820,6 @@ func (s *Server) makeFilterChainTerminatingGateway( // HTTP filter to do intention checks here instead. statPrefix := fmt.Sprintf("terminating_gateway_%s_%s_", service.NamespaceOrDefault(), service.Name) opts := listenerFilterOpts{ - useRDS: false, protocol: protocol, filterName: listener, cluster: cluster, @@ -838,6 +837,9 @@ func (s *Server) makeFilterChainTerminatingGateway( if err != nil { return nil, err } + + opts.cluster = "" + opts.useRDS = true } filter, err := makeListenerFilter(opts) @@ -1283,11 +1285,12 @@ func makeEnvoyHTTPFilter(name string, cfg proto.Message) (*envoyhttp.HttpFilter, func makeCommonTLSContextFromLeaf(cfgSnap *proxycfg.ConfigSnapshot, leaf *structs.IssuedCert) *envoyauth.CommonTlsContext { // Concatenate all the root PEMs into one. - // TODO(banks): verify this actually works with Envoy (docs are not clear). - rootPEMS := "" if cfgSnap.Roots == nil { return nil } + + // TODO(banks): verify this actually works with Envoy (docs are not clear). + rootPEMS := "" for _, root := range cfgSnap.Roots.Roots { rootPEMS += root.RootCert } diff --git a/agent/xds/routes.go b/agent/xds/routes.go index a7660d168..f7f991f7e 100644 --- a/agent/xds/routes.go +++ b/agent/xds/routes.go @@ -11,6 +11,7 @@ import ( envoymatcher "github.com/envoyproxy/go-control-plane/envoy/type/matcher" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" + "github.com/hashicorp/consul/agent/connect" "github.com/hashicorp/consul/agent/proxycfg" "github.com/hashicorp/consul/agent/structs" ) @@ -24,28 +25,103 @@ func routesFromSnapshot(cInfo connectionInfo, cfgSnap *proxycfg.ConfigSnapshot) switch cfgSnap.Kind { case structs.ServiceKindConnectProxy: - return routesFromSnapshotConnectProxy(cInfo, cfgSnap) + return routesForConnectProxy(cInfo, cfgSnap.Proxy.Upstreams, cfgSnap.ConnectProxy.DiscoveryChain) case structs.ServiceKindIngressGateway: - return routesFromSnapshotIngressGateway(cInfo, cfgSnap) + return routesForIngressGateway(cInfo, cfgSnap.IngressGateway.Upstreams, cfgSnap.IngressGateway.DiscoveryChain) + case structs.ServiceKindTerminatingGateway: + return routesFromSnapshotTerminatingGateway(cInfo, cfgSnap) default: return nil, fmt.Errorf("Invalid service kind: %v", cfgSnap.Kind) } } -// routesFromSnapshotConnectProxy returns the xDS API representation of the -// "routes" in the snapshot. -func routesFromSnapshotConnectProxy(cInfo connectionInfo, cfgSnap *proxycfg.ConfigSnapshot) ([]proto.Message, error) { +// routesFromSnapshotTerminatingGateway returns the xDS API representation of the "routes" in the snapshot. +// For any HTTP service we will return a default route. +func routesFromSnapshotTerminatingGateway(_ connectionInfo, cfgSnap *proxycfg.ConfigSnapshot) ([]proto.Message, error) { if cfgSnap == nil { return nil, errors.New("nil config given") } var resources []proto.Message - for _, u := range cfgSnap.Proxy.Upstreams { + for svc := range cfgSnap.TerminatingGateway.ServiceGroups { + clusterName := connect.ServiceSNI(svc.Name, "", svc.NamespaceOrDefault(), cfgSnap.Datacenter, cfgSnap.Roots.TrustDomain) + resolver, hasResolver := cfgSnap.TerminatingGateway.ServiceResolvers[svc] + + svcConfig := cfgSnap.TerminatingGateway.ServiceConfigs[svc] + + cfg, err := ParseProxyConfig(svcConfig.ProxyConfig) + if err != nil || cfg.Protocol != "http" { + // Routes can only be defined for HTTP services + continue + } + + if !hasResolver { + // Use a zero value resolver with no timeout and no subsets + resolver = &structs.ServiceResolverConfigEntry{} + } + route, err := makeNamedDefaultRouteWithLB(clusterName, resolver.LoadBalancer) + if err != nil { + continue + } + resources = append(resources, route) + + // If there is a service-resolver for this service then also setup routes for each subset + for name := range resolver.Subsets { + clusterName = connect.ServiceSNI(svc.Name, name, svc.NamespaceOrDefault(), cfgSnap.Datacenter, cfgSnap.Roots.TrustDomain) + route, err := makeNamedDefaultRouteWithLB(clusterName, resolver.LoadBalancer) + if err != nil { + continue + } + resources = append(resources, route) + } + } + + // TODO(rb): make sure we don't generate an empty result + return resources, nil +} + +func makeNamedDefaultRouteWithLB(clusterName string, lb structs.LoadBalancer) (*envoy.RouteConfiguration, error) { + action := makeRouteActionFromName(clusterName) + if err := injectLBToRouteAction(lb, action.Route); err != nil { + return nil, fmt.Errorf("failed to apply load balancer configuration to route action: %v", err) + } + + return &envoy.RouteConfiguration{ + Name: clusterName, + VirtualHosts: []*envoyroute.VirtualHost{ + { + Name: clusterName, + Domains: []string{"*"}, + Routes: []*envoyroute.Route{ + { + Match: makeDefaultRouteMatch(), + Action: action, + }, + }, + }, + }, + // ValidateClusters defaults to true when defined statically and false + // when done via RDS. Re-set the sane value of true to prevent + // null-routing traffic. + ValidateClusters: makeBoolValue(true), + }, nil +} + +// routesFromSnapshotConnectProxy returns the xDS API representation of the +// "routes" in the snapshot. +func routesForConnectProxy( + cInfo connectionInfo, + upstreams structs.Upstreams, + chains map[string]*structs.CompiledDiscoveryChain, +) ([]proto.Message, error) { + + var resources []proto.Message + for _, u := range upstreams { upstreamID := u.Identifier() var chain *structs.CompiledDiscoveryChain if u.DestinationType != structs.UpstreamDestTypePreparedQuery { - chain = cfgSnap.ConnectProxy.DiscoveryChain[upstreamID] + chain = chains[upstreamID] } if chain == nil || chain.IsDefault() { @@ -72,15 +148,16 @@ func routesFromSnapshotConnectProxy(cInfo connectionInfo, cfgSnap *proxycfg.Conf return resources, nil } -// routesFromSnapshotIngressGateway returns the xDS API representation of the +// routesForIngressGateway returns the xDS API representation of the // "routes" in the snapshot. -func routesFromSnapshotIngressGateway(cInfo connectionInfo, cfgSnap *proxycfg.ConfigSnapshot) ([]proto.Message, error) { - if cfgSnap == nil { - return nil, errors.New("nil config given") - } +func routesForIngressGateway( + cInfo connectionInfo, + upstreams map[proxycfg.IngressListenerKey]structs.Upstreams, + chains map[string]*structs.CompiledDiscoveryChain, +) ([]proto.Message, error) { var result []proto.Message - for listenerKey, upstreams := range cfgSnap.IngressGateway.Upstreams { + for listenerKey, upstreams := range upstreams { // Do not create any route configuration for TCP listeners if listenerKey.Protocol == "tcp" { continue @@ -95,7 +172,7 @@ func routesFromSnapshotIngressGateway(cInfo connectionInfo, cfgSnap *proxycfg.Co } for _, u := range upstreams { upstreamID := u.Identifier() - chain := cfgSnap.IngressGateway.DiscoveryChain[upstreamID] + chain := chains[upstreamID] if chain == nil { continue } @@ -193,8 +270,16 @@ func makeUpstreamRouteForDiscoveryChain( return nil, err } + if err := injectLBToRouteAction(nextNode.LoadBalancer, routeAction.Route); err != nil { + return nil, fmt.Errorf("failed to apply load balancer configuration to route action: %v", err) + } + case structs.DiscoveryGraphNodeTypeResolver: - routeAction = makeRouteActionForSingleCluster(nextNode.Resolver.Target, chain) + routeAction = makeRouteActionForChainCluster(nextNode.Resolver.Target, chain) + + if err := injectLBToRouteAction(nextNode.LoadBalancer, routeAction.Route); err != nil { + return nil, fmt.Errorf("failed to apply load balancer configuration to route action: %v", err) + } default: return nil, fmt.Errorf("unexpected graph node after route %q", nextNode.Type) @@ -247,6 +332,10 @@ func makeUpstreamRouteForDiscoveryChain( return nil, err } + if err := injectLBToRouteAction(startNode.LoadBalancer, routeAction.Route); err != nil { + return nil, fmt.Errorf("failed to apply load balancer configuration to route action: %v", err) + } + defaultRoute := &envoyroute.Route{ Match: makeDefaultRouteMatch(), Action: routeAction, @@ -255,7 +344,11 @@ func makeUpstreamRouteForDiscoveryChain( routes = []*envoyroute.Route{defaultRoute} case structs.DiscoveryGraphNodeTypeResolver: - routeAction := makeRouteActionForSingleCluster(startNode.Resolver.Target, chain) + routeAction := makeRouteActionForChainCluster(startNode.Resolver.Target, chain) + + if err := injectLBToRouteAction(startNode.LoadBalancer, routeAction.Route); err != nil { + return nil, fmt.Errorf("failed to apply load balancer configuration to route action: %v", err) + } defaultRoute := &envoyroute.Route{ Match: makeDefaultRouteMatch(), @@ -277,6 +370,62 @@ func makeUpstreamRouteForDiscoveryChain( return host, nil } +func injectLBToRouteAction(lb structs.LoadBalancer, action *envoyroute.RouteAction) error { + if !lb.IsHashBased() { + return nil + } + + result := make([]*envoyroute.RouteAction_HashPolicy, 0, len(lb.HashPolicies)) + for _, policy := range lb.HashPolicies { + if policy.SourceAddress { + result = append(result, &envoyroute.RouteAction_HashPolicy{ + PolicySpecifier: &envoyroute.RouteAction_HashPolicy_ConnectionProperties_{ + ConnectionProperties: &envoyroute.RouteAction_HashPolicy_ConnectionProperties{ + SourceIp: true, + }, + }, + Terminal: policy.Terminal, + }) + + continue + } + + switch policy.Field { + case "header": + result = append(result, &envoyroute.RouteAction_HashPolicy{ + PolicySpecifier: &envoyroute.RouteAction_HashPolicy_Header_{ + Header: &envoyroute.RouteAction_HashPolicy_Header{ + HeaderName: policy.FieldMatchValue, + }, + }, + Terminal: policy.Terminal, + }) + case "cookie": + result = append(result, &envoyroute.RouteAction_HashPolicy{ + PolicySpecifier: &envoyroute.RouteAction_HashPolicy_Cookie_{ + Cookie: &envoyroute.RouteAction_HashPolicy_Cookie{ + Name: policy.FieldMatchValue, + }, + }, + Terminal: policy.Terminal, + }) + case "query_parameter": + result = append(result, &envoyroute.RouteAction_HashPolicy{ + PolicySpecifier: &envoyroute.RouteAction_HashPolicy_QueryParameter_{ + QueryParameter: &envoyroute.RouteAction_HashPolicy_QueryParameter{ + Name: policy.FieldMatchValue, + }, + }, + Terminal: policy.Terminal, + }) + default: + return fmt.Errorf("unsupported load balancer hash policy field: %v", policy.Field) + } + } + action.HashPolicy = result + return nil +} + func makeRouteMatchForDiscoveryRoute(_ connectionInfo, discoveryRoute *structs.DiscoveryRoute) *envoyroute.RouteMatch { match := discoveryRoute.Definition.Match if match == nil || match.IsEmpty() { @@ -409,11 +558,12 @@ func makeDefaultRouteMatch() *envoyroute.RouteMatch { } } -func makeRouteActionForSingleCluster(targetID string, chain *structs.CompiledDiscoveryChain) *envoyroute.Route_Route { +func makeRouteActionForChainCluster(targetID string, chain *structs.CompiledDiscoveryChain) *envoyroute.Route_Route { target := chain.Targets[targetID] + return makeRouteActionFromName(CustomizeClusterName(target.Name, chain)) +} - clusterName := CustomizeClusterName(target.Name, chain) - +func makeRouteActionFromName(clusterName string) *envoyroute.Route_Route { return &envoyroute.Route_Route{ Route: &envoyroute.RouteAction{ ClusterSpecifier: &envoyroute.RouteAction_Cluster{ diff --git a/agent/xds/routes_test.go b/agent/xds/routes_test.go index ba3d21e74..7142ee445 100644 --- a/agent/xds/routes_test.go +++ b/agent/xds/routes_test.go @@ -7,6 +7,7 @@ import ( "time" envoy "github.com/envoyproxy/go-control-plane/envoy/api/v2" + envoyroute "github.com/envoyproxy/go-control-plane/envoy/api/v2/route" "github.com/hashicorp/consul/agent/connect" "github.com/hashicorp/consul/agent/consul/discoverychain" "github.com/hashicorp/consul/agent/proxycfg" @@ -67,6 +68,11 @@ func TestRoutesFromSnapshot(t *testing.T) { create: proxycfg.TestConfigSnapshotDiscoveryChainWithRouter, setup: nil, }, + { + name: "connect-proxy-lb-in-resolver", + create: proxycfg.TestConfigSnapshotDiscoveryChainWithLB, + setup: nil, + }, // TODO(rb): test match stanza skipped for grpc // Start ingress gateway test cases { @@ -109,6 +115,11 @@ func TestRoutesFromSnapshot(t *testing.T) { create: proxycfg.TestConfigSnapshotIngressWithRouter, setup: nil, }, + { + name: "ingress-lb-in-resolver", + create: proxycfg.TestConfigSnapshotIngressWithLB, + setup: nil, + }, { name: "ingress-http-multiple-services", create: proxycfg.TestConfigSnapshotIngress_HTTPMultipleServices, @@ -174,6 +185,50 @@ func TestRoutesFromSnapshot(t *testing.T) { } }, }, + { + name: "terminating-gateway-lb-config", + create: proxycfg.TestConfigSnapshotTerminatingGateway, + setup: func(snap *proxycfg.ConfigSnapshot) { + snap.TerminatingGateway.ServiceResolvers = map[structs.ServiceName]*structs.ServiceResolverConfigEntry{ + structs.NewServiceName("web", nil): { + Kind: structs.ServiceResolver, + Name: "web", + DefaultSubset: "v2", + Subsets: map[string]structs.ServiceResolverSubset{ + "v1": { + Filter: "Service.Meta.Version == 1", + }, + "v2": { + Filter: "Service.Meta.Version == 2", + OnlyPassing: true, + }, + }, + LoadBalancer: structs.LoadBalancer{ + Policy: "ring_hash", + RingHashConfig: structs.RingHashConfig{ + MinimumRingSize: 20, + MaximumRingSize: 50, + }, + HashPolicies: []structs.HashPolicy{ + { + Field: "cookie", + FieldMatchValue: "chocolate-chip", + Terminal: true, + }, + { + Field: "header", + FieldMatchValue: "x-user-id", + }, + { + SourceAddress: true, + Terminal: true, + }, + }, + }, + }, + } + }, + }, } for _, envoyVersion := range proxysupport.EnvoyVersions { @@ -221,3 +276,178 @@ func TestRoutesFromSnapshot(t *testing.T) { }) } } + +func TestLoadBalancer_injectLBToRouteAction(t *testing.T) { + var tests = []struct { + name string + lb structs.LoadBalancer + expected envoyroute.RouteAction + }{ + { + name: "empty", + lb: structs.LoadBalancer{ + Policy: "", + }, + // we only modify route actions for hash-based LB policies + expected: envoyroute.RouteAction{}, + }, + { + name: "least_request", + lb: structs.LoadBalancer{ + Policy: "least_request", + LeastRequestConfig: structs.LeastRequestConfig{ + ChoiceCount: 3, + }, + }, + // we only modify route actions for hash-based LB policies + expected: envoyroute.RouteAction{}, + }, + { + name: "header", + lb: structs.LoadBalancer{ + Policy: "ring_hash", + RingHashConfig: structs.RingHashConfig{ + MinimumRingSize: 3, + MaximumRingSize: 7, + }, + HashPolicies: []structs.HashPolicy{ + { + Field: "header", + FieldMatchValue: "x-route-key", + Terminal: true, + }, + }, + }, + expected: envoyroute.RouteAction{ + HashPolicy: []*envoyroute.RouteAction_HashPolicy{ + { + PolicySpecifier: &envoyroute.RouteAction_HashPolicy_Header_{ + Header: &envoyroute.RouteAction_HashPolicy_Header{ + HeaderName: "x-route-key", + }, + }, + Terminal: true, + }, + }, + }, + }, + { + name: "cookies", + lb: structs.LoadBalancer{ + Policy: "maglev", + HashPolicies: []structs.HashPolicy{ + { + Field: "cookie", + FieldMatchValue: "red-velvet", + Terminal: true, + }, + { + Field: "cookie", + FieldMatchValue: "oatmeal", + }, + }, + }, + expected: envoyroute.RouteAction{ + HashPolicy: []*envoyroute.RouteAction_HashPolicy{ + { + PolicySpecifier: &envoyroute.RouteAction_HashPolicy_Cookie_{ + Cookie: &envoyroute.RouteAction_HashPolicy_Cookie{ + Name: "red-velvet", + }, + }, + Terminal: true, + }, + { + PolicySpecifier: &envoyroute.RouteAction_HashPolicy_Cookie_{ + Cookie: &envoyroute.RouteAction_HashPolicy_Cookie{ + Name: "oatmeal", + }, + }, + }, + }, + }, + }, + { + name: "source addr", + lb: structs.LoadBalancer{ + Policy: "maglev", + HashPolicies: []structs.HashPolicy{ + { + SourceAddress: true, + Terminal: true, + }, + }, + }, + expected: envoyroute.RouteAction{ + HashPolicy: []*envoyroute.RouteAction_HashPolicy{ + { + PolicySpecifier: &envoyroute.RouteAction_HashPolicy_ConnectionProperties_{ + ConnectionProperties: &envoyroute.RouteAction_HashPolicy_ConnectionProperties{ + SourceIp: true, + }, + }, + Terminal: true, + }, + }, + }, + }, + { + name: "kitchen sink", + lb: structs.LoadBalancer{ + Policy: "maglev", + HashPolicies: []structs.HashPolicy{ + { + SourceAddress: true, + Terminal: true, + }, + { + Field: "cookie", + FieldMatchValue: "oatmeal", + }, + { + Field: "header", + FieldMatchValue: "special-header", + Terminal: true, + }, + }, + }, + expected: envoyroute.RouteAction{ + HashPolicy: []*envoyroute.RouteAction_HashPolicy{ + { + PolicySpecifier: &envoyroute.RouteAction_HashPolicy_ConnectionProperties_{ + ConnectionProperties: &envoyroute.RouteAction_HashPolicy_ConnectionProperties{ + SourceIp: true, + }, + }, + Terminal: true, + }, + { + PolicySpecifier: &envoyroute.RouteAction_HashPolicy_Cookie_{ + Cookie: &envoyroute.RouteAction_HashPolicy_Cookie{ + Name: "oatmeal", + }, + }, + }, + { + PolicySpecifier: &envoyroute.RouteAction_HashPolicy_Header_{ + Header: &envoyroute.RouteAction_HashPolicy_Header{ + HeaderName: "special-header", + }, + }, + Terminal: true, + }, + }, + }, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + ra := &envoyroute.RouteAction{} + err := injectLBToRouteAction(tc.lb, ra) + require.NoError(t, err) + + require.Equal(t, &tc.expected, ra) + }) + } +} diff --git a/agent/xds/testdata/clusters/connect-proxy-lb-in-resolver.envoy-1-12-x.golden b/agent/xds/testdata/clusters/connect-proxy-lb-in-resolver.envoy-1-12-x.golden new file mode 100644 index 000000000..3f3749bcb --- /dev/null +++ b/agent/xds/testdata/clusters/connect-proxy-lb-in-resolver.envoy-1-12-x.golden @@ -0,0 +1,175 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "lbPolicy": "RING_HASH", + "circuitBreakers": { + + }, + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "tlsCertificates": [ + { + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + }, + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + } + } + ], + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + } + } + }, + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + }, + "outlierDetection": { + + }, + "ringHashLbConfig": { + "minimumRingSize": "20", + "maximumRingSize": "30" + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "tlsCertificates": [ + { + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + }, + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + } + } + ], + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + } + } + }, + "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + }, + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "local_app", + "type": "STATIC", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "local_app", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 + } + } + } + } + ] + } + ] + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "something-else.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "something-else.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "tlsCertificates": [ + { + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + }, + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + } + } + ], + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + } + } + }, + "sni": "something-else.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + } + } + ], + "typeUrl": "type.googleapis.com/envoy.api.v2.Cluster", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/clusters/connect-proxy-lb-in-resolver.envoy-1-13-x.golden b/agent/xds/testdata/clusters/connect-proxy-lb-in-resolver.envoy-1-13-x.golden new file mode 100644 index 000000000..3f3749bcb --- /dev/null +++ b/agent/xds/testdata/clusters/connect-proxy-lb-in-resolver.envoy-1-13-x.golden @@ -0,0 +1,175 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "lbPolicy": "RING_HASH", + "circuitBreakers": { + + }, + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "tlsCertificates": [ + { + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + }, + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + } + } + ], + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + } + } + }, + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + }, + "outlierDetection": { + + }, + "ringHashLbConfig": { + "minimumRingSize": "20", + "maximumRingSize": "30" + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "tlsCertificates": [ + { + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + }, + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + } + } + ], + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + } + } + }, + "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + }, + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "local_app", + "type": "STATIC", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "local_app", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 + } + } + } + } + ] + } + ] + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "something-else.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "something-else.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "tlsCertificates": [ + { + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + }, + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + } + } + ], + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + } + } + }, + "sni": "something-else.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + } + } + ], + "typeUrl": "type.googleapis.com/envoy.api.v2.Cluster", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/clusters/connect-proxy-lb-in-resolver.envoy-1-14-x.golden b/agent/xds/testdata/clusters/connect-proxy-lb-in-resolver.envoy-1-14-x.golden new file mode 100644 index 000000000..3f3749bcb --- /dev/null +++ b/agent/xds/testdata/clusters/connect-proxy-lb-in-resolver.envoy-1-14-x.golden @@ -0,0 +1,175 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "lbPolicy": "RING_HASH", + "circuitBreakers": { + + }, + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "tlsCertificates": [ + { + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + }, + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + } + } + ], + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + } + } + }, + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + }, + "outlierDetection": { + + }, + "ringHashLbConfig": { + "minimumRingSize": "20", + "maximumRingSize": "30" + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "tlsCertificates": [ + { + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + }, + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + } + } + ], + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + } + } + }, + "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + }, + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "local_app", + "type": "STATIC", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "local_app", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 + } + } + } + } + ] + } + ] + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "something-else.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "something-else.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "tlsCertificates": [ + { + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + }, + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + } + } + ], + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + } + } + }, + "sni": "something-else.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + } + } + ], + "typeUrl": "type.googleapis.com/envoy.api.v2.Cluster", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/clusters/connect-proxy-lb-in-resolver.envoy-1-15-x.golden b/agent/xds/testdata/clusters/connect-proxy-lb-in-resolver.envoy-1-15-x.golden new file mode 100644 index 000000000..3f3749bcb --- /dev/null +++ b/agent/xds/testdata/clusters/connect-proxy-lb-in-resolver.envoy-1-15-x.golden @@ -0,0 +1,175 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "lbPolicy": "RING_HASH", + "circuitBreakers": { + + }, + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "tlsCertificates": [ + { + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + }, + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + } + } + ], + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + } + } + }, + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + }, + "outlierDetection": { + + }, + "ringHashLbConfig": { + "minimumRingSize": "20", + "maximumRingSize": "30" + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "tlsCertificates": [ + { + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + }, + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + } + } + ], + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + } + } + }, + "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + }, + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "local_app", + "type": "STATIC", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "local_app", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 + } + } + } + } + ] + } + ] + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "something-else.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "something-else.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "tlsCertificates": [ + { + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + }, + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + } + } + ], + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + } + } + }, + "sni": "something-else.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + } + } + ], + "typeUrl": "type.googleapis.com/envoy.api.v2.Cluster", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/clusters/ingress-lb-in-resolver.envoy-1-12-x.golden b/agent/xds/testdata/clusters/ingress-lb-in-resolver.envoy-1-12-x.golden new file mode 100644 index 000000000..9e3274347 --- /dev/null +++ b/agent/xds/testdata/clusters/ingress-lb-in-resolver.envoy-1-12-x.golden @@ -0,0 +1,108 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "lbPolicy": "RING_HASH", + "circuitBreakers": { + + }, + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "tlsCertificates": [ + { + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + }, + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + } + } + ], + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + } + } + }, + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + }, + "outlierDetection": { + + }, + "ringHashLbConfig": { + "minimumRingSize": "20", + "maximumRingSize": "30" + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "something-else.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "something-else.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "tlsCertificates": [ + { + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + }, + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + } + } + ], + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + } + } + }, + "sni": "something-else.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + } + } + ], + "typeUrl": "type.googleapis.com/envoy.api.v2.Cluster", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/clusters/ingress-lb-in-resolver.envoy-1-13-x.golden b/agent/xds/testdata/clusters/ingress-lb-in-resolver.envoy-1-13-x.golden new file mode 100644 index 000000000..9e3274347 --- /dev/null +++ b/agent/xds/testdata/clusters/ingress-lb-in-resolver.envoy-1-13-x.golden @@ -0,0 +1,108 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "lbPolicy": "RING_HASH", + "circuitBreakers": { + + }, + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "tlsCertificates": [ + { + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + }, + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + } + } + ], + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + } + } + }, + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + }, + "outlierDetection": { + + }, + "ringHashLbConfig": { + "minimumRingSize": "20", + "maximumRingSize": "30" + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "something-else.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "something-else.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "tlsCertificates": [ + { + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + }, + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + } + } + ], + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + } + } + }, + "sni": "something-else.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + } + } + ], + "typeUrl": "type.googleapis.com/envoy.api.v2.Cluster", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/clusters/ingress-lb-in-resolver.envoy-1-14-x.golden b/agent/xds/testdata/clusters/ingress-lb-in-resolver.envoy-1-14-x.golden new file mode 100644 index 000000000..9e3274347 --- /dev/null +++ b/agent/xds/testdata/clusters/ingress-lb-in-resolver.envoy-1-14-x.golden @@ -0,0 +1,108 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "lbPolicy": "RING_HASH", + "circuitBreakers": { + + }, + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "tlsCertificates": [ + { + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + }, + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + } + } + ], + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + } + } + }, + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + }, + "outlierDetection": { + + }, + "ringHashLbConfig": { + "minimumRingSize": "20", + "maximumRingSize": "30" + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "something-else.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "something-else.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "tlsCertificates": [ + { + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + }, + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + } + } + ], + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + } + } + }, + "sni": "something-else.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + } + } + ], + "typeUrl": "type.googleapis.com/envoy.api.v2.Cluster", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/clusters/ingress-lb-in-resolver.envoy-1-15-x.golden b/agent/xds/testdata/clusters/ingress-lb-in-resolver.envoy-1-15-x.golden new file mode 100644 index 000000000..9e3274347 --- /dev/null +++ b/agent/xds/testdata/clusters/ingress-lb-in-resolver.envoy-1-15-x.golden @@ -0,0 +1,108 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "lbPolicy": "RING_HASH", + "circuitBreakers": { + + }, + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "tlsCertificates": [ + { + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + }, + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + } + } + ], + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + } + } + }, + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + }, + "outlierDetection": { + + }, + "ringHashLbConfig": { + "minimumRingSize": "20", + "maximumRingSize": "30" + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "something-else.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "something-else.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "tlsCertificates": [ + { + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + }, + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + } + } + ], + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + } + } + }, + "sni": "something-else.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + } + } + ], + "typeUrl": "type.googleapis.com/envoy.api.v2.Cluster", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/clusters/mesh-gateway-hash-lb-ignored.envoy-1-12-x.golden b/agent/xds/testdata/clusters/mesh-gateway-hash-lb-ignored.envoy-1-12-x.golden new file mode 100644 index 000000000..afc23f9ae --- /dev/null +++ b/agent/xds/testdata/clusters/mesh-gateway-hash-lb-ignored.envoy-1-12-x.golden @@ -0,0 +1,151 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "dc2.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "123.us-west-2.elb.notaws.com", + "portValue": 443 + } + } + }, + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "123.us-east-1.elb.notaws.com", + "portValue": 443 + } + } + }, + "healthStatus": "UNHEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v1.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v2.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "outlierDetection": { + + } + } + ], + "typeUrl": "type.googleapis.com/envoy.api.v2.Cluster", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/clusters/mesh-gateway-hash-lb-ignored.envoy-1-13-x.golden b/agent/xds/testdata/clusters/mesh-gateway-hash-lb-ignored.envoy-1-13-x.golden new file mode 100644 index 000000000..afc23f9ae --- /dev/null +++ b/agent/xds/testdata/clusters/mesh-gateway-hash-lb-ignored.envoy-1-13-x.golden @@ -0,0 +1,151 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "dc2.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "123.us-west-2.elb.notaws.com", + "portValue": 443 + } + } + }, + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "123.us-east-1.elb.notaws.com", + "portValue": 443 + } + } + }, + "healthStatus": "UNHEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v1.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v2.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "outlierDetection": { + + } + } + ], + "typeUrl": "type.googleapis.com/envoy.api.v2.Cluster", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/clusters/mesh-gateway-hash-lb-ignored.envoy-1-14-x.golden b/agent/xds/testdata/clusters/mesh-gateway-hash-lb-ignored.envoy-1-14-x.golden new file mode 100644 index 000000000..afc23f9ae --- /dev/null +++ b/agent/xds/testdata/clusters/mesh-gateway-hash-lb-ignored.envoy-1-14-x.golden @@ -0,0 +1,151 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "dc2.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "123.us-west-2.elb.notaws.com", + "portValue": 443 + } + } + }, + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "123.us-east-1.elb.notaws.com", + "portValue": 443 + } + } + }, + "healthStatus": "UNHEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v1.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v2.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "outlierDetection": { + + } + } + ], + "typeUrl": "type.googleapis.com/envoy.api.v2.Cluster", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/clusters/mesh-gateway-hash-lb-ignored.envoy-1-15-x.golden b/agent/xds/testdata/clusters/mesh-gateway-hash-lb-ignored.envoy-1-15-x.golden new file mode 100644 index 000000000..afc23f9ae --- /dev/null +++ b/agent/xds/testdata/clusters/mesh-gateway-hash-lb-ignored.envoy-1-15-x.golden @@ -0,0 +1,151 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "dc2.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "123.us-west-2.elb.notaws.com", + "portValue": 443 + } + } + }, + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "123.us-east-1.elb.notaws.com", + "portValue": 443 + } + } + }, + "healthStatus": "UNHEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v1.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v2.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "outlierDetection": { + + } + } + ], + "typeUrl": "type.googleapis.com/envoy.api.v2.Cluster", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/clusters/mesh-gateway-non-hash-lb-injected.envoy-1-12-x.golden b/agent/xds/testdata/clusters/mesh-gateway-non-hash-lb-injected.envoy-1-12-x.golden new file mode 100644 index 000000000..519c2d07f --- /dev/null +++ b/agent/xds/testdata/clusters/mesh-gateway-non-hash-lb-injected.envoy-1-12-x.golden @@ -0,0 +1,163 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "lbPolicy": "LEAST_REQUEST", + "outlierDetection": { + + }, + "leastRequestLbConfig": { + "choiceCount": 5 + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "dc2.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "123.us-west-2.elb.notaws.com", + "portValue": 443 + } + } + }, + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "123.us-east-1.elb.notaws.com", + "portValue": 443 + } + } + }, + "healthStatus": "UNHEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v1.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "lbPolicy": "LEAST_REQUEST", + "outlierDetection": { + + }, + "leastRequestLbConfig": { + "choiceCount": 5 + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v2.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "lbPolicy": "LEAST_REQUEST", + "outlierDetection": { + + }, + "leastRequestLbConfig": { + "choiceCount": 5 + } + } + ], + "typeUrl": "type.googleapis.com/envoy.api.v2.Cluster", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/clusters/mesh-gateway-non-hash-lb-injected.envoy-1-13-x.golden b/agent/xds/testdata/clusters/mesh-gateway-non-hash-lb-injected.envoy-1-13-x.golden new file mode 100644 index 000000000..519c2d07f --- /dev/null +++ b/agent/xds/testdata/clusters/mesh-gateway-non-hash-lb-injected.envoy-1-13-x.golden @@ -0,0 +1,163 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "lbPolicy": "LEAST_REQUEST", + "outlierDetection": { + + }, + "leastRequestLbConfig": { + "choiceCount": 5 + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "dc2.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "123.us-west-2.elb.notaws.com", + "portValue": 443 + } + } + }, + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "123.us-east-1.elb.notaws.com", + "portValue": 443 + } + } + }, + "healthStatus": "UNHEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v1.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "lbPolicy": "LEAST_REQUEST", + "outlierDetection": { + + }, + "leastRequestLbConfig": { + "choiceCount": 5 + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v2.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "lbPolicy": "LEAST_REQUEST", + "outlierDetection": { + + }, + "leastRequestLbConfig": { + "choiceCount": 5 + } + } + ], + "typeUrl": "type.googleapis.com/envoy.api.v2.Cluster", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/clusters/mesh-gateway-non-hash-lb-injected.envoy-1-14-x.golden b/agent/xds/testdata/clusters/mesh-gateway-non-hash-lb-injected.envoy-1-14-x.golden new file mode 100644 index 000000000..519c2d07f --- /dev/null +++ b/agent/xds/testdata/clusters/mesh-gateway-non-hash-lb-injected.envoy-1-14-x.golden @@ -0,0 +1,163 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "lbPolicy": "LEAST_REQUEST", + "outlierDetection": { + + }, + "leastRequestLbConfig": { + "choiceCount": 5 + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "dc2.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "123.us-west-2.elb.notaws.com", + "portValue": 443 + } + } + }, + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "123.us-east-1.elb.notaws.com", + "portValue": 443 + } + } + }, + "healthStatus": "UNHEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v1.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "lbPolicy": "LEAST_REQUEST", + "outlierDetection": { + + }, + "leastRequestLbConfig": { + "choiceCount": 5 + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v2.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "lbPolicy": "LEAST_REQUEST", + "outlierDetection": { + + }, + "leastRequestLbConfig": { + "choiceCount": 5 + } + } + ], + "typeUrl": "type.googleapis.com/envoy.api.v2.Cluster", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/clusters/mesh-gateway-non-hash-lb-injected.envoy-1-15-x.golden b/agent/xds/testdata/clusters/mesh-gateway-non-hash-lb-injected.envoy-1-15-x.golden new file mode 100644 index 000000000..519c2d07f --- /dev/null +++ b/agent/xds/testdata/clusters/mesh-gateway-non-hash-lb-injected.envoy-1-15-x.golden @@ -0,0 +1,163 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "lbPolicy": "LEAST_REQUEST", + "outlierDetection": { + + }, + "leastRequestLbConfig": { + "choiceCount": 5 + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "dc2.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "123.us-west-2.elb.notaws.com", + "portValue": 443 + } + } + }, + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "123.us-east-1.elb.notaws.com", + "portValue": 443 + } + } + }, + "healthStatus": "UNHEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v1.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "lbPolicy": "LEAST_REQUEST", + "outlierDetection": { + + }, + "leastRequestLbConfig": { + "choiceCount": 5 + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v2.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "lbPolicy": "LEAST_REQUEST", + "outlierDetection": { + + }, + "leastRequestLbConfig": { + "choiceCount": 5 + } + } + ], + "typeUrl": "type.googleapis.com/envoy.api.v2.Cluster", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/clusters/terminating-gateway-lb-config.envoy-1-12-x.golden b/agent/xds/testdata/clusters/terminating-gateway-lb-config.envoy-1-12-x.golden new file mode 100644 index 000000000..74d755a5d --- /dev/null +++ b/agent/xds/testdata/clusters/terminating-gateway-lb-config.envoy-1-12-x.golden @@ -0,0 +1,224 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "api.altdomain", + "portValue": 8081 + } + } + }, + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + }, + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "tlsCertificates": [ + { + "certificateChain": { + "filename": "api.cert.pem" + }, + "privateKey": { + "filename": "api.key.pem" + } + } + ], + "validationContext": { + "trustedCa": { + "filename": "ca.cert.pem" + } + } + } + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "cache.mydomain", + "portValue": 8081 + } + } + }, + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "db.mydomain", + "portValue": 8081 + } + } + }, + "healthStatus": "UNHEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "lbPolicy": "RING_HASH", + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "validationContext": { + "trustedCa": { + "filename": "ca.cert.pem" + } + } + } + }, + "outlierDetection": { + + }, + "ringHashLbConfig": { + "minimumRingSize": "20", + "maximumRingSize": "50" + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "lbPolicy": "RING_HASH", + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "validationContext": { + "trustedCa": { + "filename": "ca.cert.pem" + } + } + } + }, + "outlierDetection": { + + }, + "ringHashLbConfig": { + "minimumRingSize": "20", + "maximumRingSize": "50" + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "lbPolicy": "RING_HASH", + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "validationContext": { + "trustedCa": { + "filename": "ca.cert.pem" + } + } + } + }, + "outlierDetection": { + + }, + "ringHashLbConfig": { + "minimumRingSize": "20", + "maximumRingSize": "50" + } + } + ], + "typeUrl": "type.googleapis.com/envoy.api.v2.Cluster", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/clusters/terminating-gateway-lb-config.envoy-1-13-x.golden b/agent/xds/testdata/clusters/terminating-gateway-lb-config.envoy-1-13-x.golden new file mode 100644 index 000000000..74d755a5d --- /dev/null +++ b/agent/xds/testdata/clusters/terminating-gateway-lb-config.envoy-1-13-x.golden @@ -0,0 +1,224 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "api.altdomain", + "portValue": 8081 + } + } + }, + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + }, + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "tlsCertificates": [ + { + "certificateChain": { + "filename": "api.cert.pem" + }, + "privateKey": { + "filename": "api.key.pem" + } + } + ], + "validationContext": { + "trustedCa": { + "filename": "ca.cert.pem" + } + } + } + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "cache.mydomain", + "portValue": 8081 + } + } + }, + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "db.mydomain", + "portValue": 8081 + } + } + }, + "healthStatus": "UNHEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "lbPolicy": "RING_HASH", + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "validationContext": { + "trustedCa": { + "filename": "ca.cert.pem" + } + } + } + }, + "outlierDetection": { + + }, + "ringHashLbConfig": { + "minimumRingSize": "20", + "maximumRingSize": "50" + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "lbPolicy": "RING_HASH", + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "validationContext": { + "trustedCa": { + "filename": "ca.cert.pem" + } + } + } + }, + "outlierDetection": { + + }, + "ringHashLbConfig": { + "minimumRingSize": "20", + "maximumRingSize": "50" + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "lbPolicy": "RING_HASH", + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "validationContext": { + "trustedCa": { + "filename": "ca.cert.pem" + } + } + } + }, + "outlierDetection": { + + }, + "ringHashLbConfig": { + "minimumRingSize": "20", + "maximumRingSize": "50" + } + } + ], + "typeUrl": "type.googleapis.com/envoy.api.v2.Cluster", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/clusters/terminating-gateway-lb-config.envoy-1-14-x.golden b/agent/xds/testdata/clusters/terminating-gateway-lb-config.envoy-1-14-x.golden new file mode 100644 index 000000000..74d755a5d --- /dev/null +++ b/agent/xds/testdata/clusters/terminating-gateway-lb-config.envoy-1-14-x.golden @@ -0,0 +1,224 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "api.altdomain", + "portValue": 8081 + } + } + }, + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + }, + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "tlsCertificates": [ + { + "certificateChain": { + "filename": "api.cert.pem" + }, + "privateKey": { + "filename": "api.key.pem" + } + } + ], + "validationContext": { + "trustedCa": { + "filename": "ca.cert.pem" + } + } + } + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "cache.mydomain", + "portValue": 8081 + } + } + }, + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "db.mydomain", + "portValue": 8081 + } + } + }, + "healthStatus": "UNHEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "lbPolicy": "RING_HASH", + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "validationContext": { + "trustedCa": { + "filename": "ca.cert.pem" + } + } + } + }, + "outlierDetection": { + + }, + "ringHashLbConfig": { + "minimumRingSize": "20", + "maximumRingSize": "50" + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "lbPolicy": "RING_HASH", + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "validationContext": { + "trustedCa": { + "filename": "ca.cert.pem" + } + } + } + }, + "outlierDetection": { + + }, + "ringHashLbConfig": { + "minimumRingSize": "20", + "maximumRingSize": "50" + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "lbPolicy": "RING_HASH", + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "validationContext": { + "trustedCa": { + "filename": "ca.cert.pem" + } + } + } + }, + "outlierDetection": { + + }, + "ringHashLbConfig": { + "minimumRingSize": "20", + "maximumRingSize": "50" + } + } + ], + "typeUrl": "type.googleapis.com/envoy.api.v2.Cluster", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/clusters/terminating-gateway-lb-config.envoy-1-15-x.golden b/agent/xds/testdata/clusters/terminating-gateway-lb-config.envoy-1-15-x.golden new file mode 100644 index 000000000..74d755a5d --- /dev/null +++ b/agent/xds/testdata/clusters/terminating-gateway-lb-config.envoy-1-15-x.golden @@ -0,0 +1,224 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "api.altdomain", + "portValue": 8081 + } + } + }, + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + }, + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "tlsCertificates": [ + { + "certificateChain": { + "filename": "api.cert.pem" + }, + "privateKey": { + "filename": "api.key.pem" + } + } + ], + "validationContext": { + "trustedCa": { + "filename": "ca.cert.pem" + } + } + } + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "cache.mydomain", + "portValue": 8081 + } + } + }, + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "db.mydomain", + "portValue": 8081 + } + } + }, + "healthStatus": "UNHEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "lbPolicy": "RING_HASH", + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "validationContext": { + "trustedCa": { + "filename": "ca.cert.pem" + } + } + } + }, + "outlierDetection": { + + }, + "ringHashLbConfig": { + "minimumRingSize": "20", + "maximumRingSize": "50" + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "lbPolicy": "RING_HASH", + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "validationContext": { + "trustedCa": { + "filename": "ca.cert.pem" + } + } + } + }, + "outlierDetection": { + + }, + "ringHashLbConfig": { + "minimumRingSize": "20", + "maximumRingSize": "50" + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "lbPolicy": "RING_HASH", + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "validationContext": { + "trustedCa": { + "filename": "ca.cert.pem" + } + } + } + }, + "outlierDetection": { + + }, + "ringHashLbConfig": { + "minimumRingSize": "20", + "maximumRingSize": "50" + } + } + ], + "typeUrl": "type.googleapis.com/envoy.api.v2.Cluster", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/listeners/terminating-gateway-custom-and-tagged-addresses.envoy-1-12-x.golden b/agent/xds/testdata/listeners/terminating-gateway-custom-and-tagged-addresses.envoy-1-12-x.golden index 0164fc635..72abeba6b 100644 --- a/agent/xds/testdata/listeners/terminating-gateway-custom-and-tagged-addresses.envoy-1-12-x.golden +++ b/agent/xds/testdata/listeners/terminating-gateway-custom-and-tagged-addresses.envoy-1-12-x.golden @@ -183,18 +183,33 @@ }, "filters": [ { - "name": "envoy.filters.network.rbac", + "name": "envoy.http_connection_manager", "config": { - "rules": { + "http_filters": [ + { + "config": { + "rules": { + } + }, + "name": "envoy.filters.http.rbac" + }, + { + "name": "envoy.router" + } + ], + "rds": { + "config_source": { + "ads": { + } + }, + "route_config_name": "foo" }, - "stat_prefix": "connect_authz" - } - }, - { - "name": "envoy.tcp_proxy", - "config": { - "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "stat_prefix": "terminating_gateway_default_web_foo_tcp" + "stat_prefix": "terminating_gateway_default_web_foo_http", + "tracing": { + "operation_name": "EGRESS", + "random_sampling": { + } + } } } ] @@ -402,18 +417,33 @@ }, "filters": [ { - "name": "envoy.filters.network.rbac", + "name": "envoy.http_connection_manager", "config": { - "rules": { + "http_filters": [ + { + "config": { + "rules": { + } + }, + "name": "envoy.filters.http.rbac" + }, + { + "name": "envoy.router" + } + ], + "rds": { + "config_source": { + "ads": { + } + }, + "route_config_name": "wan" }, - "stat_prefix": "connect_authz" - } - }, - { - "name": "envoy.tcp_proxy", - "config": { - "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "stat_prefix": "terminating_gateway_default_web_wan_tcp" + "stat_prefix": "terminating_gateway_default_web_wan_http", + "tracing": { + "operation_name": "EGRESS", + "random_sampling": { + } + } } } ] diff --git a/agent/xds/testdata/listeners/terminating-gateway-custom-and-tagged-addresses.envoy-1-13-x.golden b/agent/xds/testdata/listeners/terminating-gateway-custom-and-tagged-addresses.envoy-1-13-x.golden index 0164fc635..72abeba6b 100644 --- a/agent/xds/testdata/listeners/terminating-gateway-custom-and-tagged-addresses.envoy-1-13-x.golden +++ b/agent/xds/testdata/listeners/terminating-gateway-custom-and-tagged-addresses.envoy-1-13-x.golden @@ -183,18 +183,33 @@ }, "filters": [ { - "name": "envoy.filters.network.rbac", + "name": "envoy.http_connection_manager", "config": { - "rules": { + "http_filters": [ + { + "config": { + "rules": { + } + }, + "name": "envoy.filters.http.rbac" + }, + { + "name": "envoy.router" + } + ], + "rds": { + "config_source": { + "ads": { + } + }, + "route_config_name": "foo" }, - "stat_prefix": "connect_authz" - } - }, - { - "name": "envoy.tcp_proxy", - "config": { - "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "stat_prefix": "terminating_gateway_default_web_foo_tcp" + "stat_prefix": "terminating_gateway_default_web_foo_http", + "tracing": { + "operation_name": "EGRESS", + "random_sampling": { + } + } } } ] @@ -402,18 +417,33 @@ }, "filters": [ { - "name": "envoy.filters.network.rbac", + "name": "envoy.http_connection_manager", "config": { - "rules": { + "http_filters": [ + { + "config": { + "rules": { + } + }, + "name": "envoy.filters.http.rbac" + }, + { + "name": "envoy.router" + } + ], + "rds": { + "config_source": { + "ads": { + } + }, + "route_config_name": "wan" }, - "stat_prefix": "connect_authz" - } - }, - { - "name": "envoy.tcp_proxy", - "config": { - "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "stat_prefix": "terminating_gateway_default_web_wan_tcp" + "stat_prefix": "terminating_gateway_default_web_wan_http", + "tracing": { + "operation_name": "EGRESS", + "random_sampling": { + } + } } } ] diff --git a/agent/xds/testdata/listeners/terminating-gateway-custom-and-tagged-addresses.envoy-1-14-x.golden b/agent/xds/testdata/listeners/terminating-gateway-custom-and-tagged-addresses.envoy-1-14-x.golden index 0164fc635..72abeba6b 100644 --- a/agent/xds/testdata/listeners/terminating-gateway-custom-and-tagged-addresses.envoy-1-14-x.golden +++ b/agent/xds/testdata/listeners/terminating-gateway-custom-and-tagged-addresses.envoy-1-14-x.golden @@ -183,18 +183,33 @@ }, "filters": [ { - "name": "envoy.filters.network.rbac", + "name": "envoy.http_connection_manager", "config": { - "rules": { + "http_filters": [ + { + "config": { + "rules": { + } + }, + "name": "envoy.filters.http.rbac" + }, + { + "name": "envoy.router" + } + ], + "rds": { + "config_source": { + "ads": { + } + }, + "route_config_name": "foo" }, - "stat_prefix": "connect_authz" - } - }, - { - "name": "envoy.tcp_proxy", - "config": { - "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "stat_prefix": "terminating_gateway_default_web_foo_tcp" + "stat_prefix": "terminating_gateway_default_web_foo_http", + "tracing": { + "operation_name": "EGRESS", + "random_sampling": { + } + } } } ] @@ -402,18 +417,33 @@ }, "filters": [ { - "name": "envoy.filters.network.rbac", + "name": "envoy.http_connection_manager", "config": { - "rules": { + "http_filters": [ + { + "config": { + "rules": { + } + }, + "name": "envoy.filters.http.rbac" + }, + { + "name": "envoy.router" + } + ], + "rds": { + "config_source": { + "ads": { + } + }, + "route_config_name": "wan" }, - "stat_prefix": "connect_authz" - } - }, - { - "name": "envoy.tcp_proxy", - "config": { - "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "stat_prefix": "terminating_gateway_default_web_wan_tcp" + "stat_prefix": "terminating_gateway_default_web_wan_http", + "tracing": { + "operation_name": "EGRESS", + "random_sampling": { + } + } } } ] diff --git a/agent/xds/testdata/listeners/terminating-gateway-custom-and-tagged-addresses.envoy-1-15-x.golden b/agent/xds/testdata/listeners/terminating-gateway-custom-and-tagged-addresses.envoy-1-15-x.golden index 0164fc635..72abeba6b 100644 --- a/agent/xds/testdata/listeners/terminating-gateway-custom-and-tagged-addresses.envoy-1-15-x.golden +++ b/agent/xds/testdata/listeners/terminating-gateway-custom-and-tagged-addresses.envoy-1-15-x.golden @@ -183,18 +183,33 @@ }, "filters": [ { - "name": "envoy.filters.network.rbac", + "name": "envoy.http_connection_manager", "config": { - "rules": { + "http_filters": [ + { + "config": { + "rules": { + } + }, + "name": "envoy.filters.http.rbac" + }, + { + "name": "envoy.router" + } + ], + "rds": { + "config_source": { + "ads": { + } + }, + "route_config_name": "foo" }, - "stat_prefix": "connect_authz" - } - }, - { - "name": "envoy.tcp_proxy", - "config": { - "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "stat_prefix": "terminating_gateway_default_web_foo_tcp" + "stat_prefix": "terminating_gateway_default_web_foo_http", + "tracing": { + "operation_name": "EGRESS", + "random_sampling": { + } + } } } ] @@ -402,18 +417,33 @@ }, "filters": [ { - "name": "envoy.filters.network.rbac", + "name": "envoy.http_connection_manager", "config": { - "rules": { + "http_filters": [ + { + "config": { + "rules": { + } + }, + "name": "envoy.filters.http.rbac" + }, + { + "name": "envoy.router" + } + ], + "rds": { + "config_source": { + "ads": { + } + }, + "route_config_name": "wan" }, - "stat_prefix": "connect_authz" - } - }, - { - "name": "envoy.tcp_proxy", - "config": { - "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "stat_prefix": "terminating_gateway_default_web_wan_tcp" + "stat_prefix": "terminating_gateway_default_web_wan_http", + "tracing": { + "operation_name": "EGRESS", + "random_sampling": { + } + } } } ] diff --git a/agent/xds/testdata/listeners/terminating-gateway-no-api-cert.envoy-1-12-x.golden b/agent/xds/testdata/listeners/terminating-gateway-no-api-cert.envoy-1-12-x.golden index bfb7ab050..cb3860ef5 100644 --- a/agent/xds/testdata/listeners/terminating-gateway-no-api-cert.envoy-1-12-x.golden +++ b/agent/xds/testdata/listeners/terminating-gateway-no-api-cert.envoy-1-12-x.golden @@ -136,18 +136,33 @@ }, "filters": [ { - "name": "envoy.filters.network.rbac", + "name": "envoy.http_connection_manager", "config": { - "rules": { + "http_filters": [ + { + "config": { + "rules": { + } + }, + "name": "envoy.filters.http.rbac" + }, + { + "name": "envoy.router" + } + ], + "rds": { + "config_source": { + "ads": { + } + }, + "route_config_name": "default" }, - "stat_prefix": "connect_authz" - } - }, - { - "name": "envoy.tcp_proxy", - "config": { - "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "stat_prefix": "terminating_gateway_default_web_default_tcp" + "stat_prefix": "terminating_gateway_default_web_default_http", + "tracing": { + "operation_name": "EGRESS", + "random_sampling": { + } + } } } ] diff --git a/agent/xds/testdata/listeners/terminating-gateway-no-api-cert.envoy-1-13-x.golden b/agent/xds/testdata/listeners/terminating-gateway-no-api-cert.envoy-1-13-x.golden index bfb7ab050..cb3860ef5 100644 --- a/agent/xds/testdata/listeners/terminating-gateway-no-api-cert.envoy-1-13-x.golden +++ b/agent/xds/testdata/listeners/terminating-gateway-no-api-cert.envoy-1-13-x.golden @@ -136,18 +136,33 @@ }, "filters": [ { - "name": "envoy.filters.network.rbac", + "name": "envoy.http_connection_manager", "config": { - "rules": { + "http_filters": [ + { + "config": { + "rules": { + } + }, + "name": "envoy.filters.http.rbac" + }, + { + "name": "envoy.router" + } + ], + "rds": { + "config_source": { + "ads": { + } + }, + "route_config_name": "default" }, - "stat_prefix": "connect_authz" - } - }, - { - "name": "envoy.tcp_proxy", - "config": { - "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "stat_prefix": "terminating_gateway_default_web_default_tcp" + "stat_prefix": "terminating_gateway_default_web_default_http", + "tracing": { + "operation_name": "EGRESS", + "random_sampling": { + } + } } } ] diff --git a/agent/xds/testdata/listeners/terminating-gateway-no-api-cert.envoy-1-14-x.golden b/agent/xds/testdata/listeners/terminating-gateway-no-api-cert.envoy-1-14-x.golden index bfb7ab050..cb3860ef5 100644 --- a/agent/xds/testdata/listeners/terminating-gateway-no-api-cert.envoy-1-14-x.golden +++ b/agent/xds/testdata/listeners/terminating-gateway-no-api-cert.envoy-1-14-x.golden @@ -136,18 +136,33 @@ }, "filters": [ { - "name": "envoy.filters.network.rbac", + "name": "envoy.http_connection_manager", "config": { - "rules": { + "http_filters": [ + { + "config": { + "rules": { + } + }, + "name": "envoy.filters.http.rbac" + }, + { + "name": "envoy.router" + } + ], + "rds": { + "config_source": { + "ads": { + } + }, + "route_config_name": "default" }, - "stat_prefix": "connect_authz" - } - }, - { - "name": "envoy.tcp_proxy", - "config": { - "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "stat_prefix": "terminating_gateway_default_web_default_tcp" + "stat_prefix": "terminating_gateway_default_web_default_http", + "tracing": { + "operation_name": "EGRESS", + "random_sampling": { + } + } } } ] diff --git a/agent/xds/testdata/listeners/terminating-gateway-no-api-cert.envoy-1-15-x.golden b/agent/xds/testdata/listeners/terminating-gateway-no-api-cert.envoy-1-15-x.golden index bfb7ab050..cb3860ef5 100644 --- a/agent/xds/testdata/listeners/terminating-gateway-no-api-cert.envoy-1-15-x.golden +++ b/agent/xds/testdata/listeners/terminating-gateway-no-api-cert.envoy-1-15-x.golden @@ -136,18 +136,33 @@ }, "filters": [ { - "name": "envoy.filters.network.rbac", + "name": "envoy.http_connection_manager", "config": { - "rules": { + "http_filters": [ + { + "config": { + "rules": { + } + }, + "name": "envoy.filters.http.rbac" + }, + { + "name": "envoy.router" + } + ], + "rds": { + "config_source": { + "ads": { + } + }, + "route_config_name": "default" }, - "stat_prefix": "connect_authz" - } - }, - { - "name": "envoy.tcp_proxy", - "config": { - "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "stat_prefix": "terminating_gateway_default_web_default_tcp" + "stat_prefix": "terminating_gateway_default_web_default_http", + "tracing": { + "operation_name": "EGRESS", + "random_sampling": { + } + } } } ] diff --git a/agent/xds/testdata/listeners/terminating-gateway-service-subsets.envoy-1-12-x.golden b/agent/xds/testdata/listeners/terminating-gateway-service-subsets.envoy-1-12-x.golden index c77782da2..c6ab6ce7c 100644 --- a/agent/xds/testdata/listeners/terminating-gateway-service-subsets.envoy-1-12-x.golden +++ b/agent/xds/testdata/listeners/terminating-gateway-service-subsets.envoy-1-12-x.golden @@ -183,18 +183,33 @@ }, "filters": [ { - "name": "envoy.filters.network.rbac", + "name": "envoy.http_connection_manager", "config": { - "rules": { + "http_filters": [ + { + "config": { + "rules": { + } + }, + "name": "envoy.filters.http.rbac" + }, + { + "name": "envoy.router" + } + ], + "rds": { + "config_source": { + "ads": { + } + }, + "route_config_name": "default" }, - "stat_prefix": "connect_authz" - } - }, - { - "name": "envoy.tcp_proxy", - "config": { - "cluster": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "stat_prefix": "terminating_gateway_default_web_default_tcp" + "stat_prefix": "terminating_gateway_default_web_default_http", + "tracing": { + "operation_name": "EGRESS", + "random_sampling": { + } + } } } ] @@ -230,18 +245,33 @@ }, "filters": [ { - "name": "envoy.filters.network.rbac", + "name": "envoy.http_connection_manager", "config": { - "rules": { + "http_filters": [ + { + "config": { + "rules": { + } + }, + "name": "envoy.filters.http.rbac" + }, + { + "name": "envoy.router" + } + ], + "rds": { + "config_source": { + "ads": { + } + }, + "route_config_name": "default" }, - "stat_prefix": "connect_authz" - } - }, - { - "name": "envoy.tcp_proxy", - "config": { - "cluster": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "stat_prefix": "terminating_gateway_default_web_default_tcp" + "stat_prefix": "terminating_gateway_default_web_default_http", + "tracing": { + "operation_name": "EGRESS", + "random_sampling": { + } + } } } ] @@ -277,18 +307,33 @@ }, "filters": [ { - "name": "envoy.filters.network.rbac", + "name": "envoy.http_connection_manager", "config": { - "rules": { + "http_filters": [ + { + "config": { + "rules": { + } + }, + "name": "envoy.filters.http.rbac" + }, + { + "name": "envoy.router" + } + ], + "rds": { + "config_source": { + "ads": { + } + }, + "route_config_name": "default" }, - "stat_prefix": "connect_authz" - } - }, - { - "name": "envoy.tcp_proxy", - "config": { - "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "stat_prefix": "terminating_gateway_default_web_default_tcp" + "stat_prefix": "terminating_gateway_default_web_default_http", + "tracing": { + "operation_name": "EGRESS", + "random_sampling": { + } + } } } ] diff --git a/agent/xds/testdata/listeners/terminating-gateway-service-subsets.envoy-1-13-x.golden b/agent/xds/testdata/listeners/terminating-gateway-service-subsets.envoy-1-13-x.golden index c77782da2..c6ab6ce7c 100644 --- a/agent/xds/testdata/listeners/terminating-gateway-service-subsets.envoy-1-13-x.golden +++ b/agent/xds/testdata/listeners/terminating-gateway-service-subsets.envoy-1-13-x.golden @@ -183,18 +183,33 @@ }, "filters": [ { - "name": "envoy.filters.network.rbac", + "name": "envoy.http_connection_manager", "config": { - "rules": { + "http_filters": [ + { + "config": { + "rules": { + } + }, + "name": "envoy.filters.http.rbac" + }, + { + "name": "envoy.router" + } + ], + "rds": { + "config_source": { + "ads": { + } + }, + "route_config_name": "default" }, - "stat_prefix": "connect_authz" - } - }, - { - "name": "envoy.tcp_proxy", - "config": { - "cluster": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "stat_prefix": "terminating_gateway_default_web_default_tcp" + "stat_prefix": "terminating_gateway_default_web_default_http", + "tracing": { + "operation_name": "EGRESS", + "random_sampling": { + } + } } } ] @@ -230,18 +245,33 @@ }, "filters": [ { - "name": "envoy.filters.network.rbac", + "name": "envoy.http_connection_manager", "config": { - "rules": { + "http_filters": [ + { + "config": { + "rules": { + } + }, + "name": "envoy.filters.http.rbac" + }, + { + "name": "envoy.router" + } + ], + "rds": { + "config_source": { + "ads": { + } + }, + "route_config_name": "default" }, - "stat_prefix": "connect_authz" - } - }, - { - "name": "envoy.tcp_proxy", - "config": { - "cluster": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "stat_prefix": "terminating_gateway_default_web_default_tcp" + "stat_prefix": "terminating_gateway_default_web_default_http", + "tracing": { + "operation_name": "EGRESS", + "random_sampling": { + } + } } } ] @@ -277,18 +307,33 @@ }, "filters": [ { - "name": "envoy.filters.network.rbac", + "name": "envoy.http_connection_manager", "config": { - "rules": { + "http_filters": [ + { + "config": { + "rules": { + } + }, + "name": "envoy.filters.http.rbac" + }, + { + "name": "envoy.router" + } + ], + "rds": { + "config_source": { + "ads": { + } + }, + "route_config_name": "default" }, - "stat_prefix": "connect_authz" - } - }, - { - "name": "envoy.tcp_proxy", - "config": { - "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "stat_prefix": "terminating_gateway_default_web_default_tcp" + "stat_prefix": "terminating_gateway_default_web_default_http", + "tracing": { + "operation_name": "EGRESS", + "random_sampling": { + } + } } } ] diff --git a/agent/xds/testdata/listeners/terminating-gateway-service-subsets.envoy-1-14-x.golden b/agent/xds/testdata/listeners/terminating-gateway-service-subsets.envoy-1-14-x.golden index c77782da2..c6ab6ce7c 100644 --- a/agent/xds/testdata/listeners/terminating-gateway-service-subsets.envoy-1-14-x.golden +++ b/agent/xds/testdata/listeners/terminating-gateway-service-subsets.envoy-1-14-x.golden @@ -183,18 +183,33 @@ }, "filters": [ { - "name": "envoy.filters.network.rbac", + "name": "envoy.http_connection_manager", "config": { - "rules": { + "http_filters": [ + { + "config": { + "rules": { + } + }, + "name": "envoy.filters.http.rbac" + }, + { + "name": "envoy.router" + } + ], + "rds": { + "config_source": { + "ads": { + } + }, + "route_config_name": "default" }, - "stat_prefix": "connect_authz" - } - }, - { - "name": "envoy.tcp_proxy", - "config": { - "cluster": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "stat_prefix": "terminating_gateway_default_web_default_tcp" + "stat_prefix": "terminating_gateway_default_web_default_http", + "tracing": { + "operation_name": "EGRESS", + "random_sampling": { + } + } } } ] @@ -230,18 +245,33 @@ }, "filters": [ { - "name": "envoy.filters.network.rbac", + "name": "envoy.http_connection_manager", "config": { - "rules": { + "http_filters": [ + { + "config": { + "rules": { + } + }, + "name": "envoy.filters.http.rbac" + }, + { + "name": "envoy.router" + } + ], + "rds": { + "config_source": { + "ads": { + } + }, + "route_config_name": "default" }, - "stat_prefix": "connect_authz" - } - }, - { - "name": "envoy.tcp_proxy", - "config": { - "cluster": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "stat_prefix": "terminating_gateway_default_web_default_tcp" + "stat_prefix": "terminating_gateway_default_web_default_http", + "tracing": { + "operation_name": "EGRESS", + "random_sampling": { + } + } } } ] @@ -277,18 +307,33 @@ }, "filters": [ { - "name": "envoy.filters.network.rbac", + "name": "envoy.http_connection_manager", "config": { - "rules": { + "http_filters": [ + { + "config": { + "rules": { + } + }, + "name": "envoy.filters.http.rbac" + }, + { + "name": "envoy.router" + } + ], + "rds": { + "config_source": { + "ads": { + } + }, + "route_config_name": "default" }, - "stat_prefix": "connect_authz" - } - }, - { - "name": "envoy.tcp_proxy", - "config": { - "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "stat_prefix": "terminating_gateway_default_web_default_tcp" + "stat_prefix": "terminating_gateway_default_web_default_http", + "tracing": { + "operation_name": "EGRESS", + "random_sampling": { + } + } } } ] diff --git a/agent/xds/testdata/listeners/terminating-gateway-service-subsets.envoy-1-15-x.golden b/agent/xds/testdata/listeners/terminating-gateway-service-subsets.envoy-1-15-x.golden index c77782da2..c6ab6ce7c 100644 --- a/agent/xds/testdata/listeners/terminating-gateway-service-subsets.envoy-1-15-x.golden +++ b/agent/xds/testdata/listeners/terminating-gateway-service-subsets.envoy-1-15-x.golden @@ -183,18 +183,33 @@ }, "filters": [ { - "name": "envoy.filters.network.rbac", + "name": "envoy.http_connection_manager", "config": { - "rules": { + "http_filters": [ + { + "config": { + "rules": { + } + }, + "name": "envoy.filters.http.rbac" + }, + { + "name": "envoy.router" + } + ], + "rds": { + "config_source": { + "ads": { + } + }, + "route_config_name": "default" }, - "stat_prefix": "connect_authz" - } - }, - { - "name": "envoy.tcp_proxy", - "config": { - "cluster": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "stat_prefix": "terminating_gateway_default_web_default_tcp" + "stat_prefix": "terminating_gateway_default_web_default_http", + "tracing": { + "operation_name": "EGRESS", + "random_sampling": { + } + } } } ] @@ -230,18 +245,33 @@ }, "filters": [ { - "name": "envoy.filters.network.rbac", + "name": "envoy.http_connection_manager", "config": { - "rules": { + "http_filters": [ + { + "config": { + "rules": { + } + }, + "name": "envoy.filters.http.rbac" + }, + { + "name": "envoy.router" + } + ], + "rds": { + "config_source": { + "ads": { + } + }, + "route_config_name": "default" }, - "stat_prefix": "connect_authz" - } - }, - { - "name": "envoy.tcp_proxy", - "config": { - "cluster": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "stat_prefix": "terminating_gateway_default_web_default_tcp" + "stat_prefix": "terminating_gateway_default_web_default_http", + "tracing": { + "operation_name": "EGRESS", + "random_sampling": { + } + } } } ] @@ -277,18 +307,33 @@ }, "filters": [ { - "name": "envoy.filters.network.rbac", + "name": "envoy.http_connection_manager", "config": { - "rules": { + "http_filters": [ + { + "config": { + "rules": { + } + }, + "name": "envoy.filters.http.rbac" + }, + { + "name": "envoy.router" + } + ], + "rds": { + "config_source": { + "ads": { + } + }, + "route_config_name": "default" }, - "stat_prefix": "connect_authz" - } - }, - { - "name": "envoy.tcp_proxy", - "config": { - "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "stat_prefix": "terminating_gateway_default_web_default_tcp" + "stat_prefix": "terminating_gateway_default_web_default_http", + "tracing": { + "operation_name": "EGRESS", + "random_sampling": { + } + } } } ] diff --git a/agent/xds/testdata/listeners/terminating-gateway.envoy-1-12-x.golden b/agent/xds/testdata/listeners/terminating-gateway.envoy-1-12-x.golden index eba577e6c..3ef59ad7d 100644 --- a/agent/xds/testdata/listeners/terminating-gateway.envoy-1-12-x.golden +++ b/agent/xds/testdata/listeners/terminating-gateway.envoy-1-12-x.golden @@ -183,18 +183,33 @@ }, "filters": [ { - "name": "envoy.filters.network.rbac", + "name": "envoy.http_connection_manager", "config": { - "rules": { + "http_filters": [ + { + "config": { + "rules": { + } + }, + "name": "envoy.filters.http.rbac" + }, + { + "name": "envoy.router" + } + ], + "rds": { + "config_source": { + "ads": { + } + }, + "route_config_name": "default" }, - "stat_prefix": "connect_authz" - } - }, - { - "name": "envoy.tcp_proxy", - "config": { - "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "stat_prefix": "terminating_gateway_default_web_default_tcp" + "stat_prefix": "terminating_gateway_default_web_default_http", + "tracing": { + "operation_name": "EGRESS", + "random_sampling": { + } + } } } ] diff --git a/agent/xds/testdata/listeners/terminating-gateway.envoy-1-13-x.golden b/agent/xds/testdata/listeners/terminating-gateway.envoy-1-13-x.golden index eba577e6c..3ef59ad7d 100644 --- a/agent/xds/testdata/listeners/terminating-gateway.envoy-1-13-x.golden +++ b/agent/xds/testdata/listeners/terminating-gateway.envoy-1-13-x.golden @@ -183,18 +183,33 @@ }, "filters": [ { - "name": "envoy.filters.network.rbac", + "name": "envoy.http_connection_manager", "config": { - "rules": { + "http_filters": [ + { + "config": { + "rules": { + } + }, + "name": "envoy.filters.http.rbac" + }, + { + "name": "envoy.router" + } + ], + "rds": { + "config_source": { + "ads": { + } + }, + "route_config_name": "default" }, - "stat_prefix": "connect_authz" - } - }, - { - "name": "envoy.tcp_proxy", - "config": { - "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "stat_prefix": "terminating_gateway_default_web_default_tcp" + "stat_prefix": "terminating_gateway_default_web_default_http", + "tracing": { + "operation_name": "EGRESS", + "random_sampling": { + } + } } } ] diff --git a/agent/xds/testdata/listeners/terminating-gateway.envoy-1-14-x.golden b/agent/xds/testdata/listeners/terminating-gateway.envoy-1-14-x.golden index eba577e6c..3ef59ad7d 100644 --- a/agent/xds/testdata/listeners/terminating-gateway.envoy-1-14-x.golden +++ b/agent/xds/testdata/listeners/terminating-gateway.envoy-1-14-x.golden @@ -183,18 +183,33 @@ }, "filters": [ { - "name": "envoy.filters.network.rbac", + "name": "envoy.http_connection_manager", "config": { - "rules": { + "http_filters": [ + { + "config": { + "rules": { + } + }, + "name": "envoy.filters.http.rbac" + }, + { + "name": "envoy.router" + } + ], + "rds": { + "config_source": { + "ads": { + } + }, + "route_config_name": "default" }, - "stat_prefix": "connect_authz" - } - }, - { - "name": "envoy.tcp_proxy", - "config": { - "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "stat_prefix": "terminating_gateway_default_web_default_tcp" + "stat_prefix": "terminating_gateway_default_web_default_http", + "tracing": { + "operation_name": "EGRESS", + "random_sampling": { + } + } } } ] diff --git a/agent/xds/testdata/listeners/terminating-gateway.envoy-1-15-x.golden b/agent/xds/testdata/listeners/terminating-gateway.envoy-1-15-x.golden index eba577e6c..3ef59ad7d 100644 --- a/agent/xds/testdata/listeners/terminating-gateway.envoy-1-15-x.golden +++ b/agent/xds/testdata/listeners/terminating-gateway.envoy-1-15-x.golden @@ -183,18 +183,33 @@ }, "filters": [ { - "name": "envoy.filters.network.rbac", + "name": "envoy.http_connection_manager", "config": { - "rules": { + "http_filters": [ + { + "config": { + "rules": { + } + }, + "name": "envoy.filters.http.rbac" + }, + { + "name": "envoy.router" + } + ], + "rds": { + "config_source": { + "ads": { + } + }, + "route_config_name": "default" }, - "stat_prefix": "connect_authz" - } - }, - { - "name": "envoy.tcp_proxy", - "config": { - "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "stat_prefix": "terminating_gateway_default_web_default_tcp" + "stat_prefix": "terminating_gateway_default_web_default_http", + "tracing": { + "operation_name": "EGRESS", + "random_sampling": { + } + } } } ] diff --git a/agent/xds/testdata/routes/connect-proxy-lb-in-resolver.envoy-1-12-x.golden b/agent/xds/testdata/routes/connect-proxy-lb-in-resolver.envoy-1-12-x.golden new file mode 100644 index 000000000..6fa9287ba --- /dev/null +++ b/agent/xds/testdata/routes/connect-proxy-lb-in-resolver.envoy-1-12-x.golden @@ -0,0 +1,61 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration", + "name": "db", + "virtualHosts": [ + { + "name": "db", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "weightedClusters": { + "clusters": [ + { + "name": "something-else.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "weight": 9550 + }, + { + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "weight": 450 + } + ], + "totalWeight": 10000 + }, + "hashPolicy": [ + { + "cookie": { + "name": "chocolate-chip" + }, + "terminal": true + }, + { + "header": { + "headerName": "x-user-id" + } + }, + { + "connectionProperties": { + "sourceIp": true + }, + "terminal": true + } + ] + } + } + ] + } + ], + "validateClusters": true + } + ], + "typeUrl": "type.googleapis.com/envoy.api.v2.RouteConfiguration", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/routes/connect-proxy-lb-in-resolver.envoy-1-13-x.golden b/agent/xds/testdata/routes/connect-proxy-lb-in-resolver.envoy-1-13-x.golden new file mode 100644 index 000000000..6fa9287ba --- /dev/null +++ b/agent/xds/testdata/routes/connect-proxy-lb-in-resolver.envoy-1-13-x.golden @@ -0,0 +1,61 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration", + "name": "db", + "virtualHosts": [ + { + "name": "db", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "weightedClusters": { + "clusters": [ + { + "name": "something-else.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "weight": 9550 + }, + { + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "weight": 450 + } + ], + "totalWeight": 10000 + }, + "hashPolicy": [ + { + "cookie": { + "name": "chocolate-chip" + }, + "terminal": true + }, + { + "header": { + "headerName": "x-user-id" + } + }, + { + "connectionProperties": { + "sourceIp": true + }, + "terminal": true + } + ] + } + } + ] + } + ], + "validateClusters": true + } + ], + "typeUrl": "type.googleapis.com/envoy.api.v2.RouteConfiguration", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/routes/connect-proxy-lb-in-resolver.envoy-1-14-x.golden b/agent/xds/testdata/routes/connect-proxy-lb-in-resolver.envoy-1-14-x.golden new file mode 100644 index 000000000..6fa9287ba --- /dev/null +++ b/agent/xds/testdata/routes/connect-proxy-lb-in-resolver.envoy-1-14-x.golden @@ -0,0 +1,61 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration", + "name": "db", + "virtualHosts": [ + { + "name": "db", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "weightedClusters": { + "clusters": [ + { + "name": "something-else.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "weight": 9550 + }, + { + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "weight": 450 + } + ], + "totalWeight": 10000 + }, + "hashPolicy": [ + { + "cookie": { + "name": "chocolate-chip" + }, + "terminal": true + }, + { + "header": { + "headerName": "x-user-id" + } + }, + { + "connectionProperties": { + "sourceIp": true + }, + "terminal": true + } + ] + } + } + ] + } + ], + "validateClusters": true + } + ], + "typeUrl": "type.googleapis.com/envoy.api.v2.RouteConfiguration", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/routes/connect-proxy-lb-in-resolver.envoy-1-15-x.golden b/agent/xds/testdata/routes/connect-proxy-lb-in-resolver.envoy-1-15-x.golden new file mode 100644 index 000000000..6fa9287ba --- /dev/null +++ b/agent/xds/testdata/routes/connect-proxy-lb-in-resolver.envoy-1-15-x.golden @@ -0,0 +1,61 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration", + "name": "db", + "virtualHosts": [ + { + "name": "db", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "weightedClusters": { + "clusters": [ + { + "name": "something-else.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "weight": 9550 + }, + { + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "weight": 450 + } + ], + "totalWeight": 10000 + }, + "hashPolicy": [ + { + "cookie": { + "name": "chocolate-chip" + }, + "terminal": true + }, + { + "header": { + "headerName": "x-user-id" + } + }, + { + "connectionProperties": { + "sourceIp": true + }, + "terminal": true + } + ] + } + } + ] + } + ], + "validateClusters": true + } + ], + "typeUrl": "type.googleapis.com/envoy.api.v2.RouteConfiguration", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/routes/ingress-lb-in-resolver.envoy-1-12-x.golden b/agent/xds/testdata/routes/ingress-lb-in-resolver.envoy-1-12-x.golden new file mode 100644 index 000000000..1dce540e7 --- /dev/null +++ b/agent/xds/testdata/routes/ingress-lb-in-resolver.envoy-1-12-x.golden @@ -0,0 +1,62 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration", + "name": "9191", + "virtualHosts": [ + { + "name": "db", + "domains": [ + "db.ingress.*", + "db.ingress.*:9191" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "weightedClusters": { + "clusters": [ + { + "name": "something-else.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "weight": 9550 + }, + { + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "weight": 450 + } + ], + "totalWeight": 10000 + }, + "hashPolicy": [ + { + "cookie": { + "name": "chocolate-chip" + }, + "terminal": true + }, + { + "header": { + "headerName": "x-user-id" + } + }, + { + "connectionProperties": { + "sourceIp": true + }, + "terminal": true + } + ] + } + } + ] + } + ], + "validateClusters": true + } + ], + "typeUrl": "type.googleapis.com/envoy.api.v2.RouteConfiguration", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/routes/ingress-lb-in-resolver.envoy-1-13-x.golden b/agent/xds/testdata/routes/ingress-lb-in-resolver.envoy-1-13-x.golden new file mode 100644 index 000000000..1dce540e7 --- /dev/null +++ b/agent/xds/testdata/routes/ingress-lb-in-resolver.envoy-1-13-x.golden @@ -0,0 +1,62 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration", + "name": "9191", + "virtualHosts": [ + { + "name": "db", + "domains": [ + "db.ingress.*", + "db.ingress.*:9191" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "weightedClusters": { + "clusters": [ + { + "name": "something-else.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "weight": 9550 + }, + { + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "weight": 450 + } + ], + "totalWeight": 10000 + }, + "hashPolicy": [ + { + "cookie": { + "name": "chocolate-chip" + }, + "terminal": true + }, + { + "header": { + "headerName": "x-user-id" + } + }, + { + "connectionProperties": { + "sourceIp": true + }, + "terminal": true + } + ] + } + } + ] + } + ], + "validateClusters": true + } + ], + "typeUrl": "type.googleapis.com/envoy.api.v2.RouteConfiguration", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/routes/ingress-lb-in-resolver.envoy-1-14-x.golden b/agent/xds/testdata/routes/ingress-lb-in-resolver.envoy-1-14-x.golden new file mode 100644 index 000000000..1dce540e7 --- /dev/null +++ b/agent/xds/testdata/routes/ingress-lb-in-resolver.envoy-1-14-x.golden @@ -0,0 +1,62 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration", + "name": "9191", + "virtualHosts": [ + { + "name": "db", + "domains": [ + "db.ingress.*", + "db.ingress.*:9191" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "weightedClusters": { + "clusters": [ + { + "name": "something-else.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "weight": 9550 + }, + { + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "weight": 450 + } + ], + "totalWeight": 10000 + }, + "hashPolicy": [ + { + "cookie": { + "name": "chocolate-chip" + }, + "terminal": true + }, + { + "header": { + "headerName": "x-user-id" + } + }, + { + "connectionProperties": { + "sourceIp": true + }, + "terminal": true + } + ] + } + } + ] + } + ], + "validateClusters": true + } + ], + "typeUrl": "type.googleapis.com/envoy.api.v2.RouteConfiguration", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/routes/ingress-lb-in-resolver.envoy-1-15-x.golden b/agent/xds/testdata/routes/ingress-lb-in-resolver.envoy-1-15-x.golden new file mode 100644 index 000000000..1dce540e7 --- /dev/null +++ b/agent/xds/testdata/routes/ingress-lb-in-resolver.envoy-1-15-x.golden @@ -0,0 +1,62 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration", + "name": "9191", + "virtualHosts": [ + { + "name": "db", + "domains": [ + "db.ingress.*", + "db.ingress.*:9191" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "weightedClusters": { + "clusters": [ + { + "name": "something-else.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "weight": 9550 + }, + { + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "weight": 450 + } + ], + "totalWeight": 10000 + }, + "hashPolicy": [ + { + "cookie": { + "name": "chocolate-chip" + }, + "terminal": true + }, + { + "header": { + "headerName": "x-user-id" + } + }, + { + "connectionProperties": { + "sourceIp": true + }, + "terminal": true + } + ] + } + } + ] + } + ], + "validateClusters": true + } + ], + "typeUrl": "type.googleapis.com/envoy.api.v2.RouteConfiguration", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-12-x.golden b/agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-12-x.golden new file mode 100644 index 000000000..b611e2508 --- /dev/null +++ b/agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-12-x.golden @@ -0,0 +1,133 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration", + "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "virtualHosts": [ + { + "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "hashPolicy": [ + { + "cookie": { + "name": "chocolate-chip" + }, + "terminal": true + }, + { + "header": { + "headerName": "x-user-id" + } + }, + { + "connectionProperties": { + "sourceIp": true + }, + "terminal": true + } + ] + } + } + ] + } + ], + "validateClusters": true + }, + { + "@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration", + "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "virtualHosts": [ + { + "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "hashPolicy": [ + { + "cookie": { + "name": "chocolate-chip" + }, + "terminal": true + }, + { + "header": { + "headerName": "x-user-id" + } + }, + { + "connectionProperties": { + "sourceIp": true + }, + "terminal": true + } + ] + } + } + ] + } + ], + "validateClusters": true + }, + { + "@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration", + "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "virtualHosts": [ + { + "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "hashPolicy": [ + { + "cookie": { + "name": "chocolate-chip" + }, + "terminal": true + }, + { + "header": { + "headerName": "x-user-id" + } + }, + { + "connectionProperties": { + "sourceIp": true + }, + "terminal": true + } + ] + } + } + ] + } + ], + "validateClusters": true + } + ], + "typeUrl": "type.googleapis.com/envoy.api.v2.RouteConfiguration", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-13-x.golden b/agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-13-x.golden new file mode 100644 index 000000000..b611e2508 --- /dev/null +++ b/agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-13-x.golden @@ -0,0 +1,133 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration", + "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "virtualHosts": [ + { + "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "hashPolicy": [ + { + "cookie": { + "name": "chocolate-chip" + }, + "terminal": true + }, + { + "header": { + "headerName": "x-user-id" + } + }, + { + "connectionProperties": { + "sourceIp": true + }, + "terminal": true + } + ] + } + } + ] + } + ], + "validateClusters": true + }, + { + "@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration", + "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "virtualHosts": [ + { + "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "hashPolicy": [ + { + "cookie": { + "name": "chocolate-chip" + }, + "terminal": true + }, + { + "header": { + "headerName": "x-user-id" + } + }, + { + "connectionProperties": { + "sourceIp": true + }, + "terminal": true + } + ] + } + } + ] + } + ], + "validateClusters": true + }, + { + "@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration", + "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "virtualHosts": [ + { + "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "hashPolicy": [ + { + "cookie": { + "name": "chocolate-chip" + }, + "terminal": true + }, + { + "header": { + "headerName": "x-user-id" + } + }, + { + "connectionProperties": { + "sourceIp": true + }, + "terminal": true + } + ] + } + } + ] + } + ], + "validateClusters": true + } + ], + "typeUrl": "type.googleapis.com/envoy.api.v2.RouteConfiguration", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-14-x.golden b/agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-14-x.golden new file mode 100644 index 000000000..b611e2508 --- /dev/null +++ b/agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-14-x.golden @@ -0,0 +1,133 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration", + "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "virtualHosts": [ + { + "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "hashPolicy": [ + { + "cookie": { + "name": "chocolate-chip" + }, + "terminal": true + }, + { + "header": { + "headerName": "x-user-id" + } + }, + { + "connectionProperties": { + "sourceIp": true + }, + "terminal": true + } + ] + } + } + ] + } + ], + "validateClusters": true + }, + { + "@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration", + "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "virtualHosts": [ + { + "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "hashPolicy": [ + { + "cookie": { + "name": "chocolate-chip" + }, + "terminal": true + }, + { + "header": { + "headerName": "x-user-id" + } + }, + { + "connectionProperties": { + "sourceIp": true + }, + "terminal": true + } + ] + } + } + ] + } + ], + "validateClusters": true + }, + { + "@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration", + "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "virtualHosts": [ + { + "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "hashPolicy": [ + { + "cookie": { + "name": "chocolate-chip" + }, + "terminal": true + }, + { + "header": { + "headerName": "x-user-id" + } + }, + { + "connectionProperties": { + "sourceIp": true + }, + "terminal": true + } + ] + } + } + ] + } + ], + "validateClusters": true + } + ], + "typeUrl": "type.googleapis.com/envoy.api.v2.RouteConfiguration", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-15-x.golden b/agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-15-x.golden new file mode 100644 index 000000000..b611e2508 --- /dev/null +++ b/agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-15-x.golden @@ -0,0 +1,133 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration", + "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "virtualHosts": [ + { + "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "hashPolicy": [ + { + "cookie": { + "name": "chocolate-chip" + }, + "terminal": true + }, + { + "header": { + "headerName": "x-user-id" + } + }, + { + "connectionProperties": { + "sourceIp": true + }, + "terminal": true + } + ] + } + } + ] + } + ], + "validateClusters": true + }, + { + "@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration", + "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "virtualHosts": [ + { + "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "hashPolicy": [ + { + "cookie": { + "name": "chocolate-chip" + }, + "terminal": true + }, + { + "header": { + "headerName": "x-user-id" + } + }, + { + "connectionProperties": { + "sourceIp": true + }, + "terminal": true + } + ] + } + } + ] + } + ], + "validateClusters": true + }, + { + "@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration", + "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "virtualHosts": [ + { + "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "hashPolicy": [ + { + "cookie": { + "name": "chocolate-chip" + }, + "terminal": true + }, + { + "header": { + "headerName": "x-user-id" + } + }, + { + "connectionProperties": { + "sourceIp": true + }, + "terminal": true + } + ] + } + } + ] + } + ], + "validateClusters": true + } + ], + "typeUrl": "type.googleapis.com/envoy.api.v2.RouteConfiguration", + "nonce": "00000001" +} \ No newline at end of file From 58a018c20bc892d81ae83b849c8dca1e9d3aea50 Mon Sep 17 00:00:00 2001 From: freddygv Date: Fri, 28 Aug 2020 14:46:13 -0600 Subject: [PATCH 05/20] Add documentation for resolver LB cfg --- agent/structs/config_entry_discoverychain.go | 6 +- api/config_entry_discoverychain.go | 4 +- .../agent/config-entries/service-resolver.mdx | 68 ++++++++++++++++++- 3 files changed, 71 insertions(+), 7 deletions(-) diff --git a/agent/structs/config_entry_discoverychain.go b/agent/structs/config_entry_discoverychain.go index c87b46f00..79a33cb48 100644 --- a/agent/structs/config_entry_discoverychain.go +++ b/agent/structs/config_entry_discoverychain.go @@ -1028,10 +1028,10 @@ func (l LoadBalancer) IsHashBased() bool { // RingHashConfig contains configuration for the "ring_hash" policy type type RingHashConfig struct { - // MinimumRingSize determines the minimum number of hashes per destination host + // MinimumRingSize determines the minimum number of entries in the hash ring MinimumRingSize uint64 `json:",omitempty" alias:"minimum_ring_size"` - // MaximumRingSize determines the maximum number of hashes per destination host + // MaximumRingSize determines the maximum number of entries in the hash ring MaximumRingSize uint64 `json:",omitempty" alias:"maximum_ring_size"` } @@ -1058,7 +1058,7 @@ type HashPolicy struct { FieldMatchValue string `json:",omitempty" alias:"field_value"` // SourceAddress determines whether the hash should be of the source IP rather than of a field and field value. - // Cannot be specified along with Field and FieldMatchValue. + // Cannot be specified along with Field or FieldMatchValue. SourceAddress bool `json:",omitempty" alias:"source_address"` // Terminal will short circuit the computation of the hash when multiple hash policies are present. diff --git a/api/config_entry_discoverychain.go b/api/config_entry_discoverychain.go index 0bfd3dde2..5e1636fe8 100644 --- a/api/config_entry_discoverychain.go +++ b/api/config_entry_discoverychain.go @@ -228,10 +228,10 @@ type LoadBalancer struct { // RingHashConfig contains configuration for the "ring_hash" policy type type RingHashConfig struct { - // MinimumRingSize determines the minimum number of hashes per destination host + // MinimumRingSize determines the minimum number of entries in the hash ring MinimumRingSize uint64 `json:",omitempty" alias:"minimum_ring_size"` - // MaximumRingSize determines the maximum number of hashes per destination host + // MaximumRingSize determines the maximum number of entries in the hash ring MaximumRingSize uint64 `json:",omitempty" alias:"maximum_ring_size"` } diff --git a/website/pages/docs/agent/config-entries/service-resolver.mdx b/website/pages/docs/agent/config-entries/service-resolver.mdx index 7c418604a..d0cd54988 100644 --- a/website/pages/docs/agent/config-entries/service-resolver.mdx +++ b/website/pages/docs/agent/config-entries/service-resolver.mdx @@ -72,6 +72,23 @@ Kind = "service-resolver" Name = "web" ``` +Apply consistent load balancing for requests based on `x-user-id` header: + +```hcl +Kind = "service-resolver" +Name = "web" + +LoadBalancer = { + Policy = "maglev" + HashPolicies = [ + { + Field = "header" + FieldMatchValue = "x-user-id" + } + ] +} +``` + ## Available Fields - `Kind` - Must be set to `service-resolver` @@ -117,8 +134,8 @@ Name = "web" resolve instead of one defined as that service's DefaultSubset If empty the default subset is used. - If this is specified at least one of Service, Datacenter, or Namespace - should be configured. + If this is specified at least one of Service, Datacenter, or Namespace + should be configured. - `Namespace` `(string: "")` - The namespace to resolve the service from instead of the current one. @@ -149,6 +166,53 @@ Name = "web" - `Datacenters` `(array)` - A fixed list of datacenters to try during failover. + +- `LoadBalancer` `(LoadBalancer`) - Determines the load balancing policy and + configuration for services issuing requests to this upstream. + This option is available in Consul versions 1.8.4 and newer. + + **Note:** The options below are specific to Envoy proxy. + + - `Policy` `(string: "")` - The load balancing policy used to select a host. + One of: `random`, `round_robin`, `least_request`, `ring_hash`, `maglev`. + + - `RingHashConfig` `(RingHashConfig)` - Configuration for the `ring_hash` + policy type. + + - `MinimumRingRize` `(int: 1024)` - Determines the minimum number of entries + in the hash ring. + + - `MaximumRingRize` `(int: 8192)` - Determines the maximum number of entries + in the hash ring. + + - `LeastRequestConfig` `(LeastRequestConfig)` - Configuration for the `least_request` + policy type. + + - `ChoiceCount` `(int: 2)` - Determines the number of random healthy hosts + from which to select the one with the least requests. + + - `HashPolicies` `(array)` - a list of hash policies to use for + hashing load balancing algorithms. Hash policies are evaluated individually + and combined such that identical lists result in the same hash. + If no hash policies are present, or none are successfully evaluated, + then a random backend host will be selected. + + - `Field` `(string: "")` - The attribute type to hash on. + Must be one of `header`,`cookie`, or `query_parameter`. + Cannot be specified along with `SourceAddress`. + + - `FieldMatchValue` `(string: "")` - The value to hash. + ie. header name, cookie name, URL query parameter name. + Cannot be specified along with `SourceAddress`. + + - `SourceAddress` `(bool: false)` - Determines whether the hash should be of the source IP + address rather than of a field and field value. + Cannot be specified along with `Field` or `FieldMatchValue`. + + - `Terminal` `(bool: false)` - Will short circuit the computation of the hash + when multiple hash policies are present. If a hash is computed when a + Terminal policy is evaluated, then that hash will be used and subsequent + hash policies will be ignored. ## Service Subsets From d7bda050e08408c61a1fbc2fff3f008bc841a38f Mon Sep 17 00:00:00 2001 From: freddygv Date: Wed, 2 Sep 2020 09:10:50 -0600 Subject: [PATCH 06/20] Restructure structs and other PR comments --- agent/consul/discoverychain/compile.go | 8 +- agent/consul/discoverychain/compile_test.go | 168 +++--- agent/proxycfg/testing.go | 38 +- agent/structs/config_entry_discoverychain.go | 277 +++++++--- .../config_entry_discoverychain_test.go | 507 +++++++++++++++--- agent/structs/discovery_chain.go | 2 +- agent/xds/clusters.go | 66 +-- agent/xds/clusters_test.go | 118 +--- agent/xds/routes.go | 95 +--- agent/xds/routes_test.go | 214 +------- ...ignore-extra-resolvers.envoy-1-12-x.golden | 32 -- ...ignore-extra-resolvers.envoy-1-13-x.golden | 32 -- ...ignore-extra-resolvers.envoy-1-14-x.golden | 32 -- ...ignore-extra-resolvers.envoy-1-15-x.golden | 32 -- ...ateway-service-subsets.envoy-1-12-x.golden | 32 -- ...ateway-service-subsets.envoy-1-13-x.golden | 32 -- ...ateway-service-subsets.envoy-1-14-x.golden | 32 -- ...ateway-service-subsets.envoy-1-15-x.golden | 32 -- ...teway-service-timeouts.envoy-1-12-x.golden | 34 +- ...teway-service-timeouts.envoy-1-13-x.golden | 34 +- ...teway-service-timeouts.envoy-1-14-x.golden | 34 +- ...teway-service-timeouts.envoy-1-15-x.golden | 34 +- ...stname-service-subsets.envoy-1-12-x.golden | 86 --- ...stname-service-subsets.envoy-1-13-x.golden | 86 --- ...stname-service-subsets.envoy-1-14-x.golden | 86 --- ...stname-service-subsets.envoy-1-15-x.golden | 86 --- ...ignore-extra-resolvers.envoy-1-12-x.golden | 56 -- ...ignore-extra-resolvers.envoy-1-13-x.golden | 56 -- ...ignore-extra-resolvers.envoy-1-14-x.golden | 56 -- ...ignore-extra-resolvers.envoy-1-15-x.golden | 56 -- ...ateway-service-subsets.envoy-1-12-x.golden | 88 --- ...ateway-service-subsets.envoy-1-13-x.golden | 88 --- ...ateway-service-subsets.envoy-1-14-x.golden | 88 --- ...ateway-service-subsets.envoy-1-15-x.golden | 88 --- ...ting-gateway-lb-config.envoy-1-12-x.golden | 75 +-- ...ting-gateway-lb-config.envoy-1-13-x.golden | 75 +-- ...ting-gateway-lb-config.envoy-1-14-x.golden | 75 +-- ...ting-gateway-lb-config.envoy-1-15-x.golden | 75 +-- api/config_entry_discoverychain.go | 43 +- api/config_entry_discoverychain_test.go | 44 +- command/config/write/config_write_test.go | 230 ++++++++ .../agent/config-entries/service-resolver.mdx | 84 +-- .../pages/docs/internals/discovery-chain.mdx | 6 + 43 files changed, 1228 insertions(+), 2284 deletions(-) diff --git a/agent/consul/discoverychain/compile.go b/agent/consul/discoverychain/compile.go index d94667787..31c3baa96 100644 --- a/agent/consul/discoverychain/compile.go +++ b/agent/consul/discoverychain/compile.go @@ -745,9 +745,11 @@ func (c *compiler) getSplitterNode(sid structs.ServiceID) (*structs.DiscoveryGra // with distinct hash-based load balancer configs specified in their service resolvers. // We cannot apply multiple hash policies to a splitter node's route action. // Therefore, we attach the first hash-based load balancer config we encounter. - if !hasLB && node.LoadBalancer.IsHashBased() { - splitNode.LoadBalancer = node.LoadBalancer - hasLB = true + if !hasLB { + if lb := node.LoadBalancer; lb != nil && lb.EnvoyLBConfig != nil && lb.EnvoyLBConfig.IsHashBased() { + splitNode.LoadBalancer = node.LoadBalancer + hasLB = true + } } } diff --git a/agent/consul/discoverychain/compile_test.go b/agent/consul/discoverychain/compile_test.go index e5aca02b4..420436272 100644 --- a/agent/consul/discoverychain/compile_test.go +++ b/agent/consul/discoverychain/compile_test.go @@ -1761,14 +1761,16 @@ func testcase_AllBellsAndWhistles() compileTestCase { "prod": {Filter: "ServiceMeta.env == prod"}, "qa": {Filter: "ServiceMeta.env == qa"}, }, - LoadBalancer: structs.LoadBalancer{ - Policy: "ring_hash", - RingHashConfig: structs.RingHashConfig{ - MaximumRingSize: 100, - }, - HashPolicies: []structs.HashPolicy{ - { - SourceAddress: true, + LoadBalancer: &structs.LoadBalancer{ + EnvoyLBConfig: &structs.EnvoyLBConfig{ + Policy: "ring_hash", + RingHashConfig: &structs.RingHashConfig{ + MaximumRingSize: 100, + }, + HashPolicies: []structs.HashPolicy{ + { + SourceIP: true, + }, }, }, }, @@ -1833,14 +1835,16 @@ func testcase_AllBellsAndWhistles() compileTestCase { NextNode: "resolver:v3.main.default.dc1", }, }, - LoadBalancer: structs.LoadBalancer{ - Policy: "ring_hash", - RingHashConfig: structs.RingHashConfig{ - MaximumRingSize: 100, - }, - HashPolicies: []structs.HashPolicy{ - { - SourceAddress: true, + LoadBalancer: &structs.LoadBalancer{ + EnvoyLBConfig: &structs.EnvoyLBConfig{ + Policy: "ring_hash", + RingHashConfig: &structs.RingHashConfig{ + MaximumRingSize: 100, + }, + HashPolicies: []structs.HashPolicy{ + { + SourceIP: true, + }, }, }, }, @@ -1852,14 +1856,16 @@ func testcase_AllBellsAndWhistles() compileTestCase { ConnectTimeout: 5 * time.Second, Target: "prod.redirected.default.dc1", }, - LoadBalancer: structs.LoadBalancer{ - Policy: "ring_hash", - RingHashConfig: structs.RingHashConfig{ - MaximumRingSize: 100, - }, - HashPolicies: []structs.HashPolicy{ - { - SourceAddress: true, + LoadBalancer: &structs.LoadBalancer{ + EnvoyLBConfig: &structs.EnvoyLBConfig{ + Policy: "ring_hash", + RingHashConfig: &structs.RingHashConfig{ + MaximumRingSize: 100, + }, + HashPolicies: []structs.HashPolicy{ + { + SourceIP: true, + }, }, }, }, @@ -2275,24 +2281,28 @@ func testcase_LBConfig() compileTestCase { &structs.ServiceResolverConfigEntry{ Kind: "service-resolver", Name: "foo", - LoadBalancer: structs.LoadBalancer{ - Policy: "least_request", - LeastRequestConfig: structs.LeastRequestConfig{ - ChoiceCount: 3, + LoadBalancer: &structs.LoadBalancer{ + EnvoyLBConfig: &structs.EnvoyLBConfig{ + Policy: "least_request", + LeastRequestConfig: &structs.LeastRequestConfig{ + ChoiceCount: 3, + }, }, }, }, &structs.ServiceResolverConfigEntry{ Kind: "service-resolver", Name: "bar", - LoadBalancer: structs.LoadBalancer{ - Policy: "ring_hash", - RingHashConfig: structs.RingHashConfig{ - MaximumRingSize: 101, - }, - HashPolicies: []structs.HashPolicy{ - { - SourceAddress: true, + LoadBalancer: &structs.LoadBalancer{ + EnvoyLBConfig: &structs.EnvoyLBConfig{ + Policy: "ring_hash", + RingHashConfig: &structs.RingHashConfig{ + MaximumRingSize: 101, + }, + HashPolicies: []structs.HashPolicy{ + { + SourceIP: true, + }, }, }, }, @@ -2300,13 +2310,19 @@ func testcase_LBConfig() compileTestCase { &structs.ServiceResolverConfigEntry{ Kind: "service-resolver", Name: "baz", - LoadBalancer: structs.LoadBalancer{ - Policy: "maglev", - HashPolicies: []structs.HashPolicy{ - { - Field: "cookie", - FieldMatchValue: "chocolate-chip", - Terminal: true, + LoadBalancer: &structs.LoadBalancer{ + EnvoyLBConfig: &structs.EnvoyLBConfig{ + Policy: "maglev", + HashPolicies: []structs.HashPolicy{ + { + Field: "cookie", + FieldValue: "chocolate-chip", + CookieConfig: &structs.CookieConfig{ + TTL: 2 * time.Minute, + Path: "/bowl", + }, + Terminal: true, + }, }, }, }, @@ -2336,14 +2352,16 @@ func testcase_LBConfig() compileTestCase { }, // The LB config from bar is attached because splitters only care about hash-based policies, // and it's the config from bar not baz because we pick the first one we encounter in the Splits. - LoadBalancer: structs.LoadBalancer{ - Policy: "ring_hash", - RingHashConfig: structs.RingHashConfig{ - MaximumRingSize: 101, - }, - HashPolicies: []structs.HashPolicy{ - { - SourceAddress: true, + LoadBalancer: &structs.LoadBalancer{ + EnvoyLBConfig: &structs.EnvoyLBConfig{ + Policy: "ring_hash", + RingHashConfig: &structs.RingHashConfig{ + MaximumRingSize: 101, + }, + HashPolicies: []structs.HashPolicy{ + { + SourceIP: true, + }, }, }, }, @@ -2357,10 +2375,12 @@ func testcase_LBConfig() compileTestCase { ConnectTimeout: 5 * time.Second, Target: "foo.default.dc1", }, - LoadBalancer: structs.LoadBalancer{ - Policy: "least_request", - LeastRequestConfig: structs.LeastRequestConfig{ - ChoiceCount: 3, + LoadBalancer: &structs.LoadBalancer{ + EnvoyLBConfig: &structs.EnvoyLBConfig{ + Policy: "least_request", + LeastRequestConfig: &structs.LeastRequestConfig{ + ChoiceCount: 3, + }, }, }, }, @@ -2372,14 +2392,16 @@ func testcase_LBConfig() compileTestCase { ConnectTimeout: 5 * time.Second, Target: "bar.default.dc1", }, - LoadBalancer: structs.LoadBalancer{ - Policy: "ring_hash", - RingHashConfig: structs.RingHashConfig{ - MaximumRingSize: 101, - }, - HashPolicies: []structs.HashPolicy{ - { - SourceAddress: true, + LoadBalancer: &structs.LoadBalancer{ + EnvoyLBConfig: &structs.EnvoyLBConfig{ + Policy: "ring_hash", + RingHashConfig: &structs.RingHashConfig{ + MaximumRingSize: 101, + }, + HashPolicies: []structs.HashPolicy{ + { + SourceIP: true, + }, }, }, }, @@ -2392,13 +2414,19 @@ func testcase_LBConfig() compileTestCase { ConnectTimeout: 5 * time.Second, Target: "baz.default.dc1", }, - LoadBalancer: structs.LoadBalancer{ - Policy: "maglev", - HashPolicies: []structs.HashPolicy{ - { - Field: "cookie", - FieldMatchValue: "chocolate-chip", - Terminal: true, + LoadBalancer: &structs.LoadBalancer{ + EnvoyLBConfig: &structs.EnvoyLBConfig{ + Policy: "maglev", + HashPolicies: []structs.HashPolicy{ + { + Field: "cookie", + FieldValue: "chocolate-chip", + CookieConfig: &structs.CookieConfig{ + TTL: 2 * time.Minute, + Path: "/bowl", + }, + Terminal: true, + }, }, }, }, diff --git a/agent/proxycfg/testing.go b/agent/proxycfg/testing.go index 96a4c8749..0ed1acd12 100644 --- a/agent/proxycfg/testing.go +++ b/agent/proxycfg/testing.go @@ -1274,25 +1274,27 @@ func setupTestVariationConfigEntriesAndSnapshot( &structs.ServiceResolverConfigEntry{ Kind: structs.ServiceResolver, Name: "db", - LoadBalancer: structs.LoadBalancer{ - Policy: "ring_hash", - RingHashConfig: structs.RingHashConfig{ - MinimumRingSize: 20, - MaximumRingSize: 30, - }, - HashPolicies: []structs.HashPolicy{ - { - Field: "cookie", - FieldMatchValue: "chocolate-chip", - Terminal: true, + LoadBalancer: &structs.LoadBalancer{ + EnvoyLBConfig: &structs.EnvoyLBConfig{ + Policy: "ring_hash", + RingHashConfig: &structs.RingHashConfig{ + MinimumRingSize: 20, + MaximumRingSize: 30, }, - { - Field: "header", - FieldMatchValue: "x-user-id", - }, - { - SourceAddress: true, - Terminal: true, + HashPolicies: []structs.HashPolicy{ + { + Field: "cookie", + FieldValue: "chocolate-chip", + Terminal: true, + }, + { + Field: "header", + FieldValue: "x-user-id", + }, + { + SourceIP: true, + Terminal: true, + }, }, }, }, diff --git a/agent/structs/config_entry_discoverychain.go b/agent/structs/config_entry_discoverychain.go index 79a33cb48..e033f674f 100644 --- a/agent/structs/config_entry_discoverychain.go +++ b/agent/structs/config_entry_discoverychain.go @@ -3,6 +3,7 @@ package structs import ( "encoding/json" "fmt" + "github.com/golang/protobuf/ptypes" "math" "regexp" "sort" @@ -10,12 +11,29 @@ import ( "strings" "time" + envoy "github.com/envoyproxy/go-control-plane/envoy/api/v2" + envoyroute "github.com/envoyproxy/go-control-plane/envoy/api/v2/route" + "github.com/golang/protobuf/ptypes/wrappers" "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/agent/cache" "github.com/hashicorp/consul/lib" "github.com/mitchellh/hashstructure" ) +const ( + // Names of Envoy's LB policies + LBPolicyMaglev = "maglev" + LBPolicyRingHash = "ring_hash" + LBPolicyRandom = "random" + LBPolicyLeastRequest = "least_request" + LBPolicyRoundRobin = "round_robin" + + // Names of Envoy's LB policies + HashPolicyCookie = "cookie" + HashPolicyHeader = "header" + HashPolicyQueryParam = "query_parameter" +) + // ServiceRouterConfigEntry defines L7 (e.g. http) routing rules for a named // service exposed in Connect. // @@ -641,7 +659,7 @@ type ServiceResolverConfigEntry struct { // LoadBalancer determines the load balancing policy and configuration for services // issuing requests to this upstream service. - LoadBalancer LoadBalancer `json:",omitempty" alias:"load_balancer"` + LoadBalancer *LoadBalancer `json:",omitempty" alias:"load_balancer"` EnterpriseMeta `hcl:",squash" mapstructure:",squash"` RaftIndex @@ -811,53 +829,60 @@ func (e *ServiceResolverConfigEntry) Validate() error { return fmt.Errorf("Bad ConnectTimeout '%s', must be >= 0", e.ConnectTimeout) } - validPolicies := map[string]bool{ - "": true, - "random": true, - "round_robin": true, - "least_request": true, - "ring_hash": true, - "maglev": true, - } - if ok := validPolicies[e.LoadBalancer.Policy]; !ok { - return fmt.Errorf("Bad LoadBalancer policy: %q is not supported", e.LoadBalancer.Policy) - } + if e.LoadBalancer != nil && e.LoadBalancer.EnvoyLBConfig != nil { + ec := e.LoadBalancer.EnvoyLBConfig - if e.LoadBalancer.Policy != "ring_hash" && e.LoadBalancer.RingHashConfig != (RingHashConfig{}) { - return fmt.Errorf("Bad LoadBalancer configuration. "+ - "RingHashConfig specified for incompatible load balancing policy %q", e.LoadBalancer.Policy) - } - if e.LoadBalancer.Policy != "least_request" && e.LoadBalancer.LeastRequestConfig != (LeastRequestConfig{}) { - return fmt.Errorf("Bad LoadBalancer configuration. "+ - "LeastRequestConfig specified for incompatible load balancing policy %q", e.LoadBalancer.Policy) - } - if !e.LoadBalancer.IsHashBased() && len(e.LoadBalancer.HashPolicies) > 0 { - return fmt.Errorf("Bad LoadBalancer configuration: "+ - "HashPolicies specified for non-hash-based Policy: %q", e.LoadBalancer.Policy) - } + validPolicies := map[string]bool{ + "": true, + LBPolicyRandom: true, + LBPolicyRoundRobin: true, + LBPolicyLeastRequest: true, + LBPolicyRingHash: true, + LBPolicyMaglev: true, + } + if ok := validPolicies[ec.Policy]; !ok { + return fmt.Errorf("Bad LoadBalancer policy: %q is not supported", ec.Policy) + } - validFields := map[string]bool{ - "header": true, - "cookie": true, - "query_parameter": true, - } - for i, hp := range e.LoadBalancer.HashPolicies { - if ok := validFields[hp.Field]; hp.Field != "" && !ok { - return fmt.Errorf("Bad LoadBalancer HashPolicy[%d]: %q is not a supported field", i, hp.Field) + if ec.Policy != LBPolicyRingHash && ec.RingHashConfig != nil { + return fmt.Errorf("Bad LoadBalancer configuration. "+ + "RingHashConfig specified for incompatible load balancing policy %q", ec.Policy) } - if hp.SourceAddress && hp.Field != "" { - return fmt.Errorf("Bad LoadBalancer HashPolicy[%d]: "+ - "A single hash policy cannot hash both a source address and a %q", i, hp.Field) + if ec.Policy != LBPolicyLeastRequest && ec.LeastRequestConfig != nil { + return fmt.Errorf("Bad LoadBalancer configuration. "+ + "LeastRequestConfig specified for incompatible load balancing policy %q", ec.Policy) } - if hp.SourceAddress && hp.FieldMatchValue != "" { - return fmt.Errorf("Bad LoadBalancer HashPolicy[%d]: "+ - "A FieldMatchValue cannot be specified when hashing SourceAddress", i) + if !ec.IsHashBased() && len(ec.HashPolicies) > 0 { + return fmt.Errorf("Bad LoadBalancer configuration: "+ + "HashPolicies specified for non-hash-based Policy: %q", ec.Policy) } - if hp.Field != "" && hp.FieldMatchValue == "" { - return fmt.Errorf("Bad LoadBalancer HashPolicy[%d]: Field %q was specified without a FieldMatchValue", i, hp.Field) + + validFields := map[string]bool{ + HashPolicyHeader: true, + HashPolicyCookie: true, + HashPolicyQueryParam: true, } - if hp.FieldMatchValue != "" && hp.Field == "" { - return fmt.Errorf("Bad LoadBalancer HashPolicy[%d]: FieldMatchValue requires a Field to apply to", i) + for i, hp := range ec.HashPolicies { + if ok := validFields[hp.Field]; hp.Field != "" && !ok { + return fmt.Errorf("Bad LoadBalancer HashPolicy[%d]: %q is not a supported field", i, hp.Field) + } + if hp.SourceIP && hp.Field != "" { + return fmt.Errorf("Bad LoadBalancer HashPolicy[%d]: "+ + "A single hash policy cannot hash both a source address and a %q", i, hp.Field) + } + if hp.SourceIP && hp.FieldValue != "" { + return fmt.Errorf("Bad LoadBalancer HashPolicy[%d]: "+ + "A FieldValue cannot be specified when hashing SourceIP", i) + } + if hp.Field != "" && hp.FieldValue == "" { + return fmt.Errorf("Bad LoadBalancer HashPolicy[%d]: Field %q was specified without a FieldValue", i, hp.Field) + } + if hp.FieldValue != "" && hp.Field == "" { + return fmt.Errorf("Bad LoadBalancer HashPolicy[%d]: FieldValue requires a Field to apply to", i) + } + if hp.CookieConfig != nil && hp.Field != HashPolicyCookie { + return fmt.Errorf("Bad LoadBalancer HashPolicy[%d]: cookie_config provided for %q", i, hp.Field) + } } } @@ -1000,14 +1025,22 @@ type ServiceResolverFailover struct { // LoadBalancer determines the load balancing policy and configuration for services // issuing requests to this upstream service. type LoadBalancer struct { + // EnvoyLBConfig contains Envoy-specific load balancing configuration for this upstream + EnvoyLBConfig *EnvoyLBConfig `json:",omitempty" alias:"envoy_lb_config"` + + // OpaqueConfig contains load balancing configuration opaque to Consul for 3rd party proxies + OpaqueConfig string `json:",omitempty" alias:"opaque_config"` +} + +type EnvoyLBConfig struct { // Policy is the load balancing policy used to select a host Policy string `json:",omitempty"` // RingHashConfig contains configuration for the "ring_hash" policy type - RingHashConfig RingHashConfig `json:",omitempty" alias:"ring_hash_config"` + RingHashConfig *RingHashConfig `json:",omitempty" alias:"ring_hash_config"` // LeastRequestConfig contains configuration for the "least_request" policy type - LeastRequestConfig LeastRequestConfig `json:",omitempty" alias:"least_request_config"` + LeastRequestConfig *LeastRequestConfig `json:",omitempty" alias:"least_request_config"` // HashPolicies is a list of hash policies to use for hashing load balancing algorithms. // Hash policies are evaluated individually and combined such that identical lists @@ -1017,15 +1050,6 @@ type LoadBalancer struct { HashPolicies []HashPolicy `json:",omitempty" alias:"hash_policies"` } -func (l LoadBalancer) IsHashBased() bool { - switch l.Policy { - case "maglev", "ring_hash": - return true - default: - return false - } -} - // RingHashConfig contains configuration for the "ring_hash" policy type type RingHashConfig struct { // MinimumRingSize determines the minimum number of entries in the hash ring @@ -1041,25 +1065,24 @@ type LeastRequestConfig struct { ChoiceCount uint32 `json:",omitempty" alias:"choice_count"` } -// HashPolicy is a list of hash policies to use for hashing load balancing algorithms. -// Hash policies are evaluated individually and combined such that identical lists -// result in the same hash. -// If no hash policies are present, or none are successfully evaluated, -// then a random backend host will be selected. +// HashPolicy defines which attributes will be hashed by hash-based LB algorithms type HashPolicy struct { // Field is the attribute type to hash on. // Must be one of "header","cookie", or "query_parameter". // Cannot be specified along with SourceIP. Field string `json:",omitempty"` - // FieldMatchValue is the value to hash. + // FieldValue is the value to hash. // ie. header name, cookie name, URL query parameter name // Cannot be specified along with SourceIP. - FieldMatchValue string `json:",omitempty" alias:"field_value"` + FieldValue string `json:",omitempty" alias:"field_value"` - // SourceAddress determines whether the hash should be of the source IP rather than of a field and field value. - // Cannot be specified along with Field or FieldMatchValue. - SourceAddress bool `json:",omitempty" alias:"source_address"` + // CookieConfig contains configuration for the "cookie" hash policy type. + CookieConfig *CookieConfig `json:",omitempty" alias:"cookie_config"` + + // SourceIP determines whether the hash should be of the source IP rather than of a field and field value. + // Cannot be specified along with Field or FieldValue. + SourceIP bool `json:",omitempty" alias:"source_ip"` // Terminal will short circuit the computation of the hash when multiple hash policies are present. // If a hash is computed when a Terminal policy is evaluated, @@ -1067,6 +1090,134 @@ type HashPolicy struct { Terminal bool `json:",omitempty"` } +// 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. +type CookieConfig struct { + // TTL for generated cookies + TTL time.Duration `json:",omitempty"` + + // The path to set for the cookie + Path string `json:",omitempty"` +} + +func (ec *EnvoyLBConfig) IsHashBased() bool { + if ec == nil { + return false + } + + switch ec.Policy { + case LBPolicyMaglev, LBPolicyRingHash: + return true + default: + return false + } +} + +func (ec *EnvoyLBConfig) InjectToCluster(c *envoy.Cluster) error { + if ec == nil { + return nil + } + + switch ec.Policy { + case "": + return nil + case LBPolicyLeastRequest: + c.LbPolicy = envoy.Cluster_LEAST_REQUEST + + if ec.LeastRequestConfig != nil { + c.LbConfig = &envoy.Cluster_LeastRequestLbConfig_{ + LeastRequestLbConfig: &envoy.Cluster_LeastRequestLbConfig{ + ChoiceCount: &wrappers.UInt32Value{Value: ec.LeastRequestConfig.ChoiceCount}, + }, + } + } + case LBPolicyRoundRobin: + c.LbPolicy = envoy.Cluster_ROUND_ROBIN + + case LBPolicyRandom: + c.LbPolicy = envoy.Cluster_RANDOM + + case LBPolicyRingHash: + c.LbPolicy = envoy.Cluster_RING_HASH + + if ec.RingHashConfig != nil { + c.LbConfig = &envoy.Cluster_RingHashLbConfig_{ + RingHashLbConfig: &envoy.Cluster_RingHashLbConfig{ + MinimumRingSize: &wrappers.UInt64Value{Value: ec.RingHashConfig.MinimumRingSize}, + MaximumRingSize: &wrappers.UInt64Value{Value: ec.RingHashConfig.MaximumRingSize}, + }, + } + } + case LBPolicyMaglev: + c.LbPolicy = envoy.Cluster_MAGLEV + + default: + return fmt.Errorf("unsupported load balancer policy %q for cluster %q", ec.Policy, c.Name) + } + return nil +} + +func (ec *EnvoyLBConfig) InjectToRouteAction(action *envoyroute.RouteAction) error { + if ec == nil || !ec.IsHashBased() { + return nil + } + + result := make([]*envoyroute.RouteAction_HashPolicy, 0, len(ec.HashPolicies)) + for _, policy := range ec.HashPolicies { + if policy.SourceIP { + result = append(result, &envoyroute.RouteAction_HashPolicy{ + PolicySpecifier: &envoyroute.RouteAction_HashPolicy_ConnectionProperties_{ + ConnectionProperties: &envoyroute.RouteAction_HashPolicy_ConnectionProperties{ + SourceIp: true, + }, + }, + Terminal: policy.Terminal, + }) + + continue + } + + switch policy.Field { + case HashPolicyHeader: + result = append(result, &envoyroute.RouteAction_HashPolicy{ + PolicySpecifier: &envoyroute.RouteAction_HashPolicy_Header_{ + Header: &envoyroute.RouteAction_HashPolicy_Header{ + HeaderName: policy.FieldValue, + }, + }, + Terminal: policy.Terminal, + }) + case HashPolicyCookie: + cookie := envoyroute.RouteAction_HashPolicy_Cookie{ + Name: policy.FieldValue, + } + if policy.CookieConfig != nil { + cookie.Ttl = ptypes.DurationProto(policy.CookieConfig.TTL) + cookie.Path = policy.CookieConfig.Path + } + result = append(result, &envoyroute.RouteAction_HashPolicy{ + PolicySpecifier: &envoyroute.RouteAction_HashPolicy_Cookie_{ + Cookie: &cookie, + }, + Terminal: policy.Terminal, + }) + case HashPolicyQueryParam: + result = append(result, &envoyroute.RouteAction_HashPolicy{ + PolicySpecifier: &envoyroute.RouteAction_HashPolicy_QueryParameter_{ + QueryParameter: &envoyroute.RouteAction_HashPolicy_QueryParameter{ + Name: policy.FieldValue, + }, + }, + Terminal: policy.Terminal, + }) + default: + return fmt.Errorf("unsupported load balancer hash policy field: %v", policy.Field) + } + } + action.HashPolicy = result + return nil +} + type discoveryChainConfigEntry interface { ConfigEntry // ListRelatedServices returns a list of other names of services referenced diff --git a/agent/structs/config_entry_discoverychain_test.go b/agent/structs/config_entry_discoverychain_test.go index d5db08ec5..bd323855c 100644 --- a/agent/structs/config_entry_discoverychain_test.go +++ b/agent/structs/config_entry_discoverychain_test.go @@ -3,10 +3,14 @@ package structs import ( "bytes" "fmt" + "github.com/golang/protobuf/ptypes" "strings" "testing" "time" + envoy "github.com/envoyproxy/go-control-plane/envoy/api/v2" + envoyroute "github.com/envoyproxy/go-control-plane/envoy/api/v2/route" + "github.com/golang/protobuf/ptypes/wrappers" "github.com/hashicorp/consul/acl" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -552,25 +556,31 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { { name: "empty policy is valid", entry: &ServiceResolverConfigEntry{ - Kind: ServiceResolver, - Name: "test", - LoadBalancer: LoadBalancer{Policy: ""}, + Kind: ServiceResolver, + Name: "test", + LoadBalancer: &LoadBalancer{ + EnvoyLBConfig: &EnvoyLBConfig{Policy: ""}, + }, }, }, { name: "supported policy", entry: &ServiceResolverConfigEntry{ - Kind: ServiceResolver, - Name: "test", - LoadBalancer: LoadBalancer{Policy: "random"}, + Kind: ServiceResolver, + Name: "test", + LoadBalancer: &LoadBalancer{ + EnvoyLBConfig: &EnvoyLBConfig{Policy: LBPolicyRandom}, + }, }, }, { name: "unsupported policy", entry: &ServiceResolverConfigEntry{ - Kind: ServiceResolver, - Name: "test", - LoadBalancer: LoadBalancer{Policy: "fake-policy"}, + Kind: ServiceResolver, + Name: "test", + LoadBalancer: &LoadBalancer{ + EnvoyLBConfig: &EnvoyLBConfig{Policy: "fake-policy"}, + }, }, validateErr: `"fake-policy" is not supported`, }, @@ -579,9 +589,11 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { entry: &ServiceResolverConfigEntry{ Kind: ServiceResolver, Name: "test", - LoadBalancer: LoadBalancer{ - Policy: "ring_hash", - LeastRequestConfig: LeastRequestConfig{ChoiceCount: 2}, + LoadBalancer: &LoadBalancer{ + EnvoyLBConfig: &EnvoyLBConfig{ + Policy: LBPolicyRingHash, + LeastRequestConfig: &LeastRequestConfig{ChoiceCount: 10}, + }, }, }, validateErr: `LeastRequestConfig specified for incompatible load balancing policy`, @@ -591,9 +603,11 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { entry: &ServiceResolverConfigEntry{ Kind: ServiceResolver, Name: "test", - LoadBalancer: LoadBalancer{ - Policy: "least_request", - RingHashConfig: RingHashConfig{MinimumRingSize: 1024}, + LoadBalancer: &LoadBalancer{ + EnvoyLBConfig: &EnvoyLBConfig{ + Policy: LBPolicyLeastRequest, + RingHashConfig: &RingHashConfig{MinimumRingSize: 1024}, + }, }, }, validateErr: `RingHashConfig specified for incompatible load balancing policy`, @@ -603,9 +617,11 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { entry: &ServiceResolverConfigEntry{ Kind: ServiceResolver, Name: "test", - LoadBalancer: LoadBalancer{ - Policy: "ring_hash", - RingHashConfig: RingHashConfig{MinimumRingSize: 1024}, + LoadBalancer: &LoadBalancer{ + EnvoyLBConfig: &EnvoyLBConfig{ + Policy: LBPolicyRingHash, + RingHashConfig: &RingHashConfig{MinimumRingSize: 1024}, + }, }, }, }, @@ -614,9 +630,11 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { entry: &ServiceResolverConfigEntry{ Kind: ServiceResolver, Name: "test", - LoadBalancer: LoadBalancer{ - Policy: "least_request", - LeastRequestConfig: LeastRequestConfig{ChoiceCount: 2}, + LoadBalancer: &LoadBalancer{ + EnvoyLBConfig: &EnvoyLBConfig{ + Policy: LBPolicyLeastRequest, + LeastRequestConfig: &LeastRequestConfig{ChoiceCount: 2}, + }, }, }, }, @@ -625,12 +643,12 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { entry: &ServiceResolverConfigEntry{ Kind: ServiceResolver, Name: "test", - LoadBalancer: LoadBalancer{ - Policy: "", + LoadBalancer: &LoadBalancer{ + EnvoyLBConfig: &EnvoyLBConfig{Policy: ""}, }, }, check: func(t *testing.T, entry *ServiceResolverConfigEntry) { - require.Equal(t, "", entry.LoadBalancer.Policy) + require.Equal(t, "", entry.LoadBalancer.EnvoyLBConfig.Policy) }, }, { @@ -638,28 +656,77 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { entry: &ServiceResolverConfigEntry{ Kind: ServiceResolver, Name: "test", - LoadBalancer: LoadBalancer{ - Policy: "", - HashPolicies: []HashPolicy{ - { - SourceAddress: true, + LoadBalancer: &LoadBalancer{ + EnvoyLBConfig: &EnvoyLBConfig{ + Policy: "", + HashPolicies: []HashPolicy{ + { + SourceIP: true, + }, }, }, }, }, validateErr: `HashPolicies specified for non-hash-based Policy`, }, + { + name: "empty policy with hash policy", + entry: &ServiceResolverConfigEntry{ + Kind: ServiceResolver, + Name: "test", + LoadBalancer: &LoadBalancer{ + EnvoyLBConfig: &EnvoyLBConfig{ + Policy: LBPolicyMaglev, + HashPolicies: []HashPolicy{ + { + Field: HashPolicyHeader, + FieldValue: "x-user-id", + CookieConfig: &CookieConfig{ + TTL: 10 * time.Second, + Path: "/root", + }, + }, + }, + }, + }, + }, + validateErr: `cookie_config provided for "header"`, + }, + { + name: "empty policy with hash policy", + entry: &ServiceResolverConfigEntry{ + Kind: ServiceResolver, + Name: "test", + LoadBalancer: &LoadBalancer{ + EnvoyLBConfig: &EnvoyLBConfig{ + Policy: LBPolicyMaglev, + HashPolicies: []HashPolicy{ + { + Field: HashPolicyCookie, + FieldValue: "good-cookie", + CookieConfig: &CookieConfig{ + TTL: 10 * time.Second, + Path: "/oven", + }, + }, + }, + }, + }, + }, + }, { name: "supported match field", entry: &ServiceResolverConfigEntry{ Kind: ServiceResolver, Name: "test", - LoadBalancer: LoadBalancer{ - Policy: "maglev", - HashPolicies: []HashPolicy{ - { - Field: "header", - FieldMatchValue: "X-Consul-Token", + LoadBalancer: &LoadBalancer{ + EnvoyLBConfig: &EnvoyLBConfig{ + Policy: LBPolicyMaglev, + HashPolicies: []HashPolicy{ + { + Field: "header", + FieldValue: "X-Consul-Token", + }, }, }, }, @@ -670,28 +737,32 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { entry: &ServiceResolverConfigEntry{ Kind: ServiceResolver, Name: "test", - LoadBalancer: LoadBalancer{ - Policy: "maglev", - HashPolicies: []HashPolicy{ - { - Field: "not-header", + LoadBalancer: &LoadBalancer{ + EnvoyLBConfig: &EnvoyLBConfig{ + Policy: LBPolicyMaglev, + HashPolicies: []HashPolicy{ + { + Field: "fake-field", + }, }, }, }, }, - validateErr: `"not-header" is not a supported field`, + validateErr: `"fake-field" is not a supported field`, }, { name: "cannot match on source address and custom field", entry: &ServiceResolverConfigEntry{ Kind: ServiceResolver, Name: "test", - LoadBalancer: LoadBalancer{ - Policy: "maglev", - HashPolicies: []HashPolicy{ - { - Field: "header", - SourceAddress: true, + LoadBalancer: &LoadBalancer{ + EnvoyLBConfig: &EnvoyLBConfig{ + Policy: LBPolicyMaglev, + HashPolicies: []HashPolicy{ + { + Field: "header", + SourceIP: true, + }, }, }, }, @@ -703,67 +774,75 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { entry: &ServiceResolverConfigEntry{ Kind: ServiceResolver, Name: "test", - LoadBalancer: LoadBalancer{ - Policy: "maglev", - HashPolicies: []HashPolicy{ - { - FieldMatchValue: "X-Consul-Token", - SourceAddress: true, + LoadBalancer: &LoadBalancer{ + EnvoyLBConfig: &EnvoyLBConfig{ + Policy: LBPolicyMaglev, + HashPolicies: []HashPolicy{ + { + FieldValue: "X-Consul-Token", + SourceIP: true, + }, }, }, }, }, - validateErr: `A FieldMatchValue cannot be specified when hashing SourceAddress`, + validateErr: `A FieldValue cannot be specified when hashing SourceIP`, }, { name: "field without match value", entry: &ServiceResolverConfigEntry{ Kind: ServiceResolver, Name: "test", - LoadBalancer: LoadBalancer{ - Policy: "maglev", - HashPolicies: []HashPolicy{ - { - Field: "header", + LoadBalancer: &LoadBalancer{ + EnvoyLBConfig: &EnvoyLBConfig{ + Policy: LBPolicyMaglev, + HashPolicies: []HashPolicy{ + { + Field: "header", + }, }, }, }, }, - validateErr: `Field "header" was specified without a FieldMatchValue`, + validateErr: `Field "header" was specified without a FieldValue`, }, { name: "field without match value", entry: &ServiceResolverConfigEntry{ Kind: ServiceResolver, Name: "test", - LoadBalancer: LoadBalancer{ - Policy: "maglev", - HashPolicies: []HashPolicy{ - { - FieldMatchValue: "my-cookie", + LoadBalancer: &LoadBalancer{ + EnvoyLBConfig: &EnvoyLBConfig{ + Policy: LBPolicyMaglev, + HashPolicies: []HashPolicy{ + { + FieldValue: "my-cookie", + }, }, }, }, }, - validateErr: `FieldMatchValue requires a Field to apply to`, + validateErr: `FieldValue requires a Field to apply to`, }, { name: "ring hash kitchen sink", entry: &ServiceResolverConfigEntry{ Kind: ServiceResolver, Name: "test", - LoadBalancer: LoadBalancer{ - Policy: "ring_hash", - RingHashConfig: RingHashConfig{MaximumRingSize: 10, MinimumRingSize: 2}, - HashPolicies: []HashPolicy{ - { - Field: "cookie", - FieldMatchValue: "my-cookie", - }, - { - Field: "header", - FieldMatchValue: "alt-header", - Terminal: true, + LoadBalancer: &LoadBalancer{ + EnvoyLBConfig: &EnvoyLBConfig{ + Policy: LBPolicyRingHash, + RingHashConfig: &RingHashConfig{MaximumRingSize: 10, MinimumRingSize: 2}, + HashPolicies: []HashPolicy{ + { + Field: "cookie", + FieldValue: "my-cookie", + }, + { + Field: "header", + FieldValue: "alt-header", + Terminal: true, + }, }, }, }, @@ -774,9 +853,11 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { entry: &ServiceResolverConfigEntry{ Kind: ServiceResolver, Name: "test", - LoadBalancer: LoadBalancer{ - Policy: "least_request", - LeastRequestConfig: LeastRequestConfig{ChoiceCount: 20}, + LoadBalancer: &LoadBalancer{ + EnvoyLBConfig: &EnvoyLBConfig{ + Policy: LBPolicyLeastRequest, + LeastRequestConfig: &LeastRequestConfig{ChoiceCount: 20}, + }, }, }, }, @@ -1444,3 +1525,267 @@ func TestIsProtocolHTTPLike(t *testing.T) { assert.True(t, IsProtocolHTTPLike("http2")) assert.True(t, IsProtocolHTTPLike("grpc")) } + +func TestEnvoyLBConfig_InjectToRouteAction(t *testing.T) { + var tests = []struct { + name string + lb *EnvoyLBConfig + expected envoyroute.RouteAction + }{ + { + name: "empty", + lb: &EnvoyLBConfig{ + Policy: "", + }, + // we only modify route actions for hash-based LB policies + expected: envoyroute.RouteAction{}, + }, + { + name: "least request", + lb: &EnvoyLBConfig{ + Policy: LBPolicyLeastRequest, + LeastRequestConfig: &LeastRequestConfig{ + ChoiceCount: 3, + }, + }, + // we only modify route actions for hash-based LB policies + expected: envoyroute.RouteAction{}, + }, + { + name: "headers", + lb: &EnvoyLBConfig{ + Policy: "ring_hash", + RingHashConfig: &RingHashConfig{ + MinimumRingSize: 3, + MaximumRingSize: 7, + }, + HashPolicies: []HashPolicy{ + { + Field: HashPolicyHeader, + FieldValue: "x-route-key", + Terminal: true, + }, + }, + }, + expected: envoyroute.RouteAction{ + HashPolicy: []*envoyroute.RouteAction_HashPolicy{ + { + PolicySpecifier: &envoyroute.RouteAction_HashPolicy_Header_{ + Header: &envoyroute.RouteAction_HashPolicy_Header{ + HeaderName: "x-route-key", + }, + }, + Terminal: true, + }, + }, + }, + }, + { + name: "cookies", + lb: &EnvoyLBConfig{ + Policy: LBPolicyMaglev, + HashPolicies: []HashPolicy{ + { + Field: HashPolicyCookie, + FieldValue: "red-velvet", + Terminal: true, + }, + { + Field: HashPolicyCookie, + FieldValue: "oatmeal", + }, + }, + }, + expected: envoyroute.RouteAction{ + HashPolicy: []*envoyroute.RouteAction_HashPolicy{ + { + PolicySpecifier: &envoyroute.RouteAction_HashPolicy_Cookie_{ + Cookie: &envoyroute.RouteAction_HashPolicy_Cookie{ + Name: "red-velvet", + }, + }, + Terminal: true, + }, + { + PolicySpecifier: &envoyroute.RouteAction_HashPolicy_Cookie_{ + Cookie: &envoyroute.RouteAction_HashPolicy_Cookie{ + Name: "oatmeal", + }, + }, + }, + }, + }, + }, + { + name: "source addr", + lb: &EnvoyLBConfig{ + Policy: LBPolicyMaglev, + HashPolicies: []HashPolicy{ + { + SourceIP: true, + Terminal: true, + }, + }, + }, + expected: envoyroute.RouteAction{ + HashPolicy: []*envoyroute.RouteAction_HashPolicy{ + { + PolicySpecifier: &envoyroute.RouteAction_HashPolicy_ConnectionProperties_{ + ConnectionProperties: &envoyroute.RouteAction_HashPolicy_ConnectionProperties{ + SourceIp: true, + }, + }, + Terminal: true, + }, + }, + }, + }, + { + name: "kitchen sink", + lb: &EnvoyLBConfig{ + Policy: LBPolicyMaglev, + HashPolicies: []HashPolicy{ + { + SourceIP: true, + Terminal: true, + }, + { + Field: HashPolicyCookie, + FieldValue: "oatmeal", + CookieConfig: &CookieConfig{ + TTL: 10 * time.Second, + Path: "/oven", + }, + }, + { + Field: HashPolicyHeader, + FieldValue: "special-header", + Terminal: true, + }, + }, + }, + expected: envoyroute.RouteAction{ + HashPolicy: []*envoyroute.RouteAction_HashPolicy{ + { + PolicySpecifier: &envoyroute.RouteAction_HashPolicy_ConnectionProperties_{ + ConnectionProperties: &envoyroute.RouteAction_HashPolicy_ConnectionProperties{ + SourceIp: true, + }, + }, + Terminal: true, + }, + { + PolicySpecifier: &envoyroute.RouteAction_HashPolicy_Cookie_{ + Cookie: &envoyroute.RouteAction_HashPolicy_Cookie{ + Name: "oatmeal", + Ttl: ptypes.DurationProto(10 * time.Second), + Path: "/oven", + }, + }, + }, + { + PolicySpecifier: &envoyroute.RouteAction_HashPolicy_Header_{ + Header: &envoyroute.RouteAction_HashPolicy_Header{ + HeaderName: "special-header", + }, + }, + Terminal: true, + }, + }, + }, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + var ra envoyroute.RouteAction + err := tc.lb.InjectToRouteAction(&ra) + require.NoError(t, err) + + require.Equal(t, &tc.expected, &ra) + }) + } +} + +func TestEnvoyLBConfig_InjectToCluster(t *testing.T) { + var tests = []struct { + name string + lb *EnvoyLBConfig + expected envoy.Cluster + }{ + { + name: "skip empty", + lb: &EnvoyLBConfig{ + Policy: "", + }, + expected: envoy.Cluster{}, + }, + { + name: "round robin", + lb: &EnvoyLBConfig{ + Policy: LBPolicyRoundRobin, + }, + expected: envoy.Cluster{LbPolicy: envoy.Cluster_ROUND_ROBIN}, + }, + { + name: "random", + lb: &EnvoyLBConfig{ + Policy: LBPolicyRandom, + }, + expected: envoy.Cluster{LbPolicy: envoy.Cluster_RANDOM}, + }, + { + name: "maglev", + lb: &EnvoyLBConfig{ + Policy: LBPolicyMaglev, + }, + expected: envoy.Cluster{LbPolicy: envoy.Cluster_MAGLEV}, + }, + { + name: "ring_hash", + lb: &EnvoyLBConfig{ + Policy: LBPolicyRingHash, + RingHashConfig: &RingHashConfig{ + MinimumRingSize: 3, + MaximumRingSize: 7, + }, + }, + expected: envoy.Cluster{ + LbPolicy: envoy.Cluster_RING_HASH, + LbConfig: &envoy.Cluster_RingHashLbConfig_{ + RingHashLbConfig: &envoy.Cluster_RingHashLbConfig{ + MinimumRingSize: &wrappers.UInt64Value{Value: 3}, + MaximumRingSize: &wrappers.UInt64Value{Value: 7}, + }, + }, + }, + }, + { + name: "least_request", + lb: &EnvoyLBConfig{ + Policy: "least_request", + LeastRequestConfig: &LeastRequestConfig{ + ChoiceCount: 3, + }, + }, + expected: envoy.Cluster{ + LbPolicy: envoy.Cluster_LEAST_REQUEST, + LbConfig: &envoy.Cluster_LeastRequestLbConfig_{ + LeastRequestLbConfig: &envoy.Cluster_LeastRequestLbConfig{ + ChoiceCount: &wrappers.UInt32Value{Value: 3}, + }, + }, + }, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + var c envoy.Cluster + err := tc.lb.InjectToCluster(&c) + require.NoError(t, err) + + require.Equal(t, tc.expected, c) + }) + } +} diff --git a/agent/structs/discovery_chain.go b/agent/structs/discovery_chain.go index 85ee5965c..77eb03937 100644 --- a/agent/structs/discovery_chain.go +++ b/agent/structs/discovery_chain.go @@ -109,7 +109,7 @@ type DiscoveryGraphNode struct { Resolver *DiscoveryResolver `json:",omitempty"` // shared by Type==resolver || Type==splitter - LoadBalancer LoadBalancer `json:",omitempty"` + LoadBalancer *LoadBalancer `json:",omitempty"` } func (s *DiscoveryGraphNode) IsRouter() bool { diff --git a/agent/xds/clusters.go b/agent/xds/clusters.go index 8bad63b63..b87243212 100644 --- a/agent/xds/clusters.go +++ b/agent/xds/clusters.go @@ -16,7 +16,6 @@ import ( "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" "github.com/golang/protobuf/ptypes/any" - "github.com/golang/protobuf/ptypes/wrappers" "github.com/hashicorp/consul/agent/connect" "github.com/hashicorp/consul/agent/proxycfg" "github.com/hashicorp/consul/agent/structs" @@ -206,13 +205,14 @@ func (s *Server) makeGatewayServiceClusters(cfgSnap *proxycfg.ConfigSnapshot) ([ clusterName := connect.ServiceSNI(svc.Name, "", svc.NamespaceOrDefault(), cfgSnap.Datacenter, cfgSnap.Roots.TrustDomain) resolver, hasResolver := resolvers[svc] - var lb structs.LoadBalancer + var loadBalancer *structs.EnvoyLBConfig - if !hasResolver { + if hasResolver && resolver.LoadBalancer != nil { + loadBalancer = resolver.LoadBalancer.EnvoyLBConfig + + } else { // Use a zero value resolver with no timeout and no subsets resolver = &structs.ServiceResolverConfigEntry{} - } else { - lb = resolver.LoadBalancer } // When making service clusters we only pass endpoints with hostnames if the kind is a terminating gateway @@ -232,16 +232,14 @@ func (s *Server) makeGatewayServiceClusters(cfgSnap *proxycfg.ConfigSnapshot) ([ case structs.ServiceKindTerminatingGateway: injectTerminatingGatewayTLSContext(cfgSnap, cluster, svc) - err := injectLBToCluster(lb, cluster) - if err != nil { + if err := loadBalancer.InjectToCluster(cluster); err != nil { return nil, fmt.Errorf("failed to apply load balancer configuration to cluster %q: %v", clusterName, err) } case structs.ServiceKindMeshGateway: // We can't apply hash based LB config to mesh gateways because they rely on inspecting HTTP attributes // and mesh gateways do not decrypt traffic - if !lb.IsHashBased() { - err := injectLBToCluster(lb, cluster) - if err != nil { + if !loadBalancer.IsHashBased() { + if err := loadBalancer.InjectToCluster(cluster); err != nil { return nil, fmt.Errorf("failed to apply load balancer configuration to cluster %q: %v", clusterName, err) } } @@ -267,16 +265,15 @@ func (s *Server) makeGatewayServiceClusters(cfgSnap *proxycfg.ConfigSnapshot) ([ case structs.ServiceKindTerminatingGateway: injectTerminatingGatewayTLSContext(cfgSnap, cluster, svc) - err := injectLBToCluster(lb, cluster) - if err != nil { + if err := loadBalancer.InjectToCluster(cluster); err != nil { return nil, fmt.Errorf("failed to apply load balancer configuration to cluster %q: %v", clusterName, err) } + case structs.ServiceKindMeshGateway: // We can't apply hash based LB config to mesh gateways because they rely on inspecting HTTP attributes // and mesh gateways do not decrypt traffic - if !lb.IsHashBased() { - err := injectLBToCluster(lb, cluster) - if err != nil { + if !loadBalancer.IsHashBased() { + if err := loadBalancer.InjectToCluster(cluster); err != nil { return nil, fmt.Errorf("failed to apply load balancer configuration to cluster %q: %v", clusterName, err) } } @@ -516,8 +513,12 @@ func (s *Server) makeUpstreamClustersForDiscoveryChain( OutlierDetection: cfg.PassiveHealthCheck.AsOutlierDetection(), } - if err := injectLBToCluster(node.LoadBalancer, c); err != nil { - return nil, fmt.Errorf("failed to apply load balancer configuration to cluster %q: %v", sni, err) + var lb *structs.EnvoyLBConfig + if node.LoadBalancer != nil { + lb = node.LoadBalancer.EnvoyLBConfig + } + if err := lb.InjectToCluster(c); err != nil { + return nil, fmt.Errorf("failed to apply load balancer configuration to cluster %q: %v", clusterName, err) } proto := cfg.Protocol @@ -557,37 +558,6 @@ func (s *Server) makeUpstreamClustersForDiscoveryChain( return out, nil } -func injectLBToCluster(l structs.LoadBalancer, c *envoy.Cluster) error { - switch l.Policy { - case "": - return nil - case "least_request": - c.LbPolicy = envoy.Cluster_LEAST_REQUEST - c.LbConfig = &envoy.Cluster_LeastRequestLbConfig_{ - LeastRequestLbConfig: &envoy.Cluster_LeastRequestLbConfig{ - ChoiceCount: &wrappers.UInt32Value{Value: l.LeastRequestConfig.ChoiceCount}, - }, - } - case "round_robin": - c.LbPolicy = envoy.Cluster_ROUND_ROBIN - case "random": - c.LbPolicy = envoy.Cluster_RANDOM - case "ring_hash": - c.LbPolicy = envoy.Cluster_RING_HASH - c.LbConfig = &envoy.Cluster_RingHashLbConfig_{ - RingHashLbConfig: &envoy.Cluster_RingHashLbConfig{ - MinimumRingSize: &wrappers.UInt64Value{Value: l.RingHashConfig.MinimumRingSize}, - MaximumRingSize: &wrappers.UInt64Value{Value: l.RingHashConfig.MaximumRingSize}, - }, - } - case "maglev": - c.LbPolicy = envoy.Cluster_MAGLEV - default: - return fmt.Errorf("unsupported load balancer policy %q for cluster %q", l.Policy, c.Name) - } - return nil -} - // makeClusterFromUserConfig returns the listener config decoded from an // arbitrary proto3 json format string or an error if it's invalid. // diff --git a/agent/xds/clusters_test.go b/agent/xds/clusters_test.go index 14714feb7..634cbe54c 100644 --- a/agent/xds/clusters_test.go +++ b/agent/xds/clusters_test.go @@ -2,7 +2,6 @@ package xds import ( "bytes" - "github.com/golang/protobuf/ptypes/wrappers" "path/filepath" "sort" "testing" @@ -367,10 +366,12 @@ func TestClustersFromSnapshot(t *testing.T) { OnlyPassing: true, }, }, - LoadBalancer: structs.LoadBalancer{ - Policy: "least_request", - LeastRequestConfig: structs.LeastRequestConfig{ - ChoiceCount: 5, + LoadBalancer: &structs.LoadBalancer{ + EnvoyLBConfig: &structs.EnvoyLBConfig{ + Policy: "least_request", + LeastRequestConfig: &structs.LeastRequestConfig{ + ChoiceCount: 5, + }, }, }, }, @@ -394,11 +395,13 @@ func TestClustersFromSnapshot(t *testing.T) { OnlyPassing: true, }, }, - LoadBalancer: structs.LoadBalancer{ - Policy: "ring_hash", - RingHashConfig: structs.RingHashConfig{ - MinimumRingSize: 20, - MaximumRingSize: 50, + LoadBalancer: &structs.LoadBalancer{ + EnvoyLBConfig: &structs.EnvoyLBConfig{ + Policy: "ring_hash", + RingHashConfig: &structs.RingHashConfig{ + MinimumRingSize: 20, + MaximumRingSize: 50, + }, }, }, }, @@ -605,11 +608,13 @@ func TestClustersFromSnapshot(t *testing.T) { OnlyPassing: true, }, }, - LoadBalancer: structs.LoadBalancer{ - Policy: "ring_hash", - RingHashConfig: structs.RingHashConfig{ - MinimumRingSize: 20, - MaximumRingSize: 50, + LoadBalancer: &structs.LoadBalancer{ + EnvoyLBConfig: &structs.EnvoyLBConfig{ + Policy: "ring_hash", + RingHashConfig: &structs.RingHashConfig{ + MinimumRingSize: 20, + MaximumRingSize: 50, + }, }, }, }, @@ -834,86 +839,3 @@ func setupTLSRootsAndLeaf(t *testing.T, snap *proxycfg.ConfigSnapshot) { snap.Roots.Roots[0].RootCert = golden(t, "test-root-cert", "", "") } } - -func TestLoadBalancer_injectLBToCluster(t *testing.T) { - var tests = []struct { - name string - lb structs.LoadBalancer - expected envoy.Cluster - }{ - { - name: "skip empty", - lb: structs.LoadBalancer{ - Policy: "", - }, - expected: envoy.Cluster{}, - }, - { - name: "round_robin", - lb: structs.LoadBalancer{ - Policy: "round_robin", - }, - expected: envoy.Cluster{LbPolicy: envoy.Cluster_ROUND_ROBIN}, - }, - { - name: "random", - lb: structs.LoadBalancer{ - Policy: "random", - }, - expected: envoy.Cluster{LbPolicy: envoy.Cluster_RANDOM}, - }, - { - name: "maglev", - lb: structs.LoadBalancer{ - Policy: "maglev", - }, - expected: envoy.Cluster{LbPolicy: envoy.Cluster_MAGLEV}, - }, - { - name: "ring_hash", - lb: structs.LoadBalancer{ - Policy: "ring_hash", - RingHashConfig: structs.RingHashConfig{ - MinimumRingSize: 3, - MaximumRingSize: 7, - }, - }, - expected: envoy.Cluster{ - LbPolicy: envoy.Cluster_RING_HASH, - LbConfig: &envoy.Cluster_RingHashLbConfig_{ - RingHashLbConfig: &envoy.Cluster_RingHashLbConfig{ - MinimumRingSize: &wrappers.UInt64Value{Value: 3}, - MaximumRingSize: &wrappers.UInt64Value{Value: 7}, - }, - }, - }, - }, - { - name: "least_request", - lb: structs.LoadBalancer{ - Policy: "least_request", - LeastRequestConfig: structs.LeastRequestConfig{ - ChoiceCount: 3, - }, - }, - expected: envoy.Cluster{ - LbPolicy: envoy.Cluster_LEAST_REQUEST, - LbConfig: &envoy.Cluster_LeastRequestLbConfig_{ - LeastRequestLbConfig: &envoy.Cluster_LeastRequestLbConfig{ - ChoiceCount: &wrappers.UInt32Value{Value: 3}, - }, - }, - }, - }, - } - - for _, tc := range tests { - t.Run(tc.name, func(t *testing.T) { - var c envoy.Cluster - err := injectLBToCluster(tc.lb, &c) - require.NoError(t, err) - - require.Equal(t, tc.expected, c) - }) - } -} diff --git a/agent/xds/routes.go b/agent/xds/routes.go index f7f991f7e..bf1f5cc3a 100644 --- a/agent/xds/routes.go +++ b/agent/xds/routes.go @@ -43,14 +43,14 @@ func routesFromSnapshotTerminatingGateway(_ connectionInfo, cfgSnap *proxycfg.Co } var resources []proto.Message - for svc := range cfgSnap.TerminatingGateway.ServiceGroups { + for _, svc := range cfgSnap.TerminatingGateway.ValidServices() { clusterName := connect.ServiceSNI(svc.Name, "", svc.NamespaceOrDefault(), cfgSnap.Datacenter, cfgSnap.Roots.TrustDomain) resolver, hasResolver := cfgSnap.TerminatingGateway.ServiceResolvers[svc] svcConfig := cfgSnap.TerminatingGateway.ServiceConfigs[svc] cfg, err := ParseProxyConfig(svcConfig.ProxyConfig) - if err != nil || cfg.Protocol != "http" { + if err != nil || structs.IsProtocolHTTPLike(cfg.Protocol) { // Routes can only be defined for HTTP services continue } @@ -59,7 +59,12 @@ func routesFromSnapshotTerminatingGateway(_ connectionInfo, cfgSnap *proxycfg.Co // Use a zero value resolver with no timeout and no subsets resolver = &structs.ServiceResolverConfigEntry{} } - route, err := makeNamedDefaultRouteWithLB(clusterName, resolver.LoadBalancer) + + var lb *structs.EnvoyLBConfig + if resolver.LoadBalancer != nil { + lb = resolver.LoadBalancer.EnvoyLBConfig + } + route, err := makeNamedDefaultRouteWithLB(clusterName, lb) if err != nil { continue } @@ -68,7 +73,7 @@ func routesFromSnapshotTerminatingGateway(_ connectionInfo, cfgSnap *proxycfg.Co // If there is a service-resolver for this service then also setup routes for each subset for name := range resolver.Subsets { clusterName = connect.ServiceSNI(svc.Name, name, svc.NamespaceOrDefault(), cfgSnap.Datacenter, cfgSnap.Roots.TrustDomain) - route, err := makeNamedDefaultRouteWithLB(clusterName, resolver.LoadBalancer) + route, err := makeNamedDefaultRouteWithLB(clusterName, lb) if err != nil { continue } @@ -76,13 +81,13 @@ func routesFromSnapshotTerminatingGateway(_ connectionInfo, cfgSnap *proxycfg.Co } } - // TODO(rb): make sure we don't generate an empty result return resources, nil } -func makeNamedDefaultRouteWithLB(clusterName string, lb structs.LoadBalancer) (*envoy.RouteConfiguration, error) { +func makeNamedDefaultRouteWithLB(clusterName string, lb *structs.EnvoyLBConfig) (*envoy.RouteConfiguration, error) { action := makeRouteActionFromName(clusterName) - if err := injectLBToRouteAction(lb, action.Route); err != nil { + + if err := lb.InjectToRouteAction(action.Route); err != nil { return nil, fmt.Errorf("failed to apply load balancer configuration to route action: %v", err) } @@ -250,6 +255,8 @@ func makeUpstreamRouteForDiscoveryChain( return nil, fmt.Errorf("missing first node in compiled discovery chain for: %s", chain.ServiceName) } + var lb *structs.EnvoyLBConfig + switch startNode.Type { case structs.DiscoveryGraphNodeTypeRouter: routes = make([]*envoyroute.Route, 0, len(startNode.Routes)) @@ -263,6 +270,10 @@ func makeUpstreamRouteForDiscoveryChain( ) nextNode := chain.Nodes[discoveryRoute.NextNode] + if nextNode.LoadBalancer != nil { + lb = nextNode.LoadBalancer.EnvoyLBConfig + } + switch nextNode.Type { case structs.DiscoveryGraphNodeTypeSplitter: routeAction, err = makeRouteActionForSplitter(nextNode.Splits, chain) @@ -270,14 +281,14 @@ func makeUpstreamRouteForDiscoveryChain( return nil, err } - if err := injectLBToRouteAction(nextNode.LoadBalancer, routeAction.Route); err != nil { + if err := lb.InjectToRouteAction(routeAction.Route); err != nil { return nil, fmt.Errorf("failed to apply load balancer configuration to route action: %v", err) } case structs.DiscoveryGraphNodeTypeResolver: routeAction = makeRouteActionForChainCluster(nextNode.Resolver.Target, chain) - if err := injectLBToRouteAction(nextNode.LoadBalancer, routeAction.Route); err != nil { + if err := lb.InjectToRouteAction(routeAction.Route); err != nil { return nil, fmt.Errorf("failed to apply load balancer configuration to route action: %v", err) } @@ -332,7 +343,10 @@ func makeUpstreamRouteForDiscoveryChain( return nil, err } - if err := injectLBToRouteAction(startNode.LoadBalancer, routeAction.Route); err != nil { + if startNode.LoadBalancer != nil { + lb = startNode.LoadBalancer.EnvoyLBConfig + } + if err := lb.InjectToRouteAction(routeAction.Route); err != nil { return nil, fmt.Errorf("failed to apply load balancer configuration to route action: %v", err) } @@ -346,7 +360,10 @@ func makeUpstreamRouteForDiscoveryChain( case structs.DiscoveryGraphNodeTypeResolver: routeAction := makeRouteActionForChainCluster(startNode.Resolver.Target, chain) - if err := injectLBToRouteAction(startNode.LoadBalancer, routeAction.Route); err != nil { + if startNode.LoadBalancer != nil { + lb = startNode.LoadBalancer.EnvoyLBConfig + } + if err := lb.InjectToRouteAction(routeAction.Route); err != nil { return nil, fmt.Errorf("failed to apply load balancer configuration to route action: %v", err) } @@ -370,62 +387,6 @@ func makeUpstreamRouteForDiscoveryChain( return host, nil } -func injectLBToRouteAction(lb structs.LoadBalancer, action *envoyroute.RouteAction) error { - if !lb.IsHashBased() { - return nil - } - - result := make([]*envoyroute.RouteAction_HashPolicy, 0, len(lb.HashPolicies)) - for _, policy := range lb.HashPolicies { - if policy.SourceAddress { - result = append(result, &envoyroute.RouteAction_HashPolicy{ - PolicySpecifier: &envoyroute.RouteAction_HashPolicy_ConnectionProperties_{ - ConnectionProperties: &envoyroute.RouteAction_HashPolicy_ConnectionProperties{ - SourceIp: true, - }, - }, - Terminal: policy.Terminal, - }) - - continue - } - - switch policy.Field { - case "header": - result = append(result, &envoyroute.RouteAction_HashPolicy{ - PolicySpecifier: &envoyroute.RouteAction_HashPolicy_Header_{ - Header: &envoyroute.RouteAction_HashPolicy_Header{ - HeaderName: policy.FieldMatchValue, - }, - }, - Terminal: policy.Terminal, - }) - case "cookie": - result = append(result, &envoyroute.RouteAction_HashPolicy{ - PolicySpecifier: &envoyroute.RouteAction_HashPolicy_Cookie_{ - Cookie: &envoyroute.RouteAction_HashPolicy_Cookie{ - Name: policy.FieldMatchValue, - }, - }, - Terminal: policy.Terminal, - }) - case "query_parameter": - result = append(result, &envoyroute.RouteAction_HashPolicy{ - PolicySpecifier: &envoyroute.RouteAction_HashPolicy_QueryParameter_{ - QueryParameter: &envoyroute.RouteAction_HashPolicy_QueryParameter{ - Name: policy.FieldMatchValue, - }, - }, - Terminal: policy.Terminal, - }) - default: - return fmt.Errorf("unsupported load balancer hash policy field: %v", policy.Field) - } - } - action.HashPolicy = result - return nil -} - func makeRouteMatchForDiscoveryRoute(_ connectionInfo, discoveryRoute *structs.DiscoveryRoute) *envoyroute.RouteMatch { match := discoveryRoute.Definition.Match if match == nil || match.IsEmpty() { diff --git a/agent/xds/routes_test.go b/agent/xds/routes_test.go index 7142ee445..88020b247 100644 --- a/agent/xds/routes_test.go +++ b/agent/xds/routes_test.go @@ -7,7 +7,6 @@ import ( "time" envoy "github.com/envoyproxy/go-control-plane/envoy/api/v2" - envoyroute "github.com/envoyproxy/go-control-plane/envoy/api/v2/route" "github.com/hashicorp/consul/agent/connect" "github.com/hashicorp/consul/agent/consul/discoverychain" "github.com/hashicorp/consul/agent/proxycfg" @@ -203,25 +202,27 @@ func TestRoutesFromSnapshot(t *testing.T) { OnlyPassing: true, }, }, - LoadBalancer: structs.LoadBalancer{ - Policy: "ring_hash", - RingHashConfig: structs.RingHashConfig{ - MinimumRingSize: 20, - MaximumRingSize: 50, - }, - HashPolicies: []structs.HashPolicy{ - { - Field: "cookie", - FieldMatchValue: "chocolate-chip", - Terminal: true, + LoadBalancer: &structs.LoadBalancer{ + EnvoyLBConfig: &structs.EnvoyLBConfig{ + Policy: "ring_hash", + RingHashConfig: &structs.RingHashConfig{ + MinimumRingSize: 20, + MaximumRingSize: 50, }, - { - Field: "header", - FieldMatchValue: "x-user-id", - }, - { - SourceAddress: true, - Terminal: true, + HashPolicies: []structs.HashPolicy{ + { + Field: structs.HashPolicyCookie, + FieldValue: "chocolate-chip", + Terminal: true, + }, + { + Field: structs.HashPolicyHeader, + FieldValue: "x-user-id", + }, + { + SourceIP: true, + Terminal: true, + }, }, }, }, @@ -276,178 +277,3 @@ func TestRoutesFromSnapshot(t *testing.T) { }) } } - -func TestLoadBalancer_injectLBToRouteAction(t *testing.T) { - var tests = []struct { - name string - lb structs.LoadBalancer - expected envoyroute.RouteAction - }{ - { - name: "empty", - lb: structs.LoadBalancer{ - Policy: "", - }, - // we only modify route actions for hash-based LB policies - expected: envoyroute.RouteAction{}, - }, - { - name: "least_request", - lb: structs.LoadBalancer{ - Policy: "least_request", - LeastRequestConfig: structs.LeastRequestConfig{ - ChoiceCount: 3, - }, - }, - // we only modify route actions for hash-based LB policies - expected: envoyroute.RouteAction{}, - }, - { - name: "header", - lb: structs.LoadBalancer{ - Policy: "ring_hash", - RingHashConfig: structs.RingHashConfig{ - MinimumRingSize: 3, - MaximumRingSize: 7, - }, - HashPolicies: []structs.HashPolicy{ - { - Field: "header", - FieldMatchValue: "x-route-key", - Terminal: true, - }, - }, - }, - expected: envoyroute.RouteAction{ - HashPolicy: []*envoyroute.RouteAction_HashPolicy{ - { - PolicySpecifier: &envoyroute.RouteAction_HashPolicy_Header_{ - Header: &envoyroute.RouteAction_HashPolicy_Header{ - HeaderName: "x-route-key", - }, - }, - Terminal: true, - }, - }, - }, - }, - { - name: "cookies", - lb: structs.LoadBalancer{ - Policy: "maglev", - HashPolicies: []structs.HashPolicy{ - { - Field: "cookie", - FieldMatchValue: "red-velvet", - Terminal: true, - }, - { - Field: "cookie", - FieldMatchValue: "oatmeal", - }, - }, - }, - expected: envoyroute.RouteAction{ - HashPolicy: []*envoyroute.RouteAction_HashPolicy{ - { - PolicySpecifier: &envoyroute.RouteAction_HashPolicy_Cookie_{ - Cookie: &envoyroute.RouteAction_HashPolicy_Cookie{ - Name: "red-velvet", - }, - }, - Terminal: true, - }, - { - PolicySpecifier: &envoyroute.RouteAction_HashPolicy_Cookie_{ - Cookie: &envoyroute.RouteAction_HashPolicy_Cookie{ - Name: "oatmeal", - }, - }, - }, - }, - }, - }, - { - name: "source addr", - lb: structs.LoadBalancer{ - Policy: "maglev", - HashPolicies: []structs.HashPolicy{ - { - SourceAddress: true, - Terminal: true, - }, - }, - }, - expected: envoyroute.RouteAction{ - HashPolicy: []*envoyroute.RouteAction_HashPolicy{ - { - PolicySpecifier: &envoyroute.RouteAction_HashPolicy_ConnectionProperties_{ - ConnectionProperties: &envoyroute.RouteAction_HashPolicy_ConnectionProperties{ - SourceIp: true, - }, - }, - Terminal: true, - }, - }, - }, - }, - { - name: "kitchen sink", - lb: structs.LoadBalancer{ - Policy: "maglev", - HashPolicies: []structs.HashPolicy{ - { - SourceAddress: true, - Terminal: true, - }, - { - Field: "cookie", - FieldMatchValue: "oatmeal", - }, - { - Field: "header", - FieldMatchValue: "special-header", - Terminal: true, - }, - }, - }, - expected: envoyroute.RouteAction{ - HashPolicy: []*envoyroute.RouteAction_HashPolicy{ - { - PolicySpecifier: &envoyroute.RouteAction_HashPolicy_ConnectionProperties_{ - ConnectionProperties: &envoyroute.RouteAction_HashPolicy_ConnectionProperties{ - SourceIp: true, - }, - }, - Terminal: true, - }, - { - PolicySpecifier: &envoyroute.RouteAction_HashPolicy_Cookie_{ - Cookie: &envoyroute.RouteAction_HashPolicy_Cookie{ - Name: "oatmeal", - }, - }, - }, - { - PolicySpecifier: &envoyroute.RouteAction_HashPolicy_Header_{ - Header: &envoyroute.RouteAction_HashPolicy_Header{ - HeaderName: "special-header", - }, - }, - Terminal: true, - }, - }, - }, - }, - } - - for _, tc := range tests { - t.Run(tc.name, func(t *testing.T) { - ra := &envoyroute.RouteAction{} - err := injectLBToRouteAction(tc.lb, ra) - require.NoError(t, err) - - require.Equal(t, &tc.expected, ra) - }) - } -} diff --git a/agent/xds/testdata/clusters/mesh-gateway-ignore-extra-resolvers.envoy-1-12-x.golden b/agent/xds/testdata/clusters/mesh-gateway-ignore-extra-resolvers.envoy-1-12-x.golden index afc23f9ae..845881fd3 100644 --- a/agent/xds/testdata/clusters/mesh-gateway-ignore-extra-resolvers.envoy-1-12-x.golden +++ b/agent/xds/testdata/clusters/mesh-gateway-ignore-extra-resolvers.envoy-1-12-x.golden @@ -111,38 +111,6 @@ "connectTimeout": "5s", "outlierDetection": { - } - }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "v1.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": { - - } - } - }, - "connectTimeout": "5s", - "outlierDetection": { - - } - }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "v2.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": { - - } - } - }, - "connectTimeout": "5s", - "outlierDetection": { - } } ], diff --git a/agent/xds/testdata/clusters/mesh-gateway-ignore-extra-resolvers.envoy-1-13-x.golden b/agent/xds/testdata/clusters/mesh-gateway-ignore-extra-resolvers.envoy-1-13-x.golden index afc23f9ae..845881fd3 100644 --- a/agent/xds/testdata/clusters/mesh-gateway-ignore-extra-resolvers.envoy-1-13-x.golden +++ b/agent/xds/testdata/clusters/mesh-gateway-ignore-extra-resolvers.envoy-1-13-x.golden @@ -111,38 +111,6 @@ "connectTimeout": "5s", "outlierDetection": { - } - }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "v1.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": { - - } - } - }, - "connectTimeout": "5s", - "outlierDetection": { - - } - }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "v2.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": { - - } - } - }, - "connectTimeout": "5s", - "outlierDetection": { - } } ], diff --git a/agent/xds/testdata/clusters/mesh-gateway-ignore-extra-resolvers.envoy-1-14-x.golden b/agent/xds/testdata/clusters/mesh-gateway-ignore-extra-resolvers.envoy-1-14-x.golden index afc23f9ae..845881fd3 100644 --- a/agent/xds/testdata/clusters/mesh-gateway-ignore-extra-resolvers.envoy-1-14-x.golden +++ b/agent/xds/testdata/clusters/mesh-gateway-ignore-extra-resolvers.envoy-1-14-x.golden @@ -111,38 +111,6 @@ "connectTimeout": "5s", "outlierDetection": { - } - }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "v1.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": { - - } - } - }, - "connectTimeout": "5s", - "outlierDetection": { - - } - }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "v2.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": { - - } - } - }, - "connectTimeout": "5s", - "outlierDetection": { - } } ], diff --git a/agent/xds/testdata/clusters/mesh-gateway-ignore-extra-resolvers.envoy-1-15-x.golden b/agent/xds/testdata/clusters/mesh-gateway-ignore-extra-resolvers.envoy-1-15-x.golden index afc23f9ae..845881fd3 100644 --- a/agent/xds/testdata/clusters/mesh-gateway-ignore-extra-resolvers.envoy-1-15-x.golden +++ b/agent/xds/testdata/clusters/mesh-gateway-ignore-extra-resolvers.envoy-1-15-x.golden @@ -111,38 +111,6 @@ "connectTimeout": "5s", "outlierDetection": { - } - }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "v1.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": { - - } - } - }, - "connectTimeout": "5s", - "outlierDetection": { - - } - }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "v2.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": { - - } - } - }, - "connectTimeout": "5s", - "outlierDetection": { - } } ], diff --git a/agent/xds/testdata/clusters/mesh-gateway-service-subsets.envoy-1-12-x.golden b/agent/xds/testdata/clusters/mesh-gateway-service-subsets.envoy-1-12-x.golden index afc23f9ae..845881fd3 100644 --- a/agent/xds/testdata/clusters/mesh-gateway-service-subsets.envoy-1-12-x.golden +++ b/agent/xds/testdata/clusters/mesh-gateway-service-subsets.envoy-1-12-x.golden @@ -111,38 +111,6 @@ "connectTimeout": "5s", "outlierDetection": { - } - }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "v1.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": { - - } - } - }, - "connectTimeout": "5s", - "outlierDetection": { - - } - }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "v2.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": { - - } - } - }, - "connectTimeout": "5s", - "outlierDetection": { - } } ], diff --git a/agent/xds/testdata/clusters/mesh-gateway-service-subsets.envoy-1-13-x.golden b/agent/xds/testdata/clusters/mesh-gateway-service-subsets.envoy-1-13-x.golden index afc23f9ae..845881fd3 100644 --- a/agent/xds/testdata/clusters/mesh-gateway-service-subsets.envoy-1-13-x.golden +++ b/agent/xds/testdata/clusters/mesh-gateway-service-subsets.envoy-1-13-x.golden @@ -111,38 +111,6 @@ "connectTimeout": "5s", "outlierDetection": { - } - }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "v1.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": { - - } - } - }, - "connectTimeout": "5s", - "outlierDetection": { - - } - }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "v2.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": { - - } - } - }, - "connectTimeout": "5s", - "outlierDetection": { - } } ], diff --git a/agent/xds/testdata/clusters/mesh-gateway-service-subsets.envoy-1-14-x.golden b/agent/xds/testdata/clusters/mesh-gateway-service-subsets.envoy-1-14-x.golden index afc23f9ae..845881fd3 100644 --- a/agent/xds/testdata/clusters/mesh-gateway-service-subsets.envoy-1-14-x.golden +++ b/agent/xds/testdata/clusters/mesh-gateway-service-subsets.envoy-1-14-x.golden @@ -111,38 +111,6 @@ "connectTimeout": "5s", "outlierDetection": { - } - }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "v1.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": { - - } - } - }, - "connectTimeout": "5s", - "outlierDetection": { - - } - }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "v2.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": { - - } - } - }, - "connectTimeout": "5s", - "outlierDetection": { - } } ], diff --git a/agent/xds/testdata/clusters/mesh-gateway-service-subsets.envoy-1-15-x.golden b/agent/xds/testdata/clusters/mesh-gateway-service-subsets.envoy-1-15-x.golden index afc23f9ae..845881fd3 100644 --- a/agent/xds/testdata/clusters/mesh-gateway-service-subsets.envoy-1-15-x.golden +++ b/agent/xds/testdata/clusters/mesh-gateway-service-subsets.envoy-1-15-x.golden @@ -111,38 +111,6 @@ "connectTimeout": "5s", "outlierDetection": { - } - }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "v1.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": { - - } - } - }, - "connectTimeout": "5s", - "outlierDetection": { - - } - }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "v2.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": { - - } - } - }, - "connectTimeout": "5s", - "outlierDetection": { - } } ], diff --git a/agent/xds/testdata/clusters/mesh-gateway-service-timeouts.envoy-1-12-x.golden b/agent/xds/testdata/clusters/mesh-gateway-service-timeouts.envoy-1-12-x.golden index bf2d50142..845881fd3 100644 --- a/agent/xds/testdata/clusters/mesh-gateway-service-timeouts.envoy-1-12-x.golden +++ b/agent/xds/testdata/clusters/mesh-gateway-service-timeouts.envoy-1-12-x.golden @@ -12,7 +12,7 @@ } } }, - "connectTimeout": "10s", + "connectTimeout": "5s", "outlierDetection": { } @@ -111,38 +111,6 @@ "connectTimeout": "5s", "outlierDetection": { - } - }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "v1.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": { - - } - } - }, - "connectTimeout": "10s", - "outlierDetection": { - - } - }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "v2.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": { - - } - } - }, - "connectTimeout": "10s", - "outlierDetection": { - } } ], diff --git a/agent/xds/testdata/clusters/mesh-gateway-service-timeouts.envoy-1-13-x.golden b/agent/xds/testdata/clusters/mesh-gateway-service-timeouts.envoy-1-13-x.golden index bf2d50142..845881fd3 100644 --- a/agent/xds/testdata/clusters/mesh-gateway-service-timeouts.envoy-1-13-x.golden +++ b/agent/xds/testdata/clusters/mesh-gateway-service-timeouts.envoy-1-13-x.golden @@ -12,7 +12,7 @@ } } }, - "connectTimeout": "10s", + "connectTimeout": "5s", "outlierDetection": { } @@ -111,38 +111,6 @@ "connectTimeout": "5s", "outlierDetection": { - } - }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "v1.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": { - - } - } - }, - "connectTimeout": "10s", - "outlierDetection": { - - } - }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "v2.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": { - - } - } - }, - "connectTimeout": "10s", - "outlierDetection": { - } } ], diff --git a/agent/xds/testdata/clusters/mesh-gateway-service-timeouts.envoy-1-14-x.golden b/agent/xds/testdata/clusters/mesh-gateway-service-timeouts.envoy-1-14-x.golden index bf2d50142..845881fd3 100644 --- a/agent/xds/testdata/clusters/mesh-gateway-service-timeouts.envoy-1-14-x.golden +++ b/agent/xds/testdata/clusters/mesh-gateway-service-timeouts.envoy-1-14-x.golden @@ -12,7 +12,7 @@ } } }, - "connectTimeout": "10s", + "connectTimeout": "5s", "outlierDetection": { } @@ -111,38 +111,6 @@ "connectTimeout": "5s", "outlierDetection": { - } - }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "v1.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": { - - } - } - }, - "connectTimeout": "10s", - "outlierDetection": { - - } - }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "v2.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": { - - } - } - }, - "connectTimeout": "10s", - "outlierDetection": { - } } ], diff --git a/agent/xds/testdata/clusters/mesh-gateway-service-timeouts.envoy-1-15-x.golden b/agent/xds/testdata/clusters/mesh-gateway-service-timeouts.envoy-1-15-x.golden index bf2d50142..845881fd3 100644 --- a/agent/xds/testdata/clusters/mesh-gateway-service-timeouts.envoy-1-15-x.golden +++ b/agent/xds/testdata/clusters/mesh-gateway-service-timeouts.envoy-1-15-x.golden @@ -12,7 +12,7 @@ } } }, - "connectTimeout": "10s", + "connectTimeout": "5s", "outlierDetection": { } @@ -111,38 +111,6 @@ "connectTimeout": "5s", "outlierDetection": { - } - }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "v1.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": { - - } - } - }, - "connectTimeout": "10s", - "outlierDetection": { - - } - }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "v2.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": { - - } - } - }, - "connectTimeout": "10s", - "outlierDetection": { - } } ], diff --git a/agent/xds/testdata/clusters/terminating-gateway-hostname-service-subsets.envoy-1-12-x.golden b/agent/xds/testdata/clusters/terminating-gateway-hostname-service-subsets.envoy-1-12-x.golden index 44bd0fd5f..27b1ddc6c 100644 --- a/agent/xds/testdata/clusters/terminating-gateway-hostname-service-subsets.envoy-1-12-x.golden +++ b/agent/xds/testdata/clusters/terminating-gateway-hostname-service-subsets.envoy-1-12-x.golden @@ -1,60 +1,6 @@ { "versionInfo": "00000001", "resources": [ - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "alt.api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "LOGICAL_DNS", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "alt.api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "api.altdomain", - "portValue": 8081 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 - } - ] - } - ] - }, - "tlsContext": { - "commonTlsContext": { - "tlsParams": { - - }, - "tlsCertificates": [ - { - "certificateChain": { - "filename": "api.cert.pem" - }, - "privateKey": { - "filename": "api.key.pem" - } - } - ], - "validationContext": { - "trustedCa": { - "filename": "ca.cert.pem" - } - } - } - }, - "dnsRefreshRate": "10s", - "dnsLookupFamily": "V4_ONLY", - "outlierDetection": { - - } - }, { "@type": "type.googleapis.com/envoy.api.v2.Cluster", "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", @@ -173,38 +119,6 @@ } }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "prod.cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "LOGICAL_DNS", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "prod.cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "cache.mydomain", - "portValue": 8081 - } - } - }, - "healthStatus": "UNHEALTHY", - "loadBalancingWeight": 1 - } - ] - } - ] - }, - "dnsRefreshRate": "10s", - "dnsLookupFamily": "V4_ONLY", - "outlierDetection": { - - } - }, { "@type": "type.googleapis.com/envoy.api.v2.Cluster", "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", diff --git a/agent/xds/testdata/clusters/terminating-gateway-hostname-service-subsets.envoy-1-13-x.golden b/agent/xds/testdata/clusters/terminating-gateway-hostname-service-subsets.envoy-1-13-x.golden index 44bd0fd5f..27b1ddc6c 100644 --- a/agent/xds/testdata/clusters/terminating-gateway-hostname-service-subsets.envoy-1-13-x.golden +++ b/agent/xds/testdata/clusters/terminating-gateway-hostname-service-subsets.envoy-1-13-x.golden @@ -1,60 +1,6 @@ { "versionInfo": "00000001", "resources": [ - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "alt.api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "LOGICAL_DNS", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "alt.api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "api.altdomain", - "portValue": 8081 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 - } - ] - } - ] - }, - "tlsContext": { - "commonTlsContext": { - "tlsParams": { - - }, - "tlsCertificates": [ - { - "certificateChain": { - "filename": "api.cert.pem" - }, - "privateKey": { - "filename": "api.key.pem" - } - } - ], - "validationContext": { - "trustedCa": { - "filename": "ca.cert.pem" - } - } - } - }, - "dnsRefreshRate": "10s", - "dnsLookupFamily": "V4_ONLY", - "outlierDetection": { - - } - }, { "@type": "type.googleapis.com/envoy.api.v2.Cluster", "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", @@ -173,38 +119,6 @@ } }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "prod.cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "LOGICAL_DNS", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "prod.cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "cache.mydomain", - "portValue": 8081 - } - } - }, - "healthStatus": "UNHEALTHY", - "loadBalancingWeight": 1 - } - ] - } - ] - }, - "dnsRefreshRate": "10s", - "dnsLookupFamily": "V4_ONLY", - "outlierDetection": { - - } - }, { "@type": "type.googleapis.com/envoy.api.v2.Cluster", "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", diff --git a/agent/xds/testdata/clusters/terminating-gateway-hostname-service-subsets.envoy-1-14-x.golden b/agent/xds/testdata/clusters/terminating-gateway-hostname-service-subsets.envoy-1-14-x.golden index 44bd0fd5f..27b1ddc6c 100644 --- a/agent/xds/testdata/clusters/terminating-gateway-hostname-service-subsets.envoy-1-14-x.golden +++ b/agent/xds/testdata/clusters/terminating-gateway-hostname-service-subsets.envoy-1-14-x.golden @@ -1,60 +1,6 @@ { "versionInfo": "00000001", "resources": [ - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "alt.api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "LOGICAL_DNS", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "alt.api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "api.altdomain", - "portValue": 8081 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 - } - ] - } - ] - }, - "tlsContext": { - "commonTlsContext": { - "tlsParams": { - - }, - "tlsCertificates": [ - { - "certificateChain": { - "filename": "api.cert.pem" - }, - "privateKey": { - "filename": "api.key.pem" - } - } - ], - "validationContext": { - "trustedCa": { - "filename": "ca.cert.pem" - } - } - } - }, - "dnsRefreshRate": "10s", - "dnsLookupFamily": "V4_ONLY", - "outlierDetection": { - - } - }, { "@type": "type.googleapis.com/envoy.api.v2.Cluster", "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", @@ -173,38 +119,6 @@ } }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "prod.cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "LOGICAL_DNS", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "prod.cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "cache.mydomain", - "portValue": 8081 - } - } - }, - "healthStatus": "UNHEALTHY", - "loadBalancingWeight": 1 - } - ] - } - ] - }, - "dnsRefreshRate": "10s", - "dnsLookupFamily": "V4_ONLY", - "outlierDetection": { - - } - }, { "@type": "type.googleapis.com/envoy.api.v2.Cluster", "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", diff --git a/agent/xds/testdata/clusters/terminating-gateway-hostname-service-subsets.envoy-1-15-x.golden b/agent/xds/testdata/clusters/terminating-gateway-hostname-service-subsets.envoy-1-15-x.golden index 44bd0fd5f..27b1ddc6c 100644 --- a/agent/xds/testdata/clusters/terminating-gateway-hostname-service-subsets.envoy-1-15-x.golden +++ b/agent/xds/testdata/clusters/terminating-gateway-hostname-service-subsets.envoy-1-15-x.golden @@ -1,60 +1,6 @@ { "versionInfo": "00000001", "resources": [ - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "alt.api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "LOGICAL_DNS", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "alt.api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "api.altdomain", - "portValue": 8081 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 - } - ] - } - ] - }, - "tlsContext": { - "commonTlsContext": { - "tlsParams": { - - }, - "tlsCertificates": [ - { - "certificateChain": { - "filename": "api.cert.pem" - }, - "privateKey": { - "filename": "api.key.pem" - } - } - ], - "validationContext": { - "trustedCa": { - "filename": "ca.cert.pem" - } - } - } - }, - "dnsRefreshRate": "10s", - "dnsLookupFamily": "V4_ONLY", - "outlierDetection": { - - } - }, { "@type": "type.googleapis.com/envoy.api.v2.Cluster", "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", @@ -173,38 +119,6 @@ } }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "prod.cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "LOGICAL_DNS", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "prod.cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "cache.mydomain", - "portValue": 8081 - } - } - }, - "healthStatus": "UNHEALTHY", - "loadBalancingWeight": 1 - } - ] - } - ] - }, - "dnsRefreshRate": "10s", - "dnsLookupFamily": "V4_ONLY", - "outlierDetection": { - - } - }, { "@type": "type.googleapis.com/envoy.api.v2.Cluster", "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", diff --git a/agent/xds/testdata/clusters/terminating-gateway-ignore-extra-resolvers.envoy-1-12-x.golden b/agent/xds/testdata/clusters/terminating-gateway-ignore-extra-resolvers.envoy-1-12-x.golden index f9c7336e6..27b1ddc6c 100644 --- a/agent/xds/testdata/clusters/terminating-gateway-ignore-extra-resolvers.envoy-1-12-x.golden +++ b/agent/xds/testdata/clusters/terminating-gateway-ignore-extra-resolvers.envoy-1-12-x.golden @@ -119,62 +119,6 @@ } }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": { - - } - } - }, - "connectTimeout": "5s", - "tlsContext": { - "commonTlsContext": { - "tlsParams": { - - }, - "validationContext": { - "trustedCa": { - "filename": "ca.cert.pem" - } - } - } - }, - "outlierDetection": { - - } - }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": { - - } - } - }, - "connectTimeout": "5s", - "tlsContext": { - "commonTlsContext": { - "tlsParams": { - - }, - "validationContext": { - "trustedCa": { - "filename": "ca.cert.pem" - } - } - } - }, - "outlierDetection": { - - } - }, { "@type": "type.googleapis.com/envoy.api.v2.Cluster", "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", diff --git a/agent/xds/testdata/clusters/terminating-gateway-ignore-extra-resolvers.envoy-1-13-x.golden b/agent/xds/testdata/clusters/terminating-gateway-ignore-extra-resolvers.envoy-1-13-x.golden index f9c7336e6..27b1ddc6c 100644 --- a/agent/xds/testdata/clusters/terminating-gateway-ignore-extra-resolvers.envoy-1-13-x.golden +++ b/agent/xds/testdata/clusters/terminating-gateway-ignore-extra-resolvers.envoy-1-13-x.golden @@ -119,62 +119,6 @@ } }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": { - - } - } - }, - "connectTimeout": "5s", - "tlsContext": { - "commonTlsContext": { - "tlsParams": { - - }, - "validationContext": { - "trustedCa": { - "filename": "ca.cert.pem" - } - } - } - }, - "outlierDetection": { - - } - }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": { - - } - } - }, - "connectTimeout": "5s", - "tlsContext": { - "commonTlsContext": { - "tlsParams": { - - }, - "validationContext": { - "trustedCa": { - "filename": "ca.cert.pem" - } - } - } - }, - "outlierDetection": { - - } - }, { "@type": "type.googleapis.com/envoy.api.v2.Cluster", "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", diff --git a/agent/xds/testdata/clusters/terminating-gateway-ignore-extra-resolvers.envoy-1-14-x.golden b/agent/xds/testdata/clusters/terminating-gateway-ignore-extra-resolvers.envoy-1-14-x.golden index f9c7336e6..27b1ddc6c 100644 --- a/agent/xds/testdata/clusters/terminating-gateway-ignore-extra-resolvers.envoy-1-14-x.golden +++ b/agent/xds/testdata/clusters/terminating-gateway-ignore-extra-resolvers.envoy-1-14-x.golden @@ -119,62 +119,6 @@ } }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": { - - } - } - }, - "connectTimeout": "5s", - "tlsContext": { - "commonTlsContext": { - "tlsParams": { - - }, - "validationContext": { - "trustedCa": { - "filename": "ca.cert.pem" - } - } - } - }, - "outlierDetection": { - - } - }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": { - - } - } - }, - "connectTimeout": "5s", - "tlsContext": { - "commonTlsContext": { - "tlsParams": { - - }, - "validationContext": { - "trustedCa": { - "filename": "ca.cert.pem" - } - } - } - }, - "outlierDetection": { - - } - }, { "@type": "type.googleapis.com/envoy.api.v2.Cluster", "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", diff --git a/agent/xds/testdata/clusters/terminating-gateway-ignore-extra-resolvers.envoy-1-15-x.golden b/agent/xds/testdata/clusters/terminating-gateway-ignore-extra-resolvers.envoy-1-15-x.golden index f9c7336e6..27b1ddc6c 100644 --- a/agent/xds/testdata/clusters/terminating-gateway-ignore-extra-resolvers.envoy-1-15-x.golden +++ b/agent/xds/testdata/clusters/terminating-gateway-ignore-extra-resolvers.envoy-1-15-x.golden @@ -119,62 +119,6 @@ } }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": { - - } - } - }, - "connectTimeout": "5s", - "tlsContext": { - "commonTlsContext": { - "tlsParams": { - - }, - "validationContext": { - "trustedCa": { - "filename": "ca.cert.pem" - } - } - } - }, - "outlierDetection": { - - } - }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": { - - } - } - }, - "connectTimeout": "5s", - "tlsContext": { - "commonTlsContext": { - "tlsParams": { - - }, - "validationContext": { - "trustedCa": { - "filename": "ca.cert.pem" - } - } - } - }, - "outlierDetection": { - - } - }, { "@type": "type.googleapis.com/envoy.api.v2.Cluster", "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", diff --git a/agent/xds/testdata/clusters/terminating-gateway-service-subsets.envoy-1-12-x.golden b/agent/xds/testdata/clusters/terminating-gateway-service-subsets.envoy-1-12-x.golden index 8e3db0460..27b1ddc6c 100644 --- a/agent/xds/testdata/clusters/terminating-gateway-service-subsets.envoy-1-12-x.golden +++ b/agent/xds/testdata/clusters/terminating-gateway-service-subsets.envoy-1-12-x.golden @@ -119,94 +119,6 @@ } }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "prod.cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "LOGICAL_DNS", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "prod.cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "cache.mydomain", - "portValue": 8081 - } - } - }, - "healthStatus": "UNHEALTHY", - "loadBalancingWeight": 1 - } - ] - } - ] - }, - "dnsRefreshRate": "10s", - "dnsLookupFamily": "V4_ONLY", - "outlierDetection": { - - } - }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": { - - } - } - }, - "connectTimeout": "5s", - "tlsContext": { - "commonTlsContext": { - "tlsParams": { - - }, - "validationContext": { - "trustedCa": { - "filename": "ca.cert.pem" - } - } - } - }, - "outlierDetection": { - - } - }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": { - - } - } - }, - "connectTimeout": "5s", - "tlsContext": { - "commonTlsContext": { - "tlsParams": { - - }, - "validationContext": { - "trustedCa": { - "filename": "ca.cert.pem" - } - } - } - }, - "outlierDetection": { - - } - }, { "@type": "type.googleapis.com/envoy.api.v2.Cluster", "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", diff --git a/agent/xds/testdata/clusters/terminating-gateway-service-subsets.envoy-1-13-x.golden b/agent/xds/testdata/clusters/terminating-gateway-service-subsets.envoy-1-13-x.golden index 8e3db0460..27b1ddc6c 100644 --- a/agent/xds/testdata/clusters/terminating-gateway-service-subsets.envoy-1-13-x.golden +++ b/agent/xds/testdata/clusters/terminating-gateway-service-subsets.envoy-1-13-x.golden @@ -119,94 +119,6 @@ } }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "prod.cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "LOGICAL_DNS", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "prod.cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "cache.mydomain", - "portValue": 8081 - } - } - }, - "healthStatus": "UNHEALTHY", - "loadBalancingWeight": 1 - } - ] - } - ] - }, - "dnsRefreshRate": "10s", - "dnsLookupFamily": "V4_ONLY", - "outlierDetection": { - - } - }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": { - - } - } - }, - "connectTimeout": "5s", - "tlsContext": { - "commonTlsContext": { - "tlsParams": { - - }, - "validationContext": { - "trustedCa": { - "filename": "ca.cert.pem" - } - } - } - }, - "outlierDetection": { - - } - }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": { - - } - } - }, - "connectTimeout": "5s", - "tlsContext": { - "commonTlsContext": { - "tlsParams": { - - }, - "validationContext": { - "trustedCa": { - "filename": "ca.cert.pem" - } - } - } - }, - "outlierDetection": { - - } - }, { "@type": "type.googleapis.com/envoy.api.v2.Cluster", "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", diff --git a/agent/xds/testdata/clusters/terminating-gateway-service-subsets.envoy-1-14-x.golden b/agent/xds/testdata/clusters/terminating-gateway-service-subsets.envoy-1-14-x.golden index 8e3db0460..27b1ddc6c 100644 --- a/agent/xds/testdata/clusters/terminating-gateway-service-subsets.envoy-1-14-x.golden +++ b/agent/xds/testdata/clusters/terminating-gateway-service-subsets.envoy-1-14-x.golden @@ -119,94 +119,6 @@ } }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "prod.cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "LOGICAL_DNS", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "prod.cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "cache.mydomain", - "portValue": 8081 - } - } - }, - "healthStatus": "UNHEALTHY", - "loadBalancingWeight": 1 - } - ] - } - ] - }, - "dnsRefreshRate": "10s", - "dnsLookupFamily": "V4_ONLY", - "outlierDetection": { - - } - }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": { - - } - } - }, - "connectTimeout": "5s", - "tlsContext": { - "commonTlsContext": { - "tlsParams": { - - }, - "validationContext": { - "trustedCa": { - "filename": "ca.cert.pem" - } - } - } - }, - "outlierDetection": { - - } - }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": { - - } - } - }, - "connectTimeout": "5s", - "tlsContext": { - "commonTlsContext": { - "tlsParams": { - - }, - "validationContext": { - "trustedCa": { - "filename": "ca.cert.pem" - } - } - } - }, - "outlierDetection": { - - } - }, { "@type": "type.googleapis.com/envoy.api.v2.Cluster", "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", diff --git a/agent/xds/testdata/clusters/terminating-gateway-service-subsets.envoy-1-15-x.golden b/agent/xds/testdata/clusters/terminating-gateway-service-subsets.envoy-1-15-x.golden index 8e3db0460..27b1ddc6c 100644 --- a/agent/xds/testdata/clusters/terminating-gateway-service-subsets.envoy-1-15-x.golden +++ b/agent/xds/testdata/clusters/terminating-gateway-service-subsets.envoy-1-15-x.golden @@ -119,94 +119,6 @@ } }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "prod.cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "LOGICAL_DNS", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "prod.cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "cache.mydomain", - "portValue": 8081 - } - } - }, - "healthStatus": "UNHEALTHY", - "loadBalancingWeight": 1 - } - ] - } - ] - }, - "dnsRefreshRate": "10s", - "dnsLookupFamily": "V4_ONLY", - "outlierDetection": { - - } - }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": { - - } - } - }, - "connectTimeout": "5s", - "tlsContext": { - "commonTlsContext": { - "tlsParams": { - - }, - "validationContext": { - "trustedCa": { - "filename": "ca.cert.pem" - } - } - } - }, - "outlierDetection": { - - } - }, - { - "@type": "type.googleapis.com/envoy.api.v2.Cluster", - "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": { - - } - } - }, - "connectTimeout": "5s", - "tlsContext": { - "commonTlsContext": { - "tlsParams": { - - }, - "validationContext": { - "trustedCa": { - "filename": "ca.cert.pem" - } - } - } - }, - "outlierDetection": { - - } - }, { "@type": "type.googleapis.com/envoy.api.v2.Cluster", "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", diff --git a/agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-12-x.golden b/agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-12-x.golden index b611e2508..e8370f265 100644 --- a/agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-12-x.golden +++ b/agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-12-x.golden @@ -3,10 +3,10 @@ "resources": [ { "@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration", - "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "virtualHosts": [ { - "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "domains": [ "*" ], @@ -16,26 +16,7 @@ "prefix": "/" }, "route": { - "cluster": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "hashPolicy": [ - { - "cookie": { - "name": "chocolate-chip" - }, - "terminal": true - }, - { - "header": { - "headerName": "x-user-id" - } - }, - { - "connectionProperties": { - "sourceIp": true - }, - "terminal": true - } - ] + "cluster": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] @@ -45,10 +26,10 @@ }, { "@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration", - "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "virtualHosts": [ { - "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "domains": [ "*" ], @@ -58,26 +39,7 @@ "prefix": "/" }, "route": { - "cluster": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "hashPolicy": [ - { - "cookie": { - "name": "chocolate-chip" - }, - "terminal": true - }, - { - "header": { - "headerName": "x-user-id" - } - }, - { - "connectionProperties": { - "sourceIp": true - }, - "terminal": true - } - ] + "cluster": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] @@ -87,10 +49,10 @@ }, { "@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration", - "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "virtualHosts": [ { - "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "domains": [ "*" ], @@ -100,26 +62,7 @@ "prefix": "/" }, "route": { - "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "hashPolicy": [ - { - "cookie": { - "name": "chocolate-chip" - }, - "terminal": true - }, - { - "header": { - "headerName": "x-user-id" - } - }, - { - "connectionProperties": { - "sourceIp": true - }, - "terminal": true - } - ] + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] diff --git a/agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-13-x.golden b/agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-13-x.golden index b611e2508..e8370f265 100644 --- a/agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-13-x.golden +++ b/agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-13-x.golden @@ -3,10 +3,10 @@ "resources": [ { "@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration", - "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "virtualHosts": [ { - "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "domains": [ "*" ], @@ -16,26 +16,7 @@ "prefix": "/" }, "route": { - "cluster": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "hashPolicy": [ - { - "cookie": { - "name": "chocolate-chip" - }, - "terminal": true - }, - { - "header": { - "headerName": "x-user-id" - } - }, - { - "connectionProperties": { - "sourceIp": true - }, - "terminal": true - } - ] + "cluster": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] @@ -45,10 +26,10 @@ }, { "@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration", - "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "virtualHosts": [ { - "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "domains": [ "*" ], @@ -58,26 +39,7 @@ "prefix": "/" }, "route": { - "cluster": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "hashPolicy": [ - { - "cookie": { - "name": "chocolate-chip" - }, - "terminal": true - }, - { - "header": { - "headerName": "x-user-id" - } - }, - { - "connectionProperties": { - "sourceIp": true - }, - "terminal": true - } - ] + "cluster": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] @@ -87,10 +49,10 @@ }, { "@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration", - "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "virtualHosts": [ { - "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "domains": [ "*" ], @@ -100,26 +62,7 @@ "prefix": "/" }, "route": { - "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "hashPolicy": [ - { - "cookie": { - "name": "chocolate-chip" - }, - "terminal": true - }, - { - "header": { - "headerName": "x-user-id" - } - }, - { - "connectionProperties": { - "sourceIp": true - }, - "terminal": true - } - ] + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] diff --git a/agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-14-x.golden b/agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-14-x.golden index b611e2508..e8370f265 100644 --- a/agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-14-x.golden +++ b/agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-14-x.golden @@ -3,10 +3,10 @@ "resources": [ { "@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration", - "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "virtualHosts": [ { - "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "domains": [ "*" ], @@ -16,26 +16,7 @@ "prefix": "/" }, "route": { - "cluster": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "hashPolicy": [ - { - "cookie": { - "name": "chocolate-chip" - }, - "terminal": true - }, - { - "header": { - "headerName": "x-user-id" - } - }, - { - "connectionProperties": { - "sourceIp": true - }, - "terminal": true - } - ] + "cluster": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] @@ -45,10 +26,10 @@ }, { "@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration", - "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "virtualHosts": [ { - "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "domains": [ "*" ], @@ -58,26 +39,7 @@ "prefix": "/" }, "route": { - "cluster": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "hashPolicy": [ - { - "cookie": { - "name": "chocolate-chip" - }, - "terminal": true - }, - { - "header": { - "headerName": "x-user-id" - } - }, - { - "connectionProperties": { - "sourceIp": true - }, - "terminal": true - } - ] + "cluster": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] @@ -87,10 +49,10 @@ }, { "@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration", - "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "virtualHosts": [ { - "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "domains": [ "*" ], @@ -100,26 +62,7 @@ "prefix": "/" }, "route": { - "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "hashPolicy": [ - { - "cookie": { - "name": "chocolate-chip" - }, - "terminal": true - }, - { - "header": { - "headerName": "x-user-id" - } - }, - { - "connectionProperties": { - "sourceIp": true - }, - "terminal": true - } - ] + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] diff --git a/agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-15-x.golden b/agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-15-x.golden index b611e2508..e8370f265 100644 --- a/agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-15-x.golden +++ b/agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-15-x.golden @@ -3,10 +3,10 @@ "resources": [ { "@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration", - "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "virtualHosts": [ { - "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "domains": [ "*" ], @@ -16,26 +16,7 @@ "prefix": "/" }, "route": { - "cluster": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "hashPolicy": [ - { - "cookie": { - "name": "chocolate-chip" - }, - "terminal": true - }, - { - "header": { - "headerName": "x-user-id" - } - }, - { - "connectionProperties": { - "sourceIp": true - }, - "terminal": true - } - ] + "cluster": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] @@ -45,10 +26,10 @@ }, { "@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration", - "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "virtualHosts": [ { - "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "domains": [ "*" ], @@ -58,26 +39,7 @@ "prefix": "/" }, "route": { - "cluster": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "hashPolicy": [ - { - "cookie": { - "name": "chocolate-chip" - }, - "terminal": true - }, - { - "header": { - "headerName": "x-user-id" - } - }, - { - "connectionProperties": { - "sourceIp": true - }, - "terminal": true - } - ] + "cluster": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] @@ -87,10 +49,10 @@ }, { "@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration", - "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "virtualHosts": [ { - "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "domains": [ "*" ], @@ -100,26 +62,7 @@ "prefix": "/" }, "route": { - "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "hashPolicy": [ - { - "cookie": { - "name": "chocolate-chip" - }, - "terminal": true - }, - { - "header": { - "headerName": "x-user-id" - } - }, - { - "connectionProperties": { - "sourceIp": true - }, - "terminal": true - } - ] + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] diff --git a/api/config_entry_discoverychain.go b/api/config_entry_discoverychain.go index 5e1636fe8..68546b615 100644 --- a/api/config_entry_discoverychain.go +++ b/api/config_entry_discoverychain.go @@ -140,7 +140,7 @@ type ServiceResolverConfigEntry struct { // LoadBalancer determines the load balancing policy and configuration for services // issuing requests to this upstream service. - LoadBalancer LoadBalancer `json:",omitempty" alias:"load_balancer"` + LoadBalancer *LoadBalancer `json:",omitempty" alias:"load_balancer"` CreateIndex uint64 ModifyIndex uint64 @@ -209,14 +209,22 @@ type ServiceResolverFailover struct { // LoadBalancer determines the load balancing policy and configuration for services // issuing requests to this upstream service. type LoadBalancer struct { + // EnvoyLBConfig contains Envoy-specific load balancing configuration for this upstream + EnvoyLBConfig *EnvoyLBConfig `json:",omitempty" alias:"envoy_lb_config"` + + // OpaqueConfig contains load balancing configuration opaque to Consul for 3rd party proxies + OpaqueConfig string `json:",omitempty" alias:"opaque_config"` +} + +type EnvoyLBConfig struct { // Policy is the load balancing policy used to select a host Policy string `json:",omitempty"` // RingHashConfig contains configuration for the "ring_hash" policy type - RingHashConfig RingHashConfig `json:",omitempty" alias:"ring_hash_config"` + RingHashConfig *RingHashConfig `json:",omitempty" alias:"ring_hash_config"` // LeastRequestConfig contains configuration for the "least_request" policy type - LeastRequestConfig LeastRequestConfig `json:",omitempty" alias:"least_request_config"` + LeastRequestConfig *LeastRequestConfig `json:",omitempty" alias:"least_request_config"` // HashPolicies is a list of hash policies to use for hashing load balancing algorithms. // Hash policies are evaluated individually and combined such that identical lists @@ -241,28 +249,37 @@ type LeastRequestConfig struct { ChoiceCount uint32 `json:",omitempty" alias:"choice_count"` } -// HashPolicy is a list of hash policies to use for hashing load balancing algorithms. -// Hash policies are evaluated individually and combined such that identical lists -// result in the same hash. -// If no hash policies are present, or none are successfully evaluated, -// then a random backend host will be selected. +// HashPolicy defines which attributes will be hashed by hash-based LB algorithms type HashPolicy struct { // Field is the attribute type to hash on. // Must be one of "header","cookie", or "query_parameter". // Cannot be specified along with SourceIP. Field string `json:",omitempty"` - // FieldMatchValue is the value to hash. + // FieldValue is the value to hash. // ie. header name, cookie name, URL query parameter name // Cannot be specified along with SourceIP. - FieldMatchValue string `json:",omitempty" alias:"field_value"` + FieldValue string `json:",omitempty" alias:"field_value"` - // SourceAddress determines whether the hash should be of the source IP rather than of a field and field value. - // Cannot be specified along with Field and FieldMatchValue. - SourceAddress bool `json:",omitempty" alias:"source_address"` + // CookieConfig contains configuration for the "cookie" hash policy type. + CookieConfig *CookieConfig `json:",omitempty" alias:"cookie_config"` + + // SourceIP determines whether the hash should be of the source IP rather than of a field and field value. + // Cannot be specified along with Field or FieldValue. + SourceIP bool `json:",omitempty" alias:"source_ip"` // Terminal will short circuit the computation of the hash when multiple hash policies are present. // If a hash is computed when a Terminal policy is evaluated, // then that hash will be used and subsequent hash policies will be ignored. Terminal bool `json:",omitempty"` } + +// 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. +type CookieConfig struct { + // TTL for generated cookies + TTL time.Duration `json:",omitempty"` + + // The path to set for the cookie + Path string `json:",omitempty"` +} diff --git a/api/config_entry_discoverychain_test.go b/api/config_entry_discoverychain_test.go index 0e77429bb..560dc1e24 100644 --- a/api/config_entry_discoverychain_test.go +++ b/api/config_entry_discoverychain_test.go @@ -293,9 +293,11 @@ func TestAPI_ConfigEntry_ServiceResolver_LoadBalancer(t *testing.T) { Kind: ServiceResolver, Name: "test-least-req", Namespace: defaultNamespace, - LoadBalancer: LoadBalancer{ - Policy: "least_request", - LeastRequestConfig: LeastRequestConfig{ChoiceCount: 10}, + LoadBalancer: &LoadBalancer{ + EnvoyLBConfig: &EnvoyLBConfig{ + Policy: "least_request", + LeastRequestConfig: &LeastRequestConfig{ChoiceCount: 10}, + }, }, }, verify: verifyResolver, @@ -306,20 +308,30 @@ func TestAPI_ConfigEntry_ServiceResolver_LoadBalancer(t *testing.T) { Kind: ServiceResolver, Name: "test-ring-hash", Namespace: defaultNamespace, - LoadBalancer: LoadBalancer{ - Policy: "ring_hash", - RingHashConfig: RingHashConfig{ - MinimumRingSize: 1024 * 2, - MaximumRingSize: 1024 * 4, - }, - HashPolicies: []HashPolicy{ - { - Field: "header", - FieldMatchValue: "my-session-header", - Terminal: true, + LoadBalancer: &LoadBalancer{ + EnvoyLBConfig: &EnvoyLBConfig{ + Policy: "ring_hash", + RingHashConfig: &RingHashConfig{ + MinimumRingSize: 1024 * 2, + MaximumRingSize: 1024 * 4, }, - { - SourceAddress: true, + HashPolicies: []HashPolicy{ + { + Field: "header", + FieldValue: "my-session-header", + Terminal: true, + }, + { + Field: "cookie", + FieldValue: "oreo", + CookieConfig: &CookieConfig{ + Path: "/tray", + TTL: 20 * time.Millisecond, + }, + }, + { + SourceIP: true, + }, }, }, }, diff --git a/command/config/write/config_write_test.go b/command/config/write/config_write_test.go index a5b9120b2..82bbda4bb 100644 --- a/command/config/write/config_write_test.go +++ b/command/config/write/config_write_test.go @@ -1,6 +1,7 @@ package write import ( + "github.com/hashicorp/consul/agent/structs" "io" "strings" "testing" @@ -1165,6 +1166,235 @@ func TestParseConfigEntry(t *testing.T) { Name: "main", }, }, + { + name: "service-resolver: envoy hash lb kitchen sink", + snake: ` + kind = "service-resolver" + name = "main" + load_balancer = { + envoy_lb_config = { + 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 = "header" + field_value = "x-user-id" + }, + { + source_ip = true + } + ] + } + } + `, + camel: ` + Kind = "service-resolver" + Name = "main" + LoadBalancer = { + EnvoyLBConfig = { + Policy = "ring_hash" + RingHashConfig = { + MinimumRingSize = 1 + MaximumRingSize = 2 + } + HashPolicies = [ + { + Field = "cookie" + FieldValue = "good-cookie" + CookieConfig = { + TTL = "1s" + Path = "/oven" + } + Terminal = true + }, + { + Field = "header" + FieldValue = "x-user-id" + }, + { + SourceIP = true + } + ] + } + } + `, + snakeJSON: ` + { + "kind": "service-resolver", + "name": "main", + "load_balancer": { + "envoy_lb_config": { + "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": "header", + "field_value": "x-user-id" + }, + { + "source_ip": true + } + ] + } + } + } + `, + camelJSON: ` + { + "Kind": "service-resolver", + "Name": "main", + "LoadBalancer": { + "EnvoyLBConfig": { + "Policy": "ring_hash", + "RingHashConfig": { + "MinimumRingSize": 1, + "MaximumRingSize": 2 + }, + "HashPolicies": [ + { + "Field": "cookie", + "FieldValue": "good-cookie", + "CookieConfig": { + "TTL": "1s", + "Path": "/oven" + }, + "Terminal": true + }, + { + "Field": "header", + "FieldValue": "x-user-id" + }, + { + "SourceIP": true + } + ] + } + } + } + `, + expect: &api.ServiceResolverConfigEntry{ + Kind: "service-resolver", + Name: "main", + LoadBalancer: &api.LoadBalancer{ + EnvoyLBConfig: &api.EnvoyLBConfig{ + Policy: structs.LBPolicyRingHash, + RingHashConfig: &api.RingHashConfig{ + MinimumRingSize: 1, + MaximumRingSize: 2, + }, + HashPolicies: []api.HashPolicy{ + { + Field: structs.HashPolicyCookie, + FieldValue: "good-cookie", + CookieConfig: &api.CookieConfig{ + TTL: 1 * time.Second, + Path: "/oven", + }, + Terminal: true, + }, + { + Field: structs.HashPolicyHeader, + FieldValue: "x-user-id", + }, + { + SourceIP: true, + }, + }, + }, + }, + }, + }, + { + name: "service-resolver: envoy least request kitchen sink", + snake: ` + kind = "service-resolver" + name = "main" + load_balancer = { + envoy_lb_config = { + policy = "least_request" + least_request_config = { + choice_count = 2 + } + } + } + `, + camel: ` + Kind = "service-resolver" + Name = "main" + LoadBalancer = { + EnvoyLBConfig = { + Policy = "least_request" + LeastRequestConfig = { + ChoiceCount = 2 + } + } + } + `, + snakeJSON: ` + { + "kind": "service-resolver", + "name": "main", + "load_balancer": { + "envoy_lb_config": { + "policy": "least_request", + "least_request_config": { + "choice_count": 2 + } + } + } + } + `, + camelJSON: ` + { + "Kind": "service-resolver", + "Name": "main", + "LoadBalancer": { + "EnvoyLBConfig": { + "Policy": "least_request", + "LeastRequestConfig": { + "ChoiceCount": 2 + } + } + } + } + `, + expect: &api.ServiceResolverConfigEntry{ + Kind: "service-resolver", + Name: "main", + LoadBalancer: &api.LoadBalancer{ + EnvoyLBConfig: &api.EnvoyLBConfig{ + Policy: structs.LBPolicyLeastRequest, + LeastRequestConfig: &api.LeastRequestConfig{ + ChoiceCount: 2, + }, + }, + }, + }, + }, { name: "expose paths: kitchen sink proxy defaults", snake: ` diff --git a/website/pages/docs/agent/config-entries/service-resolver.mdx b/website/pages/docs/agent/config-entries/service-resolver.mdx index d0cd54988..c5a27b533 100644 --- a/website/pages/docs/agent/config-entries/service-resolver.mdx +++ b/website/pages/docs/agent/config-entries/service-resolver.mdx @@ -83,7 +83,7 @@ LoadBalancer = { HashPolicies = [ { Field = "header" - FieldMatchValue = "x-user-id" + FieldValue = "x-user-id" } ] } @@ -171,48 +171,52 @@ LoadBalancer = { configuration for services issuing requests to this upstream. This option is available in Consul versions 1.8.4 and newer. - **Note:** The options below are specific to Envoy proxy. - - - `Policy` `(string: "")` - The load balancing policy used to select a host. - One of: `random`, `round_robin`, `least_request`, `ring_hash`, `maglev`. - - - `RingHashConfig` `(RingHashConfig)` - Configuration for the `ring_hash` - policy type. - - - `MinimumRingRize` `(int: 1024)` - Determines the minimum number of entries - in the hash ring. - - - `MaximumRingRize` `(int: 8192)` - Determines the maximum number of entries - in the hash ring. - - - `LeastRequestConfig` `(LeastRequestConfig)` - Configuration for the `least_request` - policy type. - - - `ChoiceCount` `(int: 2)` - Determines the number of random healthy hosts - from which to select the one with the least requests. - - - `HashPolicies` `(array)` - a list of hash policies to use for - hashing load balancing algorithms. Hash policies are evaluated individually - and combined such that identical lists result in the same hash. - If no hash policies are present, or none are successfully evaluated, - then a random backend host will be selected. - - - `Field` `(string: "")` - The attribute type to hash on. - Must be one of `header`,`cookie`, or `query_parameter`. - Cannot be specified along with `SourceAddress`. + - `EnvoyLBConfig` `(EnvoyLBConfig)` - Envoy proxy specific load balancing configuration + for this upstream. + + - `Policy` `(string: "")` - The load balancing policy used to select a host. + One of: `random`, `round_robin`, `least_request`, `ring_hash`, `maglev`. + + - `RingHashConfig` `(RingHashConfig)` - Configuration for the `ring_hash` + policy type. - - `FieldMatchValue` `(string: "")` - The value to hash. - ie. header name, cookie name, URL query parameter name. - Cannot be specified along with `SourceAddress`. + - `MinimumRingRize` `(int: 1024)` - Determines the minimum number of entries + in the hash ring. - - `SourceAddress` `(bool: false)` - Determines whether the hash should be of the source IP - address rather than of a field and field value. - Cannot be specified along with `Field` or `FieldMatchValue`. + - `MaximumRingRize` `(int: 8192)` - Determines the maximum number of entries + in the hash ring. + + - `LeastRequestConfig` `(LeastRequestConfig)` - Configuration for the `least_request` + policy type. - - `Terminal` `(bool: false)` - Will short circuit the computation of the hash - when multiple hash policies are present. If a hash is computed when a - Terminal policy is evaluated, then that hash will be used and subsequent - hash policies will be ignored. + - `ChoiceCount` `(int: 2)` - Determines the number of random healthy hosts + from which to select the one with the least requests. + + - `HashPolicies` `(array)` - a list of hash policies to use for + hashing load balancing algorithms. Hash policies are evaluated individually + and combined such that identical lists result in the same hash. + If no hash policies are present, or none are successfully evaluated, + then a random backend host will be selected. + + - `Field` `(string: "")` - The attribute type to hash on. + Must be one of `header`,`cookie`, or `query_parameter`. + Cannot be specified along with `SourceAddress`. + + - `FieldValue` `(string: "")` - The value to hash. + ie. header name, cookie name, URL query parameter name. + Cannot be specified along with `SourceAddress`. + + - `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. + + - `SourceIP` `(bool: false)` - Determines whether the hash should be of the source IP + address rather than of a field and field value. + Cannot be specified along with `Field` or `FieldValue`. + + - `Terminal` `(bool: false)` - Will short circuit the computation of the hash + when multiple hash policies are present. If a hash is computed when a + Terminal policy is evaluated, then that hash will be used and subsequent + hash policies will be ignored. ## Service Subsets diff --git a/website/pages/docs/internals/discovery-chain.mdx b/website/pages/docs/internals/discovery-chain.mdx index 9c0ec3bb8..f42d52bb2 100644 --- a/website/pages/docs/internals/discovery-chain.mdx +++ b/website/pages/docs/internals/discovery-chain.mdx @@ -184,6 +184,12 @@ A single node in the compiled discovery chain. - `Targets` `(array)` - List of targets found in [`Targets`](#targets) to failover to in order of preference. + + - `LoadBalancer` `(LoadBalancer: `) - Copy of the underlying `service-resolver` + [`LoadBalancer`](/docs/agent/config-entries/service-resolver#loadbalancer) field. + + If a `service-splitter` splits between services with differing `LoadBalancer` configuration + the first hash-based load balancing policy is copied. #### `DiscoveryTarget` From daad3b9210fa2f11c2999d87822089ac1c234b86 Mon Sep 17 00:00:00 2001 From: freddygv Date: Wed, 2 Sep 2020 15:13:50 -0600 Subject: [PATCH 07/20] Remove LB infix and move injection to xds --- agent/consul/discoverychain/compile.go | 2 +- agent/consul/discoverychain/compile_test.go | 20 +- agent/proxycfg/testing.go | 2 +- agent/structs/config_entry_discoverychain.go | 117 +------ .../config_entry_discoverychain_test.go | 308 ++---------------- agent/xds/clusters.go | 59 +++- agent/xds/clusters_test.go | 90 ++++- agent/xds/routes.go | 79 ++++- agent/xds/routes_test.go | 185 ++++++++++- api/config_entry_discoverychain.go | 4 +- api/config_entry_discoverychain_test.go | 4 +- command/config/write/config_write_test.go | 12 +- 12 files changed, 439 insertions(+), 443 deletions(-) diff --git a/agent/consul/discoverychain/compile.go b/agent/consul/discoverychain/compile.go index 31c3baa96..2acbde76f 100644 --- a/agent/consul/discoverychain/compile.go +++ b/agent/consul/discoverychain/compile.go @@ -746,7 +746,7 @@ func (c *compiler) getSplitterNode(sid structs.ServiceID) (*structs.DiscoveryGra // We cannot apply multiple hash policies to a splitter node's route action. // Therefore, we attach the first hash-based load balancer config we encounter. if !hasLB { - if lb := node.LoadBalancer; lb != nil && lb.EnvoyLBConfig != nil && lb.EnvoyLBConfig.IsHashBased() { + if lb := node.LoadBalancer; lb != nil && lb.EnvoyConfig != nil && lb.EnvoyConfig.IsHashBased() { splitNode.LoadBalancer = node.LoadBalancer hasLB = true } diff --git a/agent/consul/discoverychain/compile_test.go b/agent/consul/discoverychain/compile_test.go index 420436272..7e4c78dc8 100644 --- a/agent/consul/discoverychain/compile_test.go +++ b/agent/consul/discoverychain/compile_test.go @@ -1762,7 +1762,7 @@ func testcase_AllBellsAndWhistles() compileTestCase { "qa": {Filter: "ServiceMeta.env == qa"}, }, LoadBalancer: &structs.LoadBalancer{ - EnvoyLBConfig: &structs.EnvoyLBConfig{ + EnvoyConfig: &structs.EnvoyLBConfig{ Policy: "ring_hash", RingHashConfig: &structs.RingHashConfig{ MaximumRingSize: 100, @@ -1836,7 +1836,7 @@ func testcase_AllBellsAndWhistles() compileTestCase { }, }, LoadBalancer: &structs.LoadBalancer{ - EnvoyLBConfig: &structs.EnvoyLBConfig{ + EnvoyConfig: &structs.EnvoyLBConfig{ Policy: "ring_hash", RingHashConfig: &structs.RingHashConfig{ MaximumRingSize: 100, @@ -1857,7 +1857,7 @@ func testcase_AllBellsAndWhistles() compileTestCase { Target: "prod.redirected.default.dc1", }, LoadBalancer: &structs.LoadBalancer{ - EnvoyLBConfig: &structs.EnvoyLBConfig{ + EnvoyConfig: &structs.EnvoyLBConfig{ Policy: "ring_hash", RingHashConfig: &structs.RingHashConfig{ MaximumRingSize: 100, @@ -2282,7 +2282,7 @@ func testcase_LBConfig() compileTestCase { Kind: "service-resolver", Name: "foo", LoadBalancer: &structs.LoadBalancer{ - EnvoyLBConfig: &structs.EnvoyLBConfig{ + EnvoyConfig: &structs.EnvoyLBConfig{ Policy: "least_request", LeastRequestConfig: &structs.LeastRequestConfig{ ChoiceCount: 3, @@ -2294,7 +2294,7 @@ func testcase_LBConfig() compileTestCase { Kind: "service-resolver", Name: "bar", LoadBalancer: &structs.LoadBalancer{ - EnvoyLBConfig: &structs.EnvoyLBConfig{ + EnvoyConfig: &structs.EnvoyLBConfig{ Policy: "ring_hash", RingHashConfig: &structs.RingHashConfig{ MaximumRingSize: 101, @@ -2311,7 +2311,7 @@ func testcase_LBConfig() compileTestCase { Kind: "service-resolver", Name: "baz", LoadBalancer: &structs.LoadBalancer{ - EnvoyLBConfig: &structs.EnvoyLBConfig{ + EnvoyConfig: &structs.EnvoyLBConfig{ Policy: "maglev", HashPolicies: []structs.HashPolicy{ { @@ -2353,7 +2353,7 @@ func testcase_LBConfig() compileTestCase { // The LB config from bar is attached because splitters only care about hash-based policies, // and it's the config from bar not baz because we pick the first one we encounter in the Splits. LoadBalancer: &structs.LoadBalancer{ - EnvoyLBConfig: &structs.EnvoyLBConfig{ + EnvoyConfig: &structs.EnvoyLBConfig{ Policy: "ring_hash", RingHashConfig: &structs.RingHashConfig{ MaximumRingSize: 101, @@ -2376,7 +2376,7 @@ func testcase_LBConfig() compileTestCase { Target: "foo.default.dc1", }, LoadBalancer: &structs.LoadBalancer{ - EnvoyLBConfig: &structs.EnvoyLBConfig{ + EnvoyConfig: &structs.EnvoyLBConfig{ Policy: "least_request", LeastRequestConfig: &structs.LeastRequestConfig{ ChoiceCount: 3, @@ -2393,7 +2393,7 @@ func testcase_LBConfig() compileTestCase { Target: "bar.default.dc1", }, LoadBalancer: &structs.LoadBalancer{ - EnvoyLBConfig: &structs.EnvoyLBConfig{ + EnvoyConfig: &structs.EnvoyLBConfig{ Policy: "ring_hash", RingHashConfig: &structs.RingHashConfig{ MaximumRingSize: 101, @@ -2415,7 +2415,7 @@ func testcase_LBConfig() compileTestCase { Target: "baz.default.dc1", }, LoadBalancer: &structs.LoadBalancer{ - EnvoyLBConfig: &structs.EnvoyLBConfig{ + EnvoyConfig: &structs.EnvoyLBConfig{ Policy: "maglev", HashPolicies: []structs.HashPolicy{ { diff --git a/agent/proxycfg/testing.go b/agent/proxycfg/testing.go index 0ed1acd12..2c6a0cd03 100644 --- a/agent/proxycfg/testing.go +++ b/agent/proxycfg/testing.go @@ -1275,7 +1275,7 @@ func setupTestVariationConfigEntriesAndSnapshot( Kind: structs.ServiceResolver, Name: "db", LoadBalancer: &structs.LoadBalancer{ - EnvoyLBConfig: &structs.EnvoyLBConfig{ + EnvoyConfig: &structs.EnvoyLBConfig{ Policy: "ring_hash", RingHashConfig: &structs.RingHashConfig{ MinimumRingSize: 20, diff --git a/agent/structs/config_entry_discoverychain.go b/agent/structs/config_entry_discoverychain.go index e033f674f..9fc2550c0 100644 --- a/agent/structs/config_entry_discoverychain.go +++ b/agent/structs/config_entry_discoverychain.go @@ -3,7 +3,6 @@ package structs import ( "encoding/json" "fmt" - "github.com/golang/protobuf/ptypes" "math" "regexp" "sort" @@ -11,9 +10,6 @@ import ( "strings" "time" - envoy "github.com/envoyproxy/go-control-plane/envoy/api/v2" - envoyroute "github.com/envoyproxy/go-control-plane/envoy/api/v2/route" - "github.com/golang/protobuf/ptypes/wrappers" "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/agent/cache" "github.com/hashicorp/consul/lib" @@ -829,8 +825,8 @@ func (e *ServiceResolverConfigEntry) Validate() error { return fmt.Errorf("Bad ConnectTimeout '%s', must be >= 0", e.ConnectTimeout) } - if e.LoadBalancer != nil && e.LoadBalancer.EnvoyLBConfig != nil { - ec := e.LoadBalancer.EnvoyLBConfig + if e.LoadBalancer != nil && e.LoadBalancer.EnvoyConfig != nil { + ec := e.LoadBalancer.EnvoyConfig validPolicies := map[string]bool{ "": true, @@ -1025,8 +1021,8 @@ type ServiceResolverFailover struct { // LoadBalancer determines the load balancing policy and configuration for services // issuing requests to this upstream service. type LoadBalancer struct { - // EnvoyLBConfig contains Envoy-specific load balancing configuration for this upstream - EnvoyLBConfig *EnvoyLBConfig `json:",omitempty" alias:"envoy_lb_config"` + // EnvoyConfig contains Envoy-specific load balancing configuration for this upstream + EnvoyConfig *EnvoyLBConfig `json:",omitempty" alias:"envoy_config"` // OpaqueConfig contains load balancing configuration opaque to Consul for 3rd party proxies OpaqueConfig string `json:",omitempty" alias:"opaque_config"` @@ -1113,111 +1109,6 @@ func (ec *EnvoyLBConfig) IsHashBased() bool { } } -func (ec *EnvoyLBConfig) InjectToCluster(c *envoy.Cluster) error { - if ec == nil { - return nil - } - - switch ec.Policy { - case "": - return nil - case LBPolicyLeastRequest: - c.LbPolicy = envoy.Cluster_LEAST_REQUEST - - if ec.LeastRequestConfig != nil { - c.LbConfig = &envoy.Cluster_LeastRequestLbConfig_{ - LeastRequestLbConfig: &envoy.Cluster_LeastRequestLbConfig{ - ChoiceCount: &wrappers.UInt32Value{Value: ec.LeastRequestConfig.ChoiceCount}, - }, - } - } - case LBPolicyRoundRobin: - c.LbPolicy = envoy.Cluster_ROUND_ROBIN - - case LBPolicyRandom: - c.LbPolicy = envoy.Cluster_RANDOM - - case LBPolicyRingHash: - c.LbPolicy = envoy.Cluster_RING_HASH - - if ec.RingHashConfig != nil { - c.LbConfig = &envoy.Cluster_RingHashLbConfig_{ - RingHashLbConfig: &envoy.Cluster_RingHashLbConfig{ - MinimumRingSize: &wrappers.UInt64Value{Value: ec.RingHashConfig.MinimumRingSize}, - MaximumRingSize: &wrappers.UInt64Value{Value: ec.RingHashConfig.MaximumRingSize}, - }, - } - } - case LBPolicyMaglev: - c.LbPolicy = envoy.Cluster_MAGLEV - - default: - return fmt.Errorf("unsupported load balancer policy %q for cluster %q", ec.Policy, c.Name) - } - return nil -} - -func (ec *EnvoyLBConfig) InjectToRouteAction(action *envoyroute.RouteAction) error { - if ec == nil || !ec.IsHashBased() { - return nil - } - - result := make([]*envoyroute.RouteAction_HashPolicy, 0, len(ec.HashPolicies)) - for _, policy := range ec.HashPolicies { - if policy.SourceIP { - result = append(result, &envoyroute.RouteAction_HashPolicy{ - PolicySpecifier: &envoyroute.RouteAction_HashPolicy_ConnectionProperties_{ - ConnectionProperties: &envoyroute.RouteAction_HashPolicy_ConnectionProperties{ - SourceIp: true, - }, - }, - Terminal: policy.Terminal, - }) - - continue - } - - switch policy.Field { - case HashPolicyHeader: - result = append(result, &envoyroute.RouteAction_HashPolicy{ - PolicySpecifier: &envoyroute.RouteAction_HashPolicy_Header_{ - Header: &envoyroute.RouteAction_HashPolicy_Header{ - HeaderName: policy.FieldValue, - }, - }, - Terminal: policy.Terminal, - }) - case HashPolicyCookie: - cookie := envoyroute.RouteAction_HashPolicy_Cookie{ - Name: policy.FieldValue, - } - if policy.CookieConfig != nil { - cookie.Ttl = ptypes.DurationProto(policy.CookieConfig.TTL) - cookie.Path = policy.CookieConfig.Path - } - result = append(result, &envoyroute.RouteAction_HashPolicy{ - PolicySpecifier: &envoyroute.RouteAction_HashPolicy_Cookie_{ - Cookie: &cookie, - }, - Terminal: policy.Terminal, - }) - case HashPolicyQueryParam: - result = append(result, &envoyroute.RouteAction_HashPolicy{ - PolicySpecifier: &envoyroute.RouteAction_HashPolicy_QueryParameter_{ - QueryParameter: &envoyroute.RouteAction_HashPolicy_QueryParameter{ - Name: policy.FieldValue, - }, - }, - Terminal: policy.Terminal, - }) - default: - return fmt.Errorf("unsupported load balancer hash policy field: %v", policy.Field) - } - } - action.HashPolicy = result - return nil -} - type discoveryChainConfigEntry interface { ConfigEntry // ListRelatedServices returns a list of other names of services referenced diff --git a/agent/structs/config_entry_discoverychain_test.go b/agent/structs/config_entry_discoverychain_test.go index bd323855c..2f5c431ca 100644 --- a/agent/structs/config_entry_discoverychain_test.go +++ b/agent/structs/config_entry_discoverychain_test.go @@ -3,14 +3,10 @@ package structs import ( "bytes" "fmt" - "github.com/golang/protobuf/ptypes" "strings" "testing" "time" - envoy "github.com/envoyproxy/go-control-plane/envoy/api/v2" - envoyroute "github.com/envoyproxy/go-control-plane/envoy/api/v2/route" - "github.com/golang/protobuf/ptypes/wrappers" "github.com/hashicorp/consul/acl" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -559,7 +555,7 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { Kind: ServiceResolver, Name: "test", LoadBalancer: &LoadBalancer{ - EnvoyLBConfig: &EnvoyLBConfig{Policy: ""}, + EnvoyConfig: &EnvoyLBConfig{Policy: ""}, }, }, }, @@ -569,7 +565,7 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { Kind: ServiceResolver, Name: "test", LoadBalancer: &LoadBalancer{ - EnvoyLBConfig: &EnvoyLBConfig{Policy: LBPolicyRandom}, + EnvoyConfig: &EnvoyLBConfig{Policy: LBPolicyRandom}, }, }, }, @@ -579,7 +575,7 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { Kind: ServiceResolver, Name: "test", LoadBalancer: &LoadBalancer{ - EnvoyLBConfig: &EnvoyLBConfig{Policy: "fake-policy"}, + EnvoyConfig: &EnvoyLBConfig{Policy: "fake-policy"}, }, }, validateErr: `"fake-policy" is not supported`, @@ -590,7 +586,7 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { Kind: ServiceResolver, Name: "test", LoadBalancer: &LoadBalancer{ - EnvoyLBConfig: &EnvoyLBConfig{ + EnvoyConfig: &EnvoyLBConfig{ Policy: LBPolicyRingHash, LeastRequestConfig: &LeastRequestConfig{ChoiceCount: 10}, }, @@ -604,7 +600,7 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { Kind: ServiceResolver, Name: "test", LoadBalancer: &LoadBalancer{ - EnvoyLBConfig: &EnvoyLBConfig{ + EnvoyConfig: &EnvoyLBConfig{ Policy: LBPolicyLeastRequest, RingHashConfig: &RingHashConfig{MinimumRingSize: 1024}, }, @@ -618,7 +614,7 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { Kind: ServiceResolver, Name: "test", LoadBalancer: &LoadBalancer{ - EnvoyLBConfig: &EnvoyLBConfig{ + EnvoyConfig: &EnvoyLBConfig{ Policy: LBPolicyRingHash, RingHashConfig: &RingHashConfig{MinimumRingSize: 1024}, }, @@ -631,7 +627,7 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { Kind: ServiceResolver, Name: "test", LoadBalancer: &LoadBalancer{ - EnvoyLBConfig: &EnvoyLBConfig{ + EnvoyConfig: &EnvoyLBConfig{ Policy: LBPolicyLeastRequest, LeastRequestConfig: &LeastRequestConfig{ChoiceCount: 2}, }, @@ -644,11 +640,11 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { Kind: ServiceResolver, Name: "test", LoadBalancer: &LoadBalancer{ - EnvoyLBConfig: &EnvoyLBConfig{Policy: ""}, + EnvoyConfig: &EnvoyLBConfig{Policy: ""}, }, }, check: func(t *testing.T, entry *ServiceResolverConfigEntry) { - require.Equal(t, "", entry.LoadBalancer.EnvoyLBConfig.Policy) + require.Equal(t, "", entry.LoadBalancer.EnvoyConfig.Policy) }, }, { @@ -657,7 +653,7 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { Kind: ServiceResolver, Name: "test", LoadBalancer: &LoadBalancer{ - EnvoyLBConfig: &EnvoyLBConfig{ + EnvoyConfig: &EnvoyLBConfig{ Policy: "", HashPolicies: []HashPolicy{ { @@ -675,7 +671,7 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { Kind: ServiceResolver, Name: "test", LoadBalancer: &LoadBalancer{ - EnvoyLBConfig: &EnvoyLBConfig{ + EnvoyConfig: &EnvoyLBConfig{ Policy: LBPolicyMaglev, HashPolicies: []HashPolicy{ { @@ -698,7 +694,7 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { Kind: ServiceResolver, Name: "test", LoadBalancer: &LoadBalancer{ - EnvoyLBConfig: &EnvoyLBConfig{ + EnvoyConfig: &EnvoyLBConfig{ Policy: LBPolicyMaglev, HashPolicies: []HashPolicy{ { @@ -720,7 +716,7 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { Kind: ServiceResolver, Name: "test", LoadBalancer: &LoadBalancer{ - EnvoyLBConfig: &EnvoyLBConfig{ + EnvoyConfig: &EnvoyLBConfig{ Policy: LBPolicyMaglev, HashPolicies: []HashPolicy{ { @@ -738,7 +734,7 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { Kind: ServiceResolver, Name: "test", LoadBalancer: &LoadBalancer{ - EnvoyLBConfig: &EnvoyLBConfig{ + EnvoyConfig: &EnvoyLBConfig{ Policy: LBPolicyMaglev, HashPolicies: []HashPolicy{ { @@ -756,7 +752,7 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { Kind: ServiceResolver, Name: "test", LoadBalancer: &LoadBalancer{ - EnvoyLBConfig: &EnvoyLBConfig{ + EnvoyConfig: &EnvoyLBConfig{ Policy: LBPolicyMaglev, HashPolicies: []HashPolicy{ { @@ -775,7 +771,7 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { Kind: ServiceResolver, Name: "test", LoadBalancer: &LoadBalancer{ - EnvoyLBConfig: &EnvoyLBConfig{ + EnvoyConfig: &EnvoyLBConfig{ Policy: LBPolicyMaglev, HashPolicies: []HashPolicy{ { @@ -794,7 +790,7 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { Kind: ServiceResolver, Name: "test", LoadBalancer: &LoadBalancer{ - EnvoyLBConfig: &EnvoyLBConfig{ + EnvoyConfig: &EnvoyLBConfig{ Policy: LBPolicyMaglev, HashPolicies: []HashPolicy{ { @@ -812,7 +808,7 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { Kind: ServiceResolver, Name: "test", LoadBalancer: &LoadBalancer{ - EnvoyLBConfig: &EnvoyLBConfig{ + EnvoyConfig: &EnvoyLBConfig{ Policy: LBPolicyMaglev, HashPolicies: []HashPolicy{ { @@ -830,7 +826,7 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { Kind: ServiceResolver, Name: "test", LoadBalancer: &LoadBalancer{ - EnvoyLBConfig: &EnvoyLBConfig{ + EnvoyConfig: &EnvoyLBConfig{ Policy: LBPolicyRingHash, RingHashConfig: &RingHashConfig{MaximumRingSize: 10, MinimumRingSize: 2}, HashPolicies: []HashPolicy{ @@ -854,7 +850,7 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { Kind: ServiceResolver, Name: "test", LoadBalancer: &LoadBalancer{ - EnvoyLBConfig: &EnvoyLBConfig{ + EnvoyConfig: &EnvoyLBConfig{ Policy: LBPolicyLeastRequest, LeastRequestConfig: &LeastRequestConfig{ChoiceCount: 20}, }, @@ -1525,267 +1521,3 @@ func TestIsProtocolHTTPLike(t *testing.T) { assert.True(t, IsProtocolHTTPLike("http2")) assert.True(t, IsProtocolHTTPLike("grpc")) } - -func TestEnvoyLBConfig_InjectToRouteAction(t *testing.T) { - var tests = []struct { - name string - lb *EnvoyLBConfig - expected envoyroute.RouteAction - }{ - { - name: "empty", - lb: &EnvoyLBConfig{ - Policy: "", - }, - // we only modify route actions for hash-based LB policies - expected: envoyroute.RouteAction{}, - }, - { - name: "least request", - lb: &EnvoyLBConfig{ - Policy: LBPolicyLeastRequest, - LeastRequestConfig: &LeastRequestConfig{ - ChoiceCount: 3, - }, - }, - // we only modify route actions for hash-based LB policies - expected: envoyroute.RouteAction{}, - }, - { - name: "headers", - lb: &EnvoyLBConfig{ - Policy: "ring_hash", - RingHashConfig: &RingHashConfig{ - MinimumRingSize: 3, - MaximumRingSize: 7, - }, - HashPolicies: []HashPolicy{ - { - Field: HashPolicyHeader, - FieldValue: "x-route-key", - Terminal: true, - }, - }, - }, - expected: envoyroute.RouteAction{ - HashPolicy: []*envoyroute.RouteAction_HashPolicy{ - { - PolicySpecifier: &envoyroute.RouteAction_HashPolicy_Header_{ - Header: &envoyroute.RouteAction_HashPolicy_Header{ - HeaderName: "x-route-key", - }, - }, - Terminal: true, - }, - }, - }, - }, - { - name: "cookies", - lb: &EnvoyLBConfig{ - Policy: LBPolicyMaglev, - HashPolicies: []HashPolicy{ - { - Field: HashPolicyCookie, - FieldValue: "red-velvet", - Terminal: true, - }, - { - Field: HashPolicyCookie, - FieldValue: "oatmeal", - }, - }, - }, - expected: envoyroute.RouteAction{ - HashPolicy: []*envoyroute.RouteAction_HashPolicy{ - { - PolicySpecifier: &envoyroute.RouteAction_HashPolicy_Cookie_{ - Cookie: &envoyroute.RouteAction_HashPolicy_Cookie{ - Name: "red-velvet", - }, - }, - Terminal: true, - }, - { - PolicySpecifier: &envoyroute.RouteAction_HashPolicy_Cookie_{ - Cookie: &envoyroute.RouteAction_HashPolicy_Cookie{ - Name: "oatmeal", - }, - }, - }, - }, - }, - }, - { - name: "source addr", - lb: &EnvoyLBConfig{ - Policy: LBPolicyMaglev, - HashPolicies: []HashPolicy{ - { - SourceIP: true, - Terminal: true, - }, - }, - }, - expected: envoyroute.RouteAction{ - HashPolicy: []*envoyroute.RouteAction_HashPolicy{ - { - PolicySpecifier: &envoyroute.RouteAction_HashPolicy_ConnectionProperties_{ - ConnectionProperties: &envoyroute.RouteAction_HashPolicy_ConnectionProperties{ - SourceIp: true, - }, - }, - Terminal: true, - }, - }, - }, - }, - { - name: "kitchen sink", - lb: &EnvoyLBConfig{ - Policy: LBPolicyMaglev, - HashPolicies: []HashPolicy{ - { - SourceIP: true, - Terminal: true, - }, - { - Field: HashPolicyCookie, - FieldValue: "oatmeal", - CookieConfig: &CookieConfig{ - TTL: 10 * time.Second, - Path: "/oven", - }, - }, - { - Field: HashPolicyHeader, - FieldValue: "special-header", - Terminal: true, - }, - }, - }, - expected: envoyroute.RouteAction{ - HashPolicy: []*envoyroute.RouteAction_HashPolicy{ - { - PolicySpecifier: &envoyroute.RouteAction_HashPolicy_ConnectionProperties_{ - ConnectionProperties: &envoyroute.RouteAction_HashPolicy_ConnectionProperties{ - SourceIp: true, - }, - }, - Terminal: true, - }, - { - PolicySpecifier: &envoyroute.RouteAction_HashPolicy_Cookie_{ - Cookie: &envoyroute.RouteAction_HashPolicy_Cookie{ - Name: "oatmeal", - Ttl: ptypes.DurationProto(10 * time.Second), - Path: "/oven", - }, - }, - }, - { - PolicySpecifier: &envoyroute.RouteAction_HashPolicy_Header_{ - Header: &envoyroute.RouteAction_HashPolicy_Header{ - HeaderName: "special-header", - }, - }, - Terminal: true, - }, - }, - }, - }, - } - - for _, tc := range tests { - t.Run(tc.name, func(t *testing.T) { - var ra envoyroute.RouteAction - err := tc.lb.InjectToRouteAction(&ra) - require.NoError(t, err) - - require.Equal(t, &tc.expected, &ra) - }) - } -} - -func TestEnvoyLBConfig_InjectToCluster(t *testing.T) { - var tests = []struct { - name string - lb *EnvoyLBConfig - expected envoy.Cluster - }{ - { - name: "skip empty", - lb: &EnvoyLBConfig{ - Policy: "", - }, - expected: envoy.Cluster{}, - }, - { - name: "round robin", - lb: &EnvoyLBConfig{ - Policy: LBPolicyRoundRobin, - }, - expected: envoy.Cluster{LbPolicy: envoy.Cluster_ROUND_ROBIN}, - }, - { - name: "random", - lb: &EnvoyLBConfig{ - Policy: LBPolicyRandom, - }, - expected: envoy.Cluster{LbPolicy: envoy.Cluster_RANDOM}, - }, - { - name: "maglev", - lb: &EnvoyLBConfig{ - Policy: LBPolicyMaglev, - }, - expected: envoy.Cluster{LbPolicy: envoy.Cluster_MAGLEV}, - }, - { - name: "ring_hash", - lb: &EnvoyLBConfig{ - Policy: LBPolicyRingHash, - RingHashConfig: &RingHashConfig{ - MinimumRingSize: 3, - MaximumRingSize: 7, - }, - }, - expected: envoy.Cluster{ - LbPolicy: envoy.Cluster_RING_HASH, - LbConfig: &envoy.Cluster_RingHashLbConfig_{ - RingHashLbConfig: &envoy.Cluster_RingHashLbConfig{ - MinimumRingSize: &wrappers.UInt64Value{Value: 3}, - MaximumRingSize: &wrappers.UInt64Value{Value: 7}, - }, - }, - }, - }, - { - name: "least_request", - lb: &EnvoyLBConfig{ - Policy: "least_request", - LeastRequestConfig: &LeastRequestConfig{ - ChoiceCount: 3, - }, - }, - expected: envoy.Cluster{ - LbPolicy: envoy.Cluster_LEAST_REQUEST, - LbConfig: &envoy.Cluster_LeastRequestLbConfig_{ - LeastRequestLbConfig: &envoy.Cluster_LeastRequestLbConfig{ - ChoiceCount: &wrappers.UInt32Value{Value: 3}, - }, - }, - }, - }, - } - - for _, tc := range tests { - t.Run(tc.name, func(t *testing.T) { - var c envoy.Cluster - err := tc.lb.InjectToCluster(&c) - require.NoError(t, err) - - require.Equal(t, tc.expected, c) - }) - } -} diff --git a/agent/xds/clusters.go b/agent/xds/clusters.go index b87243212..4c061a86f 100644 --- a/agent/xds/clusters.go +++ b/agent/xds/clusters.go @@ -16,6 +16,7 @@ import ( "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" "github.com/golang/protobuf/ptypes/any" + "github.com/golang/protobuf/ptypes/wrappers" "github.com/hashicorp/consul/agent/connect" "github.com/hashicorp/consul/agent/proxycfg" "github.com/hashicorp/consul/agent/structs" @@ -208,7 +209,7 @@ func (s *Server) makeGatewayServiceClusters(cfgSnap *proxycfg.ConfigSnapshot) ([ var loadBalancer *structs.EnvoyLBConfig if hasResolver && resolver.LoadBalancer != nil { - loadBalancer = resolver.LoadBalancer.EnvoyLBConfig + loadBalancer = resolver.LoadBalancer.EnvoyConfig } else { // Use a zero value resolver with no timeout and no subsets @@ -232,14 +233,14 @@ func (s *Server) makeGatewayServiceClusters(cfgSnap *proxycfg.ConfigSnapshot) ([ case structs.ServiceKindTerminatingGateway: injectTerminatingGatewayTLSContext(cfgSnap, cluster, svc) - if err := loadBalancer.InjectToCluster(cluster); err != nil { + if err := injectLBToCluster(loadBalancer, cluster); err != nil { return nil, fmt.Errorf("failed to apply load balancer configuration to cluster %q: %v", clusterName, err) } case structs.ServiceKindMeshGateway: // We can't apply hash based LB config to mesh gateways because they rely on inspecting HTTP attributes // and mesh gateways do not decrypt traffic if !loadBalancer.IsHashBased() { - if err := loadBalancer.InjectToCluster(cluster); err != nil { + if err := injectLBToCluster(loadBalancer, cluster); err != nil { return nil, fmt.Errorf("failed to apply load balancer configuration to cluster %q: %v", clusterName, err) } } @@ -265,7 +266,7 @@ func (s *Server) makeGatewayServiceClusters(cfgSnap *proxycfg.ConfigSnapshot) ([ case structs.ServiceKindTerminatingGateway: injectTerminatingGatewayTLSContext(cfgSnap, cluster, svc) - if err := loadBalancer.InjectToCluster(cluster); err != nil { + if err := injectLBToCluster(loadBalancer, cluster); err != nil { return nil, fmt.Errorf("failed to apply load balancer configuration to cluster %q: %v", clusterName, err) } @@ -273,7 +274,7 @@ func (s *Server) makeGatewayServiceClusters(cfgSnap *proxycfg.ConfigSnapshot) ([ // We can't apply hash based LB config to mesh gateways because they rely on inspecting HTTP attributes // and mesh gateways do not decrypt traffic if !loadBalancer.IsHashBased() { - if err := loadBalancer.InjectToCluster(cluster); err != nil { + if err := injectLBToCluster(loadBalancer, cluster); err != nil { return nil, fmt.Errorf("failed to apply load balancer configuration to cluster %q: %v", clusterName, err) } } @@ -515,9 +516,9 @@ func (s *Server) makeUpstreamClustersForDiscoveryChain( var lb *structs.EnvoyLBConfig if node.LoadBalancer != nil { - lb = node.LoadBalancer.EnvoyLBConfig + lb = node.LoadBalancer.EnvoyConfig } - if err := lb.InjectToCluster(c); err != nil { + if err := injectLBToCluster(lb, c); err != nil { return nil, fmt.Errorf("failed to apply load balancer configuration to cluster %q: %v", clusterName, err) } @@ -781,3 +782,47 @@ func makeLbEndpoint(addr string, port int, health envoycore.HealthStatus, weight LoadBalancingWeight: makeUint32Value(weight), } } + +func injectLBToCluster(ec *structs.EnvoyLBConfig, c *envoy.Cluster) error { + if ec == nil { + return nil + } + + switch ec.Policy { + case "": + return nil + case structs.LBPolicyLeastRequest: + c.LbPolicy = envoy.Cluster_LEAST_REQUEST + + if ec.LeastRequestConfig != nil { + c.LbConfig = &envoy.Cluster_LeastRequestLbConfig_{ + LeastRequestLbConfig: &envoy.Cluster_LeastRequestLbConfig{ + ChoiceCount: &wrappers.UInt32Value{Value: ec.LeastRequestConfig.ChoiceCount}, + }, + } + } + case structs.LBPolicyRoundRobin: + c.LbPolicy = envoy.Cluster_ROUND_ROBIN + + case structs.LBPolicyRandom: + c.LbPolicy = envoy.Cluster_RANDOM + + case structs.LBPolicyRingHash: + c.LbPolicy = envoy.Cluster_RING_HASH + + if ec.RingHashConfig != nil { + c.LbConfig = &envoy.Cluster_RingHashLbConfig_{ + RingHashLbConfig: &envoy.Cluster_RingHashLbConfig{ + MinimumRingSize: &wrappers.UInt64Value{Value: ec.RingHashConfig.MinimumRingSize}, + MaximumRingSize: &wrappers.UInt64Value{Value: ec.RingHashConfig.MaximumRingSize}, + }, + } + } + case structs.LBPolicyMaglev: + c.LbPolicy = envoy.Cluster_MAGLEV + + default: + return fmt.Errorf("unsupported load balancer policy %q for cluster %q", ec.Policy, c.Name) + } + return nil +} diff --git a/agent/xds/clusters_test.go b/agent/xds/clusters_test.go index 634cbe54c..76a23472e 100644 --- a/agent/xds/clusters_test.go +++ b/agent/xds/clusters_test.go @@ -9,6 +9,7 @@ import ( "time" envoy "github.com/envoyproxy/go-control-plane/envoy/api/v2" + "github.com/golang/protobuf/ptypes/wrappers" "github.com/hashicorp/consul/agent/proxycfg" "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/agent/xds/proxysupport" @@ -367,7 +368,7 @@ func TestClustersFromSnapshot(t *testing.T) { }, }, LoadBalancer: &structs.LoadBalancer{ - EnvoyLBConfig: &structs.EnvoyLBConfig{ + EnvoyConfig: &structs.EnvoyLBConfig{ Policy: "least_request", LeastRequestConfig: &structs.LeastRequestConfig{ ChoiceCount: 5, @@ -396,7 +397,7 @@ func TestClustersFromSnapshot(t *testing.T) { }, }, LoadBalancer: &structs.LoadBalancer{ - EnvoyLBConfig: &structs.EnvoyLBConfig{ + EnvoyConfig: &structs.EnvoyLBConfig{ Policy: "ring_hash", RingHashConfig: &structs.RingHashConfig{ MinimumRingSize: 20, @@ -609,7 +610,7 @@ func TestClustersFromSnapshot(t *testing.T) { }, }, LoadBalancer: &structs.LoadBalancer{ - EnvoyLBConfig: &structs.EnvoyLBConfig{ + EnvoyConfig: &structs.EnvoyLBConfig{ Policy: "ring_hash", RingHashConfig: &structs.RingHashConfig{ MinimumRingSize: 20, @@ -839,3 +840,86 @@ func setupTLSRootsAndLeaf(t *testing.T, snap *proxycfg.ConfigSnapshot) { snap.Roots.Roots[0].RootCert = golden(t, "test-root-cert", "", "") } } + +func TestEnvoyLBConfig_InjectToCluster(t *testing.T) { + var tests = []struct { + name string + lb *structs.EnvoyLBConfig + expected envoy.Cluster + }{ + { + name: "skip empty", + lb: &structs.EnvoyLBConfig{ + Policy: "", + }, + expected: envoy.Cluster{}, + }, + { + name: "round robin", + lb: &structs.EnvoyLBConfig{ + Policy: structs.LBPolicyRoundRobin, + }, + expected: envoy.Cluster{LbPolicy: envoy.Cluster_ROUND_ROBIN}, + }, + { + name: "random", + lb: &structs.EnvoyLBConfig{ + Policy: structs.LBPolicyRandom, + }, + expected: envoy.Cluster{LbPolicy: envoy.Cluster_RANDOM}, + }, + { + name: "maglev", + lb: &structs.EnvoyLBConfig{ + Policy: structs.LBPolicyMaglev, + }, + expected: envoy.Cluster{LbPolicy: envoy.Cluster_MAGLEV}, + }, + { + name: "ring_hash", + lb: &structs.EnvoyLBConfig{ + Policy: structs.LBPolicyRingHash, + RingHashConfig: &structs.RingHashConfig{ + MinimumRingSize: 3, + MaximumRingSize: 7, + }, + }, + expected: envoy.Cluster{ + LbPolicy: envoy.Cluster_RING_HASH, + LbConfig: &envoy.Cluster_RingHashLbConfig_{ + RingHashLbConfig: &envoy.Cluster_RingHashLbConfig{ + MinimumRingSize: &wrappers.UInt64Value{Value: 3}, + MaximumRingSize: &wrappers.UInt64Value{Value: 7}, + }, + }, + }, + }, + { + name: "least_request", + lb: &structs.EnvoyLBConfig{ + Policy: "least_request", + LeastRequestConfig: &structs.LeastRequestConfig{ + ChoiceCount: 3, + }, + }, + expected: envoy.Cluster{ + LbPolicy: envoy.Cluster_LEAST_REQUEST, + LbConfig: &envoy.Cluster_LeastRequestLbConfig_{ + LeastRequestLbConfig: &envoy.Cluster_LeastRequestLbConfig{ + ChoiceCount: &wrappers.UInt32Value{Value: 3}, + }, + }, + }, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + var c envoy.Cluster + err := injectLBToCluster(tc.lb, &c) + require.NoError(t, err) + + require.Equal(t, tc.expected, c) + }) + } +} diff --git a/agent/xds/routes.go b/agent/xds/routes.go index bf1f5cc3a..c95e74855 100644 --- a/agent/xds/routes.go +++ b/agent/xds/routes.go @@ -62,7 +62,7 @@ func routesFromSnapshotTerminatingGateway(_ connectionInfo, cfgSnap *proxycfg.Co var lb *structs.EnvoyLBConfig if resolver.LoadBalancer != nil { - lb = resolver.LoadBalancer.EnvoyLBConfig + lb = resolver.LoadBalancer.EnvoyConfig } route, err := makeNamedDefaultRouteWithLB(clusterName, lb) if err != nil { @@ -87,7 +87,7 @@ func routesFromSnapshotTerminatingGateway(_ connectionInfo, cfgSnap *proxycfg.Co func makeNamedDefaultRouteWithLB(clusterName string, lb *structs.EnvoyLBConfig) (*envoy.RouteConfiguration, error) { action := makeRouteActionFromName(clusterName) - if err := lb.InjectToRouteAction(action.Route); err != nil { + if err := injectLBToRouteAction(lb, action.Route); err != nil { return nil, fmt.Errorf("failed to apply load balancer configuration to route action: %v", err) } @@ -271,7 +271,7 @@ func makeUpstreamRouteForDiscoveryChain( nextNode := chain.Nodes[discoveryRoute.NextNode] if nextNode.LoadBalancer != nil { - lb = nextNode.LoadBalancer.EnvoyLBConfig + lb = nextNode.LoadBalancer.EnvoyConfig } switch nextNode.Type { @@ -281,14 +281,14 @@ func makeUpstreamRouteForDiscoveryChain( return nil, err } - if err := lb.InjectToRouteAction(routeAction.Route); err != nil { + if err := injectLBToRouteAction(lb, routeAction.Route); err != nil { return nil, fmt.Errorf("failed to apply load balancer configuration to route action: %v", err) } case structs.DiscoveryGraphNodeTypeResolver: routeAction = makeRouteActionForChainCluster(nextNode.Resolver.Target, chain) - if err := lb.InjectToRouteAction(routeAction.Route); err != nil { + if err := injectLBToRouteAction(lb, routeAction.Route); err != nil { return nil, fmt.Errorf("failed to apply load balancer configuration to route action: %v", err) } @@ -344,9 +344,9 @@ func makeUpstreamRouteForDiscoveryChain( } if startNode.LoadBalancer != nil { - lb = startNode.LoadBalancer.EnvoyLBConfig + lb = startNode.LoadBalancer.EnvoyConfig } - if err := lb.InjectToRouteAction(routeAction.Route); err != nil { + if err := injectLBToRouteAction(lb, routeAction.Route); err != nil { return nil, fmt.Errorf("failed to apply load balancer configuration to route action: %v", err) } @@ -361,9 +361,9 @@ func makeUpstreamRouteForDiscoveryChain( routeAction := makeRouteActionForChainCluster(startNode.Resolver.Target, chain) if startNode.LoadBalancer != nil { - lb = startNode.LoadBalancer.EnvoyLBConfig + lb = startNode.LoadBalancer.EnvoyConfig } - if err := lb.InjectToRouteAction(routeAction.Route); err != nil { + if err := injectLBToRouteAction(lb, routeAction.Route); err != nil { return nil, fmt.Errorf("failed to apply load balancer configuration to route action: %v", err) } @@ -569,3 +569,64 @@ func makeRouteActionForSplitter(splits []*structs.DiscoverySplit, chain *structs }, }, nil } + +func injectLBToRouteAction(ec *structs.EnvoyLBConfig, action *envoyroute.RouteAction) error { + if ec == nil || !ec.IsHashBased() { + return nil + } + + result := make([]*envoyroute.RouteAction_HashPolicy, 0, len(ec.HashPolicies)) + for _, policy := range ec.HashPolicies { + if policy.SourceIP { + result = append(result, &envoyroute.RouteAction_HashPolicy{ + PolicySpecifier: &envoyroute.RouteAction_HashPolicy_ConnectionProperties_{ + ConnectionProperties: &envoyroute.RouteAction_HashPolicy_ConnectionProperties{ + SourceIp: true, + }, + }, + Terminal: policy.Terminal, + }) + + continue + } + + switch policy.Field { + case structs.HashPolicyHeader: + result = append(result, &envoyroute.RouteAction_HashPolicy{ + PolicySpecifier: &envoyroute.RouteAction_HashPolicy_Header_{ + Header: &envoyroute.RouteAction_HashPolicy_Header{ + HeaderName: policy.FieldValue, + }, + }, + Terminal: policy.Terminal, + }) + case structs.HashPolicyCookie: + cookie := envoyroute.RouteAction_HashPolicy_Cookie{ + Name: policy.FieldValue, + } + if policy.CookieConfig != nil { + cookie.Ttl = ptypes.DurationProto(policy.CookieConfig.TTL) + cookie.Path = policy.CookieConfig.Path + } + result = append(result, &envoyroute.RouteAction_HashPolicy{ + PolicySpecifier: &envoyroute.RouteAction_HashPolicy_Cookie_{ + Cookie: &cookie, + }, + Terminal: policy.Terminal, + }) + case structs.HashPolicyQueryParam: + result = append(result, &envoyroute.RouteAction_HashPolicy{ + PolicySpecifier: &envoyroute.RouteAction_HashPolicy_QueryParameter_{ + QueryParameter: &envoyroute.RouteAction_HashPolicy_QueryParameter{ + Name: policy.FieldValue, + }, + }, + Terminal: policy.Terminal, + }) + default: + return fmt.Errorf("unsupported load balancer hash policy field: %v", policy.Field) + } + } + action.HashPolicy = result + return nil +} diff --git a/agent/xds/routes_test.go b/agent/xds/routes_test.go index 88020b247..2dd5ef38d 100644 --- a/agent/xds/routes_test.go +++ b/agent/xds/routes_test.go @@ -7,6 +7,8 @@ import ( "time" envoy "github.com/envoyproxy/go-control-plane/envoy/api/v2" + envoyroute "github.com/envoyproxy/go-control-plane/envoy/api/v2/route" + "github.com/golang/protobuf/ptypes" "github.com/hashicorp/consul/agent/connect" "github.com/hashicorp/consul/agent/consul/discoverychain" "github.com/hashicorp/consul/agent/proxycfg" @@ -203,7 +205,7 @@ func TestRoutesFromSnapshot(t *testing.T) { }, }, LoadBalancer: &structs.LoadBalancer{ - EnvoyLBConfig: &structs.EnvoyLBConfig{ + EnvoyConfig: &structs.EnvoyLBConfig{ Policy: "ring_hash", RingHashConfig: &structs.RingHashConfig{ MinimumRingSize: 20, @@ -277,3 +279,184 @@ func TestRoutesFromSnapshot(t *testing.T) { }) } } + +func TestEnvoyLBConfig_InjectToRouteAction(t *testing.T) { + var tests = []struct { + name string + lb *structs.EnvoyLBConfig + expected envoyroute.RouteAction + }{ + { + name: "empty", + lb: &structs.EnvoyLBConfig{ + Policy: "", + }, + // we only modify route actions for hash-based LB policies + expected: envoyroute.RouteAction{}, + }, + { + name: "least request", + lb: &structs.EnvoyLBConfig{ + Policy: structs.LBPolicyLeastRequest, + LeastRequestConfig: &structs.LeastRequestConfig{ + ChoiceCount: 3, + }, + }, + // we only modify route actions for hash-based LB policies + expected: envoyroute.RouteAction{}, + }, + { + name: "headers", + lb: &structs.EnvoyLBConfig{ + Policy: "ring_hash", + RingHashConfig: &structs.RingHashConfig{ + MinimumRingSize: 3, + MaximumRingSize: 7, + }, + HashPolicies: []structs.HashPolicy{ + { + Field: structs.HashPolicyHeader, + FieldValue: "x-route-key", + Terminal: true, + }, + }, + }, + expected: envoyroute.RouteAction{ + HashPolicy: []*envoyroute.RouteAction_HashPolicy{ + { + PolicySpecifier: &envoyroute.RouteAction_HashPolicy_Header_{ + Header: &envoyroute.RouteAction_HashPolicy_Header{ + HeaderName: "x-route-key", + }, + }, + Terminal: true, + }, + }, + }, + }, + { + name: "cookies", + lb: &structs.EnvoyLBConfig{ + Policy: structs.LBPolicyMaglev, + HashPolicies: []structs.HashPolicy{ + { + Field: structs.HashPolicyCookie, + FieldValue: "red-velvet", + Terminal: true, + }, + { + Field: structs.HashPolicyCookie, + FieldValue: "oatmeal", + }, + }, + }, + expected: envoyroute.RouteAction{ + HashPolicy: []*envoyroute.RouteAction_HashPolicy{ + { + PolicySpecifier: &envoyroute.RouteAction_HashPolicy_Cookie_{ + Cookie: &envoyroute.RouteAction_HashPolicy_Cookie{ + Name: "red-velvet", + }, + }, + Terminal: true, + }, + { + PolicySpecifier: &envoyroute.RouteAction_HashPolicy_Cookie_{ + Cookie: &envoyroute.RouteAction_HashPolicy_Cookie{ + Name: "oatmeal", + }, + }, + }, + }, + }, + }, + { + name: "source addr", + lb: &structs.EnvoyLBConfig{ + Policy: structs.LBPolicyMaglev, + HashPolicies: []structs.HashPolicy{ + { + SourceIP: true, + Terminal: true, + }, + }, + }, + expected: envoyroute.RouteAction{ + HashPolicy: []*envoyroute.RouteAction_HashPolicy{ + { + PolicySpecifier: &envoyroute.RouteAction_HashPolicy_ConnectionProperties_{ + ConnectionProperties: &envoyroute.RouteAction_HashPolicy_ConnectionProperties{ + SourceIp: true, + }, + }, + Terminal: true, + }, + }, + }, + }, + { + name: "kitchen sink", + lb: &structs.EnvoyLBConfig{ + Policy: structs.LBPolicyMaglev, + HashPolicies: []structs.HashPolicy{ + { + SourceIP: true, + Terminal: true, + }, + { + Field: structs.HashPolicyCookie, + FieldValue: "oatmeal", + CookieConfig: &structs.CookieConfig{ + TTL: 10 * time.Second, + Path: "/oven", + }, + }, + { + Field: structs.HashPolicyHeader, + FieldValue: "special-header", + Terminal: true, + }, + }, + }, + expected: envoyroute.RouteAction{ + HashPolicy: []*envoyroute.RouteAction_HashPolicy{ + { + PolicySpecifier: &envoyroute.RouteAction_HashPolicy_ConnectionProperties_{ + ConnectionProperties: &envoyroute.RouteAction_HashPolicy_ConnectionProperties{ + SourceIp: true, + }, + }, + Terminal: true, + }, + { + PolicySpecifier: &envoyroute.RouteAction_HashPolicy_Cookie_{ + Cookie: &envoyroute.RouteAction_HashPolicy_Cookie{ + Name: "oatmeal", + Ttl: ptypes.DurationProto(10 * time.Second), + Path: "/oven", + }, + }, + }, + { + PolicySpecifier: &envoyroute.RouteAction_HashPolicy_Header_{ + Header: &envoyroute.RouteAction_HashPolicy_Header{ + HeaderName: "special-header", + }, + }, + Terminal: true, + }, + }, + }, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + var ra envoyroute.RouteAction + err := injectLBToRouteAction(tc.lb, &ra) + require.NoError(t, err) + + require.Equal(t, &tc.expected, &ra) + }) + } +} diff --git a/api/config_entry_discoverychain.go b/api/config_entry_discoverychain.go index 68546b615..640525e85 100644 --- a/api/config_entry_discoverychain.go +++ b/api/config_entry_discoverychain.go @@ -209,8 +209,8 @@ type ServiceResolverFailover struct { // LoadBalancer determines the load balancing policy and configuration for services // issuing requests to this upstream service. type LoadBalancer struct { - // EnvoyLBConfig contains Envoy-specific load balancing configuration for this upstream - EnvoyLBConfig *EnvoyLBConfig `json:",omitempty" alias:"envoy_lb_config"` + // EnvoyConfig contains Envoy-specific load balancing configuration for this upstream + EnvoyConfig *EnvoyLBConfig `json:",omitempty" alias:"envoy_config"` // OpaqueConfig contains load balancing configuration opaque to Consul for 3rd party proxies OpaqueConfig string `json:",omitempty" alias:"opaque_config"` diff --git a/api/config_entry_discoverychain_test.go b/api/config_entry_discoverychain_test.go index 560dc1e24..efdc34702 100644 --- a/api/config_entry_discoverychain_test.go +++ b/api/config_entry_discoverychain_test.go @@ -294,7 +294,7 @@ func TestAPI_ConfigEntry_ServiceResolver_LoadBalancer(t *testing.T) { Name: "test-least-req", Namespace: defaultNamespace, LoadBalancer: &LoadBalancer{ - EnvoyLBConfig: &EnvoyLBConfig{ + EnvoyConfig: &EnvoyLBConfig{ Policy: "least_request", LeastRequestConfig: &LeastRequestConfig{ChoiceCount: 10}, }, @@ -309,7 +309,7 @@ func TestAPI_ConfigEntry_ServiceResolver_LoadBalancer(t *testing.T) { Name: "test-ring-hash", Namespace: defaultNamespace, LoadBalancer: &LoadBalancer{ - EnvoyLBConfig: &EnvoyLBConfig{ + EnvoyConfig: &EnvoyLBConfig{ Policy: "ring_hash", RingHashConfig: &RingHashConfig{ MinimumRingSize: 1024 * 2, diff --git a/command/config/write/config_write_test.go b/command/config/write/config_write_test.go index 82bbda4bb..79f962835 100644 --- a/command/config/write/config_write_test.go +++ b/command/config/write/config_write_test.go @@ -1172,7 +1172,7 @@ func TestParseConfigEntry(t *testing.T) { kind = "service-resolver" name = "main" load_balancer = { - envoy_lb_config = { + envoy_config = { policy = "ring_hash" ring_hash_config = { minimum_ring_size = 1 @@ -1235,7 +1235,7 @@ func TestParseConfigEntry(t *testing.T) { "kind": "service-resolver", "name": "main", "load_balancer": { - "envoy_lb_config": { + "envoy_config": { "policy": "ring_hash", "ring_hash_config": { "minimum_ring_size": 1, @@ -1300,7 +1300,7 @@ func TestParseConfigEntry(t *testing.T) { Kind: "service-resolver", Name: "main", LoadBalancer: &api.LoadBalancer{ - EnvoyLBConfig: &api.EnvoyLBConfig{ + EnvoyConfig: &api.EnvoyLBConfig{ Policy: structs.LBPolicyRingHash, RingHashConfig: &api.RingHashConfig{ MinimumRingSize: 1, @@ -1334,7 +1334,7 @@ func TestParseConfigEntry(t *testing.T) { kind = "service-resolver" name = "main" load_balancer = { - envoy_lb_config = { + envoy_config = { policy = "least_request" least_request_config = { choice_count = 2 @@ -1359,7 +1359,7 @@ func TestParseConfigEntry(t *testing.T) { "kind": "service-resolver", "name": "main", "load_balancer": { - "envoy_lb_config": { + "envoy_config": { "policy": "least_request", "least_request_config": { "choice_count": 2 @@ -1386,7 +1386,7 @@ func TestParseConfigEntry(t *testing.T) { Kind: "service-resolver", Name: "main", LoadBalancer: &api.LoadBalancer{ - EnvoyLBConfig: &api.EnvoyLBConfig{ + EnvoyConfig: &api.EnvoyLBConfig{ Policy: structs.LBPolicyLeastRequest, LeastRequestConfig: &api.LeastRequestConfig{ ChoiceCount: 2, From c4bce2154bd31a240d46e86ae3013f977fd5cfd4 Mon Sep 17 00:00:00 2001 From: freddygv Date: Wed, 2 Sep 2020 15:49:03 -0600 Subject: [PATCH 08/20] Move valid policies to pkg level --- agent/structs/config_entry_discoverychain.go | 35 +++++++++++--------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/agent/structs/config_entry_discoverychain.go b/agent/structs/config_entry_discoverychain.go index 9fc2550c0..d0cd7e46d 100644 --- a/agent/structs/config_entry_discoverychain.go +++ b/agent/structs/config_entry_discoverychain.go @@ -30,6 +30,23 @@ const ( HashPolicyQueryParam = "query_parameter" ) +var ( + validLBPolicies = map[string]bool{ + "": true, + LBPolicyRandom: true, + LBPolicyRoundRobin: true, + LBPolicyLeastRequest: true, + LBPolicyRingHash: true, + LBPolicyMaglev: true, + } + + validHashPolicies = map[string]bool{ + HashPolicyHeader: true, + HashPolicyCookie: true, + HashPolicyQueryParam: true, + } +) + // ServiceRouterConfigEntry defines L7 (e.g. http) routing rules for a named // service exposed in Connect. // @@ -828,15 +845,7 @@ func (e *ServiceResolverConfigEntry) Validate() error { if e.LoadBalancer != nil && e.LoadBalancer.EnvoyConfig != nil { ec := e.LoadBalancer.EnvoyConfig - validPolicies := map[string]bool{ - "": true, - LBPolicyRandom: true, - LBPolicyRoundRobin: true, - LBPolicyLeastRequest: true, - LBPolicyRingHash: true, - LBPolicyMaglev: true, - } - if ok := validPolicies[ec.Policy]; !ok { + if ok := validLBPolicies[ec.Policy]; !ok { return fmt.Errorf("Bad LoadBalancer policy: %q is not supported", ec.Policy) } @@ -853,15 +862,11 @@ func (e *ServiceResolverConfigEntry) Validate() error { "HashPolicies specified for non-hash-based Policy: %q", ec.Policy) } - validFields := map[string]bool{ - HashPolicyHeader: true, - HashPolicyCookie: true, - HashPolicyQueryParam: true, - } for i, hp := range ec.HashPolicies { - if ok := validFields[hp.Field]; hp.Field != "" && !ok { + if ok := validHashPolicies[hp.Field]; hp.Field != "" && !ok { return fmt.Errorf("Bad LoadBalancer HashPolicy[%d]: %q is not a supported field", i, hp.Field) } + if hp.SourceIP && hp.Field != "" { return fmt.Errorf("Bad LoadBalancer HashPolicy[%d]: "+ "A single hash policy cannot hash both a source address and a %q", i, hp.Field) From 02d6acd8fc6783511e52a3b3c5045cd1ba125ee9 Mon Sep 17 00:00:00 2001 From: freddygv Date: Thu, 3 Sep 2020 08:55:57 -0600 Subject: [PATCH 09/20] Ensure resolver node with LB isn't considered default --- agent/consul/discoverychain/compile_test.go | 65 ++++++++++++++++++++- agent/structs/discovery_chain.go | 3 + api/discovery_chain.go | 3 + 3 files changed, 69 insertions(+), 2 deletions(-) diff --git a/agent/consul/discoverychain/compile_test.go b/agent/consul/discoverychain/compile_test.go index 7e4c78dc8..af6597175 100644 --- a/agent/consul/discoverychain/compile_test.go +++ b/agent/consul/discoverychain/compile_test.go @@ -51,7 +51,8 @@ func TestCompile(t *testing.T) { "default resolver with external sni": testcase_DefaultResolver_ExternalSNI(), "resolver with no entries and inferring defaults": testcase_DefaultResolver(), "default resolver with proxy defaults": testcase_DefaultResolver_WithProxyDefaults(), - "loadbalancer config": testcase_LBConfig(), + "loadbalancer splitter and resolver": testcase_LBSplitterAndResolver(), + "loadbalancer resolver": testcase_LBResolver(), "service redirect to service with default resolver is not a default chain": testcase_RedirectToDefaultResolverIsNotDefaultChain(), "all the bells and whistles": testcase_AllBellsAndWhistles(), @@ -2259,7 +2260,7 @@ func testcase_CircularSplit() compileTestCase { } } -func testcase_LBConfig() compileTestCase { +func testcase_LBSplitterAndResolver() compileTestCase { entries := newEntries() setServiceProtocol(entries, "foo", "http") setServiceProtocol(entries, "bar", "http") @@ -2442,6 +2443,66 @@ func testcase_LBConfig() compileTestCase { return compileTestCase{entries: entries, expect: expect} } +// ensure chain with LB cfg in resolver isn't a default chain (!IsDefault) +func testcase_LBResolver() compileTestCase { + entries := newEntries() + setServiceProtocol(entries, "main", "http") + + entries.AddResolvers( + &structs.ServiceResolverConfigEntry{ + Kind: "service-resolver", + Name: "main", + LoadBalancer: &structs.LoadBalancer{ + EnvoyConfig: &structs.EnvoyLBConfig{ + Policy: "ring_hash", + RingHashConfig: &structs.RingHashConfig{ + MaximumRingSize: 101, + }, + HashPolicies: []structs.HashPolicy{ + { + SourceIP: true, + }, + }, + }, + }, + }, + ) + + expect := &structs.CompiledDiscoveryChain{ + Protocol: "http", + StartNode: "resolver:main.default.dc1", + Nodes: map[string]*structs.DiscoveryGraphNode{ + "resolver:main.default.dc1": { + Type: structs.DiscoveryGraphNodeTypeResolver, + Name: "main.default.dc1", + Resolver: &structs.DiscoveryResolver{ + Default: true, + ConnectTimeout: 5 * time.Second, + Target: "main.default.dc1", + }, + LoadBalancer: &structs.LoadBalancer{ + EnvoyConfig: &structs.EnvoyLBConfig{ + Policy: "ring_hash", + RingHashConfig: &structs.RingHashConfig{ + MaximumRingSize: 101, + }, + HashPolicies: []structs.HashPolicy{ + { + SourceIP: true, + }, + }, + }, + }, + }, + }, + Targets: map[string]*structs.DiscoveryTarget{ + "main.default.dc1": newTarget("main", "", "default", "dc1", nil), + }, + } + + return compileTestCase{entries: entries, expect: expect} +} + func newSimpleRoute(name string, muts ...func(*structs.ServiceRoute)) structs.ServiceRoute { r := structs.ServiceRoute{ Match: &structs.ServiceRouteMatch{ diff --git a/agent/structs/discovery_chain.go b/agent/structs/discovery_chain.go index 77eb03937..5e2ff9498 100644 --- a/agent/structs/discovery_chain.go +++ b/agent/structs/discovery_chain.go @@ -82,6 +82,9 @@ func (c *CompiledDiscoveryChain) IsDefault() bool { if !node.Resolver.Default { return false } + if node.LoadBalancer != nil { + return false + } target := c.Targets[node.Resolver.Target] diff --git a/api/discovery_chain.go b/api/discovery_chain.go index 75fdbaee2..f67f881c2 100644 --- a/api/discovery_chain.go +++ b/api/discovery_chain.go @@ -147,6 +147,9 @@ type DiscoveryGraphNode struct { // fields for Type==resolver Resolver *DiscoveryResolver + + // shared by Type==resolver || Type==splitter + LoadBalancer *LoadBalancer `json:",omitempty"` } // compiled form of ServiceRoute From 0ac632c465ef2823922ec7d96094ca8ab27e5c64 Mon Sep 17 00:00:00 2001 From: freddygv Date: Thu, 3 Sep 2020 08:56:17 -0600 Subject: [PATCH 10/20] Fixup stray LB infix refs --- command/config/write/config_write_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/command/config/write/config_write_test.go b/command/config/write/config_write_test.go index 79f962835..6b0579066 100644 --- a/command/config/write/config_write_test.go +++ b/command/config/write/config_write_test.go @@ -1203,7 +1203,7 @@ func TestParseConfigEntry(t *testing.T) { Kind = "service-resolver" Name = "main" LoadBalancer = { - EnvoyLBConfig = { + EnvoyConfig = { Policy = "ring_hash" RingHashConfig = { MinimumRingSize = 1 @@ -1268,7 +1268,7 @@ func TestParseConfigEntry(t *testing.T) { "Kind": "service-resolver", "Name": "main", "LoadBalancer": { - "EnvoyLBConfig": { + "EnvoyConfig": { "Policy": "ring_hash", "RingHashConfig": { "MinimumRingSize": 1, @@ -1346,7 +1346,7 @@ func TestParseConfigEntry(t *testing.T) { Kind = "service-resolver" Name = "main" LoadBalancer = { - EnvoyLBConfig = { + EnvoyConfig = { Policy = "least_request" LeastRequestConfig = { ChoiceCount = 2 @@ -1373,7 +1373,7 @@ func TestParseConfigEntry(t *testing.T) { "Kind": "service-resolver", "Name": "main", "LoadBalancer": { - "EnvoyLBConfig": { + "EnvoyConfig": { "Policy": "least_request", "LeastRequestConfig": { "ChoiceCount": 2 From 0c50b8e769e3ffc094846b28d132407e89c8b595 Mon Sep 17 00:00:00 2001 From: freddygv Date: Thu, 3 Sep 2020 08:57:48 -0600 Subject: [PATCH 11/20] Add explicit protocol overrides in tgw xds test cases --- agent/proxycfg/testing.go | 2 +- agent/xds/clusters.go | 8 +- agent/xds/clusters_test.go | 18 ++++ agent/xds/listeners_test.go | 16 +--- agent/xds/routes_test.go | 3 + ...ignore-extra-resolvers.envoy-1-12-x.golden | 32 +++++++ ...ignore-extra-resolvers.envoy-1-13-x.golden | 32 +++++++ ...ignore-extra-resolvers.envoy-1-14-x.golden | 32 +++++++ ...ignore-extra-resolvers.envoy-1-15-x.golden | 32 +++++++ ...ateway-service-subsets.envoy-1-12-x.golden | 32 +++++++ ...ateway-service-subsets.envoy-1-13-x.golden | 32 +++++++ ...ateway-service-subsets.envoy-1-14-x.golden | 32 +++++++ ...ateway-service-subsets.envoy-1-15-x.golden | 32 +++++++ ...teway-service-timeouts.envoy-1-12-x.golden | 34 ++++++- ...teway-service-timeouts.envoy-1-13-x.golden | 34 ++++++- ...teway-service-timeouts.envoy-1-14-x.golden | 34 ++++++- ...teway-service-timeouts.envoy-1-15-x.golden | 34 ++++++- ...stname-service-subsets.envoy-1-12-x.golden | 86 ++++++++++++++++++ ...stname-service-subsets.envoy-1-13-x.golden | 86 ++++++++++++++++++ ...stname-service-subsets.envoy-1-14-x.golden | 86 ++++++++++++++++++ ...stname-service-subsets.envoy-1-15-x.golden | 86 ++++++++++++++++++ ...ignore-extra-resolvers.envoy-1-12-x.golden | 56 ++++++++++++ ...ignore-extra-resolvers.envoy-1-13-x.golden | 56 ++++++++++++ ...ignore-extra-resolvers.envoy-1-14-x.golden | 56 ++++++++++++ ...ignore-extra-resolvers.envoy-1-15-x.golden | 56 ++++++++++++ ...ateway-service-subsets.envoy-1-12-x.golden | 88 +++++++++++++++++++ ...ateway-service-subsets.envoy-1-13-x.golden | 88 +++++++++++++++++++ ...ateway-service-subsets.envoy-1-14-x.golden | 88 +++++++++++++++++++ ...ateway-service-subsets.envoy-1-15-x.golden | 88 +++++++++++++++++++ ...m-and-tagged-addresses.envoy-1-12-x.golden | 70 +++++---------- ...m-and-tagged-addresses.envoy-1-13-x.golden | 70 +++++---------- ...m-and-tagged-addresses.envoy-1-14-x.golden | 70 +++++---------- ...m-and-tagged-addresses.envoy-1-15-x.golden | 70 +++++---------- ...ng-gateway-no-api-cert.envoy-1-12-x.golden | 35 +++----- ...ng-gateway-no-api-cert.envoy-1-13-x.golden | 35 +++----- ...ng-gateway-no-api-cert.envoy-1-14-x.golden | 35 +++----- ...ng-gateway-no-api-cert.envoy-1-15-x.golden | 35 +++----- .../terminating-gateway.envoy-1-12-x.golden | 35 +++----- .../terminating-gateway.envoy-1-13-x.golden | 35 +++----- .../terminating-gateway.envoy-1-14-x.golden | 35 +++----- .../terminating-gateway.envoy-1-15-x.golden | 35 +++----- 41 files changed, 1497 insertions(+), 422 deletions(-) diff --git a/agent/proxycfg/testing.go b/agent/proxycfg/testing.go index 2c6a0cd03..3dd4b6bd3 100644 --- a/agent/proxycfg/testing.go +++ b/agent/proxycfg/testing.go @@ -1883,7 +1883,7 @@ func testConfigSnapshotTerminatingGateway(t testing.T, populateServices bool) *C snap.TerminatingGateway.ServiceConfigs = map[structs.ServiceName]*structs.ServiceConfigResponse{ web: { - ProxyConfig: map[string]interface{}{"protocol": "http"}, + ProxyConfig: map[string]interface{}{"protocol": "tcp"}, }, api: { ProxyConfig: map[string]interface{}{"protocol": "tcp"}, diff --git a/agent/xds/clusters.go b/agent/xds/clusters.go index 4c061a86f..8491ab088 100644 --- a/agent/xds/clusters.go +++ b/agent/xds/clusters.go @@ -208,13 +208,13 @@ func (s *Server) makeGatewayServiceClusters(cfgSnap *proxycfg.ConfigSnapshot) ([ var loadBalancer *structs.EnvoyLBConfig - if hasResolver && resolver.LoadBalancer != nil { - loadBalancer = resolver.LoadBalancer.EnvoyConfig - - } else { + if !hasResolver { // Use a zero value resolver with no timeout and no subsets resolver = &structs.ServiceResolverConfigEntry{} } + if resolver.LoadBalancer != nil { + loadBalancer = resolver.LoadBalancer.EnvoyConfig + } // When making service clusters we only pass endpoints with hostnames if the kind is a terminating gateway // This is because the services a mesh gateway will route to are not external services and are not addressed by a hostname. diff --git a/agent/xds/clusters_test.go b/agent/xds/clusters_test.go index 76a23472e..024a4511b 100644 --- a/agent/xds/clusters_test.go +++ b/agent/xds/clusters_test.go @@ -527,6 +527,12 @@ func TestClustersFromSnapshot(t *testing.T) { }, }, } + snap.TerminatingGateway.ServiceConfigs[structs.NewServiceName("web", nil)] = &structs.ServiceConfigResponse{ + ProxyConfig: map[string]interface{}{"protocol": "http"}, + } + snap.TerminatingGateway.ServiceConfigs[structs.NewServiceName("cache", nil)] = &structs.ServiceConfigResponse{ + ProxyConfig: map[string]interface{}{"protocol": "http"}, + } }, }, { @@ -553,6 +559,12 @@ func TestClustersFromSnapshot(t *testing.T) { }, }, } + snap.TerminatingGateway.ServiceConfigs[structs.NewServiceName("api", nil)] = &structs.ServiceConfigResponse{ + ProxyConfig: map[string]interface{}{"protocol": "http"}, + } + snap.TerminatingGateway.ServiceConfigs[structs.NewServiceName("cache", nil)] = &structs.ServiceConfigResponse{ + ProxyConfig: map[string]interface{}{"protocol": "http"}, + } }, }, { @@ -589,6 +601,9 @@ func TestClustersFromSnapshot(t *testing.T) { }, }, } + snap.TerminatingGateway.ServiceConfigs[structs.NewServiceName("web", nil)] = &structs.ServiceConfigResponse{ + ProxyConfig: map[string]interface{}{"protocol": "http"}, + } }, }, { @@ -620,6 +635,9 @@ func TestClustersFromSnapshot(t *testing.T) { }, }, } + snap.TerminatingGateway.ServiceConfigs[structs.NewServiceName("web", nil)] = &structs.ServiceConfigResponse{ + ProxyConfig: map[string]interface{}{"protocol": "http"}, + } }, }, { diff --git a/agent/xds/listeners_test.go b/agent/xds/listeners_test.go index b972eaf5d..5b08ab637 100644 --- a/agent/xds/listeners_test.go +++ b/agent/xds/listeners_test.go @@ -436,19 +436,9 @@ func TestListenersFromSnapshot(t *testing.T) { }, }, }, - structs.NewServiceName("web", nil): { - Kind: structs.ServiceResolver, - Name: "web", - Subsets: map[string]structs.ServiceResolverSubset{ - "v1": { - Filter: "Service.Meta.version == 1", - }, - "v2": { - Filter: "Service.Meta.version == 2", - OnlyPassing: true, - }, - }, - }, + } + snap.TerminatingGateway.ServiceConfigs[structs.NewServiceName("web", nil)] = &structs.ServiceConfigResponse{ + ProxyConfig: map[string]interface{}{"protocol": "http"}, } }, }, diff --git a/agent/xds/routes_test.go b/agent/xds/routes_test.go index 2dd5ef38d..518102321 100644 --- a/agent/xds/routes_test.go +++ b/agent/xds/routes_test.go @@ -230,6 +230,9 @@ func TestRoutesFromSnapshot(t *testing.T) { }, }, } + snap.TerminatingGateway.ServiceConfigs[structs.NewServiceName("web", nil)] = &structs.ServiceConfigResponse{ + ProxyConfig: map[string]interface{}{"protocol": "http"}, + } }, }, } diff --git a/agent/xds/testdata/clusters/mesh-gateway-ignore-extra-resolvers.envoy-1-12-x.golden b/agent/xds/testdata/clusters/mesh-gateway-ignore-extra-resolvers.envoy-1-12-x.golden index 845881fd3..afc23f9ae 100644 --- a/agent/xds/testdata/clusters/mesh-gateway-ignore-extra-resolvers.envoy-1-12-x.golden +++ b/agent/xds/testdata/clusters/mesh-gateway-ignore-extra-resolvers.envoy-1-12-x.golden @@ -111,6 +111,38 @@ "connectTimeout": "5s", "outlierDetection": { + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v1.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v2.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "outlierDetection": { + } } ], diff --git a/agent/xds/testdata/clusters/mesh-gateway-ignore-extra-resolvers.envoy-1-13-x.golden b/agent/xds/testdata/clusters/mesh-gateway-ignore-extra-resolvers.envoy-1-13-x.golden index 845881fd3..afc23f9ae 100644 --- a/agent/xds/testdata/clusters/mesh-gateway-ignore-extra-resolvers.envoy-1-13-x.golden +++ b/agent/xds/testdata/clusters/mesh-gateway-ignore-extra-resolvers.envoy-1-13-x.golden @@ -111,6 +111,38 @@ "connectTimeout": "5s", "outlierDetection": { + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v1.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v2.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "outlierDetection": { + } } ], diff --git a/agent/xds/testdata/clusters/mesh-gateway-ignore-extra-resolvers.envoy-1-14-x.golden b/agent/xds/testdata/clusters/mesh-gateway-ignore-extra-resolvers.envoy-1-14-x.golden index 845881fd3..afc23f9ae 100644 --- a/agent/xds/testdata/clusters/mesh-gateway-ignore-extra-resolvers.envoy-1-14-x.golden +++ b/agent/xds/testdata/clusters/mesh-gateway-ignore-extra-resolvers.envoy-1-14-x.golden @@ -111,6 +111,38 @@ "connectTimeout": "5s", "outlierDetection": { + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v1.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v2.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "outlierDetection": { + } } ], diff --git a/agent/xds/testdata/clusters/mesh-gateway-ignore-extra-resolvers.envoy-1-15-x.golden b/agent/xds/testdata/clusters/mesh-gateway-ignore-extra-resolvers.envoy-1-15-x.golden index 845881fd3..afc23f9ae 100644 --- a/agent/xds/testdata/clusters/mesh-gateway-ignore-extra-resolvers.envoy-1-15-x.golden +++ b/agent/xds/testdata/clusters/mesh-gateway-ignore-extra-resolvers.envoy-1-15-x.golden @@ -111,6 +111,38 @@ "connectTimeout": "5s", "outlierDetection": { + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v1.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v2.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "outlierDetection": { + } } ], diff --git a/agent/xds/testdata/clusters/mesh-gateway-service-subsets.envoy-1-12-x.golden b/agent/xds/testdata/clusters/mesh-gateway-service-subsets.envoy-1-12-x.golden index 845881fd3..afc23f9ae 100644 --- a/agent/xds/testdata/clusters/mesh-gateway-service-subsets.envoy-1-12-x.golden +++ b/agent/xds/testdata/clusters/mesh-gateway-service-subsets.envoy-1-12-x.golden @@ -111,6 +111,38 @@ "connectTimeout": "5s", "outlierDetection": { + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v1.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v2.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "outlierDetection": { + } } ], diff --git a/agent/xds/testdata/clusters/mesh-gateway-service-subsets.envoy-1-13-x.golden b/agent/xds/testdata/clusters/mesh-gateway-service-subsets.envoy-1-13-x.golden index 845881fd3..afc23f9ae 100644 --- a/agent/xds/testdata/clusters/mesh-gateway-service-subsets.envoy-1-13-x.golden +++ b/agent/xds/testdata/clusters/mesh-gateway-service-subsets.envoy-1-13-x.golden @@ -111,6 +111,38 @@ "connectTimeout": "5s", "outlierDetection": { + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v1.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v2.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "outlierDetection": { + } } ], diff --git a/agent/xds/testdata/clusters/mesh-gateway-service-subsets.envoy-1-14-x.golden b/agent/xds/testdata/clusters/mesh-gateway-service-subsets.envoy-1-14-x.golden index 845881fd3..afc23f9ae 100644 --- a/agent/xds/testdata/clusters/mesh-gateway-service-subsets.envoy-1-14-x.golden +++ b/agent/xds/testdata/clusters/mesh-gateway-service-subsets.envoy-1-14-x.golden @@ -111,6 +111,38 @@ "connectTimeout": "5s", "outlierDetection": { + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v1.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v2.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "outlierDetection": { + } } ], diff --git a/agent/xds/testdata/clusters/mesh-gateway-service-subsets.envoy-1-15-x.golden b/agent/xds/testdata/clusters/mesh-gateway-service-subsets.envoy-1-15-x.golden index 845881fd3..afc23f9ae 100644 --- a/agent/xds/testdata/clusters/mesh-gateway-service-subsets.envoy-1-15-x.golden +++ b/agent/xds/testdata/clusters/mesh-gateway-service-subsets.envoy-1-15-x.golden @@ -111,6 +111,38 @@ "connectTimeout": "5s", "outlierDetection": { + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v1.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v2.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "outlierDetection": { + } } ], diff --git a/agent/xds/testdata/clusters/mesh-gateway-service-timeouts.envoy-1-12-x.golden b/agent/xds/testdata/clusters/mesh-gateway-service-timeouts.envoy-1-12-x.golden index 845881fd3..bf2d50142 100644 --- a/agent/xds/testdata/clusters/mesh-gateway-service-timeouts.envoy-1-12-x.golden +++ b/agent/xds/testdata/clusters/mesh-gateway-service-timeouts.envoy-1-12-x.golden @@ -12,7 +12,7 @@ } } }, - "connectTimeout": "5s", + "connectTimeout": "10s", "outlierDetection": { } @@ -111,6 +111,38 @@ "connectTimeout": "5s", "outlierDetection": { + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v1.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "10s", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v2.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "10s", + "outlierDetection": { + } } ], diff --git a/agent/xds/testdata/clusters/mesh-gateway-service-timeouts.envoy-1-13-x.golden b/agent/xds/testdata/clusters/mesh-gateway-service-timeouts.envoy-1-13-x.golden index 845881fd3..bf2d50142 100644 --- a/agent/xds/testdata/clusters/mesh-gateway-service-timeouts.envoy-1-13-x.golden +++ b/agent/xds/testdata/clusters/mesh-gateway-service-timeouts.envoy-1-13-x.golden @@ -12,7 +12,7 @@ } } }, - "connectTimeout": "5s", + "connectTimeout": "10s", "outlierDetection": { } @@ -111,6 +111,38 @@ "connectTimeout": "5s", "outlierDetection": { + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v1.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "10s", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v2.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "10s", + "outlierDetection": { + } } ], diff --git a/agent/xds/testdata/clusters/mesh-gateway-service-timeouts.envoy-1-14-x.golden b/agent/xds/testdata/clusters/mesh-gateway-service-timeouts.envoy-1-14-x.golden index 845881fd3..bf2d50142 100644 --- a/agent/xds/testdata/clusters/mesh-gateway-service-timeouts.envoy-1-14-x.golden +++ b/agent/xds/testdata/clusters/mesh-gateway-service-timeouts.envoy-1-14-x.golden @@ -12,7 +12,7 @@ } } }, - "connectTimeout": "5s", + "connectTimeout": "10s", "outlierDetection": { } @@ -111,6 +111,38 @@ "connectTimeout": "5s", "outlierDetection": { + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v1.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "10s", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v2.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "10s", + "outlierDetection": { + } } ], diff --git a/agent/xds/testdata/clusters/mesh-gateway-service-timeouts.envoy-1-15-x.golden b/agent/xds/testdata/clusters/mesh-gateway-service-timeouts.envoy-1-15-x.golden index 845881fd3..bf2d50142 100644 --- a/agent/xds/testdata/clusters/mesh-gateway-service-timeouts.envoy-1-15-x.golden +++ b/agent/xds/testdata/clusters/mesh-gateway-service-timeouts.envoy-1-15-x.golden @@ -12,7 +12,7 @@ } } }, - "connectTimeout": "5s", + "connectTimeout": "10s", "outlierDetection": { } @@ -111,6 +111,38 @@ "connectTimeout": "5s", "outlierDetection": { + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v1.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "10s", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v2.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "10s", + "outlierDetection": { + } } ], diff --git a/agent/xds/testdata/clusters/terminating-gateway-hostname-service-subsets.envoy-1-12-x.golden b/agent/xds/testdata/clusters/terminating-gateway-hostname-service-subsets.envoy-1-12-x.golden index 27b1ddc6c..44bd0fd5f 100644 --- a/agent/xds/testdata/clusters/terminating-gateway-hostname-service-subsets.envoy-1-12-x.golden +++ b/agent/xds/testdata/clusters/terminating-gateway-hostname-service-subsets.envoy-1-12-x.golden @@ -1,6 +1,60 @@ { "versionInfo": "00000001", "resources": [ + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "alt.api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "alt.api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "api.altdomain", + "portValue": 8081 + } + } + }, + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + }, + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "tlsCertificates": [ + { + "certificateChain": { + "filename": "api.cert.pem" + }, + "privateKey": { + "filename": "api.key.pem" + } + } + ], + "validationContext": { + "trustedCa": { + "filename": "ca.cert.pem" + } + } + } + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } + }, { "@type": "type.googleapis.com/envoy.api.v2.Cluster", "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", @@ -119,6 +173,38 @@ } }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "prod.cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "prod.cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "cache.mydomain", + "portValue": 8081 + } + } + }, + "healthStatus": "UNHEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } + }, { "@type": "type.googleapis.com/envoy.api.v2.Cluster", "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", diff --git a/agent/xds/testdata/clusters/terminating-gateway-hostname-service-subsets.envoy-1-13-x.golden b/agent/xds/testdata/clusters/terminating-gateway-hostname-service-subsets.envoy-1-13-x.golden index 27b1ddc6c..44bd0fd5f 100644 --- a/agent/xds/testdata/clusters/terminating-gateway-hostname-service-subsets.envoy-1-13-x.golden +++ b/agent/xds/testdata/clusters/terminating-gateway-hostname-service-subsets.envoy-1-13-x.golden @@ -1,6 +1,60 @@ { "versionInfo": "00000001", "resources": [ + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "alt.api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "alt.api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "api.altdomain", + "portValue": 8081 + } + } + }, + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + }, + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "tlsCertificates": [ + { + "certificateChain": { + "filename": "api.cert.pem" + }, + "privateKey": { + "filename": "api.key.pem" + } + } + ], + "validationContext": { + "trustedCa": { + "filename": "ca.cert.pem" + } + } + } + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } + }, { "@type": "type.googleapis.com/envoy.api.v2.Cluster", "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", @@ -119,6 +173,38 @@ } }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "prod.cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "prod.cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "cache.mydomain", + "portValue": 8081 + } + } + }, + "healthStatus": "UNHEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } + }, { "@type": "type.googleapis.com/envoy.api.v2.Cluster", "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", diff --git a/agent/xds/testdata/clusters/terminating-gateway-hostname-service-subsets.envoy-1-14-x.golden b/agent/xds/testdata/clusters/terminating-gateway-hostname-service-subsets.envoy-1-14-x.golden index 27b1ddc6c..44bd0fd5f 100644 --- a/agent/xds/testdata/clusters/terminating-gateway-hostname-service-subsets.envoy-1-14-x.golden +++ b/agent/xds/testdata/clusters/terminating-gateway-hostname-service-subsets.envoy-1-14-x.golden @@ -1,6 +1,60 @@ { "versionInfo": "00000001", "resources": [ + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "alt.api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "alt.api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "api.altdomain", + "portValue": 8081 + } + } + }, + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + }, + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "tlsCertificates": [ + { + "certificateChain": { + "filename": "api.cert.pem" + }, + "privateKey": { + "filename": "api.key.pem" + } + } + ], + "validationContext": { + "trustedCa": { + "filename": "ca.cert.pem" + } + } + } + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } + }, { "@type": "type.googleapis.com/envoy.api.v2.Cluster", "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", @@ -119,6 +173,38 @@ } }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "prod.cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "prod.cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "cache.mydomain", + "portValue": 8081 + } + } + }, + "healthStatus": "UNHEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } + }, { "@type": "type.googleapis.com/envoy.api.v2.Cluster", "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", diff --git a/agent/xds/testdata/clusters/terminating-gateway-hostname-service-subsets.envoy-1-15-x.golden b/agent/xds/testdata/clusters/terminating-gateway-hostname-service-subsets.envoy-1-15-x.golden index 27b1ddc6c..44bd0fd5f 100644 --- a/agent/xds/testdata/clusters/terminating-gateway-hostname-service-subsets.envoy-1-15-x.golden +++ b/agent/xds/testdata/clusters/terminating-gateway-hostname-service-subsets.envoy-1-15-x.golden @@ -1,6 +1,60 @@ { "versionInfo": "00000001", "resources": [ + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "alt.api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "alt.api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "api.altdomain", + "portValue": 8081 + } + } + }, + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + }, + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "tlsCertificates": [ + { + "certificateChain": { + "filename": "api.cert.pem" + }, + "privateKey": { + "filename": "api.key.pem" + } + } + ], + "validationContext": { + "trustedCa": { + "filename": "ca.cert.pem" + } + } + } + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } + }, { "@type": "type.googleapis.com/envoy.api.v2.Cluster", "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", @@ -119,6 +173,38 @@ } }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "prod.cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "prod.cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "cache.mydomain", + "portValue": 8081 + } + } + }, + "healthStatus": "UNHEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } + }, { "@type": "type.googleapis.com/envoy.api.v2.Cluster", "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", diff --git a/agent/xds/testdata/clusters/terminating-gateway-ignore-extra-resolvers.envoy-1-12-x.golden b/agent/xds/testdata/clusters/terminating-gateway-ignore-extra-resolvers.envoy-1-12-x.golden index 27b1ddc6c..f9c7336e6 100644 --- a/agent/xds/testdata/clusters/terminating-gateway-ignore-extra-resolvers.envoy-1-12-x.golden +++ b/agent/xds/testdata/clusters/terminating-gateway-ignore-extra-resolvers.envoy-1-12-x.golden @@ -119,6 +119,62 @@ } }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "validationContext": { + "trustedCa": { + "filename": "ca.cert.pem" + } + } + } + }, + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "validationContext": { + "trustedCa": { + "filename": "ca.cert.pem" + } + } + } + }, + "outlierDetection": { + + } + }, { "@type": "type.googleapis.com/envoy.api.v2.Cluster", "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", diff --git a/agent/xds/testdata/clusters/terminating-gateway-ignore-extra-resolvers.envoy-1-13-x.golden b/agent/xds/testdata/clusters/terminating-gateway-ignore-extra-resolvers.envoy-1-13-x.golden index 27b1ddc6c..f9c7336e6 100644 --- a/agent/xds/testdata/clusters/terminating-gateway-ignore-extra-resolvers.envoy-1-13-x.golden +++ b/agent/xds/testdata/clusters/terminating-gateway-ignore-extra-resolvers.envoy-1-13-x.golden @@ -119,6 +119,62 @@ } }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "validationContext": { + "trustedCa": { + "filename": "ca.cert.pem" + } + } + } + }, + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "validationContext": { + "trustedCa": { + "filename": "ca.cert.pem" + } + } + } + }, + "outlierDetection": { + + } + }, { "@type": "type.googleapis.com/envoy.api.v2.Cluster", "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", diff --git a/agent/xds/testdata/clusters/terminating-gateway-ignore-extra-resolvers.envoy-1-14-x.golden b/agent/xds/testdata/clusters/terminating-gateway-ignore-extra-resolvers.envoy-1-14-x.golden index 27b1ddc6c..f9c7336e6 100644 --- a/agent/xds/testdata/clusters/terminating-gateway-ignore-extra-resolvers.envoy-1-14-x.golden +++ b/agent/xds/testdata/clusters/terminating-gateway-ignore-extra-resolvers.envoy-1-14-x.golden @@ -119,6 +119,62 @@ } }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "validationContext": { + "trustedCa": { + "filename": "ca.cert.pem" + } + } + } + }, + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "validationContext": { + "trustedCa": { + "filename": "ca.cert.pem" + } + } + } + }, + "outlierDetection": { + + } + }, { "@type": "type.googleapis.com/envoy.api.v2.Cluster", "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", diff --git a/agent/xds/testdata/clusters/terminating-gateway-ignore-extra-resolvers.envoy-1-15-x.golden b/agent/xds/testdata/clusters/terminating-gateway-ignore-extra-resolvers.envoy-1-15-x.golden index 27b1ddc6c..f9c7336e6 100644 --- a/agent/xds/testdata/clusters/terminating-gateway-ignore-extra-resolvers.envoy-1-15-x.golden +++ b/agent/xds/testdata/clusters/terminating-gateway-ignore-extra-resolvers.envoy-1-15-x.golden @@ -119,6 +119,62 @@ } }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "validationContext": { + "trustedCa": { + "filename": "ca.cert.pem" + } + } + } + }, + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "validationContext": { + "trustedCa": { + "filename": "ca.cert.pem" + } + } + } + }, + "outlierDetection": { + + } + }, { "@type": "type.googleapis.com/envoy.api.v2.Cluster", "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", diff --git a/agent/xds/testdata/clusters/terminating-gateway-service-subsets.envoy-1-12-x.golden b/agent/xds/testdata/clusters/terminating-gateway-service-subsets.envoy-1-12-x.golden index 27b1ddc6c..8e3db0460 100644 --- a/agent/xds/testdata/clusters/terminating-gateway-service-subsets.envoy-1-12-x.golden +++ b/agent/xds/testdata/clusters/terminating-gateway-service-subsets.envoy-1-12-x.golden @@ -119,6 +119,94 @@ } }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "prod.cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "prod.cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "cache.mydomain", + "portValue": 8081 + } + } + }, + "healthStatus": "UNHEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "validationContext": { + "trustedCa": { + "filename": "ca.cert.pem" + } + } + } + }, + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "validationContext": { + "trustedCa": { + "filename": "ca.cert.pem" + } + } + } + }, + "outlierDetection": { + + } + }, { "@type": "type.googleapis.com/envoy.api.v2.Cluster", "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", diff --git a/agent/xds/testdata/clusters/terminating-gateway-service-subsets.envoy-1-13-x.golden b/agent/xds/testdata/clusters/terminating-gateway-service-subsets.envoy-1-13-x.golden index 27b1ddc6c..8e3db0460 100644 --- a/agent/xds/testdata/clusters/terminating-gateway-service-subsets.envoy-1-13-x.golden +++ b/agent/xds/testdata/clusters/terminating-gateway-service-subsets.envoy-1-13-x.golden @@ -119,6 +119,94 @@ } }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "prod.cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "prod.cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "cache.mydomain", + "portValue": 8081 + } + } + }, + "healthStatus": "UNHEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "validationContext": { + "trustedCa": { + "filename": "ca.cert.pem" + } + } + } + }, + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "validationContext": { + "trustedCa": { + "filename": "ca.cert.pem" + } + } + } + }, + "outlierDetection": { + + } + }, { "@type": "type.googleapis.com/envoy.api.v2.Cluster", "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", diff --git a/agent/xds/testdata/clusters/terminating-gateway-service-subsets.envoy-1-14-x.golden b/agent/xds/testdata/clusters/terminating-gateway-service-subsets.envoy-1-14-x.golden index 27b1ddc6c..8e3db0460 100644 --- a/agent/xds/testdata/clusters/terminating-gateway-service-subsets.envoy-1-14-x.golden +++ b/agent/xds/testdata/clusters/terminating-gateway-service-subsets.envoy-1-14-x.golden @@ -119,6 +119,94 @@ } }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "prod.cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "prod.cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "cache.mydomain", + "portValue": 8081 + } + } + }, + "healthStatus": "UNHEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "validationContext": { + "trustedCa": { + "filename": "ca.cert.pem" + } + } + } + }, + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "validationContext": { + "trustedCa": { + "filename": "ca.cert.pem" + } + } + } + }, + "outlierDetection": { + + } + }, { "@type": "type.googleapis.com/envoy.api.v2.Cluster", "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", diff --git a/agent/xds/testdata/clusters/terminating-gateway-service-subsets.envoy-1-15-x.golden b/agent/xds/testdata/clusters/terminating-gateway-service-subsets.envoy-1-15-x.golden index 27b1ddc6c..8e3db0460 100644 --- a/agent/xds/testdata/clusters/terminating-gateway-service-subsets.envoy-1-15-x.golden +++ b/agent/xds/testdata/clusters/terminating-gateway-service-subsets.envoy-1-15-x.golden @@ -119,6 +119,94 @@ } }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "prod.cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "prod.cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "cache.mydomain", + "portValue": 8081 + } + } + }, + "healthStatus": "UNHEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "validationContext": { + "trustedCa": { + "filename": "ca.cert.pem" + } + } + } + }, + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.api.v2.Cluster", + "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + } + } + }, + "connectTimeout": "5s", + "tlsContext": { + "commonTlsContext": { + "tlsParams": { + + }, + "validationContext": { + "trustedCa": { + "filename": "ca.cert.pem" + } + } + } + }, + "outlierDetection": { + + } + }, { "@type": "type.googleapis.com/envoy.api.v2.Cluster", "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", diff --git a/agent/xds/testdata/listeners/terminating-gateway-custom-and-tagged-addresses.envoy-1-12-x.golden b/agent/xds/testdata/listeners/terminating-gateway-custom-and-tagged-addresses.envoy-1-12-x.golden index 72abeba6b..0164fc635 100644 --- a/agent/xds/testdata/listeners/terminating-gateway-custom-and-tagged-addresses.envoy-1-12-x.golden +++ b/agent/xds/testdata/listeners/terminating-gateway-custom-and-tagged-addresses.envoy-1-12-x.golden @@ -183,33 +183,18 @@ }, "filters": [ { - "name": "envoy.http_connection_manager", + "name": "envoy.filters.network.rbac", "config": { - "http_filters": [ - { - "config": { - "rules": { - } - }, - "name": "envoy.filters.http.rbac" - }, - { - "name": "envoy.router" - } - ], - "rds": { - "config_source": { - "ads": { - } - }, - "route_config_name": "foo" + "rules": { }, - "stat_prefix": "terminating_gateway_default_web_foo_http", - "tracing": { - "operation_name": "EGRESS", - "random_sampling": { - } - } + "stat_prefix": "connect_authz" + } + }, + { + "name": "envoy.tcp_proxy", + "config": { + "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "stat_prefix": "terminating_gateway_default_web_foo_tcp" } } ] @@ -417,33 +402,18 @@ }, "filters": [ { - "name": "envoy.http_connection_manager", + "name": "envoy.filters.network.rbac", "config": { - "http_filters": [ - { - "config": { - "rules": { - } - }, - "name": "envoy.filters.http.rbac" - }, - { - "name": "envoy.router" - } - ], - "rds": { - "config_source": { - "ads": { - } - }, - "route_config_name": "wan" + "rules": { }, - "stat_prefix": "terminating_gateway_default_web_wan_http", - "tracing": { - "operation_name": "EGRESS", - "random_sampling": { - } - } + "stat_prefix": "connect_authz" + } + }, + { + "name": "envoy.tcp_proxy", + "config": { + "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "stat_prefix": "terminating_gateway_default_web_wan_tcp" } } ] diff --git a/agent/xds/testdata/listeners/terminating-gateway-custom-and-tagged-addresses.envoy-1-13-x.golden b/agent/xds/testdata/listeners/terminating-gateway-custom-and-tagged-addresses.envoy-1-13-x.golden index 72abeba6b..0164fc635 100644 --- a/agent/xds/testdata/listeners/terminating-gateway-custom-and-tagged-addresses.envoy-1-13-x.golden +++ b/agent/xds/testdata/listeners/terminating-gateway-custom-and-tagged-addresses.envoy-1-13-x.golden @@ -183,33 +183,18 @@ }, "filters": [ { - "name": "envoy.http_connection_manager", + "name": "envoy.filters.network.rbac", "config": { - "http_filters": [ - { - "config": { - "rules": { - } - }, - "name": "envoy.filters.http.rbac" - }, - { - "name": "envoy.router" - } - ], - "rds": { - "config_source": { - "ads": { - } - }, - "route_config_name": "foo" + "rules": { }, - "stat_prefix": "terminating_gateway_default_web_foo_http", - "tracing": { - "operation_name": "EGRESS", - "random_sampling": { - } - } + "stat_prefix": "connect_authz" + } + }, + { + "name": "envoy.tcp_proxy", + "config": { + "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "stat_prefix": "terminating_gateway_default_web_foo_tcp" } } ] @@ -417,33 +402,18 @@ }, "filters": [ { - "name": "envoy.http_connection_manager", + "name": "envoy.filters.network.rbac", "config": { - "http_filters": [ - { - "config": { - "rules": { - } - }, - "name": "envoy.filters.http.rbac" - }, - { - "name": "envoy.router" - } - ], - "rds": { - "config_source": { - "ads": { - } - }, - "route_config_name": "wan" + "rules": { }, - "stat_prefix": "terminating_gateway_default_web_wan_http", - "tracing": { - "operation_name": "EGRESS", - "random_sampling": { - } - } + "stat_prefix": "connect_authz" + } + }, + { + "name": "envoy.tcp_proxy", + "config": { + "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "stat_prefix": "terminating_gateway_default_web_wan_tcp" } } ] diff --git a/agent/xds/testdata/listeners/terminating-gateway-custom-and-tagged-addresses.envoy-1-14-x.golden b/agent/xds/testdata/listeners/terminating-gateway-custom-and-tagged-addresses.envoy-1-14-x.golden index 72abeba6b..0164fc635 100644 --- a/agent/xds/testdata/listeners/terminating-gateway-custom-and-tagged-addresses.envoy-1-14-x.golden +++ b/agent/xds/testdata/listeners/terminating-gateway-custom-and-tagged-addresses.envoy-1-14-x.golden @@ -183,33 +183,18 @@ }, "filters": [ { - "name": "envoy.http_connection_manager", + "name": "envoy.filters.network.rbac", "config": { - "http_filters": [ - { - "config": { - "rules": { - } - }, - "name": "envoy.filters.http.rbac" - }, - { - "name": "envoy.router" - } - ], - "rds": { - "config_source": { - "ads": { - } - }, - "route_config_name": "foo" + "rules": { }, - "stat_prefix": "terminating_gateway_default_web_foo_http", - "tracing": { - "operation_name": "EGRESS", - "random_sampling": { - } - } + "stat_prefix": "connect_authz" + } + }, + { + "name": "envoy.tcp_proxy", + "config": { + "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "stat_prefix": "terminating_gateway_default_web_foo_tcp" } } ] @@ -417,33 +402,18 @@ }, "filters": [ { - "name": "envoy.http_connection_manager", + "name": "envoy.filters.network.rbac", "config": { - "http_filters": [ - { - "config": { - "rules": { - } - }, - "name": "envoy.filters.http.rbac" - }, - { - "name": "envoy.router" - } - ], - "rds": { - "config_source": { - "ads": { - } - }, - "route_config_name": "wan" + "rules": { }, - "stat_prefix": "terminating_gateway_default_web_wan_http", - "tracing": { - "operation_name": "EGRESS", - "random_sampling": { - } - } + "stat_prefix": "connect_authz" + } + }, + { + "name": "envoy.tcp_proxy", + "config": { + "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "stat_prefix": "terminating_gateway_default_web_wan_tcp" } } ] diff --git a/agent/xds/testdata/listeners/terminating-gateway-custom-and-tagged-addresses.envoy-1-15-x.golden b/agent/xds/testdata/listeners/terminating-gateway-custom-and-tagged-addresses.envoy-1-15-x.golden index 72abeba6b..0164fc635 100644 --- a/agent/xds/testdata/listeners/terminating-gateway-custom-and-tagged-addresses.envoy-1-15-x.golden +++ b/agent/xds/testdata/listeners/terminating-gateway-custom-and-tagged-addresses.envoy-1-15-x.golden @@ -183,33 +183,18 @@ }, "filters": [ { - "name": "envoy.http_connection_manager", + "name": "envoy.filters.network.rbac", "config": { - "http_filters": [ - { - "config": { - "rules": { - } - }, - "name": "envoy.filters.http.rbac" - }, - { - "name": "envoy.router" - } - ], - "rds": { - "config_source": { - "ads": { - } - }, - "route_config_name": "foo" + "rules": { }, - "stat_prefix": "terminating_gateway_default_web_foo_http", - "tracing": { - "operation_name": "EGRESS", - "random_sampling": { - } - } + "stat_prefix": "connect_authz" + } + }, + { + "name": "envoy.tcp_proxy", + "config": { + "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "stat_prefix": "terminating_gateway_default_web_foo_tcp" } } ] @@ -417,33 +402,18 @@ }, "filters": [ { - "name": "envoy.http_connection_manager", + "name": "envoy.filters.network.rbac", "config": { - "http_filters": [ - { - "config": { - "rules": { - } - }, - "name": "envoy.filters.http.rbac" - }, - { - "name": "envoy.router" - } - ], - "rds": { - "config_source": { - "ads": { - } - }, - "route_config_name": "wan" + "rules": { }, - "stat_prefix": "terminating_gateway_default_web_wan_http", - "tracing": { - "operation_name": "EGRESS", - "random_sampling": { - } - } + "stat_prefix": "connect_authz" + } + }, + { + "name": "envoy.tcp_proxy", + "config": { + "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "stat_prefix": "terminating_gateway_default_web_wan_tcp" } } ] diff --git a/agent/xds/testdata/listeners/terminating-gateway-no-api-cert.envoy-1-12-x.golden b/agent/xds/testdata/listeners/terminating-gateway-no-api-cert.envoy-1-12-x.golden index cb3860ef5..bfb7ab050 100644 --- a/agent/xds/testdata/listeners/terminating-gateway-no-api-cert.envoy-1-12-x.golden +++ b/agent/xds/testdata/listeners/terminating-gateway-no-api-cert.envoy-1-12-x.golden @@ -136,33 +136,18 @@ }, "filters": [ { - "name": "envoy.http_connection_manager", + "name": "envoy.filters.network.rbac", "config": { - "http_filters": [ - { - "config": { - "rules": { - } - }, - "name": "envoy.filters.http.rbac" - }, - { - "name": "envoy.router" - } - ], - "rds": { - "config_source": { - "ads": { - } - }, - "route_config_name": "default" + "rules": { }, - "stat_prefix": "terminating_gateway_default_web_default_http", - "tracing": { - "operation_name": "EGRESS", - "random_sampling": { - } - } + "stat_prefix": "connect_authz" + } + }, + { + "name": "envoy.tcp_proxy", + "config": { + "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "stat_prefix": "terminating_gateway_default_web_default_tcp" } } ] diff --git a/agent/xds/testdata/listeners/terminating-gateway-no-api-cert.envoy-1-13-x.golden b/agent/xds/testdata/listeners/terminating-gateway-no-api-cert.envoy-1-13-x.golden index cb3860ef5..bfb7ab050 100644 --- a/agent/xds/testdata/listeners/terminating-gateway-no-api-cert.envoy-1-13-x.golden +++ b/agent/xds/testdata/listeners/terminating-gateway-no-api-cert.envoy-1-13-x.golden @@ -136,33 +136,18 @@ }, "filters": [ { - "name": "envoy.http_connection_manager", + "name": "envoy.filters.network.rbac", "config": { - "http_filters": [ - { - "config": { - "rules": { - } - }, - "name": "envoy.filters.http.rbac" - }, - { - "name": "envoy.router" - } - ], - "rds": { - "config_source": { - "ads": { - } - }, - "route_config_name": "default" + "rules": { }, - "stat_prefix": "terminating_gateway_default_web_default_http", - "tracing": { - "operation_name": "EGRESS", - "random_sampling": { - } - } + "stat_prefix": "connect_authz" + } + }, + { + "name": "envoy.tcp_proxy", + "config": { + "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "stat_prefix": "terminating_gateway_default_web_default_tcp" } } ] diff --git a/agent/xds/testdata/listeners/terminating-gateway-no-api-cert.envoy-1-14-x.golden b/agent/xds/testdata/listeners/terminating-gateway-no-api-cert.envoy-1-14-x.golden index cb3860ef5..bfb7ab050 100644 --- a/agent/xds/testdata/listeners/terminating-gateway-no-api-cert.envoy-1-14-x.golden +++ b/agent/xds/testdata/listeners/terminating-gateway-no-api-cert.envoy-1-14-x.golden @@ -136,33 +136,18 @@ }, "filters": [ { - "name": "envoy.http_connection_manager", + "name": "envoy.filters.network.rbac", "config": { - "http_filters": [ - { - "config": { - "rules": { - } - }, - "name": "envoy.filters.http.rbac" - }, - { - "name": "envoy.router" - } - ], - "rds": { - "config_source": { - "ads": { - } - }, - "route_config_name": "default" + "rules": { }, - "stat_prefix": "terminating_gateway_default_web_default_http", - "tracing": { - "operation_name": "EGRESS", - "random_sampling": { - } - } + "stat_prefix": "connect_authz" + } + }, + { + "name": "envoy.tcp_proxy", + "config": { + "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "stat_prefix": "terminating_gateway_default_web_default_tcp" } } ] diff --git a/agent/xds/testdata/listeners/terminating-gateway-no-api-cert.envoy-1-15-x.golden b/agent/xds/testdata/listeners/terminating-gateway-no-api-cert.envoy-1-15-x.golden index cb3860ef5..bfb7ab050 100644 --- a/agent/xds/testdata/listeners/terminating-gateway-no-api-cert.envoy-1-15-x.golden +++ b/agent/xds/testdata/listeners/terminating-gateway-no-api-cert.envoy-1-15-x.golden @@ -136,33 +136,18 @@ }, "filters": [ { - "name": "envoy.http_connection_manager", + "name": "envoy.filters.network.rbac", "config": { - "http_filters": [ - { - "config": { - "rules": { - } - }, - "name": "envoy.filters.http.rbac" - }, - { - "name": "envoy.router" - } - ], - "rds": { - "config_source": { - "ads": { - } - }, - "route_config_name": "default" + "rules": { }, - "stat_prefix": "terminating_gateway_default_web_default_http", - "tracing": { - "operation_name": "EGRESS", - "random_sampling": { - } - } + "stat_prefix": "connect_authz" + } + }, + { + "name": "envoy.tcp_proxy", + "config": { + "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "stat_prefix": "terminating_gateway_default_web_default_tcp" } } ] diff --git a/agent/xds/testdata/listeners/terminating-gateway.envoy-1-12-x.golden b/agent/xds/testdata/listeners/terminating-gateway.envoy-1-12-x.golden index 3ef59ad7d..eba577e6c 100644 --- a/agent/xds/testdata/listeners/terminating-gateway.envoy-1-12-x.golden +++ b/agent/xds/testdata/listeners/terminating-gateway.envoy-1-12-x.golden @@ -183,33 +183,18 @@ }, "filters": [ { - "name": "envoy.http_connection_manager", + "name": "envoy.filters.network.rbac", "config": { - "http_filters": [ - { - "config": { - "rules": { - } - }, - "name": "envoy.filters.http.rbac" - }, - { - "name": "envoy.router" - } - ], - "rds": { - "config_source": { - "ads": { - } - }, - "route_config_name": "default" + "rules": { }, - "stat_prefix": "terminating_gateway_default_web_default_http", - "tracing": { - "operation_name": "EGRESS", - "random_sampling": { - } - } + "stat_prefix": "connect_authz" + } + }, + { + "name": "envoy.tcp_proxy", + "config": { + "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "stat_prefix": "terminating_gateway_default_web_default_tcp" } } ] diff --git a/agent/xds/testdata/listeners/terminating-gateway.envoy-1-13-x.golden b/agent/xds/testdata/listeners/terminating-gateway.envoy-1-13-x.golden index 3ef59ad7d..eba577e6c 100644 --- a/agent/xds/testdata/listeners/terminating-gateway.envoy-1-13-x.golden +++ b/agent/xds/testdata/listeners/terminating-gateway.envoy-1-13-x.golden @@ -183,33 +183,18 @@ }, "filters": [ { - "name": "envoy.http_connection_manager", + "name": "envoy.filters.network.rbac", "config": { - "http_filters": [ - { - "config": { - "rules": { - } - }, - "name": "envoy.filters.http.rbac" - }, - { - "name": "envoy.router" - } - ], - "rds": { - "config_source": { - "ads": { - } - }, - "route_config_name": "default" + "rules": { }, - "stat_prefix": "terminating_gateway_default_web_default_http", - "tracing": { - "operation_name": "EGRESS", - "random_sampling": { - } - } + "stat_prefix": "connect_authz" + } + }, + { + "name": "envoy.tcp_proxy", + "config": { + "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "stat_prefix": "terminating_gateway_default_web_default_tcp" } } ] diff --git a/agent/xds/testdata/listeners/terminating-gateway.envoy-1-14-x.golden b/agent/xds/testdata/listeners/terminating-gateway.envoy-1-14-x.golden index 3ef59ad7d..eba577e6c 100644 --- a/agent/xds/testdata/listeners/terminating-gateway.envoy-1-14-x.golden +++ b/agent/xds/testdata/listeners/terminating-gateway.envoy-1-14-x.golden @@ -183,33 +183,18 @@ }, "filters": [ { - "name": "envoy.http_connection_manager", + "name": "envoy.filters.network.rbac", "config": { - "http_filters": [ - { - "config": { - "rules": { - } - }, - "name": "envoy.filters.http.rbac" - }, - { - "name": "envoy.router" - } - ], - "rds": { - "config_source": { - "ads": { - } - }, - "route_config_name": "default" + "rules": { }, - "stat_prefix": "terminating_gateway_default_web_default_http", - "tracing": { - "operation_name": "EGRESS", - "random_sampling": { - } - } + "stat_prefix": "connect_authz" + } + }, + { + "name": "envoy.tcp_proxy", + "config": { + "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "stat_prefix": "terminating_gateway_default_web_default_tcp" } } ] diff --git a/agent/xds/testdata/listeners/terminating-gateway.envoy-1-15-x.golden b/agent/xds/testdata/listeners/terminating-gateway.envoy-1-15-x.golden index 3ef59ad7d..eba577e6c 100644 --- a/agent/xds/testdata/listeners/terminating-gateway.envoy-1-15-x.golden +++ b/agent/xds/testdata/listeners/terminating-gateway.envoy-1-15-x.golden @@ -183,33 +183,18 @@ }, "filters": [ { - "name": "envoy.http_connection_manager", + "name": "envoy.filters.network.rbac", "config": { - "http_filters": [ - { - "config": { - "rules": { - } - }, - "name": "envoy.filters.http.rbac" - }, - { - "name": "envoy.router" - } - ], - "rds": { - "config_source": { - "ads": { - } - }, - "route_config_name": "default" + "rules": { }, - "stat_prefix": "terminating_gateway_default_web_default_http", - "tracing": { - "operation_name": "EGRESS", - "random_sampling": { - } - } + "stat_prefix": "connect_authz" + } + }, + { + "name": "envoy.tcp_proxy", + "config": { + "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "stat_prefix": "terminating_gateway_default_web_default_tcp" } } ] From 23147c1d5bbb374a4566d89e1314734cb3d5bc54 Mon Sep 17 00:00:00 2001 From: freddygv Date: Thu, 3 Sep 2020 10:21:20 -0600 Subject: [PATCH 12/20] Fix http assertion in route creation --- agent/xds/routes.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/agent/xds/routes.go b/agent/xds/routes.go index c95e74855..0f73e2bb4 100644 --- a/agent/xds/routes.go +++ b/agent/xds/routes.go @@ -50,7 +50,10 @@ func routesFromSnapshotTerminatingGateway(_ connectionInfo, cfgSnap *proxycfg.Co svcConfig := cfgSnap.TerminatingGateway.ServiceConfigs[svc] cfg, err := ParseProxyConfig(svcConfig.ProxyConfig) - if err != nil || structs.IsProtocolHTTPLike(cfg.Protocol) { + if err != nil { + return nil, fmt.Errorf("failed to parse upstream config: %v", err) + } + if !structs.IsProtocolHTTPLike(cfg.Protocol) { // Routes can only be defined for HTTP services continue } From b149185794ba9bafe81e9d845b1f1d9207244e2b Mon Sep 17 00:00:00 2001 From: freddygv Date: Thu, 3 Sep 2020 12:35:11 -0600 Subject: [PATCH 13/20] Update golden files after default route fix for tgw --- ...ting-gateway-lb-config.envoy-1-12-x.golden | 75 ++++++++++++++++--- ...ting-gateway-lb-config.envoy-1-13-x.golden | 75 ++++++++++++++++--- ...ting-gateway-lb-config.envoy-1-14-x.golden | 75 ++++++++++++++++--- ...ting-gateway-lb-config.envoy-1-15-x.golden | 75 ++++++++++++++++--- 4 files changed, 264 insertions(+), 36 deletions(-) diff --git a/agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-12-x.golden b/agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-12-x.golden index e8370f265..b611e2508 100644 --- a/agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-12-x.golden +++ b/agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-12-x.golden @@ -3,10 +3,10 @@ "resources": [ { "@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration", - "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "virtualHosts": [ { - "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "domains": [ "*" ], @@ -16,7 +16,26 @@ "prefix": "/" }, "route": { - "cluster": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "cluster": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "hashPolicy": [ + { + "cookie": { + "name": "chocolate-chip" + }, + "terminal": true + }, + { + "header": { + "headerName": "x-user-id" + } + }, + { + "connectionProperties": { + "sourceIp": true + }, + "terminal": true + } + ] } } ] @@ -26,10 +45,10 @@ }, { "@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration", - "name": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "virtualHosts": [ { - "name": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "domains": [ "*" ], @@ -39,7 +58,26 @@ "prefix": "/" }, "route": { - "cluster": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "cluster": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "hashPolicy": [ + { + "cookie": { + "name": "chocolate-chip" + }, + "terminal": true + }, + { + "header": { + "headerName": "x-user-id" + } + }, + { + "connectionProperties": { + "sourceIp": true + }, + "terminal": true + } + ] } } ] @@ -49,10 +87,10 @@ }, { "@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration", - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "virtualHosts": [ { - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "domains": [ "*" ], @@ -62,7 +100,26 @@ "prefix": "/" }, "route": { - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "hashPolicy": [ + { + "cookie": { + "name": "chocolate-chip" + }, + "terminal": true + }, + { + "header": { + "headerName": "x-user-id" + } + }, + { + "connectionProperties": { + "sourceIp": true + }, + "terminal": true + } + ] } } ] diff --git a/agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-13-x.golden b/agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-13-x.golden index e8370f265..b611e2508 100644 --- a/agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-13-x.golden +++ b/agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-13-x.golden @@ -3,10 +3,10 @@ "resources": [ { "@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration", - "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "virtualHosts": [ { - "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "domains": [ "*" ], @@ -16,7 +16,26 @@ "prefix": "/" }, "route": { - "cluster": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "cluster": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "hashPolicy": [ + { + "cookie": { + "name": "chocolate-chip" + }, + "terminal": true + }, + { + "header": { + "headerName": "x-user-id" + } + }, + { + "connectionProperties": { + "sourceIp": true + }, + "terminal": true + } + ] } } ] @@ -26,10 +45,10 @@ }, { "@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration", - "name": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "virtualHosts": [ { - "name": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "domains": [ "*" ], @@ -39,7 +58,26 @@ "prefix": "/" }, "route": { - "cluster": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "cluster": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "hashPolicy": [ + { + "cookie": { + "name": "chocolate-chip" + }, + "terminal": true + }, + { + "header": { + "headerName": "x-user-id" + } + }, + { + "connectionProperties": { + "sourceIp": true + }, + "terminal": true + } + ] } } ] @@ -49,10 +87,10 @@ }, { "@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration", - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "virtualHosts": [ { - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "domains": [ "*" ], @@ -62,7 +100,26 @@ "prefix": "/" }, "route": { - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "hashPolicy": [ + { + "cookie": { + "name": "chocolate-chip" + }, + "terminal": true + }, + { + "header": { + "headerName": "x-user-id" + } + }, + { + "connectionProperties": { + "sourceIp": true + }, + "terminal": true + } + ] } } ] diff --git a/agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-14-x.golden b/agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-14-x.golden index e8370f265..b611e2508 100644 --- a/agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-14-x.golden +++ b/agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-14-x.golden @@ -3,10 +3,10 @@ "resources": [ { "@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration", - "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "virtualHosts": [ { - "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "domains": [ "*" ], @@ -16,7 +16,26 @@ "prefix": "/" }, "route": { - "cluster": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "cluster": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "hashPolicy": [ + { + "cookie": { + "name": "chocolate-chip" + }, + "terminal": true + }, + { + "header": { + "headerName": "x-user-id" + } + }, + { + "connectionProperties": { + "sourceIp": true + }, + "terminal": true + } + ] } } ] @@ -26,10 +45,10 @@ }, { "@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration", - "name": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "virtualHosts": [ { - "name": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "domains": [ "*" ], @@ -39,7 +58,26 @@ "prefix": "/" }, "route": { - "cluster": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "cluster": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "hashPolicy": [ + { + "cookie": { + "name": "chocolate-chip" + }, + "terminal": true + }, + { + "header": { + "headerName": "x-user-id" + } + }, + { + "connectionProperties": { + "sourceIp": true + }, + "terminal": true + } + ] } } ] @@ -49,10 +87,10 @@ }, { "@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration", - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "virtualHosts": [ { - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "domains": [ "*" ], @@ -62,7 +100,26 @@ "prefix": "/" }, "route": { - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "hashPolicy": [ + { + "cookie": { + "name": "chocolate-chip" + }, + "terminal": true + }, + { + "header": { + "headerName": "x-user-id" + } + }, + { + "connectionProperties": { + "sourceIp": true + }, + "terminal": true + } + ] } } ] diff --git a/agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-15-x.golden b/agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-15-x.golden index e8370f265..b611e2508 100644 --- a/agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-15-x.golden +++ b/agent/xds/testdata/routes/terminating-gateway-lb-config.envoy-1-15-x.golden @@ -3,10 +3,10 @@ "resources": [ { "@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration", - "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "virtualHosts": [ { - "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "domains": [ "*" ], @@ -16,7 +16,26 @@ "prefix": "/" }, "route": { - "cluster": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "cluster": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "hashPolicy": [ + { + "cookie": { + "name": "chocolate-chip" + }, + "terminal": true + }, + { + "header": { + "headerName": "x-user-id" + } + }, + { + "connectionProperties": { + "sourceIp": true + }, + "terminal": true + } + ] } } ] @@ -26,10 +45,10 @@ }, { "@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration", - "name": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "virtualHosts": [ { - "name": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "domains": [ "*" ], @@ -39,7 +58,26 @@ "prefix": "/" }, "route": { - "cluster": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "cluster": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "hashPolicy": [ + { + "cookie": { + "name": "chocolate-chip" + }, + "terminal": true + }, + { + "header": { + "headerName": "x-user-id" + } + }, + { + "connectionProperties": { + "sourceIp": true + }, + "terminal": true + } + ] } } ] @@ -49,10 +87,10 @@ }, { "@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration", - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "virtualHosts": [ { - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "domains": [ "*" ], @@ -62,7 +100,26 @@ "prefix": "/" }, "route": { - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "hashPolicy": [ + { + "cookie": { + "name": "chocolate-chip" + }, + "terminal": true + }, + { + "header": { + "headerName": "x-user-id" + } + }, + { + "connectionProperties": { + "sourceIp": true + }, + "terminal": true + } + ] } } ] From 56fdae9ace58d860c36794b972082d76e900170a Mon Sep 17 00:00:00 2001 From: freddygv Date: Thu, 3 Sep 2020 13:08:44 -0600 Subject: [PATCH 14/20] Update resolver defaulting --- agent/consul/discoverychain/compile_test.go | 8 ++++---- agent/structs/config_entry_discoverychain.go | 3 ++- agent/structs/discovery_chain.go | 3 --- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/agent/consul/discoverychain/compile_test.go b/agent/consul/discoverychain/compile_test.go index af6597175..1d5c3e582 100644 --- a/agent/consul/discoverychain/compile_test.go +++ b/agent/consul/discoverychain/compile_test.go @@ -2372,7 +2372,7 @@ func testcase_LBSplitterAndResolver() compileTestCase { Type: structs.DiscoveryGraphNodeTypeResolver, Name: "foo.default.dc1", Resolver: &structs.DiscoveryResolver{ - Default: true, + Default: false, ConnectTimeout: 5 * time.Second, Target: "foo.default.dc1", }, @@ -2389,7 +2389,7 @@ func testcase_LBSplitterAndResolver() compileTestCase { Type: structs.DiscoveryGraphNodeTypeResolver, Name: "bar.default.dc1", Resolver: &structs.DiscoveryResolver{ - Default: true, + Default: false, ConnectTimeout: 5 * time.Second, Target: "bar.default.dc1", }, @@ -2411,7 +2411,7 @@ func testcase_LBSplitterAndResolver() compileTestCase { Type: structs.DiscoveryGraphNodeTypeResolver, Name: "baz.default.dc1", Resolver: &structs.DiscoveryResolver{ - Default: true, + Default: false, ConnectTimeout: 5 * time.Second, Target: "baz.default.dc1", }, @@ -2476,7 +2476,7 @@ func testcase_LBResolver() compileTestCase { Type: structs.DiscoveryGraphNodeTypeResolver, Name: "main.default.dc1", Resolver: &structs.DiscoveryResolver{ - Default: true, + Default: false, ConnectTimeout: 5 * time.Second, Target: "main.default.dc1", }, diff --git a/agent/structs/config_entry_discoverychain.go b/agent/structs/config_entry_discoverychain.go index d0cd7e46d..96ef3b3a2 100644 --- a/agent/structs/config_entry_discoverychain.go +++ b/agent/structs/config_entry_discoverychain.go @@ -730,7 +730,8 @@ func (e *ServiceResolverConfigEntry) IsDefault() bool { len(e.Subsets) == 0 && e.Redirect == nil && len(e.Failover) == 0 && - e.ConnectTimeout == 0 + e.ConnectTimeout == 0 && + e.LoadBalancer == nil } func (e *ServiceResolverConfigEntry) GetKind() string { diff --git a/agent/structs/discovery_chain.go b/agent/structs/discovery_chain.go index 5e2ff9498..77eb03937 100644 --- a/agent/structs/discovery_chain.go +++ b/agent/structs/discovery_chain.go @@ -82,9 +82,6 @@ func (c *CompiledDiscoveryChain) IsDefault() bool { if !node.Resolver.Default { return false } - if node.LoadBalancer != nil { - return false - } target := c.Targets[node.Resolver.Target] From 3e4bc36941b9825ef5a4e7ea84db3ec2ce158c61 Mon Sep 17 00:00:00 2001 From: freddygv Date: Thu, 3 Sep 2020 16:19:58 -0600 Subject: [PATCH 15/20] Add server receiver to routes and log tgw err --- agent/xds/routes.go | 10 +++++++--- agent/xds/routes_test.go | 7 ++++++- agent/xds/server.go | 2 +- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/agent/xds/routes.go b/agent/xds/routes.go index 0f73e2bb4..3c3e79222 100644 --- a/agent/xds/routes.go +++ b/agent/xds/routes.go @@ -3,6 +3,7 @@ package xds import ( "errors" "fmt" + "github.com/hashicorp/consul/logging" "net" "strings" @@ -18,7 +19,7 @@ import ( // routesFromSnapshot returns the xDS API representation of the "routes" in the // snapshot. -func routesFromSnapshot(cInfo connectionInfo, cfgSnap *proxycfg.ConfigSnapshot) ([]proto.Message, error) { +func (s *Server) routesFromSnapshot(cInfo connectionInfo, cfgSnap *proxycfg.ConfigSnapshot) ([]proto.Message, error) { if cfgSnap == nil { return nil, errors.New("nil config given") } @@ -29,7 +30,7 @@ func routesFromSnapshot(cInfo connectionInfo, cfgSnap *proxycfg.ConfigSnapshot) case structs.ServiceKindIngressGateway: return routesForIngressGateway(cInfo, cfgSnap.IngressGateway.Upstreams, cfgSnap.IngressGateway.DiscoveryChain) case structs.ServiceKindTerminatingGateway: - return routesFromSnapshotTerminatingGateway(cInfo, cfgSnap) + return s.routesFromSnapshotTerminatingGateway(cInfo, cfgSnap) default: return nil, fmt.Errorf("Invalid service kind: %v", cfgSnap.Kind) } @@ -37,10 +38,11 @@ func routesFromSnapshot(cInfo connectionInfo, cfgSnap *proxycfg.ConfigSnapshot) // routesFromSnapshotTerminatingGateway returns the xDS API representation of the "routes" in the snapshot. // For any HTTP service we will return a default route. -func routesFromSnapshotTerminatingGateway(_ connectionInfo, cfgSnap *proxycfg.ConfigSnapshot) ([]proto.Message, error) { +func (s *Server) routesFromSnapshotTerminatingGateway(_ connectionInfo, cfgSnap *proxycfg.ConfigSnapshot) ([]proto.Message, error) { if cfgSnap == nil { return nil, errors.New("nil config given") } + logger := s.Logger.Named(logging.TerminatingGateway) var resources []proto.Message for _, svc := range cfgSnap.TerminatingGateway.ValidServices() { @@ -69,6 +71,7 @@ func routesFromSnapshotTerminatingGateway(_ connectionInfo, cfgSnap *proxycfg.Co } route, err := makeNamedDefaultRouteWithLB(clusterName, lb) if err != nil { + logger.Error("failed to make route", "cluster", clusterName, "error", err) continue } resources = append(resources, route) @@ -78,6 +81,7 @@ func routesFromSnapshotTerminatingGateway(_ connectionInfo, cfgSnap *proxycfg.Co clusterName = connect.ServiceSNI(svc.Name, name, svc.NamespaceOrDefault(), cfgSnap.Datacenter, cfgSnap.Roots.TrustDomain) route, err := makeNamedDefaultRouteWithLB(clusterName, lb) if err != nil { + logger.Error("failed to make route", "cluster", clusterName, "error", err) continue } resources = append(resources, route) diff --git a/agent/xds/routes_test.go b/agent/xds/routes_test.go index 518102321..600d8ee6d 100644 --- a/agent/xds/routes_test.go +++ b/agent/xds/routes_test.go @@ -14,6 +14,7 @@ import ( "github.com/hashicorp/consul/agent/proxycfg" "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/agent/xds/proxysupport" + "github.com/hashicorp/consul/sdk/testutil" testinf "github.com/mitchellh/go-testing-interface" "github.com/stretchr/testify/require" ) @@ -257,11 +258,15 @@ func TestRoutesFromSnapshot(t *testing.T) { tt.setup(snap) } + logger := testutil.Logger(t) + s := Server{ + Logger: logger, + } cInfo := connectionInfo{ Token: "my-token", ProxyFeatures: sf, } - routes, err := routesFromSnapshot(cInfo, snap) + routes, err := s.routesFromSnapshot(cInfo, snap) require.NoError(err) sort.Slice(routes, func(i, j int) bool { return routes[i].(*envoy.RouteConfiguration).Name < routes[j].(*envoy.RouteConfiguration).Name diff --git a/agent/xds/server.go b/agent/xds/server.go index 8eaa299d9..ed148da49 100644 --- a/agent/xds/server.go +++ b/agent/xds/server.go @@ -218,7 +218,7 @@ func (s *Server) process(stream ADSStream, reqCh <-chan *envoy.DiscoveryRequest) }, RouteType: { typeURL: RouteType, - resources: routesFromSnapshot, + resources: s.routesFromSnapshot, stream: stream, allowEmptyFn: func(cfgSnap *proxycfg.ConfigSnapshot) bool { return cfgSnap.Kind == structs.ServiceKindIngressGateway From 1ee039ed9515a010c6885ffadc0c43ac1e568065 Mon Sep 17 00:00:00 2001 From: freddygv Date: Fri, 4 Sep 2020 12:45:05 -0600 Subject: [PATCH 16/20] Set tgw filter router config name to cluster name --- agent/xds/listeners.go | 55 +++++++++---------- ...ateway-service-subsets.envoy-1-12-x.golden | 6 +- ...ateway-service-subsets.envoy-1-13-x.golden | 6 +- ...ateway-service-subsets.envoy-1-14-x.golden | 6 +- ...ateway-service-subsets.envoy-1-15-x.golden | 6 +- 5 files changed, 38 insertions(+), 41 deletions(-) diff --git a/agent/xds/listeners.go b/agent/xds/listeners.go index cfdfd4d7f..64ea87268 100644 --- a/agent/xds/listeners.go +++ b/agent/xds/listeners.go @@ -317,6 +317,7 @@ func (s *Server) makeIngressGatewayListeners(address string, cfgSnap *proxycfg.C useRDS: true, protocol: listenerKey.Protocol, filterName: listenerKey.RouteName(), + routeName: listenerKey.RouteName(), cluster: "", statPrefix: "ingress_upstream_", routePath: "", @@ -557,6 +558,7 @@ func (s *Server) makePublicListener(cInfo connectionInfo, cfgSnap *proxycfg.Conf useRDS: false, protocol: cfg.Protocol, filterName: "public_listener", + routeName: "public_listener", cluster: LocalAppClusterName, statPrefix: "", routePath: "", @@ -651,6 +653,7 @@ func (s *Server) makeExposedCheckListener(cfgSnap *proxycfg.ConfigSnapshot, clus useRDS: false, protocol: path.Protocol, filterName: filterName, + routeName: filterName, cluster: cluster, statPrefix: "", routePath: path.Path, @@ -822,6 +825,7 @@ func (s *Server) makeFilterChainTerminatingGateway( opts := listenerFilterOpts{ protocol: protocol, filterName: listener, + routeName: cluster, // Set cluster name for route config since each will have its own cluster: cluster, statPrefix: statPrefix, routePath: "", @@ -1001,6 +1005,7 @@ func (s *Server) makeUpstreamListenerForDiscoveryChain( useRDS: useRDS, protocol: cfg.Protocol, filterName: upstreamID, + routeName: upstreamID, cluster: clusterName, statPrefix: "upstream_", routePath: "", @@ -1074,6 +1079,7 @@ type listenerFilterOpts struct { useRDS bool protocol string filterName string + routeName string cluster string statPrefix string routePath string @@ -1083,12 +1089,8 @@ type listenerFilterOpts struct { func makeListenerFilter(opts listenerFilterOpts) (*envoylistener.Filter, error) { switch opts.protocol { - case "grpc": - return makeHTTPFilter(opts.useRDS, opts.filterName, opts.cluster, opts.statPrefix, opts.routePath, opts.ingress, true, true, opts.httpAuthzFilter) - case "http2": - return makeHTTPFilter(opts.useRDS, opts.filterName, opts.cluster, opts.statPrefix, opts.routePath, opts.ingress, false, true, opts.httpAuthzFilter) - case "http": - return makeHTTPFilter(opts.useRDS, opts.filterName, opts.cluster, opts.statPrefix, opts.routePath, opts.ingress, false, false, opts.httpAuthzFilter) + case "grpc", "http2", "http": + return makeHTTPFilter(opts) case "tcp": fallthrough default: @@ -1131,23 +1133,18 @@ func makeStatPrefix(protocol, prefix, filterName string) string { return fmt.Sprintf("%s%s_%s", prefix, strings.Replace(filterName, ":", "_", -1), protocol) } -func makeHTTPFilter( - useRDS bool, - filterName, cluster, statPrefix, routePath string, - ingress, grpc, http2 bool, - authzFilter *envoyhttp.HttpFilter, -) (*envoylistener.Filter, error) { +func makeHTTPFilter(opts listenerFilterOpts) (*envoylistener.Filter, error) { op := envoyhttp.HttpConnectionManager_Tracing_INGRESS - if !ingress { + if !opts.ingress { op = envoyhttp.HttpConnectionManager_Tracing_EGRESS } proto := "http" - if grpc { - proto = "grpc" + if opts.protocol == "grpc" { + proto = opts.protocol } cfg := &envoyhttp.HttpConnectionManager{ - StatPrefix: makeStatPrefix(proto, statPrefix, filterName), + StatPrefix: makeStatPrefix(proto, opts.statPrefix, opts.filterName), CodecType: envoyhttp.HttpConnectionManager_AUTO, HttpFilters: []*envoyhttp.HttpFilter{ { @@ -1163,13 +1160,13 @@ func makeHTTPFilter( }, } - if useRDS { - if cluster != "" { + if opts.useRDS { + if opts.cluster != "" { return nil, fmt.Errorf("cannot specify cluster name when using RDS") } cfg.RouteSpecifier = &envoyhttp.HttpConnectionManager_Rds{ Rds: &envoyhttp.Rds{ - RouteConfigName: filterName, + RouteConfigName: opts.routeName, ConfigSource: &envoycore.ConfigSource{ ConfigSourceSpecifier: &envoycore.ConfigSource_Ads{ Ads: &envoycore.AggregatedConfigSource{}, @@ -1178,7 +1175,7 @@ func makeHTTPFilter( }, } } else { - if cluster == "" { + if opts.cluster == "" { return nil, fmt.Errorf("must specify cluster name when not using RDS") } route := &envoyroute.Route{ @@ -1195,22 +1192,22 @@ func makeHTTPFilter( Action: &envoyroute.Route_Route{ Route: &envoyroute.RouteAction{ ClusterSpecifier: &envoyroute.RouteAction_Cluster{ - Cluster: cluster, + Cluster: opts.cluster, }, }, }, } // If a path is provided, do not match on a catch-all prefix - if routePath != "" { - route.Match.PathSpecifier = &envoyroute.RouteMatch_Path{Path: routePath} + if opts.routePath != "" { + route.Match.PathSpecifier = &envoyroute.RouteMatch_Path{Path: opts.routePath} } cfg.RouteSpecifier = &envoyhttp.HttpConnectionManager_RouteConfig{ RouteConfig: &envoy.RouteConfiguration{ - Name: filterName, + Name: opts.routeName, VirtualHosts: []*envoyroute.VirtualHost{ { - Name: filterName, + Name: opts.filterName, Domains: []string{"*"}, Routes: []*envoyroute.Route{ route, @@ -1221,7 +1218,7 @@ func makeHTTPFilter( } } - if http2 { + if opts.protocol == "http2" || opts.protocol == "grpc" { cfg.Http2ProtocolOptions = &envoycore.Http2ProtocolOptions{} } @@ -1229,11 +1226,11 @@ func makeHTTPFilter( // (other than the "envoy.grpc_http1_bridge" filter) in the http filter // chain of a public listener is the authz filter to prevent unauthorized // access and that every filter chain uses our TLS certs. - if authzFilter != nil { - cfg.HttpFilters = append([]*envoyhttp.HttpFilter{authzFilter}, cfg.HttpFilters...) + if opts.httpAuthzFilter != nil { + cfg.HttpFilters = append([]*envoyhttp.HttpFilter{opts.httpAuthzFilter}, cfg.HttpFilters...) } - if grpc { + if opts.protocol == "grpc" { // Add grpc bridge before router and authz cfg.HttpFilters = append([]*envoyhttp.HttpFilter{{ Name: "envoy.grpc_http1_bridge", diff --git a/agent/xds/testdata/listeners/terminating-gateway-service-subsets.envoy-1-12-x.golden b/agent/xds/testdata/listeners/terminating-gateway-service-subsets.envoy-1-12-x.golden index c6ab6ce7c..9947e4838 100644 --- a/agent/xds/testdata/listeners/terminating-gateway-service-subsets.envoy-1-12-x.golden +++ b/agent/xds/testdata/listeners/terminating-gateway-service-subsets.envoy-1-12-x.golden @@ -202,7 +202,7 @@ "ads": { } }, - "route_config_name": "default" + "route_config_name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" }, "stat_prefix": "terminating_gateway_default_web_default_http", "tracing": { @@ -264,7 +264,7 @@ "ads": { } }, - "route_config_name": "default" + "route_config_name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" }, "stat_prefix": "terminating_gateway_default_web_default_http", "tracing": { @@ -326,7 +326,7 @@ "ads": { } }, - "route_config_name": "default" + "route_config_name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" }, "stat_prefix": "terminating_gateway_default_web_default_http", "tracing": { diff --git a/agent/xds/testdata/listeners/terminating-gateway-service-subsets.envoy-1-13-x.golden b/agent/xds/testdata/listeners/terminating-gateway-service-subsets.envoy-1-13-x.golden index c6ab6ce7c..9947e4838 100644 --- a/agent/xds/testdata/listeners/terminating-gateway-service-subsets.envoy-1-13-x.golden +++ b/agent/xds/testdata/listeners/terminating-gateway-service-subsets.envoy-1-13-x.golden @@ -202,7 +202,7 @@ "ads": { } }, - "route_config_name": "default" + "route_config_name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" }, "stat_prefix": "terminating_gateway_default_web_default_http", "tracing": { @@ -264,7 +264,7 @@ "ads": { } }, - "route_config_name": "default" + "route_config_name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" }, "stat_prefix": "terminating_gateway_default_web_default_http", "tracing": { @@ -326,7 +326,7 @@ "ads": { } }, - "route_config_name": "default" + "route_config_name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" }, "stat_prefix": "terminating_gateway_default_web_default_http", "tracing": { diff --git a/agent/xds/testdata/listeners/terminating-gateway-service-subsets.envoy-1-14-x.golden b/agent/xds/testdata/listeners/terminating-gateway-service-subsets.envoy-1-14-x.golden index c6ab6ce7c..9947e4838 100644 --- a/agent/xds/testdata/listeners/terminating-gateway-service-subsets.envoy-1-14-x.golden +++ b/agent/xds/testdata/listeners/terminating-gateway-service-subsets.envoy-1-14-x.golden @@ -202,7 +202,7 @@ "ads": { } }, - "route_config_name": "default" + "route_config_name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" }, "stat_prefix": "terminating_gateway_default_web_default_http", "tracing": { @@ -264,7 +264,7 @@ "ads": { } }, - "route_config_name": "default" + "route_config_name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" }, "stat_prefix": "terminating_gateway_default_web_default_http", "tracing": { @@ -326,7 +326,7 @@ "ads": { } }, - "route_config_name": "default" + "route_config_name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" }, "stat_prefix": "terminating_gateway_default_web_default_http", "tracing": { diff --git a/agent/xds/testdata/listeners/terminating-gateway-service-subsets.envoy-1-15-x.golden b/agent/xds/testdata/listeners/terminating-gateway-service-subsets.envoy-1-15-x.golden index c6ab6ce7c..9947e4838 100644 --- a/agent/xds/testdata/listeners/terminating-gateway-service-subsets.envoy-1-15-x.golden +++ b/agent/xds/testdata/listeners/terminating-gateway-service-subsets.envoy-1-15-x.golden @@ -202,7 +202,7 @@ "ads": { } }, - "route_config_name": "default" + "route_config_name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" }, "stat_prefix": "terminating_gateway_default_web_default_http", "tracing": { @@ -264,7 +264,7 @@ "ads": { } }, - "route_config_name": "default" + "route_config_name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" }, "stat_prefix": "terminating_gateway_default_web_default_http", "tracing": { @@ -326,7 +326,7 @@ "ads": { } }, - "route_config_name": "default" + "route_config_name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" }, "stat_prefix": "terminating_gateway_default_web_default_http", "tracing": { From 5871b667a5c60f9b829a3ebf185c4deced3e4f27 Mon Sep 17 00:00:00 2001 From: freddygv Date: Fri, 11 Sep 2020 09:21:43 -0600 Subject: [PATCH 17/20] Revert EnvoyConfig nesting --- agent/consul/discoverychain/compile.go | 2 +- agent/consul/discoverychain/compile_test.go | 184 ++++++------ agent/proxycfg/testing.go | 36 ++- agent/structs/config_entry_discoverychain.go | 36 +-- .../config_entry_discoverychain_test.go | 176 +++++------- agent/xds/clusters.go | 12 +- agent/xds/clusters_test.go | 42 ++- agent/xds/routes.go | 22 +- agent/xds/routes_test.go | 50 ++-- api/config_entry_discoverychain.go | 8 - api/config_entry_discoverychain_test.go | 46 ++- command/config/write/config_write_test.go | 266 ++++++++---------- 12 files changed, 388 insertions(+), 492 deletions(-) diff --git a/agent/consul/discoverychain/compile.go b/agent/consul/discoverychain/compile.go index 2acbde76f..d305e5da4 100644 --- a/agent/consul/discoverychain/compile.go +++ b/agent/consul/discoverychain/compile.go @@ -746,7 +746,7 @@ func (c *compiler) getSplitterNode(sid structs.ServiceID) (*structs.DiscoveryGra // We cannot apply multiple hash policies to a splitter node's route action. // Therefore, we attach the first hash-based load balancer config we encounter. if !hasLB { - if lb := node.LoadBalancer; lb != nil && lb.EnvoyConfig != nil && lb.EnvoyConfig.IsHashBased() { + if lb := node.LoadBalancer; lb != nil && lb.IsHashBased() { splitNode.LoadBalancer = node.LoadBalancer hasLB = true } diff --git a/agent/consul/discoverychain/compile_test.go b/agent/consul/discoverychain/compile_test.go index 1d5c3e582..4f13f2d55 100644 --- a/agent/consul/discoverychain/compile_test.go +++ b/agent/consul/discoverychain/compile_test.go @@ -1763,15 +1763,13 @@ func testcase_AllBellsAndWhistles() compileTestCase { "qa": {Filter: "ServiceMeta.env == qa"}, }, LoadBalancer: &structs.LoadBalancer{ - EnvoyConfig: &structs.EnvoyLBConfig{ - Policy: "ring_hash", - RingHashConfig: &structs.RingHashConfig{ - MaximumRingSize: 100, - }, - HashPolicies: []structs.HashPolicy{ - { - SourceIP: true, - }, + Policy: "ring_hash", + RingHashConfig: &structs.RingHashConfig{ + MaximumRingSize: 100, + }, + HashPolicies: []structs.HashPolicy{ + { + SourceIP: true, }, }, }, @@ -1837,15 +1835,13 @@ func testcase_AllBellsAndWhistles() compileTestCase { }, }, LoadBalancer: &structs.LoadBalancer{ - EnvoyConfig: &structs.EnvoyLBConfig{ - Policy: "ring_hash", - RingHashConfig: &structs.RingHashConfig{ - MaximumRingSize: 100, - }, - HashPolicies: []structs.HashPolicy{ - { - SourceIP: true, - }, + Policy: "ring_hash", + RingHashConfig: &structs.RingHashConfig{ + MaximumRingSize: 100, + }, + HashPolicies: []structs.HashPolicy{ + { + SourceIP: true, }, }, }, @@ -1858,15 +1854,13 @@ func testcase_AllBellsAndWhistles() compileTestCase { Target: "prod.redirected.default.dc1", }, LoadBalancer: &structs.LoadBalancer{ - EnvoyConfig: &structs.EnvoyLBConfig{ - Policy: "ring_hash", - RingHashConfig: &structs.RingHashConfig{ - MaximumRingSize: 100, - }, - HashPolicies: []structs.HashPolicy{ - { - SourceIP: true, - }, + Policy: "ring_hash", + RingHashConfig: &structs.RingHashConfig{ + MaximumRingSize: 100, + }, + HashPolicies: []structs.HashPolicy{ + { + SourceIP: true, }, }, }, @@ -2283,11 +2277,9 @@ func testcase_LBSplitterAndResolver() compileTestCase { Kind: "service-resolver", Name: "foo", LoadBalancer: &structs.LoadBalancer{ - EnvoyConfig: &structs.EnvoyLBConfig{ - Policy: "least_request", - LeastRequestConfig: &structs.LeastRequestConfig{ - ChoiceCount: 3, - }, + Policy: "least_request", + LeastRequestConfig: &structs.LeastRequestConfig{ + ChoiceCount: 3, }, }, }, @@ -2295,15 +2287,13 @@ func testcase_LBSplitterAndResolver() compileTestCase { Kind: "service-resolver", Name: "bar", LoadBalancer: &structs.LoadBalancer{ - EnvoyConfig: &structs.EnvoyLBConfig{ - Policy: "ring_hash", - RingHashConfig: &structs.RingHashConfig{ - MaximumRingSize: 101, - }, - HashPolicies: []structs.HashPolicy{ - { - SourceIP: true, - }, + Policy: "ring_hash", + RingHashConfig: &structs.RingHashConfig{ + MaximumRingSize: 101, + }, + HashPolicies: []structs.HashPolicy{ + { + SourceIP: true, }, }, }, @@ -2312,18 +2302,16 @@ func testcase_LBSplitterAndResolver() compileTestCase { Kind: "service-resolver", Name: "baz", LoadBalancer: &structs.LoadBalancer{ - EnvoyConfig: &structs.EnvoyLBConfig{ - Policy: "maglev", - HashPolicies: []structs.HashPolicy{ - { - Field: "cookie", - FieldValue: "chocolate-chip", - CookieConfig: &structs.CookieConfig{ - TTL: 2 * time.Minute, - Path: "/bowl", - }, - Terminal: true, + Policy: "maglev", + HashPolicies: []structs.HashPolicy{ + { + Field: "cookie", + FieldValue: "chocolate-chip", + CookieConfig: &structs.CookieConfig{ + TTL: 2 * time.Minute, + Path: "/bowl", }, + Terminal: true, }, }, }, @@ -2354,15 +2342,13 @@ func testcase_LBSplitterAndResolver() compileTestCase { // The LB config from bar is attached because splitters only care about hash-based policies, // and it's the config from bar not baz because we pick the first one we encounter in the Splits. LoadBalancer: &structs.LoadBalancer{ - EnvoyConfig: &structs.EnvoyLBConfig{ - Policy: "ring_hash", - RingHashConfig: &structs.RingHashConfig{ - MaximumRingSize: 101, - }, - HashPolicies: []structs.HashPolicy{ - { - SourceIP: true, - }, + Policy: "ring_hash", + RingHashConfig: &structs.RingHashConfig{ + MaximumRingSize: 101, + }, + HashPolicies: []structs.HashPolicy{ + { + SourceIP: true, }, }, }, @@ -2377,11 +2363,9 @@ func testcase_LBSplitterAndResolver() compileTestCase { Target: "foo.default.dc1", }, LoadBalancer: &structs.LoadBalancer{ - EnvoyConfig: &structs.EnvoyLBConfig{ - Policy: "least_request", - LeastRequestConfig: &structs.LeastRequestConfig{ - ChoiceCount: 3, - }, + Policy: "least_request", + LeastRequestConfig: &structs.LeastRequestConfig{ + ChoiceCount: 3, }, }, }, @@ -2394,15 +2378,13 @@ func testcase_LBSplitterAndResolver() compileTestCase { Target: "bar.default.dc1", }, LoadBalancer: &structs.LoadBalancer{ - EnvoyConfig: &structs.EnvoyLBConfig{ - Policy: "ring_hash", - RingHashConfig: &structs.RingHashConfig{ - MaximumRingSize: 101, - }, - HashPolicies: []structs.HashPolicy{ - { - SourceIP: true, - }, + Policy: "ring_hash", + RingHashConfig: &structs.RingHashConfig{ + MaximumRingSize: 101, + }, + HashPolicies: []structs.HashPolicy{ + { + SourceIP: true, }, }, }, @@ -2416,18 +2398,16 @@ func testcase_LBSplitterAndResolver() compileTestCase { Target: "baz.default.dc1", }, LoadBalancer: &structs.LoadBalancer{ - EnvoyConfig: &structs.EnvoyLBConfig{ - Policy: "maglev", - HashPolicies: []structs.HashPolicy{ - { - Field: "cookie", - FieldValue: "chocolate-chip", - CookieConfig: &structs.CookieConfig{ - TTL: 2 * time.Minute, - Path: "/bowl", - }, - Terminal: true, + Policy: "maglev", + HashPolicies: []structs.HashPolicy{ + { + Field: "cookie", + FieldValue: "chocolate-chip", + CookieConfig: &structs.CookieConfig{ + TTL: 2 * time.Minute, + Path: "/bowl", }, + Terminal: true, }, }, }, @@ -2453,15 +2433,13 @@ func testcase_LBResolver() compileTestCase { Kind: "service-resolver", Name: "main", LoadBalancer: &structs.LoadBalancer{ - EnvoyConfig: &structs.EnvoyLBConfig{ - Policy: "ring_hash", - RingHashConfig: &structs.RingHashConfig{ - MaximumRingSize: 101, - }, - HashPolicies: []structs.HashPolicy{ - { - SourceIP: true, - }, + Policy: "ring_hash", + RingHashConfig: &structs.RingHashConfig{ + MaximumRingSize: 101, + }, + HashPolicies: []structs.HashPolicy{ + { + SourceIP: true, }, }, }, @@ -2481,15 +2459,13 @@ func testcase_LBResolver() compileTestCase { Target: "main.default.dc1", }, LoadBalancer: &structs.LoadBalancer{ - EnvoyConfig: &structs.EnvoyLBConfig{ - Policy: "ring_hash", - RingHashConfig: &structs.RingHashConfig{ - MaximumRingSize: 101, - }, - HashPolicies: []structs.HashPolicy{ - { - SourceIP: true, - }, + Policy: "ring_hash", + RingHashConfig: &structs.RingHashConfig{ + MaximumRingSize: 101, + }, + HashPolicies: []structs.HashPolicy{ + { + SourceIP: true, }, }, }, diff --git a/agent/proxycfg/testing.go b/agent/proxycfg/testing.go index 3dd4b6bd3..0514b8984 100644 --- a/agent/proxycfg/testing.go +++ b/agent/proxycfg/testing.go @@ -1275,26 +1275,24 @@ func setupTestVariationConfigEntriesAndSnapshot( Kind: structs.ServiceResolver, Name: "db", LoadBalancer: &structs.LoadBalancer{ - EnvoyConfig: &structs.EnvoyLBConfig{ - Policy: "ring_hash", - RingHashConfig: &structs.RingHashConfig{ - MinimumRingSize: 20, - MaximumRingSize: 30, + Policy: "ring_hash", + RingHashConfig: &structs.RingHashConfig{ + MinimumRingSize: 20, + MaximumRingSize: 30, + }, + HashPolicies: []structs.HashPolicy{ + { + Field: "cookie", + FieldValue: "chocolate-chip", + Terminal: true, }, - HashPolicies: []structs.HashPolicy{ - { - Field: "cookie", - FieldValue: "chocolate-chip", - Terminal: true, - }, - { - Field: "header", - FieldValue: "x-user-id", - }, - { - SourceIP: true, - Terminal: true, - }, + { + Field: "header", + FieldValue: "x-user-id", + }, + { + SourceIP: true, + Terminal: true, }, }, }, diff --git a/agent/structs/config_entry_discoverychain.go b/agent/structs/config_entry_discoverychain.go index 96ef3b3a2..b977f8987 100644 --- a/agent/structs/config_entry_discoverychain.go +++ b/agent/structs/config_entry_discoverychain.go @@ -843,27 +843,27 @@ func (e *ServiceResolverConfigEntry) Validate() error { return fmt.Errorf("Bad ConnectTimeout '%s', must be >= 0", e.ConnectTimeout) } - if e.LoadBalancer != nil && e.LoadBalancer.EnvoyConfig != nil { - ec := e.LoadBalancer.EnvoyConfig + if e.LoadBalancer != nil { + lb := e.LoadBalancer - if ok := validLBPolicies[ec.Policy]; !ok { - return fmt.Errorf("Bad LoadBalancer policy: %q is not supported", ec.Policy) + if ok := validLBPolicies[lb.Policy]; !ok { + return fmt.Errorf("Bad LoadBalancer policy: %q is not supported", lb.Policy) } - if ec.Policy != LBPolicyRingHash && ec.RingHashConfig != nil { + if lb.Policy != LBPolicyRingHash && lb.RingHashConfig != nil { return fmt.Errorf("Bad LoadBalancer configuration. "+ - "RingHashConfig specified for incompatible load balancing policy %q", ec.Policy) + "RingHashConfig specified for incompatible load balancing policy %q", lb.Policy) } - if ec.Policy != LBPolicyLeastRequest && ec.LeastRequestConfig != nil { + if lb.Policy != LBPolicyLeastRequest && lb.LeastRequestConfig != nil { return fmt.Errorf("Bad LoadBalancer configuration. "+ - "LeastRequestConfig specified for incompatible load balancing policy %q", ec.Policy) + "LeastRequestConfig specified for incompatible load balancing policy %q", lb.Policy) } - if !ec.IsHashBased() && len(ec.HashPolicies) > 0 { + if !lb.IsHashBased() && len(lb.HashPolicies) > 0 { return fmt.Errorf("Bad LoadBalancer configuration: "+ - "HashPolicies specified for non-hash-based Policy: %q", ec.Policy) + "HashPolicies specified for non-hash-based Policy: %q", lb.Policy) } - for i, hp := range ec.HashPolicies { + for i, hp := range lb.HashPolicies { if ok := validHashPolicies[hp.Field]; hp.Field != "" && !ok { return fmt.Errorf("Bad LoadBalancer HashPolicy[%d]: %q is not a supported field", i, hp.Field) } @@ -1027,14 +1027,6 @@ type ServiceResolverFailover struct { // LoadBalancer determines the load balancing policy and configuration for services // issuing requests to this upstream service. type LoadBalancer struct { - // EnvoyConfig contains Envoy-specific load balancing configuration for this upstream - EnvoyConfig *EnvoyLBConfig `json:",omitempty" alias:"envoy_config"` - - // OpaqueConfig contains load balancing configuration opaque to Consul for 3rd party proxies - OpaqueConfig string `json:",omitempty" alias:"opaque_config"` -} - -type EnvoyLBConfig struct { // Policy is the load balancing policy used to select a host Policy string `json:",omitempty"` @@ -1102,12 +1094,12 @@ type CookieConfig struct { Path string `json:",omitempty"` } -func (ec *EnvoyLBConfig) IsHashBased() bool { - if ec == nil { +func (lb *LoadBalancer) IsHashBased() bool { + if lb == nil { return false } - switch ec.Policy { + switch lb.Policy { case LBPolicyMaglev, LBPolicyRingHash: return true default: diff --git a/agent/structs/config_entry_discoverychain_test.go b/agent/structs/config_entry_discoverychain_test.go index 2f5c431ca..3e5d99f9e 100644 --- a/agent/structs/config_entry_discoverychain_test.go +++ b/agent/structs/config_entry_discoverychain_test.go @@ -555,7 +555,7 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { Kind: ServiceResolver, Name: "test", LoadBalancer: &LoadBalancer{ - EnvoyConfig: &EnvoyLBConfig{Policy: ""}, + Policy: "", }, }, }, @@ -565,7 +565,7 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { Kind: ServiceResolver, Name: "test", LoadBalancer: &LoadBalancer{ - EnvoyConfig: &EnvoyLBConfig{Policy: LBPolicyRandom}, + Policy: LBPolicyRandom, }, }, }, @@ -575,7 +575,7 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { Kind: ServiceResolver, Name: "test", LoadBalancer: &LoadBalancer{ - EnvoyConfig: &EnvoyLBConfig{Policy: "fake-policy"}, + Policy: "fake-policy", }, }, validateErr: `"fake-policy" is not supported`, @@ -586,10 +586,8 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { Kind: ServiceResolver, Name: "test", LoadBalancer: &LoadBalancer{ - EnvoyConfig: &EnvoyLBConfig{ - Policy: LBPolicyRingHash, - LeastRequestConfig: &LeastRequestConfig{ChoiceCount: 10}, - }, + Policy: LBPolicyRingHash, + LeastRequestConfig: &LeastRequestConfig{ChoiceCount: 10}, }, }, validateErr: `LeastRequestConfig specified for incompatible load balancing policy`, @@ -600,10 +598,8 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { Kind: ServiceResolver, Name: "test", LoadBalancer: &LoadBalancer{ - EnvoyConfig: &EnvoyLBConfig{ - Policy: LBPolicyLeastRequest, - RingHashConfig: &RingHashConfig{MinimumRingSize: 1024}, - }, + Policy: LBPolicyLeastRequest, + RingHashConfig: &RingHashConfig{MinimumRingSize: 1024}, }, }, validateErr: `RingHashConfig specified for incompatible load balancing policy`, @@ -614,10 +610,8 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { Kind: ServiceResolver, Name: "test", LoadBalancer: &LoadBalancer{ - EnvoyConfig: &EnvoyLBConfig{ - Policy: LBPolicyRingHash, - RingHashConfig: &RingHashConfig{MinimumRingSize: 1024}, - }, + Policy: LBPolicyRingHash, + RingHashConfig: &RingHashConfig{MinimumRingSize: 1024}, }, }, }, @@ -627,10 +621,8 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { Kind: ServiceResolver, Name: "test", LoadBalancer: &LoadBalancer{ - EnvoyConfig: &EnvoyLBConfig{ - Policy: LBPolicyLeastRequest, - LeastRequestConfig: &LeastRequestConfig{ChoiceCount: 2}, - }, + Policy: LBPolicyLeastRequest, + LeastRequestConfig: &LeastRequestConfig{ChoiceCount: 2}, }, }, }, @@ -640,11 +632,11 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { Kind: ServiceResolver, Name: "test", LoadBalancer: &LoadBalancer{ - EnvoyConfig: &EnvoyLBConfig{Policy: ""}, + Policy: "", }, }, check: func(t *testing.T, entry *ServiceResolverConfigEntry) { - require.Equal(t, "", entry.LoadBalancer.EnvoyConfig.Policy) + require.Equal(t, "", entry.LoadBalancer.Policy) }, }, { @@ -653,12 +645,10 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { Kind: ServiceResolver, Name: "test", LoadBalancer: &LoadBalancer{ - EnvoyConfig: &EnvoyLBConfig{ - Policy: "", - HashPolicies: []HashPolicy{ - { - SourceIP: true, - }, + Policy: "", + HashPolicies: []HashPolicy{ + { + SourceIP: true, }, }, }, @@ -671,16 +661,14 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { Kind: ServiceResolver, Name: "test", LoadBalancer: &LoadBalancer{ - EnvoyConfig: &EnvoyLBConfig{ - Policy: LBPolicyMaglev, - HashPolicies: []HashPolicy{ - { - Field: HashPolicyHeader, - FieldValue: "x-user-id", - CookieConfig: &CookieConfig{ - TTL: 10 * time.Second, - Path: "/root", - }, + Policy: LBPolicyMaglev, + HashPolicies: []HashPolicy{ + { + Field: HashPolicyHeader, + FieldValue: "x-user-id", + CookieConfig: &CookieConfig{ + TTL: 10 * time.Second, + Path: "/root", }, }, }, @@ -694,16 +682,14 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { Kind: ServiceResolver, Name: "test", LoadBalancer: &LoadBalancer{ - EnvoyConfig: &EnvoyLBConfig{ - Policy: LBPolicyMaglev, - HashPolicies: []HashPolicy{ - { - Field: HashPolicyCookie, - FieldValue: "good-cookie", - CookieConfig: &CookieConfig{ - TTL: 10 * time.Second, - Path: "/oven", - }, + Policy: LBPolicyMaglev, + HashPolicies: []HashPolicy{ + { + Field: HashPolicyCookie, + FieldValue: "good-cookie", + CookieConfig: &CookieConfig{ + TTL: 10 * time.Second, + Path: "/oven", }, }, }, @@ -716,13 +702,11 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { Kind: ServiceResolver, Name: "test", LoadBalancer: &LoadBalancer{ - EnvoyConfig: &EnvoyLBConfig{ - Policy: LBPolicyMaglev, - HashPolicies: []HashPolicy{ - { - Field: "header", - FieldValue: "X-Consul-Token", - }, + Policy: LBPolicyMaglev, + HashPolicies: []HashPolicy{ + { + Field: "header", + FieldValue: "X-Consul-Token", }, }, }, @@ -734,12 +718,10 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { Kind: ServiceResolver, Name: "test", LoadBalancer: &LoadBalancer{ - EnvoyConfig: &EnvoyLBConfig{ - Policy: LBPolicyMaglev, - HashPolicies: []HashPolicy{ - { - Field: "fake-field", - }, + Policy: LBPolicyMaglev, + HashPolicies: []HashPolicy{ + { + Field: "fake-field", }, }, }, @@ -752,13 +734,11 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { Kind: ServiceResolver, Name: "test", LoadBalancer: &LoadBalancer{ - EnvoyConfig: &EnvoyLBConfig{ - Policy: LBPolicyMaglev, - HashPolicies: []HashPolicy{ - { - Field: "header", - SourceIP: true, - }, + Policy: LBPolicyMaglev, + HashPolicies: []HashPolicy{ + { + Field: "header", + SourceIP: true, }, }, }, @@ -771,13 +751,11 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { Kind: ServiceResolver, Name: "test", LoadBalancer: &LoadBalancer{ - EnvoyConfig: &EnvoyLBConfig{ - Policy: LBPolicyMaglev, - HashPolicies: []HashPolicy{ - { - FieldValue: "X-Consul-Token", - SourceIP: true, - }, + Policy: LBPolicyMaglev, + HashPolicies: []HashPolicy{ + { + FieldValue: "X-Consul-Token", + SourceIP: true, }, }, }, @@ -790,12 +768,10 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { Kind: ServiceResolver, Name: "test", LoadBalancer: &LoadBalancer{ - EnvoyConfig: &EnvoyLBConfig{ - Policy: LBPolicyMaglev, - HashPolicies: []HashPolicy{ - { - Field: "header", - }, + Policy: LBPolicyMaglev, + HashPolicies: []HashPolicy{ + { + Field: "header", }, }, }, @@ -808,12 +784,10 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { Kind: ServiceResolver, Name: "test", LoadBalancer: &LoadBalancer{ - EnvoyConfig: &EnvoyLBConfig{ - Policy: LBPolicyMaglev, - HashPolicies: []HashPolicy{ - { - FieldValue: "my-cookie", - }, + Policy: LBPolicyMaglev, + HashPolicies: []HashPolicy{ + { + FieldValue: "my-cookie", }, }, }, @@ -826,19 +800,17 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { Kind: ServiceResolver, Name: "test", LoadBalancer: &LoadBalancer{ - EnvoyConfig: &EnvoyLBConfig{ - Policy: LBPolicyRingHash, - RingHashConfig: &RingHashConfig{MaximumRingSize: 10, MinimumRingSize: 2}, - HashPolicies: []HashPolicy{ - { - Field: "cookie", - FieldValue: "my-cookie", - }, - { - Field: "header", - FieldValue: "alt-header", - Terminal: true, - }, + Policy: LBPolicyRingHash, + RingHashConfig: &RingHashConfig{MaximumRingSize: 10, MinimumRingSize: 2}, + HashPolicies: []HashPolicy{ + { + Field: "cookie", + FieldValue: "my-cookie", + }, + { + Field: "header", + FieldValue: "alt-header", + Terminal: true, }, }, }, @@ -850,10 +822,8 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { Kind: ServiceResolver, Name: "test", LoadBalancer: &LoadBalancer{ - EnvoyConfig: &EnvoyLBConfig{ - Policy: LBPolicyLeastRequest, - LeastRequestConfig: &LeastRequestConfig{ChoiceCount: 20}, - }, + Policy: LBPolicyLeastRequest, + LeastRequestConfig: &LeastRequestConfig{ChoiceCount: 20}, }, }, }, diff --git a/agent/xds/clusters.go b/agent/xds/clusters.go index 8491ab088..9f2831b64 100644 --- a/agent/xds/clusters.go +++ b/agent/xds/clusters.go @@ -206,14 +206,14 @@ func (s *Server) makeGatewayServiceClusters(cfgSnap *proxycfg.ConfigSnapshot) ([ clusterName := connect.ServiceSNI(svc.Name, "", svc.NamespaceOrDefault(), cfgSnap.Datacenter, cfgSnap.Roots.TrustDomain) resolver, hasResolver := resolvers[svc] - var loadBalancer *structs.EnvoyLBConfig + var loadBalancer *structs.LoadBalancer if !hasResolver { // Use a zero value resolver with no timeout and no subsets resolver = &structs.ServiceResolverConfigEntry{} } if resolver.LoadBalancer != nil { - loadBalancer = resolver.LoadBalancer.EnvoyConfig + loadBalancer = resolver.LoadBalancer } // When making service clusters we only pass endpoints with hostnames if the kind is a terminating gateway @@ -514,9 +514,9 @@ func (s *Server) makeUpstreamClustersForDiscoveryChain( OutlierDetection: cfg.PassiveHealthCheck.AsOutlierDetection(), } - var lb *structs.EnvoyLBConfig + var lb *structs.LoadBalancer if node.LoadBalancer != nil { - lb = node.LoadBalancer.EnvoyConfig + lb = node.LoadBalancer } if err := injectLBToCluster(lb, c); err != nil { return nil, fmt.Errorf("failed to apply load balancer configuration to cluster %q: %v", clusterName, err) @@ -595,7 +595,7 @@ func makeClusterFromUserConfig(configJSON string) (*envoy.Cluster, error) { return &c, err } - // No @type so try decoding as a straight listener. + // No @type so try decoding as a straight cluster. err := jsonpb.UnmarshalString(configJSON, &c) return &c, err } @@ -783,7 +783,7 @@ func makeLbEndpoint(addr string, port int, health envoycore.HealthStatus, weight } } -func injectLBToCluster(ec *structs.EnvoyLBConfig, c *envoy.Cluster) error { +func injectLBToCluster(ec *structs.LoadBalancer, c *envoy.Cluster) error { if ec == nil { return nil } diff --git a/agent/xds/clusters_test.go b/agent/xds/clusters_test.go index 024a4511b..f81430ab9 100644 --- a/agent/xds/clusters_test.go +++ b/agent/xds/clusters_test.go @@ -368,11 +368,9 @@ func TestClustersFromSnapshot(t *testing.T) { }, }, LoadBalancer: &structs.LoadBalancer{ - EnvoyConfig: &structs.EnvoyLBConfig{ - Policy: "least_request", - LeastRequestConfig: &structs.LeastRequestConfig{ - ChoiceCount: 5, - }, + Policy: "least_request", + LeastRequestConfig: &structs.LeastRequestConfig{ + ChoiceCount: 5, }, }, }, @@ -397,12 +395,10 @@ func TestClustersFromSnapshot(t *testing.T) { }, }, LoadBalancer: &structs.LoadBalancer{ - EnvoyConfig: &structs.EnvoyLBConfig{ - Policy: "ring_hash", - RingHashConfig: &structs.RingHashConfig{ - MinimumRingSize: 20, - MaximumRingSize: 50, - }, + Policy: "ring_hash", + RingHashConfig: &structs.RingHashConfig{ + MinimumRingSize: 20, + MaximumRingSize: 50, }, }, }, @@ -625,12 +621,10 @@ func TestClustersFromSnapshot(t *testing.T) { }, }, LoadBalancer: &structs.LoadBalancer{ - EnvoyConfig: &structs.EnvoyLBConfig{ - Policy: "ring_hash", - RingHashConfig: &structs.RingHashConfig{ - MinimumRingSize: 20, - MaximumRingSize: 50, - }, + Policy: "ring_hash", + RingHashConfig: &structs.RingHashConfig{ + MinimumRingSize: 20, + MaximumRingSize: 50, }, }, }, @@ -862,40 +856,40 @@ func setupTLSRootsAndLeaf(t *testing.T, snap *proxycfg.ConfigSnapshot) { func TestEnvoyLBConfig_InjectToCluster(t *testing.T) { var tests = []struct { name string - lb *structs.EnvoyLBConfig + lb *structs.LoadBalancer expected envoy.Cluster }{ { name: "skip empty", - lb: &structs.EnvoyLBConfig{ + lb: &structs.LoadBalancer{ Policy: "", }, expected: envoy.Cluster{}, }, { name: "round robin", - lb: &structs.EnvoyLBConfig{ + lb: &structs.LoadBalancer{ Policy: structs.LBPolicyRoundRobin, }, expected: envoy.Cluster{LbPolicy: envoy.Cluster_ROUND_ROBIN}, }, { name: "random", - lb: &structs.EnvoyLBConfig{ + lb: &structs.LoadBalancer{ Policy: structs.LBPolicyRandom, }, expected: envoy.Cluster{LbPolicy: envoy.Cluster_RANDOM}, }, { name: "maglev", - lb: &structs.EnvoyLBConfig{ + lb: &structs.LoadBalancer{ Policy: structs.LBPolicyMaglev, }, expected: envoy.Cluster{LbPolicy: envoy.Cluster_MAGLEV}, }, { name: "ring_hash", - lb: &structs.EnvoyLBConfig{ + lb: &structs.LoadBalancer{ Policy: structs.LBPolicyRingHash, RingHashConfig: &structs.RingHashConfig{ MinimumRingSize: 3, @@ -914,7 +908,7 @@ func TestEnvoyLBConfig_InjectToCluster(t *testing.T) { }, { name: "least_request", - lb: &structs.EnvoyLBConfig{ + lb: &structs.LoadBalancer{ Policy: "least_request", LeastRequestConfig: &structs.LeastRequestConfig{ ChoiceCount: 3, diff --git a/agent/xds/routes.go b/agent/xds/routes.go index 3c3e79222..b31e1fcfc 100644 --- a/agent/xds/routes.go +++ b/agent/xds/routes.go @@ -65,9 +65,9 @@ func (s *Server) routesFromSnapshotTerminatingGateway(_ connectionInfo, cfgSnap resolver = &structs.ServiceResolverConfigEntry{} } - var lb *structs.EnvoyLBConfig + var lb *structs.LoadBalancer if resolver.LoadBalancer != nil { - lb = resolver.LoadBalancer.EnvoyConfig + lb = resolver.LoadBalancer } route, err := makeNamedDefaultRouteWithLB(clusterName, lb) if err != nil { @@ -91,7 +91,7 @@ func (s *Server) routesFromSnapshotTerminatingGateway(_ connectionInfo, cfgSnap return resources, nil } -func makeNamedDefaultRouteWithLB(clusterName string, lb *structs.EnvoyLBConfig) (*envoy.RouteConfiguration, error) { +func makeNamedDefaultRouteWithLB(clusterName string, lb *structs.LoadBalancer) (*envoy.RouteConfiguration, error) { action := makeRouteActionFromName(clusterName) if err := injectLBToRouteAction(lb, action.Route); err != nil { @@ -262,7 +262,7 @@ func makeUpstreamRouteForDiscoveryChain( return nil, fmt.Errorf("missing first node in compiled discovery chain for: %s", chain.ServiceName) } - var lb *structs.EnvoyLBConfig + var lb *structs.LoadBalancer switch startNode.Type { case structs.DiscoveryGraphNodeTypeRouter: @@ -278,7 +278,7 @@ func makeUpstreamRouteForDiscoveryChain( nextNode := chain.Nodes[discoveryRoute.NextNode] if nextNode.LoadBalancer != nil { - lb = nextNode.LoadBalancer.EnvoyConfig + lb = nextNode.LoadBalancer } switch nextNode.Type { @@ -351,7 +351,7 @@ func makeUpstreamRouteForDiscoveryChain( } if startNode.LoadBalancer != nil { - lb = startNode.LoadBalancer.EnvoyConfig + lb = startNode.LoadBalancer } if err := injectLBToRouteAction(lb, routeAction.Route); err != nil { return nil, fmt.Errorf("failed to apply load balancer configuration to route action: %v", err) @@ -368,7 +368,7 @@ func makeUpstreamRouteForDiscoveryChain( routeAction := makeRouteActionForChainCluster(startNode.Resolver.Target, chain) if startNode.LoadBalancer != nil { - lb = startNode.LoadBalancer.EnvoyConfig + lb = startNode.LoadBalancer } if err := injectLBToRouteAction(lb, routeAction.Route); err != nil { return nil, fmt.Errorf("failed to apply load balancer configuration to route action: %v", err) @@ -577,13 +577,13 @@ func makeRouteActionForSplitter(splits []*structs.DiscoverySplit, chain *structs }, nil } -func injectLBToRouteAction(ec *structs.EnvoyLBConfig, action *envoyroute.RouteAction) error { - if ec == nil || !ec.IsHashBased() { +func injectLBToRouteAction(lb *structs.LoadBalancer, action *envoyroute.RouteAction) error { + if lb == nil || !lb.IsHashBased() { return nil } - result := make([]*envoyroute.RouteAction_HashPolicy, 0, len(ec.HashPolicies)) - for _, policy := range ec.HashPolicies { + result := make([]*envoyroute.RouteAction_HashPolicy, 0, len(lb.HashPolicies)) + for _, policy := range lb.HashPolicies { if policy.SourceIP { result = append(result, &envoyroute.RouteAction_HashPolicy{ PolicySpecifier: &envoyroute.RouteAction_HashPolicy_ConnectionProperties_{ diff --git a/agent/xds/routes_test.go b/agent/xds/routes_test.go index 600d8ee6d..43d2857ae 100644 --- a/agent/xds/routes_test.go +++ b/agent/xds/routes_test.go @@ -206,26 +206,24 @@ func TestRoutesFromSnapshot(t *testing.T) { }, }, LoadBalancer: &structs.LoadBalancer{ - EnvoyConfig: &structs.EnvoyLBConfig{ - Policy: "ring_hash", - RingHashConfig: &structs.RingHashConfig{ - MinimumRingSize: 20, - MaximumRingSize: 50, + Policy: "ring_hash", + RingHashConfig: &structs.RingHashConfig{ + MinimumRingSize: 20, + MaximumRingSize: 50, + }, + HashPolicies: []structs.HashPolicy{ + { + Field: structs.HashPolicyCookie, + FieldValue: "chocolate-chip", + Terminal: true, }, - HashPolicies: []structs.HashPolicy{ - { - Field: structs.HashPolicyCookie, - FieldValue: "chocolate-chip", - Terminal: true, - }, - { - Field: structs.HashPolicyHeader, - FieldValue: "x-user-id", - }, - { - SourceIP: true, - Terminal: true, - }, + { + Field: structs.HashPolicyHeader, + FieldValue: "x-user-id", + }, + { + SourceIP: true, + Terminal: true, }, }, }, @@ -291,12 +289,12 @@ func TestRoutesFromSnapshot(t *testing.T) { func TestEnvoyLBConfig_InjectToRouteAction(t *testing.T) { var tests = []struct { name string - lb *structs.EnvoyLBConfig + lb *structs.LoadBalancer expected envoyroute.RouteAction }{ { name: "empty", - lb: &structs.EnvoyLBConfig{ + lb: &structs.LoadBalancer{ Policy: "", }, // we only modify route actions for hash-based LB policies @@ -304,7 +302,7 @@ func TestEnvoyLBConfig_InjectToRouteAction(t *testing.T) { }, { name: "least request", - lb: &structs.EnvoyLBConfig{ + lb: &structs.LoadBalancer{ Policy: structs.LBPolicyLeastRequest, LeastRequestConfig: &structs.LeastRequestConfig{ ChoiceCount: 3, @@ -315,7 +313,7 @@ func TestEnvoyLBConfig_InjectToRouteAction(t *testing.T) { }, { name: "headers", - lb: &structs.EnvoyLBConfig{ + lb: &structs.LoadBalancer{ Policy: "ring_hash", RingHashConfig: &structs.RingHashConfig{ MinimumRingSize: 3, @@ -344,7 +342,7 @@ func TestEnvoyLBConfig_InjectToRouteAction(t *testing.T) { }, { name: "cookies", - lb: &structs.EnvoyLBConfig{ + lb: &structs.LoadBalancer{ Policy: structs.LBPolicyMaglev, HashPolicies: []structs.HashPolicy{ { @@ -380,7 +378,7 @@ func TestEnvoyLBConfig_InjectToRouteAction(t *testing.T) { }, { name: "source addr", - lb: &structs.EnvoyLBConfig{ + lb: &structs.LoadBalancer{ Policy: structs.LBPolicyMaglev, HashPolicies: []structs.HashPolicy{ { @@ -404,7 +402,7 @@ func TestEnvoyLBConfig_InjectToRouteAction(t *testing.T) { }, { name: "kitchen sink", - lb: &structs.EnvoyLBConfig{ + lb: &structs.LoadBalancer{ Policy: structs.LBPolicyMaglev, HashPolicies: []structs.HashPolicy{ { diff --git a/api/config_entry_discoverychain.go b/api/config_entry_discoverychain.go index 640525e85..d7a02f839 100644 --- a/api/config_entry_discoverychain.go +++ b/api/config_entry_discoverychain.go @@ -209,14 +209,6 @@ type ServiceResolverFailover struct { // LoadBalancer determines the load balancing policy and configuration for services // issuing requests to this upstream service. type LoadBalancer struct { - // EnvoyConfig contains Envoy-specific load balancing configuration for this upstream - EnvoyConfig *EnvoyLBConfig `json:",omitempty" alias:"envoy_config"` - - // OpaqueConfig contains load balancing configuration opaque to Consul for 3rd party proxies - OpaqueConfig string `json:",omitempty" alias:"opaque_config"` -} - -type EnvoyLBConfig struct { // Policy is the load balancing policy used to select a host Policy string `json:",omitempty"` diff --git a/api/config_entry_discoverychain_test.go b/api/config_entry_discoverychain_test.go index efdc34702..abd34dabc 100644 --- a/api/config_entry_discoverychain_test.go +++ b/api/config_entry_discoverychain_test.go @@ -294,10 +294,8 @@ func TestAPI_ConfigEntry_ServiceResolver_LoadBalancer(t *testing.T) { Name: "test-least-req", Namespace: defaultNamespace, LoadBalancer: &LoadBalancer{ - EnvoyConfig: &EnvoyLBConfig{ - Policy: "least_request", - LeastRequestConfig: &LeastRequestConfig{ChoiceCount: 10}, - }, + Policy: "least_request", + LeastRequestConfig: &LeastRequestConfig{ChoiceCount: 10}, }, }, verify: verifyResolver, @@ -309,30 +307,28 @@ func TestAPI_ConfigEntry_ServiceResolver_LoadBalancer(t *testing.T) { Name: "test-ring-hash", Namespace: defaultNamespace, LoadBalancer: &LoadBalancer{ - EnvoyConfig: &EnvoyLBConfig{ - Policy: "ring_hash", - RingHashConfig: &RingHashConfig{ - MinimumRingSize: 1024 * 2, - MaximumRingSize: 1024 * 4, + Policy: "ring_hash", + RingHashConfig: &RingHashConfig{ + MinimumRingSize: 1024 * 2, + MaximumRingSize: 1024 * 4, + }, + HashPolicies: []HashPolicy{ + { + Field: "header", + FieldValue: "my-session-header", + Terminal: true, }, - HashPolicies: []HashPolicy{ - { - Field: "header", - FieldValue: "my-session-header", - Terminal: true, - }, - { - Field: "cookie", - FieldValue: "oreo", - CookieConfig: &CookieConfig{ - Path: "/tray", - TTL: 20 * time.Millisecond, - }, - }, - { - SourceIP: true, + { + Field: "cookie", + FieldValue: "oreo", + CookieConfig: &CookieConfig{ + Path: "/tray", + TTL: 20 * time.Millisecond, }, }, + { + SourceIP: true, + }, }, }, }, diff --git a/command/config/write/config_write_test.go b/command/config/write/config_write_test.go index 6b0579066..601d232a5 100644 --- a/command/config/write/config_write_test.go +++ b/command/config/write/config_write_test.go @@ -1172,62 +1172,58 @@ func TestParseConfigEntry(t *testing.T) { kind = "service-resolver" name = "main" load_balancer = { - envoy_config = { - 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 = "header" - field_value = "x-user-id" - }, - { - source_ip = true - } - ] + 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 = "header" + field_value = "x-user-id" + }, + { + source_ip = true + } + ] } `, camel: ` Kind = "service-resolver" Name = "main" LoadBalancer = { - EnvoyConfig = { - Policy = "ring_hash" - RingHashConfig = { - MinimumRingSize = 1 - MaximumRingSize = 2 - } - HashPolicies = [ - { - Field = "cookie" - FieldValue = "good-cookie" - CookieConfig = { - TTL = "1s" - Path = "/oven" - } - Terminal = true - }, - { - Field = "header" - FieldValue = "x-user-id" - }, - { - SourceIP = true - } - ] + Policy = "ring_hash" + RingHashConfig = { + MinimumRingSize = 1 + MaximumRingSize = 2 } + HashPolicies = [ + { + Field = "cookie" + FieldValue = "good-cookie" + CookieConfig = { + TTL = "1s" + Path = "/oven" + } + Terminal = true + }, + { + Field = "header" + FieldValue = "x-user-id" + }, + { + SourceIP = true + } + ] } `, snakeJSON: ` @@ -1235,31 +1231,29 @@ func TestParseConfigEntry(t *testing.T) { "kind": "service-resolver", "name": "main", "load_balancer": { - "envoy_config": { - "policy": "ring_hash", - "ring_hash_config": { - "minimum_ring_size": 1, - "maximum_ring_size": 2 + "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 }, - "hash_policies": [ - { - "field": "cookie", - "field_value": "good-cookie", - "cookie_config": { - "ttl": "1s", - "path": "/oven" - }, - "terminal": true - }, - { - "field": "header", - "field_value": "x-user-id" - }, - { - "source_ip": true - } - ] - } + { + "field": "header", + "field_value": "x-user-id" + }, + { + "source_ip": true + } + ] } } `, @@ -1268,31 +1262,29 @@ func TestParseConfigEntry(t *testing.T) { "Kind": "service-resolver", "Name": "main", "LoadBalancer": { - "EnvoyConfig": { - "Policy": "ring_hash", - "RingHashConfig": { - "MinimumRingSize": 1, - "MaximumRingSize": 2 + "Policy": "ring_hash", + "RingHashConfig": { + "MinimumRingSize": 1, + "MaximumRingSize": 2 + }, + "HashPolicies": [ + { + "Field": "cookie", + "FieldValue": "good-cookie", + "CookieConfig": { + "TTL": "1s", + "Path": "/oven" + }, + "Terminal": true }, - "HashPolicies": [ - { - "Field": "cookie", - "FieldValue": "good-cookie", - "CookieConfig": { - "TTL": "1s", - "Path": "/oven" - }, - "Terminal": true - }, - { - "Field": "header", - "FieldValue": "x-user-id" - }, - { - "SourceIP": true - } - ] - } + { + "Field": "header", + "FieldValue": "x-user-id" + }, + { + "SourceIP": true + } + ] } } `, @@ -1300,29 +1292,27 @@ func TestParseConfigEntry(t *testing.T) { Kind: "service-resolver", Name: "main", LoadBalancer: &api.LoadBalancer{ - EnvoyConfig: &api.EnvoyLBConfig{ - Policy: structs.LBPolicyRingHash, - RingHashConfig: &api.RingHashConfig{ - MinimumRingSize: 1, - MaximumRingSize: 2, + Policy: structs.LBPolicyRingHash, + RingHashConfig: &api.RingHashConfig{ + MinimumRingSize: 1, + MaximumRingSize: 2, + }, + HashPolicies: []api.HashPolicy{ + { + Field: structs.HashPolicyCookie, + FieldValue: "good-cookie", + CookieConfig: &api.CookieConfig{ + TTL: 1 * time.Second, + Path: "/oven", + }, + Terminal: true, }, - HashPolicies: []api.HashPolicy{ - { - Field: structs.HashPolicyCookie, - FieldValue: "good-cookie", - CookieConfig: &api.CookieConfig{ - TTL: 1 * time.Second, - Path: "/oven", - }, - Terminal: true, - }, - { - Field: structs.HashPolicyHeader, - FieldValue: "x-user-id", - }, - { - SourceIP: true, - }, + { + Field: structs.HashPolicyHeader, + FieldValue: "x-user-id", + }, + { + SourceIP: true, }, }, }, @@ -1334,11 +1324,9 @@ func TestParseConfigEntry(t *testing.T) { kind = "service-resolver" name = "main" load_balancer = { - envoy_config = { - policy = "least_request" - least_request_config = { - choice_count = 2 - } + policy = "least_request" + least_request_config = { + choice_count = 2 } } `, @@ -1346,11 +1334,9 @@ func TestParseConfigEntry(t *testing.T) { Kind = "service-resolver" Name = "main" LoadBalancer = { - EnvoyConfig = { - Policy = "least_request" - LeastRequestConfig = { - ChoiceCount = 2 - } + Policy = "least_request" + LeastRequestConfig = { + ChoiceCount = 2 } } `, @@ -1359,11 +1345,9 @@ func TestParseConfigEntry(t *testing.T) { "kind": "service-resolver", "name": "main", "load_balancer": { - "envoy_config": { - "policy": "least_request", - "least_request_config": { - "choice_count": 2 - } + "policy": "least_request", + "least_request_config": { + "choice_count": 2 } } } @@ -1373,11 +1357,9 @@ func TestParseConfigEntry(t *testing.T) { "Kind": "service-resolver", "Name": "main", "LoadBalancer": { - "EnvoyConfig": { - "Policy": "least_request", - "LeastRequestConfig": { - "ChoiceCount": 2 - } + "Policy": "least_request", + "LeastRequestConfig": { + "ChoiceCount": 2 } } } @@ -1386,11 +1368,9 @@ func TestParseConfigEntry(t *testing.T) { Kind: "service-resolver", Name: "main", LoadBalancer: &api.LoadBalancer{ - EnvoyConfig: &api.EnvoyLBConfig{ - Policy: structs.LBPolicyLeastRequest, - LeastRequestConfig: &api.LeastRequestConfig{ - ChoiceCount: 2, - }, + Policy: structs.LBPolicyLeastRequest, + LeastRequestConfig: &api.LeastRequestConfig{ + ChoiceCount: 2, }, }, }, From ae8c609f10fe28da9660e55b1d5b04a7780042f6 Mon Sep 17 00:00:00 2001 From: freddygv Date: Fri, 11 Sep 2020 10:49:26 -0600 Subject: [PATCH 18/20] PR comments --- agent/xds/clusters.go | 84 ++++++++++++++++++++-------------------- agent/xds/routes.go | 90 ++++++++++++++++++++++--------------------- 2 files changed, 88 insertions(+), 86 deletions(-) diff --git a/agent/xds/clusters.go b/agent/xds/clusters.go index 9f2831b64..aade20700 100644 --- a/agent/xds/clusters.go +++ b/agent/xds/clusters.go @@ -33,7 +33,7 @@ func (s *Server) clustersFromSnapshot(_ connectionInfo, cfgSnap *proxycfg.Config case structs.ServiceKindConnectProxy: return s.clustersFromSnapshotConnectProxy(cfgSnap) case structs.ServiceKindTerminatingGateway: - return s.makeGatewayServiceClusters(cfgSnap) + return s.makeGatewayServiceClusters(cfgSnap, cfgSnap.TerminatingGateway.ServiceGroups, cfgSnap.TerminatingGateway.ServiceResolvers) case structs.ServiceKindMeshGateway: return s.clustersFromSnapshotMeshGateway(cfgSnap) case structs.ServiceKindIngressGateway: @@ -175,7 +175,7 @@ func (s *Server) clustersFromSnapshotMeshGateway(cfgSnap *proxycfg.ConfigSnapsho } // generate the per-service/subset clusters - c, err := s.makeGatewayServiceClusters(cfgSnap) + c, err := s.makeGatewayServiceClusters(cfgSnap, cfgSnap.MeshGateway.ServiceGroups, cfgSnap.MeshGateway.ServiceResolvers) if err != nil { return nil, err } @@ -184,18 +184,16 @@ func (s *Server) clustersFromSnapshotMeshGateway(cfgSnap *proxycfg.ConfigSnapsho return clusters, nil } -func (s *Server) makeGatewayServiceClusters(cfgSnap *proxycfg.ConfigSnapshot) ([]proto.Message, error) { - var services map[structs.ServiceName]structs.CheckServiceNodes - var resolvers map[structs.ServiceName]*structs.ServiceResolverConfigEntry +func (s *Server) makeGatewayServiceClusters( + cfgSnap *proxycfg.ConfigSnapshot, + services map[structs.ServiceName]structs.CheckServiceNodes, + resolvers map[structs.ServiceName]*structs.ServiceResolverConfigEntry, +) ([]proto.Message, error) { + var hostnameEndpoints structs.CheckServiceNodes switch cfgSnap.Kind { - case structs.ServiceKindTerminatingGateway: - services = cfgSnap.TerminatingGateway.ServiceGroups - resolvers = cfgSnap.TerminatingGateway.ServiceResolvers - case structs.ServiceKindMeshGateway: - services = cfgSnap.MeshGateway.ServiceGroups - resolvers = cfgSnap.MeshGateway.ServiceResolvers + case structs.ServiceKindTerminatingGateway, structs.ServiceKindMeshGateway: default: return nil, fmt.Errorf("unsupported gateway kind %q", cfgSnap.Kind) } @@ -229,21 +227,8 @@ func (s *Server) makeGatewayServiceClusters(cfgSnap *proxycfg.ConfigSnapshot) ([ } cluster := s.makeGatewayCluster(cfgSnap, opts) - switch cfgSnap.Kind { - case structs.ServiceKindTerminatingGateway: - injectTerminatingGatewayTLSContext(cfgSnap, cluster, svc) - - if err := injectLBToCluster(loadBalancer, cluster); err != nil { - return nil, fmt.Errorf("failed to apply load balancer configuration to cluster %q: %v", clusterName, err) - } - case structs.ServiceKindMeshGateway: - // We can't apply hash based LB config to mesh gateways because they rely on inspecting HTTP attributes - // and mesh gateways do not decrypt traffic - if !loadBalancer.IsHashBased() { - if err := injectLBToCluster(loadBalancer, cluster); err != nil { - return nil, fmt.Errorf("failed to apply load balancer configuration to cluster %q: %v", clusterName, err) - } - } + if err := s.injectGatewayServiceAddons(cfgSnap, cluster, svc, loadBalancer); err != nil { + return nil, err } clusters = append(clusters, cluster) @@ -262,22 +247,8 @@ func (s *Server) makeGatewayServiceClusters(cfgSnap *proxycfg.ConfigSnapshot) ([ } cluster := s.makeGatewayCluster(cfgSnap, opts) - switch cfgSnap.Kind { - case structs.ServiceKindTerminatingGateway: - injectTerminatingGatewayTLSContext(cfgSnap, cluster, svc) - - if err := injectLBToCluster(loadBalancer, cluster); err != nil { - return nil, fmt.Errorf("failed to apply load balancer configuration to cluster %q: %v", clusterName, err) - } - - case structs.ServiceKindMeshGateway: - // We can't apply hash based LB config to mesh gateways because they rely on inspecting HTTP attributes - // and mesh gateways do not decrypt traffic - if !loadBalancer.IsHashBased() { - if err := injectLBToCluster(loadBalancer, cluster); err != nil { - return nil, fmt.Errorf("failed to apply load balancer configuration to cluster %q: %v", clusterName, err) - } - } + if err := s.injectGatewayServiceAddons(cfgSnap, cluster, svc, loadBalancer); err != nil { + return nil, err } clusters = append(clusters, cluster) } @@ -286,6 +257,35 @@ func (s *Server) makeGatewayServiceClusters(cfgSnap *proxycfg.ConfigSnapshot) ([ return clusters, nil } +func (s *Server) injectGatewayServiceAddons(cfgSnap *proxycfg.ConfigSnapshot, c *envoy.Cluster, svc structs.ServiceName, lb *structs.LoadBalancer) error { + switch cfgSnap.Kind { + case structs.ServiceKindMeshGateway: + // We can't apply hash based LB config to mesh gateways because they rely on inspecting HTTP attributes + // and mesh gateways do not decrypt traffic + if !lb.IsHashBased() { + if err := injectLBToCluster(lb, c); err != nil { + return fmt.Errorf("failed to apply load balancer configuration to cluster %q: %v", c.Name, err) + } + } + case structs.ServiceKindTerminatingGateway: + // Context used for TLS origination to the cluster + if mapping, ok := cfgSnap.TerminatingGateway.GatewayServices[svc]; ok && mapping.CAFile != "" { + context := envoyauth.UpstreamTlsContext{ + CommonTlsContext: makeCommonTLSContextFromFiles(mapping.CAFile, mapping.CertFile, mapping.KeyFile), + } + if mapping.SNI != "" { + context.Sni = mapping.SNI + } + c.TlsContext = &context + } + if err := injectLBToCluster(lb, c); err != nil { + return fmt.Errorf("failed to apply load balancer configuration to cluster %q: %v", c.Name, err) + } + + } + return nil +} + func (s *Server) clustersFromSnapshotIngressGateway(cfgSnap *proxycfg.ConfigSnapshot) ([]proto.Message, error) { var clusters []proto.Message createdClusters := make(map[string]bool) diff --git a/agent/xds/routes.go b/agent/xds/routes.go index b31e1fcfc..ad20f5f18 100644 --- a/agent/xds/routes.go +++ b/agent/xds/routes.go @@ -3,7 +3,6 @@ package xds import ( "errors" "fmt" - "github.com/hashicorp/consul/logging" "net" "strings" @@ -15,6 +14,7 @@ import ( "github.com/hashicorp/consul/agent/connect" "github.com/hashicorp/consul/agent/proxycfg" "github.com/hashicorp/consul/agent/structs" + "github.com/hashicorp/consul/logging" ) // routesFromSnapshot returns the xDS API representation of the "routes" in the @@ -36,6 +36,47 @@ func (s *Server) routesFromSnapshot(cInfo connectionInfo, cfgSnap *proxycfg.Conf } } +// routesFromSnapshotConnectProxy returns the xDS API representation of the +// "routes" in the snapshot. +func routesForConnectProxy( + cInfo connectionInfo, + upstreams structs.Upstreams, + chains map[string]*structs.CompiledDiscoveryChain, +) ([]proto.Message, error) { + + var resources []proto.Message + for _, u := range upstreams { + upstreamID := u.Identifier() + + var chain *structs.CompiledDiscoveryChain + if u.DestinationType != structs.UpstreamDestTypePreparedQuery { + chain = chains[upstreamID] + } + + if chain == nil || chain.IsDefault() { + // TODO(rb): make this do the old school stuff too + } else { + virtualHost, err := makeUpstreamRouteForDiscoveryChain(cInfo, upstreamID, chain, []string{"*"}) + if err != nil { + return nil, err + } + + route := &envoy.RouteConfiguration{ + Name: upstreamID, + VirtualHosts: []*envoyroute.VirtualHost{virtualHost}, + // ValidateClusters defaults to true when defined statically and false + // when done via RDS. Re-set the sane value of true to prevent + // null-routing traffic. + ValidateClusters: makeBoolValue(true), + } + resources = append(resources, route) + } + } + + // TODO(rb): make sure we don't generate an empty result + return resources, nil +} + // routesFromSnapshotTerminatingGateway returns the xDS API representation of the "routes" in the snapshot. // For any HTTP service we will return a default route. func (s *Server) routesFromSnapshotTerminatingGateway(_ connectionInfo, cfgSnap *proxycfg.ConfigSnapshot) ([]proto.Message, error) { @@ -119,47 +160,6 @@ func makeNamedDefaultRouteWithLB(clusterName string, lb *structs.LoadBalancer) ( }, nil } -// routesFromSnapshotConnectProxy returns the xDS API representation of the -// "routes" in the snapshot. -func routesForConnectProxy( - cInfo connectionInfo, - upstreams structs.Upstreams, - chains map[string]*structs.CompiledDiscoveryChain, -) ([]proto.Message, error) { - - var resources []proto.Message - for _, u := range upstreams { - upstreamID := u.Identifier() - - var chain *structs.CompiledDiscoveryChain - if u.DestinationType != structs.UpstreamDestTypePreparedQuery { - chain = chains[upstreamID] - } - - if chain == nil || chain.IsDefault() { - // TODO(rb): make this do the old school stuff too - } else { - virtualHost, err := makeUpstreamRouteForDiscoveryChain(cInfo, upstreamID, chain, []string{"*"}) - if err != nil { - return nil, err - } - - route := &envoy.RouteConfiguration{ - Name: upstreamID, - VirtualHosts: []*envoyroute.VirtualHost{virtualHost}, - // ValidateClusters defaults to true when defined statically and false - // when done via RDS. Re-set the sane value of true to prevent - // null-routing traffic. - ValidateClusters: makeBoolValue(true), - } - resources = append(resources, route) - } - } - - // TODO(rb): make sure we don't generate an empty result - return resources, nil -} - // routesForIngressGateway returns the xDS API representation of the // "routes" in the snapshot. func routesForIngressGateway( @@ -262,8 +262,6 @@ func makeUpstreamRouteForDiscoveryChain( return nil, fmt.Errorf("missing first node in compiled discovery chain for: %s", chain.ServiceName) } - var lb *structs.LoadBalancer - switch startNode.Type { case structs.DiscoveryGraphNodeTypeRouter: routes = make([]*envoyroute.Route, 0, len(startNode.Routes)) @@ -277,6 +275,8 @@ func makeUpstreamRouteForDiscoveryChain( ) nextNode := chain.Nodes[discoveryRoute.NextNode] + + var lb *structs.LoadBalancer if nextNode.LoadBalancer != nil { lb = nextNode.LoadBalancer } @@ -350,6 +350,7 @@ func makeUpstreamRouteForDiscoveryChain( return nil, err } + var lb *structs.LoadBalancer if startNode.LoadBalancer != nil { lb = startNode.LoadBalancer } @@ -367,6 +368,7 @@ func makeUpstreamRouteForDiscoveryChain( case structs.DiscoveryGraphNodeTypeResolver: routeAction := makeRouteActionForChainCluster(startNode.Resolver.Target, chain) + var lb *structs.LoadBalancer if startNode.LoadBalancer != nil { lb = startNode.LoadBalancer } From 5707ac9d17a946781b70315e3b8ddded8d1e7abb Mon Sep 17 00:00:00 2001 From: freddygv Date: Fri, 11 Sep 2020 10:50:57 -0600 Subject: [PATCH 19/20] Update website docs --- .../agent/config-entries/service-resolver.mdx | 89 ++++++++++--------- 1 file changed, 45 insertions(+), 44 deletions(-) diff --git a/website/pages/docs/agent/config-entries/service-resolver.mdx b/website/pages/docs/agent/config-entries/service-resolver.mdx index c5a27b533..531749441 100644 --- a/website/pages/docs/agent/config-entries/service-resolver.mdx +++ b/website/pages/docs/agent/config-entries/service-resolver.mdx @@ -169,54 +169,55 @@ LoadBalancer = { - `LoadBalancer` `(LoadBalancer`) - Determines the load balancing policy and configuration for services issuing requests to this upstream. - This option is available in Consul versions 1.8.4 and newer. + This option is available in Consul versions 1.9.0 and newer. - - `EnvoyLBConfig` `(EnvoyLBConfig)` - Envoy proxy specific load balancing configuration - for this upstream. - - - `Policy` `(string: "")` - The load balancing policy used to select a host. - One of: `random`, `round_robin`, `least_request`, `ring_hash`, `maglev`. - - - `RingHashConfig` `(RingHashConfig)` - Configuration for the `ring_hash` - policy type. - - - `MinimumRingRize` `(int: 1024)` - Determines the minimum number of entries - in the hash ring. - - - `MaximumRingRize` `(int: 8192)` - Determines the maximum number of entries - in the hash ring. + - `Policy` `(string: "")` - The load balancing policy used to select a host. + One of: `random`, `round_robin`, `least_request`, `ring_hash`, `maglev`. + + - `RingHashConfig` `(RingHashConfig)` - Configuration for the `ring_hash` + policy type. - - `LeastRequestConfig` `(LeastRequestConfig)` - Configuration for the `least_request` - policy type. - - - `ChoiceCount` `(int: 2)` - Determines the number of random healthy hosts - from which to select the one with the least requests. + - `MinimumRingRize` `(int: 1024)` - Determines the minimum number of entries + in the hash ring. - - `HashPolicies` `(array)` - a list of hash policies to use for - hashing load balancing algorithms. Hash policies are evaluated individually - and combined such that identical lists result in the same hash. - If no hash policies are present, or none are successfully evaluated, - then a random backend host will be selected. + - `MaximumRingRize` `(int: 8192)` - Determines the maximum number of entries + in the hash ring. + + - `LeastRequestConfig` `(LeastRequestConfig)` - Configuration for the `least_request` + policy type. + + - `ChoiceCount` `(int: 2)` - Determines the number of random healthy hosts + from which to select the one with the least requests. + + - `HashPolicies` `(array)` - a list of hash policies to use for + hashing load balancing algorithms. Hash policies are evaluated individually + and combined such that identical lists result in the same hash. + If no hash policies are present, or none are successfully evaluated, + then a random backend host will be selected. + + - `Field` `(string: "")` - The attribute type to hash on. + Must be one of `header`,`cookie`, or `query_parameter`. + Cannot be specified along with `SourceAddress`. - - `Field` `(string: "")` - The attribute type to hash on. - Must be one of `header`,`cookie`, or `query_parameter`. - Cannot be specified along with `SourceAddress`. - - - `FieldValue` `(string: "")` - The value to hash. - ie. header name, cookie name, URL query parameter name. - Cannot be specified along with `SourceAddress`. - - - `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. - - - `SourceIP` `(bool: false)` - Determines whether the hash should be of the source IP - address rather than of a field and field value. - Cannot be specified along with `Field` or `FieldValue`. - - - `Terminal` `(bool: false)` - Will short circuit the computation of the hash - when multiple hash policies are present. If a hash is computed when a - Terminal policy is evaluated, then that hash will be used and subsequent - hash policies will be ignored. + - `FieldValue` `(string: "")` - The value to hash. + ie. header name, cookie name, URL query parameter name. + Cannot be specified along with `SourceAddress`. + + - `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. + + - `TTL` `(duration: 0s)` - TTL for generated cookies. + + - `Path` `(string: "")` - The path to set for the cookie. + + - `SourceIP` `(bool: false)` - Determines whether the hash should be of the source IP + address rather than of a field and field value. + Cannot be specified along with `Field` or `FieldValue`. + + - `Terminal` `(bool: false)` - Will short circuit the computation of the hash + when multiple hash policies are present. If a hash is computed when a + Terminal policy is evaluated, then that hash will be used and subsequent + hash policies will be ignored. ## Service Subsets From 60cb306524e6c5979f9fabe3988dfac43475eeb6 Mon Sep 17 00:00:00 2001 From: freddygv Date: Fri, 11 Sep 2020 18:34:03 -0600 Subject: [PATCH 20/20] Add session flag to cookie config --- agent/proxycfg/testing.go | 5 + agent/structs/config_entry_discoverychain.go | 14 +- .../config_entry_discoverychain_test.go | 25 ++- agent/structs/config_entry_test.go | 150 ++++++++++++++++++ agent/xds/routes.go | 11 +- agent/xds/routes_test.go | 73 +++++++++ ...t-proxy-lb-in-resolver.envoy-1-12-x.golden | 6 + ...t-proxy-lb-in-resolver.envoy-1-13-x.golden | 6 + ...t-proxy-lb-in-resolver.envoy-1-14-x.golden | 6 + ...t-proxy-lb-in-resolver.envoy-1-15-x.golden | 6 + ...ingress-lb-in-resolver.envoy-1-12-x.golden | 6 + ...ingress-lb-in-resolver.envoy-1-13-x.golden | 6 + ...ingress-lb-in-resolver.envoy-1-14-x.golden | 6 + ...ingress-lb-in-resolver.envoy-1-15-x.golden | 6 + api/config_entry_discoverychain.go | 5 +- api/config_entry_discoverychain_test.go | 8 + api/config_entry_test.go | 106 +++++++++++++ command/config/write/config_write_test.go | 45 ++++++ .../agent/config-entries/service-resolver.mdx | 4 +- 19 files changed, 486 insertions(+), 8 deletions(-) diff --git a/agent/proxycfg/testing.go b/agent/proxycfg/testing.go index 0514b8984..1c0174493 100644 --- a/agent/proxycfg/testing.go +++ b/agent/proxycfg/testing.go @@ -1286,6 +1286,11 @@ func setupTestVariationConfigEntriesAndSnapshot( FieldValue: "chocolate-chip", Terminal: true, }, + { + Field: "cookie", + FieldValue: "chocolate-chip", + CookieConfig: &structs.CookieConfig{Session: true}, + }, { Field: "header", FieldValue: "x-user-id", diff --git a/agent/structs/config_entry_discoverychain.go b/agent/structs/config_entry_discoverychain.go index b977f8987..0317f144a 100644 --- a/agent/structs/config_entry_discoverychain.go +++ b/agent/structs/config_entry_discoverychain.go @@ -882,8 +882,13 @@ func (e *ServiceResolverConfigEntry) Validate() error { if hp.FieldValue != "" && hp.Field == "" { return fmt.Errorf("Bad LoadBalancer HashPolicy[%d]: FieldValue requires a Field to apply to", i) } - if hp.CookieConfig != nil && hp.Field != HashPolicyCookie { - return fmt.Errorf("Bad LoadBalancer HashPolicy[%d]: cookie_config provided for %q", i, hp.Field) + if hp.CookieConfig != nil { + if hp.Field != HashPolicyCookie { + 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. // This is specified to have Envoy generate a cookie for a client on its first request. 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"` // The path to set for the cookie diff --git a/agent/structs/config_entry_discoverychain_test.go b/agent/structs/config_entry_discoverychain_test.go index 3e5d99f9e..09ca4eaa6 100644 --- a/agent/structs/config_entry_discoverychain_test.go +++ b/agent/structs/config_entry_discoverychain_test.go @@ -656,7 +656,7 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { validateErr: `HashPolicies specified for non-hash-based Policy`, }, { - name: "empty policy with hash policy", + name: "cookie config with header policy", entry: &ServiceResolverConfigEntry{ Kind: ServiceResolver, Name: "test", @@ -677,7 +677,28 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) { 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{ Kind: ServiceResolver, Name: "test", diff --git a/agent/structs/config_entry_test.go b/agent/structs/config_entry_test.go index 34ccfbaf4..0b056390f 100644 --- a/agent/structs/config_entry_test.go +++ b/agent/structs/config_entry_test.go @@ -531,6 +531,156 @@ func TestDecodeConfigEntry(t *testing.T) { 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", snake: ` diff --git a/agent/xds/routes.go b/agent/xds/routes.go index ad20f5f18..c50528d0a 100644 --- a/agent/xds/routes.go +++ b/agent/xds/routes.go @@ -5,6 +5,7 @@ import ( "fmt" "net" "strings" + "time" envoy "github.com/envoyproxy/go-control-plane/envoy/api/v2" 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, } if policy.CookieConfig != nil { - cookie.Ttl = ptypes.DurationProto(policy.CookieConfig.TTL) 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{ PolicySpecifier: &envoyroute.RouteAction_HashPolicy_Cookie_{ diff --git a/agent/xds/routes_test.go b/agent/xds/routes_test.go index 43d2857ae..bb20fc537 100644 --- a/agent/xds/routes_test.go +++ b/agent/xds/routes_test.go @@ -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", lb: &structs.LoadBalancer{ @@ -417,6 +473,14 @@ func TestEnvoyLBConfig_InjectToRouteAction(t *testing.T) { Path: "/oven", }, }, + { + Field: structs.HashPolicyCookie, + FieldValue: "chocolate-chip", + CookieConfig: &structs.CookieConfig{ + Session: true, + Path: "/oven", + }, + }, { Field: structs.HashPolicyHeader, 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_{ Header: &envoyroute.RouteAction_HashPolicy_Header{ diff --git a/agent/xds/testdata/routes/connect-proxy-lb-in-resolver.envoy-1-12-x.golden b/agent/xds/testdata/routes/connect-proxy-lb-in-resolver.envoy-1-12-x.golden index 6fa9287ba..608140c66 100644 --- a/agent/xds/testdata/routes/connect-proxy-lb-in-resolver.envoy-1-12-x.golden +++ b/agent/xds/testdata/routes/connect-proxy-lb-in-resolver.envoy-1-12-x.golden @@ -36,6 +36,12 @@ }, "terminal": true }, + { + "cookie": { + "name": "chocolate-chip", + "ttl": "0s" + } + }, { "header": { "headerName": "x-user-id" diff --git a/agent/xds/testdata/routes/connect-proxy-lb-in-resolver.envoy-1-13-x.golden b/agent/xds/testdata/routes/connect-proxy-lb-in-resolver.envoy-1-13-x.golden index 6fa9287ba..608140c66 100644 --- a/agent/xds/testdata/routes/connect-proxy-lb-in-resolver.envoy-1-13-x.golden +++ b/agent/xds/testdata/routes/connect-proxy-lb-in-resolver.envoy-1-13-x.golden @@ -36,6 +36,12 @@ }, "terminal": true }, + { + "cookie": { + "name": "chocolate-chip", + "ttl": "0s" + } + }, { "header": { "headerName": "x-user-id" diff --git a/agent/xds/testdata/routes/connect-proxy-lb-in-resolver.envoy-1-14-x.golden b/agent/xds/testdata/routes/connect-proxy-lb-in-resolver.envoy-1-14-x.golden index 6fa9287ba..608140c66 100644 --- a/agent/xds/testdata/routes/connect-proxy-lb-in-resolver.envoy-1-14-x.golden +++ b/agent/xds/testdata/routes/connect-proxy-lb-in-resolver.envoy-1-14-x.golden @@ -36,6 +36,12 @@ }, "terminal": true }, + { + "cookie": { + "name": "chocolate-chip", + "ttl": "0s" + } + }, { "header": { "headerName": "x-user-id" diff --git a/agent/xds/testdata/routes/connect-proxy-lb-in-resolver.envoy-1-15-x.golden b/agent/xds/testdata/routes/connect-proxy-lb-in-resolver.envoy-1-15-x.golden index 6fa9287ba..608140c66 100644 --- a/agent/xds/testdata/routes/connect-proxy-lb-in-resolver.envoy-1-15-x.golden +++ b/agent/xds/testdata/routes/connect-proxy-lb-in-resolver.envoy-1-15-x.golden @@ -36,6 +36,12 @@ }, "terminal": true }, + { + "cookie": { + "name": "chocolate-chip", + "ttl": "0s" + } + }, { "header": { "headerName": "x-user-id" diff --git a/agent/xds/testdata/routes/ingress-lb-in-resolver.envoy-1-12-x.golden b/agent/xds/testdata/routes/ingress-lb-in-resolver.envoy-1-12-x.golden index 1dce540e7..fa9217491 100644 --- a/agent/xds/testdata/routes/ingress-lb-in-resolver.envoy-1-12-x.golden +++ b/agent/xds/testdata/routes/ingress-lb-in-resolver.envoy-1-12-x.golden @@ -37,6 +37,12 @@ }, "terminal": true }, + { + "cookie": { + "name": "chocolate-chip", + "ttl": "0s" + } + }, { "header": { "headerName": "x-user-id" diff --git a/agent/xds/testdata/routes/ingress-lb-in-resolver.envoy-1-13-x.golden b/agent/xds/testdata/routes/ingress-lb-in-resolver.envoy-1-13-x.golden index 1dce540e7..fa9217491 100644 --- a/agent/xds/testdata/routes/ingress-lb-in-resolver.envoy-1-13-x.golden +++ b/agent/xds/testdata/routes/ingress-lb-in-resolver.envoy-1-13-x.golden @@ -37,6 +37,12 @@ }, "terminal": true }, + { + "cookie": { + "name": "chocolate-chip", + "ttl": "0s" + } + }, { "header": { "headerName": "x-user-id" diff --git a/agent/xds/testdata/routes/ingress-lb-in-resolver.envoy-1-14-x.golden b/agent/xds/testdata/routes/ingress-lb-in-resolver.envoy-1-14-x.golden index 1dce540e7..fa9217491 100644 --- a/agent/xds/testdata/routes/ingress-lb-in-resolver.envoy-1-14-x.golden +++ b/agent/xds/testdata/routes/ingress-lb-in-resolver.envoy-1-14-x.golden @@ -37,6 +37,12 @@ }, "terminal": true }, + { + "cookie": { + "name": "chocolate-chip", + "ttl": "0s" + } + }, { "header": { "headerName": "x-user-id" diff --git a/agent/xds/testdata/routes/ingress-lb-in-resolver.envoy-1-15-x.golden b/agent/xds/testdata/routes/ingress-lb-in-resolver.envoy-1-15-x.golden index 1dce540e7..fa9217491 100644 --- a/agent/xds/testdata/routes/ingress-lb-in-resolver.envoy-1-15-x.golden +++ b/agent/xds/testdata/routes/ingress-lb-in-resolver.envoy-1-15-x.golden @@ -37,6 +37,12 @@ }, "terminal": true }, + { + "cookie": { + "name": "chocolate-chip", + "ttl": "0s" + } + }, { "header": { "headerName": "x-user-id" diff --git a/api/config_entry_discoverychain.go b/api/config_entry_discoverychain.go index d7a02f839..5b989e105 100644 --- a/api/config_entry_discoverychain.go +++ b/api/config_entry_discoverychain.go @@ -269,7 +269,10 @@ type HashPolicy struct { // 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. 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"` // The path to set for the cookie diff --git a/api/config_entry_discoverychain_test.go b/api/config_entry_discoverychain_test.go index abd34dabc..c5e6d82d9 100644 --- a/api/config_entry_discoverychain_test.go +++ b/api/config_entry_discoverychain_test.go @@ -326,6 +326,14 @@ func TestAPI_ConfigEntry_ServiceResolver_LoadBalancer(t *testing.T) { TTL: 20 * time.Millisecond, }, }, + { + Field: "cookie", + FieldValue: "sugar", + CookieConfig: &CookieConfig{ + Session: true, + Path: "/tin", + }, + }, { SourceIP: true, }, diff --git a/api/config_entry_test.go b/api/config_entry_test.go index aa384bb9f..3bb223958 100644 --- a/api/config_entry_test.go +++ b/api/config_entry_test.go @@ -613,6 +613,112 @@ func TestDecodeConfigEntry(t *testing.T) { 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", body: ` diff --git a/command/config/write/config_write_test.go b/command/config/write/config_write_test.go index 601d232a5..e4d9e2788 100644 --- a/command/config/write/config_write_test.go +++ b/command/config/write/config_write_test.go @@ -1187,6 +1187,15 @@ func TestParseConfigEntry(t *testing.T) { } terminal = true }, + { + field = "cookie" + field_value = "less-good-cookie" + cookie_config = { + session = true + path = "/toaster" + } + terminal = true + }, { field = "header" field_value = "x-user-id" @@ -1216,6 +1225,15 @@ func TestParseConfigEntry(t *testing.T) { } Terminal = true }, + { + Field = "cookie" + FieldValue = "less-good-cookie" + CookieConfig = { + Session = true + Path = "/toaster" + } + Terminal = true + }, { Field = "header" FieldValue = "x-user-id" @@ -1246,6 +1264,15 @@ func TestParseConfigEntry(t *testing.T) { }, "terminal": true }, + { + "field": "cookie", + "field_value": "less-good-cookie", + "cookie_config": { + "session": true, + "path": "/toaster" + }, + "terminal": true + }, { "field": "header", "field_value": "x-user-id" @@ -1277,6 +1304,15 @@ func TestParseConfigEntry(t *testing.T) { }, "Terminal": true }, + { + "Field": "cookie", + "FieldValue": "less-good-cookie", + "CookieConfig": { + "Session": true, + "Path": "/toaster" + }, + "Terminal": true + }, { "Field": "header", "FieldValue": "x-user-id" @@ -1307,6 +1343,15 @@ func TestParseConfigEntry(t *testing.T) { }, Terminal: true, }, + { + Field: structs.HashPolicyCookie, + FieldValue: "less-good-cookie", + CookieConfig: &api.CookieConfig{ + Session: true, + Path: "/toaster", + }, + Terminal: true, + }, { Field: structs.HashPolicyHeader, FieldValue: "x-user-id", diff --git a/website/pages/docs/agent/config-entries/service-resolver.mdx b/website/pages/docs/agent/config-entries/service-resolver.mdx index 531749441..115fd966c 100644 --- a/website/pages/docs/agent/config-entries/service-resolver.mdx +++ b/website/pages/docs/agent/config-entries/service-resolver.mdx @@ -206,7 +206,9 @@ LoadBalancer = { - `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. - - `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.