From 01a0142d1f26a90ec2de4abbb2f19d449f270644 Mon Sep 17 00:00:00 2001 From: Eric Haberkorn Date: Fri, 6 Jan 2023 12:13:40 -0500 Subject: [PATCH] Add the Lua Envoy extension (#15906) --- .changelog/15906.txt | 7 + agent/structs/config_entry.go | 2 + ..._test.go => builtin_extension_oss_test.go} | 116 +++++++- .../lambda}/copied.go | 2 +- .../lambda/lambda.go} | 56 ++-- .../builtinextensions/lambda/lambda_test.go | 85 ++++++ agent/xds/builtinextensions/lua/copied.go | 59 ++++ agent/xds/builtinextensions/lua/lua.go | 141 ++++++++++ agent/xds/builtinextensions/lua/lua_test.go | 92 +++++++ agent/xds/builtinextensiontemplate/plugin.go | 35 +++ .../template.go} | 102 +++++-- agent/xds/clusters.go | 3 +- agent/xds/delta.go | 69 ++++- agent/xds/extensions.go | 24 ++ agent/xds/listeners.go | 54 ++-- agent/xds/listeners_ingress.go | 20 +- agent/xds/rbac.go | 85 ++++++ agent/xds/rbac_test.go | 51 ++++ agent/xds/server.go | 17 -- .../serverlessplugin/lambda_patcher_test.go | 71 ----- agent/xds/serverlessplugin/patcher.go | 52 ---- ...-connect-proxy-opposite-meta.latest.golden | 0 ...terminating-gateway-upstream.latest.golden | 0 .../lambda-connect-proxy.latest.golden | 0 ...teway-with-service-resolvers.latest.golden | 0 .../lambda-terminating-gateway.latest.golden | 0 ...terminating-gateway-upstream.latest.golden | 145 ++++++++++ ...a-inbound-applies-to-inbound.latest.golden | 145 ++++++++++ ...-doesnt-applies-to-upstreams.latest.golden | 145 ++++++++++ ...utbound-applies-to-upstreams.latest.golden | 145 ++++++++++ ...ound-doesnt-apply-to-inbound.latest.golden | 145 ++++++++++ ...-connect-proxy-opposite-meta.latest.golden | 0 ...terminating-gateway-upstream.latest.golden | 0 .../lambda-connect-proxy.latest.golden | 0 ...teway-with-service-resolvers.latest.golden | 0 .../lambda-terminating-gateway.latest.golden | 0 ...terminating-gateway-upstream.latest.golden | 75 +++++ ...a-inbound-applies-to-inbound.latest.golden | 75 +++++ ...-doesnt-applies-to-upstreams.latest.golden | 75 +++++ ...utbound-applies-to-upstreams.latest.golden | 75 +++++ ...ound-doesnt-apply-to-inbound.latest.golden | 75 +++++ ...-connect-proxy-opposite-meta.latest.golden | 0 ...terminating-gateway-upstream.latest.golden | 0 .../lambda-connect-proxy.latest.golden | 0 ...teway-with-service-resolvers.latest.golden | 0 .../lambda-terminating-gateway.latest.golden | 0 ...terminating-gateway-upstream.latest.golden | 152 +++++++++++ ...a-inbound-applies-to-inbound.latest.golden | 257 ++++++++++++++++++ ...-doesnt-applies-to-upstreams.latest.golden | 152 +++++++++++ ...utbound-applies-to-upstreams.latest.golden | 159 +++++++++++ ...ound-doesnt-apply-to-inbound.latest.golden | 250 +++++++++++++++++ ...-connect-proxy-opposite-meta.latest.golden | 0 ...terminating-gateway-upstream.latest.golden | 0 .../routes/lambda-connect-proxy.latest.golden | 0 ...teway-with-service-resolvers.latest.golden | 0 .../lambda-terminating-gateway.latest.golden | 0 ...terminating-gateway-upstream.latest.golden | 5 + ...a-inbound-applies-to-inbound.latest.golden | 5 + ...-doesnt-applies-to-upstreams.latest.golden | 5 + ...utbound-applies-to-upstreams.latest.golden | 5 + ...ound-doesnt-apply-to-inbound.latest.golden | 5 + ...and-failover-to-cluster-peer.latest.golden | 4 +- ...ress-with-chain-and-failover.latest.golden | 4 +- ...efaults-passive-health-check.latest.golden | 6 +- ...efaults-passive-health-check.latest.golden | 4 +- ...service-passive-health-check.latest.golden | 4 +- ...ough-local-gateway-triggered.latest.golden | 4 +- ...ilover-through-local-gateway.latest.golden | 4 +- ...ugh-remote-gateway-triggered.latest.golden | 4 +- ...lover-through-remote-gateway.latest.golden | 4 +- ...ough-local-gateway-triggered.latest.golden | 4 +- ...ilover-through-local-gateway.latest.golden | 4 +- ...ugh-remote-gateway-triggered.latest.golden | 4 +- ...lover-through-remote-gateway.latest.golden | 4 +- .../custom-trace-listener.latest.golden | 88 ++++++ .../grpc-public-listener.latest.golden | 8 - .../http-listener-with-timeouts.latest.golden | 88 ++++++ .../http-public-listener.latest.golden | 88 ++++++ .../http2-public-listener.latest.golden | 88 ++++++ ...ngress-with-chain-and-router.latest.golden | 2 +- agent/xds/xdscommon/xdscommon.go | 22 ++ api/config_entry.go | 5 + .../case-cross-peers-http/alpha/setup.sh | 25 ++ .../case-cross-peers-http/primary/verify.bats | 13 + .../connect/envoy/case-http/verify.bats | 4 +- .../connect/envoy/case-lua/capture.sh | 4 + .../connect/envoy/case-lua/service_s1.hcl | 16 ++ .../connect/envoy/case-lua/service_s2.hcl | 5 + .../connect/envoy/case-lua/setup.sh | 33 +++ .../connect/envoy/case-lua/vars.sh | 3 + .../connect/envoy/case-lua/verify.bats | 39 +++ 91 files changed, 3530 insertions(+), 293 deletions(-) create mode 100644 .changelog/15906.txt rename agent/xds/{serverless_plugin_oss_test.go => builtin_extension_oss_test.go} (63%) rename agent/xds/{serverlessplugin => builtinextensions/lambda}/copied.go (98%) rename agent/xds/{serverlessplugin/lambda_patcher.go => builtinextensions/lambda/lambda.go} (75%) create mode 100644 agent/xds/builtinextensions/lambda/lambda_test.go create mode 100644 agent/xds/builtinextensions/lua/copied.go create mode 100644 agent/xds/builtinextensions/lua/lua.go create mode 100644 agent/xds/builtinextensions/lua/lua_test.go create mode 100644 agent/xds/builtinextensiontemplate/plugin.go rename agent/xds/{serverlessplugin/serverlessplugin.go => builtinextensiontemplate/template.go} (50%) create mode 100644 agent/xds/extensions.go delete mode 100644 agent/xds/serverlessplugin/lambda_patcher_test.go delete mode 100644 agent/xds/serverlessplugin/patcher.go rename agent/xds/testdata/{serverless_plugin => builtin_extension}/clusters/lambda-connect-proxy-opposite-meta.latest.golden (100%) rename agent/xds/testdata/{serverless_plugin => builtin_extension}/clusters/lambda-connect-proxy-with-terminating-gateway-upstream.latest.golden (100%) rename agent/xds/testdata/{serverless_plugin => builtin_extension}/clusters/lambda-connect-proxy.latest.golden (100%) rename agent/xds/testdata/{serverless_plugin => builtin_extension}/clusters/lambda-terminating-gateway-with-service-resolvers.latest.golden (100%) rename agent/xds/testdata/{serverless_plugin => builtin_extension}/clusters/lambda-terminating-gateway.latest.golden (100%) create mode 100644 agent/xds/testdata/builtin_extension/clusters/lua-connect-proxy-with-terminating-gateway-upstream.latest.golden create mode 100644 agent/xds/testdata/builtin_extension/clusters/lua-inbound-applies-to-inbound.latest.golden create mode 100644 agent/xds/testdata/builtin_extension/clusters/lua-inbound-doesnt-applies-to-upstreams.latest.golden create mode 100644 agent/xds/testdata/builtin_extension/clusters/lua-outbound-applies-to-upstreams.latest.golden create mode 100644 agent/xds/testdata/builtin_extension/clusters/lua-outbound-doesnt-apply-to-inbound.latest.golden rename agent/xds/testdata/{serverless_plugin => builtin_extension}/endpoints/lambda-connect-proxy-opposite-meta.latest.golden (100%) rename agent/xds/testdata/{serverless_plugin => builtin_extension}/endpoints/lambda-connect-proxy-with-terminating-gateway-upstream.latest.golden (100%) rename agent/xds/testdata/{serverless_plugin => builtin_extension}/endpoints/lambda-connect-proxy.latest.golden (100%) rename agent/xds/testdata/{serverless_plugin => builtin_extension}/endpoints/lambda-terminating-gateway-with-service-resolvers.latest.golden (100%) rename agent/xds/testdata/{serverless_plugin => builtin_extension}/endpoints/lambda-terminating-gateway.latest.golden (100%) create mode 100644 agent/xds/testdata/builtin_extension/endpoints/lua-connect-proxy-with-terminating-gateway-upstream.latest.golden create mode 100644 agent/xds/testdata/builtin_extension/endpoints/lua-inbound-applies-to-inbound.latest.golden create mode 100644 agent/xds/testdata/builtin_extension/endpoints/lua-inbound-doesnt-applies-to-upstreams.latest.golden create mode 100644 agent/xds/testdata/builtin_extension/endpoints/lua-outbound-applies-to-upstreams.latest.golden create mode 100644 agent/xds/testdata/builtin_extension/endpoints/lua-outbound-doesnt-apply-to-inbound.latest.golden rename agent/xds/testdata/{serverless_plugin => builtin_extension}/listeners/lambda-connect-proxy-opposite-meta.latest.golden (100%) rename agent/xds/testdata/{serverless_plugin => builtin_extension}/listeners/lambda-connect-proxy-with-terminating-gateway-upstream.latest.golden (100%) rename agent/xds/testdata/{serverless_plugin => builtin_extension}/listeners/lambda-connect-proxy.latest.golden (100%) rename agent/xds/testdata/{serverless_plugin => builtin_extension}/listeners/lambda-terminating-gateway-with-service-resolvers.latest.golden (100%) rename agent/xds/testdata/{serverless_plugin => builtin_extension}/listeners/lambda-terminating-gateway.latest.golden (100%) create mode 100644 agent/xds/testdata/builtin_extension/listeners/lua-connect-proxy-with-terminating-gateway-upstream.latest.golden create mode 100644 agent/xds/testdata/builtin_extension/listeners/lua-inbound-applies-to-inbound.latest.golden create mode 100644 agent/xds/testdata/builtin_extension/listeners/lua-inbound-doesnt-applies-to-upstreams.latest.golden create mode 100644 agent/xds/testdata/builtin_extension/listeners/lua-outbound-applies-to-upstreams.latest.golden create mode 100644 agent/xds/testdata/builtin_extension/listeners/lua-outbound-doesnt-apply-to-inbound.latest.golden rename agent/xds/testdata/{serverless_plugin => builtin_extension}/routes/lambda-connect-proxy-opposite-meta.latest.golden (100%) rename agent/xds/testdata/{serverless_plugin => builtin_extension}/routes/lambda-connect-proxy-with-terminating-gateway-upstream.latest.golden (100%) rename agent/xds/testdata/{serverless_plugin => builtin_extension}/routes/lambda-connect-proxy.latest.golden (100%) rename agent/xds/testdata/{serverless_plugin => builtin_extension}/routes/lambda-terminating-gateway-with-service-resolvers.latest.golden (100%) rename agent/xds/testdata/{serverless_plugin => builtin_extension}/routes/lambda-terminating-gateway.latest.golden (100%) create mode 100644 agent/xds/testdata/builtin_extension/routes/lua-connect-proxy-with-terminating-gateway-upstream.latest.golden create mode 100644 agent/xds/testdata/builtin_extension/routes/lua-inbound-applies-to-inbound.latest.golden create mode 100644 agent/xds/testdata/builtin_extension/routes/lua-inbound-doesnt-applies-to-upstreams.latest.golden create mode 100644 agent/xds/testdata/builtin_extension/routes/lua-outbound-applies-to-upstreams.latest.golden create mode 100644 agent/xds/testdata/builtin_extension/routes/lua-outbound-doesnt-apply-to-inbound.latest.golden create mode 100644 test/integration/connect/envoy/case-lua/capture.sh create mode 100644 test/integration/connect/envoy/case-lua/service_s1.hcl create mode 100644 test/integration/connect/envoy/case-lua/service_s2.hcl create mode 100644 test/integration/connect/envoy/case-lua/setup.sh create mode 100644 test/integration/connect/envoy/case-lua/vars.sh create mode 100644 test/integration/connect/envoy/case-lua/verify.bats diff --git a/.changelog/15906.txt b/.changelog/15906.txt new file mode 100644 index 000000000..b1a4ba476 --- /dev/null +++ b/.changelog/15906.txt @@ -0,0 +1,7 @@ +```release-note:feature +xds: Add a built-in Envoy extension that inserts Lua HTTP filters. +``` + +```release-note:feature +xds: Insert originator service identity into Envoy's dynamic metadata under the `consul` namespace. +``` diff --git a/agent/structs/config_entry.go b/agent/structs/config_entry.go index f42356bec..65615103e 100644 --- a/agent/structs/config_entry.go +++ b/agent/structs/config_entry.go @@ -58,6 +58,7 @@ var AllConfigEntryKinds = []string{ const ( BuiltinAWSLambdaExtension string = "builtin/aws/lambda" + BuiltinLuaExtension string = "builtin/lua" ) // ConfigEntry is the interface for centralized configuration stored in Raft. @@ -314,6 +315,7 @@ func (es EnvoyExtensions) ToAPI() []api.EnvoyExtension { func builtInExtension(name string) bool { extensions := map[string]struct{}{ BuiltinAWSLambdaExtension: {}, + BuiltinLuaExtension: {}, } _, ok := extensions[name] diff --git a/agent/xds/serverless_plugin_oss_test.go b/agent/xds/builtin_extension_oss_test.go similarity index 63% rename from agent/xds/serverless_plugin_oss_test.go rename to agent/xds/builtin_extension_oss_test.go index e97d0ea10..d85c11aeb 100644 --- a/agent/xds/serverless_plugin_oss_test.go +++ b/agent/xds/builtin_extension_oss_test.go @@ -19,17 +19,17 @@ import ( "github.com/hashicorp/consul/agent/proxycfg" "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/agent/xds/proxysupport" - "github.com/hashicorp/consul/agent/xds/serverlessplugin" "github.com/hashicorp/consul/agent/xds/xdscommon" + "github.com/hashicorp/consul/api" "github.com/hashicorp/consul/sdk/testutil" ) -func TestServerlessPluginFromSnapshot(t *testing.T) { +func TestBuiltinExtensionsFromSnapshot(t *testing.T) { // If opposite is true, the returned service defaults config entry will have // payload-passthrough=true and invocation-mode=asynchronous. // Otherwise payload-passthrough=false and invocation-mode=synchronous. // This is used to test all the permutations. - makeServiceDefaults := func(opposite bool) *structs.ServiceConfigEntry { + makeLambdaServiceDefaults := func(opposite bool) *structs.ServiceConfigEntry { payloadPassthrough := true if opposite { payloadPassthrough = false @@ -46,7 +46,7 @@ func TestServerlessPluginFromSnapshot(t *testing.T) { Protocol: "http", EnvoyExtensions: []structs.EnvoyExtension{ { - Name: structs.BuiltinAWSLambdaExtension, + Name: api.BuiltinAWSLambdaExtension, Arguments: map[string]interface{}{ "ARN": "lambda-arn", "PayloadPassthrough": payloadPassthrough, @@ -58,6 +58,32 @@ func TestServerlessPluginFromSnapshot(t *testing.T) { } } + makeLuaServiceDefaults := func(inbound bool) *structs.ServiceConfigEntry { + listener := "inbound" + if !inbound { + listener = "outbound" + } + + return &structs.ServiceConfigEntry{ + Kind: structs.ServiceDefaults, + Name: "db", + Protocol: "http", + EnvoyExtensions: []structs.EnvoyExtension{ + { + Name: api.BuiltinLuaExtension, + Arguments: map[string]interface{}{ + "ProxyType": "connect-proxy", + "Listener": listener, + "Script": ` +function envoy_on_request(request_handle) + request_handle:headers():add("test", "test") +end`, + }, + }, + }, + } + } + tests := []struct { name string create func(t testinf.T) *proxycfg.ConfigSnapshot @@ -65,20 +91,20 @@ func TestServerlessPluginFromSnapshot(t *testing.T) { { name: "lambda-connect-proxy", create: func(t testinf.T) *proxycfg.ConfigSnapshot { - return proxycfg.TestConfigSnapshotDiscoveryChain(t, "default", nil, nil, makeServiceDefaults(false)) + return proxycfg.TestConfigSnapshotDiscoveryChain(t, "default", nil, nil, makeLambdaServiceDefaults(false)) }, }, // Make sure that if the upstream type is different from ExtensionConfiguration.Kind is, that the resources are not patched. { name: "lambda-connect-proxy-with-terminating-gateway-upstream", create: func(t testinf.T) *proxycfg.ConfigSnapshot { - return proxycfg.TestConfigSnapshotDiscoveryChain(t, "register-to-terminating-gateway", nil, nil, makeServiceDefaults(false)) + return proxycfg.TestConfigSnapshotDiscoveryChain(t, "register-to-terminating-gateway", nil, nil, makeLambdaServiceDefaults(false)) }, }, { name: "lambda-connect-proxy-opposite-meta", create: func(t testinf.T) *proxycfg.ConfigSnapshot { - return proxycfg.TestConfigSnapshotDiscoveryChain(t, "default", nil, nil, makeServiceDefaults(true)) + return proxycfg.TestConfigSnapshotDiscoveryChain(t, "default", nil, nil, makeLambdaServiceDefaults(true)) }, }, { @@ -91,6 +117,66 @@ func TestServerlessPluginFromSnapshot(t *testing.T) { name: "lambda-terminating-gateway-with-service-resolvers", create: proxycfg.TestConfigSnapshotTerminatingGatewayWithLambdaServiceAndServiceResolvers, }, + { + name: "lua-outbound-applies-to-upstreams", + create: func(t testinf.T) *proxycfg.ConfigSnapshot { + return proxycfg.TestConfigSnapshotDiscoveryChain(t, "default", nil, nil, makeLuaServiceDefaults(false)) + }, + }, + { + name: "lua-inbound-doesnt-applies-to-upstreams", + create: func(t testinf.T) *proxycfg.ConfigSnapshot { + return proxycfg.TestConfigSnapshotDiscoveryChain(t, "default", nil, nil, makeLuaServiceDefaults(true)) + }, + }, + { + name: "lua-inbound-applies-to-inbound", + create: func(t testinf.T) *proxycfg.ConfigSnapshot { + return proxycfg.TestConfigSnapshot(t, func(ns *structs.NodeService) { + ns.Proxy.Config["protocol"] = "http" + ns.Proxy.EnvoyExtensions = []structs.EnvoyExtension{ + { + Name: api.BuiltinLuaExtension, + Arguments: map[string]interface{}{ + "ProxyType": "connect-proxy", + "Listener": "inbound", + "Script": ` +function envoy_on_request(request_handle) + request_handle:headers():add("test", "test") +end`, + }, + }, + } + }, nil) + }, + }, + { + name: "lua-outbound-doesnt-apply-to-inbound", + create: func(t testinf.T) *proxycfg.ConfigSnapshot { + return proxycfg.TestConfigSnapshot(t, func(ns *structs.NodeService) { + ns.Proxy.Config["protocol"] = "http" + ns.Proxy.EnvoyExtensions = []structs.EnvoyExtension{ + { + Name: api.BuiltinLuaExtension, + Arguments: map[string]interface{}{ + "ProxyType": "connect-proxy", + "Listener": "outbound", + "Script": ` +function envoy_on_request(request_handle) + request_handle:headers():add("test", "test") +end`, + }, + }, + } + }, nil) + }, + }, + { + name: "lua-connect-proxy-with-terminating-gateway-upstream", + create: func(t testinf.T) *proxycfg.ConfigSnapshot { + return proxycfg.TestConfigSnapshotDiscoveryChain(t, "register-to-terminating-gateway", nil, nil, makeLambdaServiceDefaults(false)) + }, + }, } latestEnvoyVersion := proxysupport.EnvoyVersions[0] @@ -115,15 +201,15 @@ func TestServerlessPluginFromSnapshot(t *testing.T) { require.NoError(t, err) indexedResources := indexResources(g.Logger, res) - var newResourceMap *xdscommon.IndexedResources cfgs := xdscommon.GetExtensionConfigurations(snap) for _, extensions := range cfgs { for _, ext := range extensions { - switch ext.EnvoyExtension.Name { - case structs.BuiltinAWSLambdaExtension: - newResourceMap, err = serverlessplugin.Extend(indexedResources, ext) - require.NoError(t, err) - } + builtInExtension, ok := GetBuiltInExtension(ext) + require.True(t, ok) + err = builtInExtension.Validate(ext) + require.NoError(t, err) + indexedResources, err = builtInExtension.Extend(indexedResources, ext) + require.NoError(t, err) } } @@ -172,7 +258,7 @@ func TestServerlessPluginFromSnapshot(t *testing.T) { for _, entity := range entities { var msgs []proto.Message - for _, e := range newResourceMap.Index[entity.key] { + for _, e := range indexedResources.Index[entity.key] { msgs = append(msgs, e) } @@ -184,7 +270,7 @@ func TestServerlessPluginFromSnapshot(t *testing.T) { gotJSON := protoToJSON(t, r) require.JSONEq(t, goldenEnvoy(t, - filepath.Join("serverless_plugin", entity.name, tt.name), + filepath.Join("builtin_extension", entity.name, tt.name), envoyVersion, latestEnvoyVersion, gotJSON), gotJSON) }) } diff --git a/agent/xds/serverlessplugin/copied.go b/agent/xds/builtinextensions/lambda/copied.go similarity index 98% rename from agent/xds/serverlessplugin/copied.go rename to agent/xds/builtinextensions/lambda/copied.go index 3e99038aa..7a6ef32b2 100644 --- a/agent/xds/serverlessplugin/copied.go +++ b/agent/xds/builtinextensions/lambda/copied.go @@ -1,4 +1,4 @@ -package serverlessplugin +package lambda import ( envoy_core_v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" diff --git a/agent/xds/serverlessplugin/lambda_patcher.go b/agent/xds/builtinextensions/lambda/lambda.go similarity index 75% rename from agent/xds/serverlessplugin/lambda_patcher.go rename to agent/xds/builtinextensions/lambda/lambda.go index 743bfabbb..cdbae360b 100644 --- a/agent/xds/serverlessplugin/lambda_patcher.go +++ b/agent/xds/builtinextensions/lambda/lambda.go @@ -1,4 +1,4 @@ -package serverlessplugin +package lambda import ( "errors" @@ -14,46 +14,48 @@ import ( envoy_tls_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/tls/v3" envoy_resource_v3 "github.com/envoyproxy/go-control-plane/pkg/resource/v3" pstruct "github.com/golang/protobuf/ptypes/struct" - "github.com/hashicorp/consul/agent/structs" "github.com/mitchellh/mapstructure" + "github.com/hashicorp/consul/agent/xds/builtinextensiontemplate" + "github.com/hashicorp/consul/agent/xds/xdscommon" "github.com/hashicorp/consul/api" + "github.com/hashicorp/go-multierror" ) -type lambdaPatcher struct { - ARN string `mapstructure:"ARN"` - PayloadPassthrough bool `mapstructure:"PayloadPassthrough"` - Region string `mapstructure:"Region"` +type lambda struct { + ARN string + PayloadPassthrough bool + Region string Kind api.ServiceKind - InvocationMode string `mapstructure:"InvocationMode"` + InvocationMode string } -var _ patcher = (*lambdaPatcher)(nil) +var _ builtinextensiontemplate.Plugin = (*lambda)(nil) -func makeLambdaPatcher(ext api.EnvoyExtension, upstreamKind api.ServiceKind) (patcher, bool) { - var patcher lambdaPatcher +// MakeLambdaExtension is a builtinextensiontemplate.PluginConstructor for a builtinextensiontemplate.EnvoyExtension. +func MakeLambdaExtension(ext xdscommon.ExtensionConfiguration) (builtinextensiontemplate.Plugin, error) { + var resultErr error + var plugin lambda - if ext.Name != structs.BuiltinAWSLambdaExtension { - return nil, false + if name := ext.EnvoyExtension.Name; name != api.BuiltinAWSLambdaExtension { + return nil, fmt.Errorf("expected extension name 'lambda' but got %q", name) } - // TODO this blows up if types aren't encode properly. We need to check this earlier in the Validate RPC. - err := mapstructure.Decode(ext.Arguments, &patcher) - if err != nil { - return nil, false + if err := mapstructure.Decode(ext.EnvoyExtension.Arguments, &plugin); err != nil { + return nil, fmt.Errorf("error decoding extension arguments: %v", err) } - if patcher.ARN == "" { - return nil, false + if plugin.ARN == "" { + resultErr = multierror.Append(resultErr, fmt.Errorf("ARN is required")) } - if patcher.Region == "" { - return nil, false + if plugin.Region == "" { + resultErr = multierror.Append(resultErr, fmt.Errorf("Region is required")) } - patcher.Kind = upstreamKind + plugin.Kind = ext.OutgoingProxyKind() - return patcher, true + return plugin, resultErr } func toEnvoyInvocationMode(s string) envoy_lambda_v3.Config_InvocationMode { @@ -64,11 +66,11 @@ func toEnvoyInvocationMode(s string) envoy_lambda_v3.Config_InvocationMode { return m } -func (p lambdaPatcher) CanPatch(kind api.ServiceKind) bool { - return kind == p.Kind +func (p lambda) CanApply(config xdscommon.ExtensionConfiguration) bool { + return config.Kind == p.Kind } -func (p lambdaPatcher) PatchRoute(route *envoy_route_v3.RouteConfiguration) (*envoy_route_v3.RouteConfiguration, bool, error) { +func (p lambda) PatchRoute(route *envoy_route_v3.RouteConfiguration) (*envoy_route_v3.RouteConfiguration, bool, error) { if p.Kind != api.ServiceKindTerminatingGateway { return route, false, nil } @@ -90,7 +92,7 @@ func (p lambdaPatcher) PatchRoute(route *envoy_route_v3.RouteConfiguration) (*en return route, true, nil } -func (p lambdaPatcher) PatchCluster(c *envoy_cluster_v3.Cluster) (*envoy_cluster_v3.Cluster, bool, error) { +func (p lambda) PatchCluster(c *envoy_cluster_v3.Cluster) (*envoy_cluster_v3.Cluster, bool, error) { transportSocket, err := makeUpstreamTLSTransportSocket(&envoy_tls_v3.UpstreamTlsContext{ Sni: "*.amazonaws.com", }) @@ -144,7 +146,7 @@ func (p lambdaPatcher) PatchCluster(c *envoy_cluster_v3.Cluster) (*envoy_cluster return cluster, true, nil } -func (p lambdaPatcher) PatchFilter(filter *envoy_listener_v3.Filter) (*envoy_listener_v3.Filter, bool, error) { +func (p lambda) PatchFilter(filter *envoy_listener_v3.Filter) (*envoy_listener_v3.Filter, bool, error) { if filter.Name != "envoy.filters.network.http_connection_manager" { return filter, false, nil } diff --git a/agent/xds/builtinextensions/lambda/lambda_test.go b/agent/xds/builtinextensions/lambda/lambda_test.go new file mode 100644 index 000000000..dbdd70bfc --- /dev/null +++ b/agent/xds/builtinextensions/lambda/lambda_test.go @@ -0,0 +1,85 @@ +package lambda + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/hashicorp/consul/agent/xds/xdscommon" + "github.com/hashicorp/consul/api" +) + +func TestMakeLambdaExtension(t *testing.T) { + kind := api.ServiceKindTerminatingGateway + cases := map[string]struct { + extensionName string + arn string + payloadPassthrough bool + region string + expected lambda + ok bool + }{ + "no arguments": { + ok: false, + }, + "a bad name": { + arn: "arn", + region: "blah", + extensionName: "bad", + ok: false, + }, + "missing arn": { + region: "blah", + ok: false, + }, + "missing region": { + arn: "arn", + ok: false, + }, + "including payload passthrough": { + arn: "arn", + region: "blah", + payloadPassthrough: true, + expected: lambda{ + ARN: "arn", + PayloadPassthrough: true, + Region: "blah", + Kind: kind, + }, + ok: true, + }, + } + + for n, tc := range cases { + t.Run(n, func(t *testing.T) { + extensionName := api.BuiltinAWSLambdaExtension + if tc.extensionName != "" { + extensionName = tc.extensionName + } + svc := api.CompoundServiceName{Name: "svc"} + ext := xdscommon.ExtensionConfiguration{ + ServiceName: svc, + Upstreams: map[api.CompoundServiceName]xdscommon.UpstreamData{ + svc: {OutgoingProxyKind: kind}, + }, + EnvoyExtension: api.EnvoyExtension{ + Name: extensionName, + Arguments: map[string]interface{}{ + "ARN": tc.arn, + "Region": tc.region, + "PayloadPassthrough": tc.payloadPassthrough, + }, + }, + } + + plugin, err := MakeLambdaExtension(ext) + + if tc.ok { + require.NoError(t, err) + require.Equal(t, tc.expected, plugin) + } else { + require.Error(t, err) + } + }) + } +} diff --git a/agent/xds/builtinextensions/lua/copied.go b/agent/xds/builtinextensions/lua/copied.go new file mode 100644 index 000000000..fdc6ba9b7 --- /dev/null +++ b/agent/xds/builtinextensions/lua/copied.go @@ -0,0 +1,59 @@ +package lua + +import ( + envoy_core_v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" + envoy_listener_v3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3" + envoy_http_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3" + envoy_tls_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/tls/v3" + + "github.com/golang/protobuf/ptypes" + + "github.com/golang/protobuf/proto" +) + +// This is copied from xds and not put into the shared package because I'm not +// convinced it should be shared. + +func makeUpstreamTLSTransportSocket(tlsContext *envoy_tls_v3.UpstreamTlsContext) (*envoy_core_v3.TransportSocket, error) { + if tlsContext == nil { + return nil, nil + } + return makeTransportSocket("tls", tlsContext) +} + +func makeTransportSocket(name string, config proto.Message) (*envoy_core_v3.TransportSocket, error) { + any, err := ptypes.MarshalAny(config) + if err != nil { + return nil, err + } + return &envoy_core_v3.TransportSocket{ + Name: name, + ConfigType: &envoy_core_v3.TransportSocket_TypedConfig{ + TypedConfig: any, + }, + }, nil +} + +func makeEnvoyHTTPFilter(name string, cfg proto.Message) (*envoy_http_v3.HttpFilter, error) { + any, err := ptypes.MarshalAny(cfg) + if err != nil { + return nil, err + } + + return &envoy_http_v3.HttpFilter{ + Name: name, + ConfigType: &envoy_http_v3.HttpFilter_TypedConfig{TypedConfig: any}, + }, nil +} + +func makeFilter(name string, cfg proto.Message) (*envoy_listener_v3.Filter, error) { + any, err := ptypes.MarshalAny(cfg) + if err != nil { + return nil, err + } + + return &envoy_listener_v3.Filter{ + Name: name, + ConfigType: &envoy_listener_v3.Filter_TypedConfig{TypedConfig: any}, + }, nil +} diff --git a/agent/xds/builtinextensions/lua/lua.go b/agent/xds/builtinextensions/lua/lua.go new file mode 100644 index 000000000..d782c6a18 --- /dev/null +++ b/agent/xds/builtinextensions/lua/lua.go @@ -0,0 +1,141 @@ +package lua + +import ( + "errors" + "fmt" + + envoy_cluster_v3 "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3" + envoy_listener_v3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3" + envoy_route_v3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3" + envoy_lua_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/lua/v3" + envoy_http_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3" + envoy_resource_v3 "github.com/envoyproxy/go-control-plane/pkg/resource/v3" + "github.com/hashicorp/go-multierror" + "github.com/mitchellh/mapstructure" + + "github.com/hashicorp/consul/agent/xds/builtinextensiontemplate" + "github.com/hashicorp/consul/agent/xds/xdscommon" + "github.com/hashicorp/consul/api" +) + +type lua struct { + ProxyType string + Listener string + Script string +} + +var _ builtinextensiontemplate.Plugin = (*lua)(nil) + +// MakeLuaExtension is a builtinextensiontemplate.PluginConstructor for a builtinextensiontemplate.EnvoyExtension. +func MakeLuaExtension(ext xdscommon.ExtensionConfiguration) (builtinextensiontemplate.Plugin, error) { + var resultErr error + var plugin lua + + if name := ext.EnvoyExtension.Name; name != api.BuiltinLuaExtension { + return nil, fmt.Errorf("expected extension name 'lua' but got %q", name) + } + + if err := mapstructure.Decode(ext.EnvoyExtension.Arguments, &plugin); err != nil { + return nil, fmt.Errorf("error decoding extension arguments: %v", err) + } + + if plugin.Script == "" { + resultErr = multierror.Append(resultErr, fmt.Errorf("Script is required")) + } + + if err := validateProxyType(plugin.ProxyType); err != nil { + resultErr = multierror.Append(resultErr, err) + } + + if err := validateListener(plugin.Listener); err != nil { + resultErr = multierror.Append(resultErr, err) + } + + return plugin, resultErr +} + +func validateProxyType(t string) error { + if t != "connect-proxy" { + return fmt.Errorf("unexpected ProxyType %q", t) + } + + return nil +} + +func validateListener(t string) error { + if t != "inbound" && t != "outbound" { + return fmt.Errorf("unexpected Listener %q", t) + } + + return nil +} + +// CanApply determines if the extension can apply to the given extension configuration. +func (p lua) CanApply(config xdscommon.ExtensionConfiguration) bool { + return string(config.Kind) == p.ProxyType && p.matchesListenerDirection(config) +} + +func (p lua) matchesListenerDirection(config xdscommon.ExtensionConfiguration) bool { + return (config.IsUpstream() && p.Listener == "outbound") || (!config.IsUpstream() && p.Listener == "inbound") +} + +// PatchRoute does nothing. +func (p lua) PatchRoute(route *envoy_route_v3.RouteConfiguration) (*envoy_route_v3.RouteConfiguration, bool, error) { + return route, false, nil +} + +// PatchCluster does nothing. +func (p lua) PatchCluster(c *envoy_cluster_v3.Cluster) (*envoy_cluster_v3.Cluster, bool, error) { + return c, false, nil +} + +// PatchFilter inserts a lua filter directly prior to envoy.filters.http.router. +func (p lua) PatchFilter(filter *envoy_listener_v3.Filter) (*envoy_listener_v3.Filter, bool, error) { + if filter.Name != "envoy.filters.network.http_connection_manager" { + return filter, false, nil + } + if typedConfig := filter.GetTypedConfig(); typedConfig == nil { + return filter, false, errors.New("error getting typed config for http filter") + } + + config := envoy_resource_v3.GetHTTPConnectionManager(filter) + if config == nil { + return filter, false, errors.New("error unmarshalling filter") + } + luaHttpFilter, err := makeEnvoyHTTPFilter( + "envoy.filters.http.lua", + &envoy_lua_v3.Lua{ + InlineCode: p.Script, + }, + ) + if err != nil { + return filter, false, err + } + + var ( + changedFilters = make([]*envoy_http_v3.HttpFilter, 0, len(config.HttpFilters)+1) + changed bool + ) + + // We need to be careful about overwriting http filters completely because + // http filters validates intentions with the RBAC filter. This inserts the + // lua filter before envoy.filters.http.router while keeping everything + // else intact. + for _, httpFilter := range config.HttpFilters { + if httpFilter.Name == "envoy.filters.http.router" { + changedFilters = append(changedFilters, luaHttpFilter) + changed = true + } + changedFilters = append(changedFilters, httpFilter) + } + if changed { + config.HttpFilters = changedFilters + } + + newFilter, err := makeFilter("envoy.filters.network.http_connection_manager", config) + if err != nil { + return filter, false, errors.New("error making new filter") + } + + return newFilter, true, nil +} diff --git a/agent/xds/builtinextensions/lua/lua_test.go b/agent/xds/builtinextensions/lua/lua_test.go new file mode 100644 index 000000000..4d1802a8a --- /dev/null +++ b/agent/xds/builtinextensions/lua/lua_test.go @@ -0,0 +1,92 @@ +package lua + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/hashicorp/consul/agent/xds/xdscommon" + "github.com/hashicorp/consul/api" +) + +func TestMakeLuaPatcher(t *testing.T) { + makeArguments := func(overrides map[string]interface{}) map[string]interface{} { + m := map[string]interface{}{ + "ProxyType": "connect-proxy", + "Listener": "inbound", + "Script": "lua-script", + } + + for k, v := range overrides { + m[k] = v + } + + return m + } + + cases := map[string]struct { + extensionName string + arguments map[string]interface{} + expected lua + ok bool + }{ + "with no arguments": { + arguments: nil, + ok: false, + }, + "with an invalid name": { + arguments: makeArguments(map[string]interface{}{}), + extensionName: "bad", + ok: false, + }, + "empty script": { + arguments: makeArguments(map[string]interface{}{"Script": ""}), + ok: false, + }, + "invalid proxy type": { + arguments: makeArguments(map[string]interface{}{"ProxyType": "terminating-gateway"}), + ok: false, + }, + "invalid listener": { + arguments: makeArguments(map[string]interface{}{"Listener": "invalid"}), + ok: false, + }, + "valid everything": { + arguments: makeArguments(map[string]interface{}{}), + expected: lua{ + ProxyType: "connect-proxy", + Listener: "inbound", + Script: "lua-script", + }, + ok: true, + }, + } + + for n, tc := range cases { + t.Run(n, func(t *testing.T) { + + extensionName := api.BuiltinLuaExtension + if tc.extensionName != "" { + extensionName = tc.extensionName + } + + svc := api.CompoundServiceName{Name: "svc"} + ext := xdscommon.ExtensionConfiguration{ + ServiceName: svc, + EnvoyExtension: api.EnvoyExtension{ + Name: extensionName, + Arguments: tc.arguments, + }, + } + + patcher, err := MakeLuaExtension(ext) + + if tc.ok { + require.NoError(t, err) + require.Equal(t, tc.expected, patcher) + } else { + require.Error(t, err) + } + }) + } +} diff --git a/agent/xds/builtinextensiontemplate/plugin.go b/agent/xds/builtinextensiontemplate/plugin.go new file mode 100644 index 000000000..f6d606e59 --- /dev/null +++ b/agent/xds/builtinextensiontemplate/plugin.go @@ -0,0 +1,35 @@ +package builtinextensiontemplate + +import ( + envoy_cluster_v3 "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3" + envoy_listener_v3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3" + envoy_route_v3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3" + + "github.com/hashicorp/consul/agent/xds/xdscommon" +) + +// Plugin is the interface that each extension must implement. It +// is responsible for modifying the xDS structures based on only the state of +// the extension. +type Plugin interface { + // CanApply determines if the extension can mutate resources for the given xdscommon.ExtensionConfiguration. + CanApply(xdscommon.ExtensionConfiguration) bool + + // PatchRoute patches a route to include the custom Envoy configuration + // required to integrate with the built in extension template. + PatchRoute(*envoy_route_v3.RouteConfiguration) (*envoy_route_v3.RouteConfiguration, bool, error) + + // PatchCluster patches a cluster to include the custom Envoy configuration + // required to integrate with the built in extension template. + PatchCluster(*envoy_cluster_v3.Cluster) (*envoy_cluster_v3.Cluster, bool, error) + + // PatchFilter patches an Envoy filter to include the custom Envoy + // configuration required to integrate with the built in extension template. + PatchFilter(*envoy_listener_v3.Filter) (*envoy_listener_v3.Filter, bool, error) +} + +// PluginConstructor is used to construct a plugin based on +// xdscommon.ExtensionConfiguration. This function should contain all the logic around +// turning an extension's arguments into a plugin. The PluginConstructor will be used +// as the Constructor field on an EnvoyExtension. +type PluginConstructor func(extension xdscommon.ExtensionConfiguration) (Plugin, error) diff --git a/agent/xds/serverlessplugin/serverlessplugin.go b/agent/xds/builtinextensiontemplate/template.go similarity index 50% rename from agent/xds/serverlessplugin/serverlessplugin.go rename to agent/xds/builtinextensiontemplate/template.go index 76cfe6ba6..774b0b7ed 100644 --- a/agent/xds/serverlessplugin/serverlessplugin.go +++ b/agent/xds/builtinextensiontemplate/template.go @@ -1,4 +1,4 @@ -package serverlessplugin +package builtinextensiontemplate import ( "fmt" @@ -14,13 +14,35 @@ import ( "github.com/hashicorp/consul/api" ) +type EnvoyExtension struct { + Constructor PluginConstructor + plugin Plugin + ready bool +} + +var _ xdscommon.EnvoyExtension = (*EnvoyExtension)(nil) + +// Validate ensures the data in ExtensionConfiguration can successfuly be used +// to apply the specified Envoy extension. +func (envoyExtension *EnvoyExtension) Validate(config xdscommon.ExtensionConfiguration) error { + plugin, err := envoyExtension.Constructor(config) + + envoyExtension.plugin = plugin + envoyExtension.ready = err == nil + + return err +} + // Extend updates indexed xDS structures to include patches for -// serverless integrations. It is responsible for constructing all of the -// patchers and forwarding xDS structs onto the appropriate patcher. If any -// portion of this function fails, it will record the error and continue. The -// behavior is appropriate since the unpatched xDS structures this receives are -// typically invalid. -func Extend(resources *xdscommon.IndexedResources, config xdscommon.ExtensionConfiguration) (*xdscommon.IndexedResources, error) { +// built-in extensions. It is responsible for applying Plugins to +// the the appropriate xDS resources. If any portion of this function fails, +// it will attempt continue and return an error. The caller can then determine +// if it is better to use a partially applied extension or error out. +func (envoyExtension *EnvoyExtension) Extend(resources *xdscommon.IndexedResources, config xdscommon.ExtensionConfiguration) (*xdscommon.IndexedResources, error) { + if !envoyExtension.ready { + panic("envoy extension used without being properly constructed") + } + var resultErr error switch config.Kind { @@ -29,16 +51,7 @@ func Extend(resources *xdscommon.IndexedResources, config xdscommon.ExtensionCon return resources, nil } - if !config.IsUpstream() { - return resources, nil - } - - patcher := makePatcher(config) - if patcher == nil { - return resources, nil - } - - if !patcher.CanPatch(config.Kind) { + if !envoyExtension.plugin.CanApply(config) { return resources, nil } @@ -50,11 +63,19 @@ func Extend(resources *xdscommon.IndexedResources, config xdscommon.ExtensionCon for nameOrSNI, msg := range resources.Index[indexType] { switch resource := msg.(type) { case *envoy_cluster_v3.Cluster: - if !config.MatchesUpstreamServiceSNI(nameOrSNI) { + // If the Envoy extension configuration is for an upstream service, the Cluster's + // name must match the upstream service's SNI. + if config.IsUpstream() && !config.MatchesUpstreamServiceSNI(nameOrSNI) { continue } - newCluster, patched, err := patcher.PatchCluster(resource) + // If the extension's config is for an an inbound listener, the Cluster's name + // must be xdscommon.LocalAppClusterName. + if !config.IsUpstream() && nameOrSNI == xdscommon.LocalAppClusterName { + continue + } + + newCluster, patched, err := envoyExtension.plugin.PatchCluster(resource) if err != nil { resultErr = multierror.Append(resultErr, fmt.Errorf("error patching cluster: %w", err)) continue @@ -64,7 +85,7 @@ func Extend(resources *xdscommon.IndexedResources, config xdscommon.ExtensionCon } case *envoy_listener_v3.Listener: - newListener, patched, err := patchListener(config, resource, patcher) + newListener, patched, err := envoyExtension.patchListener(config, resource) if err != nil { resultErr = multierror.Append(resultErr, fmt.Errorf("error patching listener: %w", err)) continue @@ -74,11 +95,18 @@ func Extend(resources *xdscommon.IndexedResources, config xdscommon.ExtensionCon } case *envoy_route_v3.RouteConfiguration: - if !config.MatchesUpstreamServiceSNI(nameOrSNI) { + // If the Envoy extension configuration is for an upstream service, the route's + // name must match the upstream service's SNI. + if config.IsUpstream() && !config.MatchesUpstreamServiceSNI(nameOrSNI) { continue } - newRoute, patched, err := patcher.PatchRoute(resource) + // There aren't routes for inbound services. + if !config.IsUpstream() { + continue + } + + newRoute, patched, err := envoyExtension.plugin.PatchRoute(resource) if err != nil { resultErr = multierror.Append(resultErr, fmt.Errorf("error patching route: %w", err)) continue @@ -96,17 +124,22 @@ func Extend(resources *xdscommon.IndexedResources, config xdscommon.ExtensionCon return resources, resultErr } -func patchListener(config xdscommon.ExtensionConfiguration, l *envoy_listener_v3.Listener, p patcher) (proto.Message, bool, error) { +func (envoyExtension EnvoyExtension) patchListener(config xdscommon.ExtensionConfiguration, l *envoy_listener_v3.Listener) (proto.Message, bool, error) { switch config.Kind { case api.ServiceKindTerminatingGateway: - return patchTerminatingGatewayListener(config, l, p) + return envoyExtension.patchTerminatingGatewayListener(config, l) case api.ServiceKindConnectProxy: - return patchConnectProxyListener(config, l, p) + return envoyExtension.patchConnectProxyListener(config, l) } return l, false, nil } -func patchTerminatingGatewayListener(config xdscommon.ExtensionConfiguration, l *envoy_listener_v3.Listener, p patcher) (proto.Message, bool, error) { +func (envoyExtension EnvoyExtension) patchTerminatingGatewayListener(config xdscommon.ExtensionConfiguration, l *envoy_listener_v3.Listener) (proto.Message, bool, error) { + // We don't support directly targeting terminating gateways with extensions. + if !config.IsUpstream() { + return l, false, nil + } + var resultErr error patched := false for _, filterChain := range l.FilterChains { @@ -116,6 +149,7 @@ func patchTerminatingGatewayListener(config xdscommon.ExtensionConfiguration, l continue } + // The filter chain's SNI must match the upstream service's SNI. if !config.MatchesUpstreamServiceSNI(sni) { continue } @@ -123,7 +157,7 @@ func patchTerminatingGatewayListener(config xdscommon.ExtensionConfiguration, l var filters []*envoy_listener_v3.Filter for _, filter := range filterChain.Filters { - newFilter, ok, err := p.PatchFilter(filter) + newFilter, ok, err := envoyExtension.plugin.PatchFilter(filter) if err != nil { resultErr = multierror.Append(resultErr, fmt.Errorf("error patching listener filter: %w", err)) @@ -140,7 +174,7 @@ func patchTerminatingGatewayListener(config xdscommon.ExtensionConfiguration, l return l, patched, resultErr } -func patchConnectProxyListener(config xdscommon.ExtensionConfiguration, l *envoy_listener_v3.Listener, p patcher) (proto.Message, bool, error) { +func (envoyExtension EnvoyExtension) patchConnectProxyListener(config xdscommon.ExtensionConfiguration, l *envoy_listener_v3.Listener) (proto.Message, bool, error) { var resultErr error envoyID := "" @@ -148,7 +182,15 @@ func patchConnectProxyListener(config xdscommon.ExtensionConfiguration, l *envoy envoyID = l.Name[:i] } - if envoyID != config.EnvoyID() { + // If the Envoy extension configuration is for an upstream service, the listener's + // name must match the upstream service's EnvoyID. + if config.IsUpstream() && envoyID != config.EnvoyID() { + return l, false, nil + } + + // If the Envoy extension configuration is for inbound resources, the + // listener must be named xdscommon.PublicListenerName. + if !config.IsUpstream() && envoyID != xdscommon.PublicListenerName { return l, false, nil } @@ -158,7 +200,7 @@ func patchConnectProxyListener(config xdscommon.ExtensionConfiguration, l *envoy var filters []*envoy_listener_v3.Filter for _, filter := range filterChain.Filters { - newFilter, ok, err := p.PatchFilter(filter) + newFilter, ok, err := envoyExtension.plugin.PatchFilter(filter) if err != nil { resultErr = multierror.Append(resultErr, fmt.Errorf("error patching listener filter: %w", err)) filters = append(filters, filter) diff --git a/agent/xds/clusters.go b/agent/xds/clusters.go index 15dea732c..f892bdd5f 100644 --- a/agent/xds/clusters.go +++ b/agent/xds/clusters.go @@ -26,6 +26,7 @@ import ( "github.com/hashicorp/consul/agent/connect" "github.com/hashicorp/consul/agent/proxycfg" "github.com/hashicorp/consul/agent/structs" + "github.com/hashicorp/consul/agent/xds/xdscommon" "github.com/hashicorp/consul/proto/pbpeering" ) @@ -73,7 +74,7 @@ func (s *ResourceGenerator) clustersFromSnapshotConnectProxy(cfgSnap *proxycfg.C clusters := make([]proto.Message, 0, len(cfgSnap.ConnectProxy.DiscoveryChain)+1) // Include the "app" cluster for the public listener - appCluster, err := s.makeAppCluster(cfgSnap, LocalAppClusterName, "", cfgSnap.Proxy.LocalServicePort) + appCluster, err := s.makeAppCluster(cfgSnap, xdscommon.LocalAppClusterName, "", cfgSnap.Proxy.LocalServicePort) if err != nil { return nil, err } diff --git a/agent/xds/delta.go b/agent/xds/delta.go index 2671eabb9..2f46e0b97 100644 --- a/agent/xds/delta.go +++ b/agent/xds/delta.go @@ -25,7 +25,6 @@ import ( external "github.com/hashicorp/consul/agent/grpc-external" "github.com/hashicorp/consul/agent/proxycfg" "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/agent/xds/serverlessplugin" "github.com/hashicorp/consul/agent/xds/xdscommon" "github.com/hashicorp/consul/logging" ) @@ -251,17 +250,9 @@ func (s *Server) processDelta(stream ADSDeltaStream, reqCh <-chan *envoy_discove s.ResourceMapMutateFn(newResourceMap) } - cfgs := xdscommon.GetExtensionConfigurations(cfgSnap) - for _, extensions := range cfgs { - for _, ext := range extensions { - switch ext.EnvoyExtension.Name { - case structs.BuiltinAWSLambdaExtension: - newResourceMap, err = serverlessplugin.Extend(newResourceMap, ext) - if err != nil && ext.EnvoyExtension.Required { - return status.Errorf(codes.Unavailable, "failed to patch xDS resources in the serverless plugin: %v", err) - } - } - } + if err = s.applyEnvoyExtensions(newResourceMap, cfgSnap); err != nil { + // err is already the result of calling status.Errorf + return err } if err := populateChildIndexMap(newResourceMap); err != nil { @@ -401,6 +392,60 @@ func (s *Server) processDelta(stream ADSDeltaStream, reqCh <-chan *envoy_discove } } +func (s *Server) applyEnvoyExtensions(resources *xdscommon.IndexedResources, cfgSnap *proxycfg.ConfigSnapshot) error { + var err error + cfgs := xdscommon.GetExtensionConfigurations(cfgSnap) + + for _, extensions := range cfgs { + for _, ext := range extensions { + logFn := s.Logger.Warn + if ext.EnvoyExtension.Required { + logFn = s.Logger.Error + } + extensionContext := []interface{}{ + "extension", ext.EnvoyExtension.Name, + "service", ext.ServiceName.Name, + "namespace", ext.ServiceName.Namespace, + "partition", ext.ServiceName.Partition, + } + + extension, ok := GetBuiltInExtension(ext) + if !ok { + logFn("failed to find extension", extensionContext...) + + if ext.EnvoyExtension.Required { + return status.Errorf(codes.Unavailable, "failed to find extension %q for service %q", ext.EnvoyExtension.Name, ext.ServiceName.Name) + } + + continue + } + + err = extension.Validate(ext) + if err != nil { + extensionContext = append(extensionContext, "error", err) + logFn("failed to validate extension arguments", extensionContext...) + if ext.EnvoyExtension.Required { + return status.Errorf(codes.Unavailable, "failed to validate arguments for extension %q for service %q", ext.EnvoyExtension.Name, ext.ServiceName.Name) + } + + continue + } + + resources, err = extension.Extend(resources, ext) + if err == nil { + continue + } + + logFn("failed to apply envoy extension", extensionContext...) + if ext.EnvoyExtension.Required { + return status.Errorf(codes.Unavailable, "failed to patch xDS resources in the %q plugin: %v", ext.EnvoyExtension.Name, err) + } + } + } + + return nil +} + var xDSUpdateOrder = []xDSUpdateOperation{ // 1. CDS updates (if any) must always be pushed first. {TypeUrl: xdscommon.ClusterType, Upsert: true}, diff --git a/agent/xds/extensions.go b/agent/xds/extensions.go new file mode 100644 index 000000000..778cca115 --- /dev/null +++ b/agent/xds/extensions.go @@ -0,0 +1,24 @@ +package xds + +import ( + "github.com/hashicorp/consul/agent/xds/builtinextensions/lambda" + "github.com/hashicorp/consul/agent/xds/builtinextensions/lua" + "github.com/hashicorp/consul/agent/xds/builtinextensiontemplate" + "github.com/hashicorp/consul/agent/xds/xdscommon" + "github.com/hashicorp/consul/api" +) + +func GetBuiltInExtension(ext xdscommon.ExtensionConfiguration) (builtinextensiontemplate.EnvoyExtension, bool) { + var c builtinextensiontemplate.PluginConstructor + switch ext.EnvoyExtension.Name { + case api.BuiltinAWSLambdaExtension: + c = lambda.MakeLambdaExtension + case api.BuiltinLuaExtension: + c = lua.MakeLuaExtension + default: + var e builtinextensiontemplate.EnvoyExtension + return e, false + } + + return builtinextensiontemplate.EnvoyExtension{Constructor: c}, true +} diff --git a/agent/xds/listeners.go b/agent/xds/listeners.go index 607c3814b..7586860db 100644 --- a/agent/xds/listeners.go +++ b/agent/xds/listeners.go @@ -41,6 +41,7 @@ import ( "github.com/hashicorp/consul/agent/proxycfg" "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/agent/xds/accesslogs" + "github.com/hashicorp/consul/agent/xds/xdscommon" "github.com/hashicorp/consul/lib" "github.com/hashicorp/consul/lib/stringslice" "github.com/hashicorp/consul/proto/pbpeering" @@ -76,7 +77,7 @@ func (s *ResourceGenerator) listenersFromSnapshotConnectProxy(cfgSnap *proxycfg. var err error // Configure inbound listener. - resources[0], err = s.makeInboundListener(cfgSnap, PublicListenerName) + resources[0], err = s.makeInboundListener(cfgSnap, xdscommon.PublicListenerName) if err != nil { return nil, err } @@ -641,7 +642,7 @@ func (s *ResourceGenerator) listenersFromSnapshotConnectProxy(cfgSnap *proxycfg. // Configure additional listener for exposed check paths for _, path := range paths { - clusterName := LocalAppClusterName + clusterName := xdscommon.LocalAppClusterName if path.LocalPathPort != cfgSnap.Proxy.LocalServicePort { clusterName = makeExposeClusterName(path.LocalPathPort) } @@ -1350,7 +1351,7 @@ func (s *ResourceGenerator) makeInboundListener(cfgSnap *proxycfg.ConfigSnapshot protocol: cfg.Protocol, filterName: name, routeName: name, - cluster: LocalAppClusterName, + cluster: xdscommon.LocalAppClusterName, requestTimeoutMs: cfg.LocalRequestTimeoutMs, idleTimeoutMs: cfg.LocalIdleTimeoutMs, tracing: tracing, @@ -1358,7 +1359,7 @@ func (s *ResourceGenerator) makeInboundListener(cfgSnap *proxycfg.ConfigSnapshot logger: s.Logger, } if useHTTPFilter { - filterOpts.httpAuthzFilter, err = makeRBACHTTPFilter( + rbacFilter, err := makeRBACHTTPFilter( cfgSnap.ConnectProxy.Intentions, cfgSnap.IntentionDefaultAllow, rbacLocalInfo{ @@ -1371,9 +1372,22 @@ func (s *ResourceGenerator) makeInboundListener(cfgSnap *proxycfg.ConfigSnapshot if err != nil { return nil, err } - if meshConfig := cfgSnap.MeshConfig(); meshConfig == nil || meshConfig.HTTP == nil || !meshConfig.HTTP.SanitizeXForwardedClientCert { + + filterOpts.httpAuthzFilters = []*envoy_http_v3.HttpFilter{rbacFilter} + + meshConfig := cfgSnap.MeshConfig() + includeXFCC := meshConfig == nil || meshConfig.HTTP == nil || !meshConfig.HTTP.SanitizeXForwardedClientCert + notGRPC := cfg.Protocol != "grpc" + if includeXFCC && notGRPC { filterOpts.forwardClientDetails = true filterOpts.forwardClientPolicy = envoy_http_v3.HttpConnectionManager_APPEND_FORWARD + + addMeta, err := parseXFCCToDynamicMetaHTTPFilter() + if err != nil { + return nil, err + } + filterOpts.httpAuthzFilters = append(filterOpts.httpAuthzFilters, addMeta) + } } @@ -1472,16 +1486,16 @@ func (s *ResourceGenerator) makeExposedCheckListener(cfgSnap *proxycfg.ConfigSna filterName := fmt.Sprintf("exposed_path_filter_%s_%d", strippedPath, path.ListenerPort) filterOpts := listenerFilterOpts{ - useRDS: false, - protocol: path.Protocol, - filterName: filterName, - routeName: filterName, - cluster: cluster, - statPrefix: "", - routePath: path.Path, - httpAuthzFilter: nil, - accessLogs: &cfgSnap.Proxy.AccessLogs, - logger: s.Logger, + useRDS: false, + protocol: path.Protocol, + filterName: filterName, + routeName: filterName, + cluster: cluster, + statPrefix: "", + routePath: path.Path, + httpAuthzFilters: nil, + accessLogs: &cfgSnap.Proxy.AccessLogs, + logger: s.Logger, // in the exposed check listener we don't set the tracing configuration } f, err := makeListenerFilter(filterOpts) @@ -1761,7 +1775,7 @@ func (s *ResourceGenerator) makeFilterChainTerminatingGateway(cfgSnap *proxycfg. if useHTTPFilter { var err error - opts.httpAuthzFilter, err = makeRBACHTTPFilter( + rbacFilter, err := makeRBACHTTPFilter( tgtwyOpts.intentions, cfgSnap.IntentionDefaultAllow, rbacLocalInfo{ @@ -1775,6 +1789,8 @@ func (s *ResourceGenerator) makeFilterChainTerminatingGateway(cfgSnap *proxycfg. return nil, err } + opts.httpAuthzFilters = []*envoy_http_v3.HttpFilter{rbacFilter} + opts.cluster = "" opts.useRDS = true @@ -2280,7 +2296,7 @@ type listenerFilterOpts struct { // HTTP listener filter options forwardClientDetails bool forwardClientPolicy envoy_http_v3.HttpConnectionManager_ForwardClientCertDetails - httpAuthzFilter *envoy_http_v3.HttpFilter + httpAuthzFilters []*envoy_http_v3.HttpFilter idleTimeoutMs *int requestTimeoutMs *int routeName string @@ -2486,8 +2502,8 @@ func makeHTTPFilter(opts listenerFilterOpts) (*envoy_listener_v3.Filter, error) // (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 opts.httpAuthzFilter != nil { - cfg.HttpFilters = append([]*envoy_http_v3.HttpFilter{opts.httpAuthzFilter}, cfg.HttpFilters...) + if len(opts.httpAuthzFilters) > 0 { + cfg.HttpFilters = append(opts.httpAuthzFilters, cfg.HttpFilters...) } if opts.protocol == "grpc" { diff --git a/agent/xds/listeners_ingress.go b/agent/xds/listeners_ingress.go index ea3bee476..ddea1f5c0 100644 --- a/agent/xds/listeners_ingress.go +++ b/agent/xds/listeners_ingress.go @@ -102,16 +102,16 @@ func (s *ResourceGenerator) makeIngressGatewayListeners(address string, cfgSnap listener := makeListener(listenerOpts) filterOpts := listenerFilterOpts{ - useRDS: true, - protocol: listenerKey.Protocol, - filterName: listenerKey.RouteName(), - routeName: listenerKey.RouteName(), - cluster: "", - statPrefix: "ingress_upstream_", - routePath: "", - httpAuthzFilter: nil, - accessLogs: &cfgSnap.Proxy.AccessLogs, - logger: s.Logger, + useRDS: true, + protocol: listenerKey.Protocol, + filterName: listenerKey.RouteName(), + routeName: listenerKey.RouteName(), + cluster: "", + statPrefix: "ingress_upstream_", + routePath: "", + httpAuthzFilters: nil, + accessLogs: &cfgSnap.Proxy.AccessLogs, + logger: s.Logger, } // Generate any filter chains needed for services with custom TLS certs diff --git a/agent/xds/rbac.go b/agent/xds/rbac.go index f2a50127a..d237b3e7b 100644 --- a/agent/xds/rbac.go +++ b/agent/xds/rbac.go @@ -8,6 +8,7 @@ import ( envoy_listener_v3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3" envoy_rbac_v3 "github.com/envoyproxy/go-control-plane/envoy/config/rbac/v3" envoy_route_v3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3" + envoy_http_header_to_meta_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/header_to_metadata/v3" envoy_http_rbac_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/rbac/v3" envoy_http_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3" envoy_network_rbac_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/rbac/v3" @@ -753,6 +754,90 @@ func xfccPrincipal(src rbacService) *envoy_rbac_v3.Principal { } const anyPath = `[^/]+` +const trustDomain = anyPath + "." + anyPath + +// downstreamServiceIdentityMatcher needs to match XFCC headers in two cases: +// 1. Requests to cluster peered services through a mesh gateway. In this case, the XFCC header looks like the following (I added a new line after each ; for readability) +// By=spiffe://950df996-caef-ddef-ec5f-8d18a153b7b2.consul/gateway/mesh/dc/alpha; +// Hash=...; +// Cert=...; +// Chain=...; +// Subject=""; +// URI=spiffe://c7e1d24a-eed8-10a3-286a-52bdb6b6a6fd.consul/ns/default/dc/primary/svc/s1,By=spiffe://950df996-caef-ddef-ec5f-8d18a153b7b2.consul/ns/default/dc/alpha/svc/s2; +// Hash=...; +// Cert=...; +// Chain=...; +// Subject=""; +// URI=spiffe://950df996-caef-ddef-ec5f-8d18a153b7b2.consul/gateway/mesh/dc/alpha +// +// 2. Requests directly to another service +// By=spiffe://ae9dbea8-c1dd-7356-b211-c564f7917100.consul/ns/default/dc/primary/svc/s2; +// Hash=396218588ebc1655d32a49b68cedd6b66b9de7b3d69d0c0451bc5818132377d0; +// Cert=...; +// Chain=...; +// Subject=""; +// URI=spiffe://ae9dbea8-c1dd-7356-b211-c564f7917100.consul/ns/default/dc/primary/svc/s1 +// +// In either case, the regex matches the downstream service's spiffe id because mesh gateways use a different spiffe id format. +// Envoy requires us to include the trailing and leading .* to properly extract the properly submatch. +const downstreamServiceIdentityMatcher = ".*URI=spiffe://(" + trustDomain + + ")(?:/ap/(" + anyPath + + "))?/ns/(" + anyPath + + ")/dc/(" + anyPath + + ")/svc/([^/;,]+).*" + +func parseXFCCToDynamicMetaHTTPFilter() (*envoy_http_v3.HttpFilter, error) { + var rules []*envoy_http_header_to_meta_v3.Config_Rule + + fields := []struct { + name string + sub string + }{ + { + name: "trust-domain", + sub: `\1`, + }, + { + name: "partition", + sub: `\2`, + }, + { + name: "namespace", + sub: `\3`, + }, + { + name: "datacenter", + sub: `\4`, + }, + { + name: "service", + sub: `\5`, + }, + } + + for _, f := range fields { + rules = append(rules, &envoy_http_header_to_meta_v3.Config_Rule{ + Header: "x-forwarded-client-cert", + OnHeaderPresent: &envoy_http_header_to_meta_v3.Config_KeyValuePair{ + MetadataNamespace: "consul", + Key: f.name, + RegexValueRewrite: &envoy_matcher_v3.RegexMatchAndSubstitute{ + Pattern: &envoy_matcher_v3.RegexMatcher{ + Regex: downstreamServiceIdentityMatcher, + EngineType: &envoy_matcher_v3.RegexMatcher_GoogleRe2{ + GoogleRe2: &envoy_matcher_v3.RegexMatcher_GoogleRE2{}, + }, + }, + Substitution: f.sub, + }, + }, + }) + } + + cfg := &envoy_http_header_to_meta_v3.Config{RequestRules: rules} + + return makeEnvoyHTTPFilter("envoy.filters.http.header_to_metadata", cfg) +} func makeSpiffePattern(src rbacService) string { var ( diff --git a/agent/xds/rbac_test.go b/agent/xds/rbac_test.go index dd850e2f4..e0ab50054 100644 --- a/agent/xds/rbac_test.go +++ b/agent/xds/rbac_test.go @@ -3,6 +3,7 @@ package xds import ( "fmt" "path/filepath" + "regexp" "sort" "testing" @@ -1006,3 +1007,53 @@ func makeServiceNameSlice(slice []string) []rbacService { } return out } + +func TestSpiffeMatcher(t *testing.T) { + cases := map[string]struct { + xfcc string + trustDomain string + namespace string + partition string + datacenter string + service string + }{ + "between admin partitions": { + xfcc: `By=spiffe://70c72965-291c-d138-e5a6-cfd8a66b395e.consul/ap/ap1/ns/default/dc/primary/svc/s2;Hash=377330adafa619abe52672246b7be7410d74b7497e9d88a8396d641fd6f82ad2;Cert="-----BEGIN%20CERTIFICATE-----%0AMIICGTCCAb%2BgAwIBAgIBCzAKBggqhkjOPQQDAjAwMS4wLAYDVQQDEyVwcmktMTJj%0AOWtvbS5jb25zdWwuY2EuNzBjNzI5NjUuY29uc3VsMB4XDTIyMTIyMjE0MjE1NVoX%0ADTIyMTIyNTE0MjE1NVowADBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABPuJbVdQ%0AYsT8RnvMLT%2FpsuZwltWbCkwxzBR03%2FEC4f7TyLy1Mfe6gm%2Fz5K8Tc29d7W16PBT0%0AR%2B1XPfpigopVanyjgfkwgfYwDgYDVR0PAQH%2FBAQDAgO4MB0GA1UdJQQWMBQGCCsG%0AAQUFBwMCBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMCkGA1UdDgQiBCBBxpy1QXfp%0AS4V8QFH%2BEfF39VP51Qbhlj75N5gbUSxGajArBgNVHSMEJDAigCCjWP%2BlGhzd4jbD%0A2QI66cvAAgIkLqG0lz0PyzTz76QoOzBfBgNVHREBAf8EVTBThlFzcGlmZmU6Ly83%0AMGM3Mjk2NS0yOTFjLWQxMzgtZTVhNi1jZmQ4YTY2YjM5NWUuY29uc3VsL25zL2Rl%0AZmF1bHQvZGMvcHJpbWFyeS9zdmMvczEwCgYIKoZIzj0EAwIDSAAwRQIhAJxWHplX%0Aqgmd4cRDMllJsCtOmTZ3v%2B6qDnc545tm%2Bg%2FzAiBwWOqqTZ81BtAtzzWpip1XmUFR%0Afv2SYupWQueXYrOjhw%3D%3D%0A-----END%20CERTIFICATE-----%0A";Chain="-----BEGIN%20CERTIFICATE-----%0AMIICGTCCAb%2BgAwIBAgIBCzAKBggqhkjOPQQDAjAwMS4wLAYDVQQDEyVwcmktMTJj%0AOWtvbS5jb25zdWwuY2EuNzBjNzI5NjUuY29uc3VsMB4XDTIyMTIyMjE0MjE1NVoX%0ADTIyMTIyNTE0MjE1NVowADBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABPuJbVdQ%0AYsT8RnvMLT%2FpsuZwltWbCkwxzBR03%2FEC4f7TyLy1Mfe6gm%2Fz5K8Tc29d7W16PBT0%0AR%2B1XPfpigopVanyjgfkwgfYwDgYDVR0PAQH%2FBAQDAgO4MB0GA1UdJQQWMBQGCCsG%0AAQUFBwMCBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMCkGA1UdDgQiBCBBxpy1QXfp%0AS4V8QFH%2BEfF39VP51Qbhlj75N5gbUSxGajArBgNVHSMEJDAigCCjWP%2BlGhzd4jbD%0A2QI66cvAAgIkLqG0lz0PyzTz76QoOzBfBgNVHREBAf8EVTBThlFzcGlmZmU6Ly83%0AMGM3Mjk2NS0yOTFjLWQxMzgtZTVhNi1jZmQ4YTY2YjM5NWUuY29uc3VsL25zL2Rl%0AZmF1bHQvZGMvcHJpbWFyeS9zdmMvczEwCgYIKoZIzj0EAwIDSAAwRQIhAJxWHplX%0Aqgmd4cRDMllJsCtOmTZ3v%2B6qDnc545tm%2Bg%2FzAiBwWOqqTZ81BtAtzzWpip1XmUFR%0Afv2SYupWQueXYrOjhw%3D%3D%0A-----END%20CERTIFICATE-----%0A";Subject="";URI=spiffe://70c72965-291c-d138-e5a6-cfd8a66b395e.consul/ap/ap9/ns/default/dc/primary/svc/s1`, + trustDomain: "70c72965-291c-d138-e5a6-cfd8a66b395e.consul", + namespace: "default", + partition: "ap9", + datacenter: "primary", + service: "s1", + }, + "between services": { + xfcc: `By=spiffe://f1efe25e-a9b1-1ae1-b580-98000b84a935.consul/ns/default/dc/primary/svc/s2;Hash=c552ee3990fd6e9bb38b1a8bdd28e8358c339d282e6bb92fc86d04915407f47d;Cert="-----BEGIN%20CERTIFICATE-----%0AMIICGjCCAcCgAwIBAgIBCzAKBggqhkjOPQQDAjAxMS8wLQYDVQQDEyZwcmktOGFt%0AMjNueXouY29uc3VsLmNhLmYxZWZlMjVlLmNvbnN1bDAeFw0yMjEyMjIxNTIxMDVa%0AFw0yMjEyMjUxNTIxMDVaMAAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASrChLh%0AelrBB5e8X78fSvbKxD8yieadFg4XUeJtZh2xwdWckCGDEtT984ihgM8Hu4E%2FGpgD%0AJcExohFnS4H%2BG3uco4H5MIH2MA4GA1UdDwEB%2FwQEAwIDuDAdBgNVHSUEFjAUBggr%0ABgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH%2FBAIwADApBgNVHQ4EIgQghpyuV%2F4g%0Ac6x%2B5jC9uOZQMY4Km2YZwAnSmmTydjjn7qwwKwYDVR0jBCQwIoAgdO0jdTJzfKYq%0ARCYrWbHr7q%2Bq66ispOnMs6HsEwlxV%2F8wXwYDVR0RAQH%2FBFUwU4ZRc3BpZmZlOi8v%0AZjFlZmUyNWUtYTliMS0xYWUxLWI1ODAtOTgwMDBiODRhOTM1LmNvbnN1bC9ucy9k%0AZWZhdWx0L2RjL3ByaW1hcnkvc3ZjL3MxMAoGCCqGSM49BAMCA0gAMEUCIQDTNsze%0AXCj16YvFsX0PUeUBcX4Hh0nmIkMOHCQiPkXTiAIgKJKf038s6muFJw9UQJJ5SSg%2F%0A3RL1wIWXRhsqy1Y89JQ%3D%0A-----END%20CERTIFICATE-----%0A";Chain="-----BEGIN%20CERTIFICATE-----%0AMIICGjCCAcCgAwIBAgIBCzAKBggqhkjOPQQDAjAxMS8wLQYDVQQDEyZwcmktOGFt%0AMjNueXouY29uc3VsLmNhLmYxZWZlMjVlLmNvbnN1bDAeFw0yMjEyMjIxNTIxMDVa%0AFw0yMjEyMjUxNTIxMDVaMAAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASrChLh%0AelrBB5e8X78fSvbKxD8yieadFg4XUeJtZh2xwdWckCGDEtT984ihgM8Hu4E%2FGpgD%0AJcExohFnS4H%2BG3uco4H5MIH2MA4GA1UdDwEB%2FwQEAwIDuDAdBgNVHSUEFjAUBggr%0ABgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH%2FBAIwADApBgNVHQ4EIgQghpyuV%2F4g%0Ac6x%2B5jC9uOZQMY4Km2YZwAnSmmTydjjn7qwwKwYDVR0jBCQwIoAgdO0jdTJzfKYq%0ARCYrWbHr7q%2Bq66ispOnMs6HsEwlxV%2F8wXwYDVR0RAQH%2FBFUwU4ZRc3BpZmZlOi8v%0AZjFlZmUyNWUtYTliMS0xYWUxLWI1ODAtOTgwMDBiODRhOTM1LmNvbnN1bC9ucy9k%0AZWZhdWx0L2RjL3ByaW1hcnkvc3ZjL3MxMAoGCCqGSM49BAMCA0gAMEUCIQDTNsze%0AXCj16YvFsX0PUeUBcX4Hh0nmIkMOHCQiPkXTiAIgKJKf038s6muFJw9UQJJ5SSg%2F%0A3RL1wIWXRhsqy1Y89JQ%3D%0A-----END%20CERTIFICATE-----%0A";Subject="";URI=spiffe://f1efe25e-a9b1-1ae1-b580-98000b84a935.consul/ns/default/dc/primary/svc/s1`, + trustDomain: "f1efe25e-a9b1-1ae1-b580-98000b84a935.consul", + namespace: "default", + datacenter: "primary", + service: "s1", + }, + "between peers": { + xfcc: `By=spiffe://ca9857da-71aa-c5be-ec8f-abcd90cae693.consul/gateway/mesh/dc/alpha;Hash=419c850ddc7a32edc752d73bb0f0c6e4c2f5b40feae7cf0cdeeb6f3dd759ed1f;Cert="-----BEGIN%20CERTIFICATE-----%0AMIICGzCCAcCgAwIBAgIBCzAKBggqhkjOPQQDAjAxMS8wLQYDVQQDEyZwcmktcTgw%0AdmcxMXQuY29uc3VsLmNhLmZjOWEwOGVmLmNvbnN1bDAeFw0yMjEyMjIxNTIyNTBa%0AFw0yMjEyMjUxNTIyNTBaMAAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQnQtQ6%0AFS%2FqjpopxZIaJtYL3pOx%2BgrzoLtKStCS0SUtGbTBmxmTeIX5l5HHD4yqCWk4M1Iv%0AXNflWvKcpw5KS1tLo4H5MIH2MA4GA1UdDwEB%2FwQEAwIDuDAdBgNVHSUEFjAUBggr%0ABgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH%2FBAIwADApBgNVHQ4EIgQg%2B8FyVm2p%0AdpzfijuCYeByJQH5mUkqY6%2FciCC2yScNusQwKwYDVR0jBCQwIoAgy0MyubT%2BMNQv%0A%2BuZGeBqa1yU9Fx9641epfbY%2BuSs7cbowXwYDVR0RAQH%2FBFUwU4ZRc3BpZmZlOi8v%0AZmM5YTA4ZWYtZWZiNC1iYmM5LWIzZWMtYjkzZTc2OGFiZmMyLmNvbnN1bC9ucy9k%0AZWZhdWx0L2RjL3ByaW1hcnkvc3ZjL3MxMAoGCCqGSM49BAMCA0kAMEYCIQDp7hX0%0AJ%2FjrAP71jDt2w3uKQJnfZ93d%2FRub2t%2FRwQfsVAIhAL4VUbk5XUvBzwabuEfMCf4O%0AT5rjXDbCWYNN2m4xZFtt%0A-----END%20CERTIFICATE-----%0A";Chain="-----BEGIN%20CERTIFICATE-----%0AMIICGzCCAcCgAwIBAgIBCzAKBggqhkjOPQQDAjAxMS8wLQYDVQQDEyZwcmktcTgw%0AdmcxMXQuY29uc3VsLmNhLmZjOWEwOGVmLmNvbnN1bDAeFw0yMjEyMjIxNTIyNTBa%0AFw0yMjEyMjUxNTIyNTBaMAAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQnQtQ6%0AFS%2FqjpopxZIaJtYL3pOx%2BgrzoLtKStCS0SUtGbTBmxmTeIX5l5HHD4yqCWk4M1Iv%0AXNflWvKcpw5KS1tLo4H5MIH2MA4GA1UdDwEB%2FwQEAwIDuDAdBgNVHSUEFjAUBggr%0ABgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH%2FBAIwADApBgNVHQ4EIgQg%2B8FyVm2p%0AdpzfijuCYeByJQH5mUkqY6%2FciCC2yScNusQwKwYDVR0jBCQwIoAgy0MyubT%2BMNQv%0A%2BuZGeBqa1yU9Fx9641epfbY%2BuSs7cbowXwYDVR0RAQH%2FBFUwU4ZRc3BpZmZlOi8v%0AZmM5YTA4ZWYtZWZiNC1iYmM5LWIzZWMtYjkzZTc2OGFiZmMyLmNvbnN1bC9ucy9k%0AZWZhdWx0L2RjL3ByaW1hcnkvc3ZjL3MxMAoGCCqGSM49BAMCA0kAMEYCIQDp7hX0%0AJ%2FjrAP71jDt2w3uKQJnfZ93d%2FRub2t%2FRwQfsVAIhAL4VUbk5XUvBzwabuEfMCf4O%0AT5rjXDbCWYNN2m4xZFtt%0A-----END%20CERTIFICATE-----%0A";Subject="";URI=spiffe://fc9a08ef-efb4-bbc9-b3ec-b93e768abfc2.consul/ns/default/dc/primary/svc/s1,By=spiffe://ca9857da-71aa-c5be-ec8f-abcd90cae693.consul/ns/default/dc/alpha/svc/s2;Hash=1db4ea1e68df1ea0cec7d7ba882ca734d3e1a29a0fe64e73275b6ab796234295;Cert="-----BEGIN%20CERTIFICATE-----%0AMIICEjCCAbmgAwIBAgIBDDAKBggqhkjOPQQDAjAxMS8wLQYDVQQDEyZwcmktMXky%0AZXVpbHkuY29uc3VsLmNhLmNhOTg1N2RhLmNvbnN1bDAeFw0yMjEyMjIxNTIzMDVa%0AFw0yMjEyMjUxNTIzMDVaMAAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAROaLaT%0A%2BzyYZKfujWX4vOde%2BnnsGP3z0xaEGQFbgi%2BGU%2BrFfMdadzYF1oXDItS%2FpuBADuha%0Ao0iH2i2aRPUbTm4Ko4HyMIHvMA4GA1UdDwEB%2FwQEAwIDuDAdBgNVHSUEFjAUBggr%0ABgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH%2FBAIwADApBgNVHQ4EIgQgWTznn%2BPz%0A4eNoiwdO%2FID3uqbyiBJBFbZFAGs7m5KnoCkwKwYDVR0jBCQwIoAgAdVe5N4m4Qlv%0Afgp9tvw0MGq7puWWuLfiw7qghdr1VDIwWAYDVR0RAQH%2FBE4wTIZKc3BpZmZlOi8v%0AY2E5ODU3ZGEtNzFhYS1jNWJlLWVjOGYtYWJjZDkwY2FlNjkzLmNvbnN1bC9nYXRl%0Ad2F5L21lc2gvZGMvYWxwaGEwCgYIKoZIzj0EAwIDRwAwRAIgJu5Z6O10nQe9HAzk%0ARonRMODgENawDHbErpkQ1q91ZTYCIEHccGIEp3OybkvkmIB9s%2Bu%2FbguUjJ4ZKAiD%0AV0dKf1Ao%0A-----END%20CERTIFICATE-----%0A";Chain="-----BEGIN%20CERTIFICATE-----%0AMIICEjCCAbmgAwIBAgIBDDAKBggqhkjOPQQDAjAxMS8wLQYDVQQDEyZwcmktMXky%0AZXVpbHkuY29uc3VsLmNhLmNhOTg1N2RhLmNvbnN1bDAeFw0yMjEyMjIxNTIzMDVa%0AFw0yMjEyMjUxNTIzMDVaMAAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAROaLaT%0A%2BzyYZKfujWX4vOde%2BnnsGP3z0xaEGQFbgi%2BGU%2BrFfMdadzYF1oXDItS%2FpuBADuha%0Ao0iH2i2aRPUbTm4Ko4HyMIHvMA4GA1UdDwEB%2FwQEAwIDuDAdBgNVHSUEFjAUBggr%0ABgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH%2FBAIwADApBgNVHQ4EIgQgWTznn%2BPz%0A4eNoiwdO%2FID3uqbyiBJBFbZFAGs7m5KnoCkwKwYDVR0jBCQwIoAgAdVe5N4m4Qlv%0Afgp9tvw0MGq7puWWuLfiw7qghdr1VDIwWAYDVR0RAQH%2FBE4wTIZKc3BpZmZlOi8v%0AY2E5ODU3ZGEtNzFhYS1jNWJlLWVjOGYtYWJjZDkwY2FlNjkzLmNvbnN1bC9nYXRl%0Ad2F5L21lc2gvZGMvYWxwaGEwCgYIKoZIzj0EAwIDRwAwRAIgJu5Z6O10nQe9HAzk%0ARonRMODgENawDHbErpkQ1q91ZTYCIEHccGIEp3OybkvkmIB9s%2Bu%2FbguUjJ4ZKAiD%0AV0dKf1Ao%0A-----END%20CERTIFICATE-----%0A";Subject="";URI=spiffe://ca9857da-71aa-c5be-ec8f-abcd90cae693.consul/gateway/mesh/dc/alpha`, + trustDomain: "fc9a08ef-efb4-bbc9-b3ec-b93e768abfc2.consul", + namespace: "default", + datacenter: "primary", + service: "s1", + }, + } + + re := regexp.MustCompile(downstreamServiceIdentityMatcher) + + for n, c := range cases { + t.Run(n, func(t *testing.T) { + matches := re.FindAllStringSubmatch(c.xfcc, -1) + require.Len(t, matches, 1) + + m := matches[0] + require.Equal(t, c.trustDomain, m[1]) + require.Equal(t, c.partition, m[2]) + require.Equal(t, c.namespace, m[3]) + require.Equal(t, c.datacenter, m[4]) + require.Equal(t, c.service, m[5]) + }) + } +} diff --git a/agent/xds/server.go b/agent/xds/server.go index f3d36bdad..23de8bc4b 100644 --- a/agent/xds/server.go +++ b/agent/xds/server.go @@ -48,26 +48,9 @@ var StatsSummaries = []prometheus.SummaryDefinition{ type ADSStream = envoy_discovery_v3.AggregatedDiscoveryService_StreamAggregatedResourcesServer const ( - // PublicListenerName is the name we give the public listener in Envoy config. - PublicListenerName = "public_listener" - // OutboundListenerName is the name we give the outbound Envoy listener when transparent proxy mode is enabled. OutboundListenerName = "outbound_listener" - // LocalAppClusterName is the name we give the local application "cluster" in - // Envoy config. Note that all cluster names may collide with service names - // since we want cluster names and service names to match to enable nice - // metrics correlation without massaging prefixes on cluster names. - // - // We should probably make this more unlikely to collide however changing it - // potentially breaks upgrade compatibility without restarting all Envoy's as - // it will no longer match their existing cluster name. Changing this will - // affect metrics output so could break dashboards (for local app traffic). - // - // We should probably just make it configurable if anyone actually has - // services named "local_app" in the future. - LocalAppClusterName = "local_app" - // LocalAgentClusterName is the name we give the local agent "cluster" in // Envoy config. Note that all cluster names may collide with service names // since we want cluster names and service names to match to enable nice diff --git a/agent/xds/serverlessplugin/lambda_patcher_test.go b/agent/xds/serverlessplugin/lambda_patcher_test.go deleted file mode 100644 index ff61ebbb9..000000000 --- a/agent/xds/serverlessplugin/lambda_patcher_test.go +++ /dev/null @@ -1,71 +0,0 @@ -package serverlessplugin - -import ( - "testing" - - "github.com/hashicorp/consul/agent/structs" - "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/api" -) - -func TestMakeLambdaPatcher(t *testing.T) { - kind := api.ServiceKindTerminatingGateway - cases := []struct { - name string - arn string - payloadPassthrough bool - region string - expected lambdaPatcher - ok bool - }{ - { - name: "no extension", - ok: false, - }, - { - name: "missing arn", - region: "blah", - ok: false, - }, - { - name: "missing region", - arn: "arn", - ok: false, - }, - { - name: "including payload passthrough", - arn: "arn", - region: "blah", - payloadPassthrough: true, - expected: lambdaPatcher{ - ARN: "arn", - PayloadPassthrough: true, - Region: "blah", - Kind: kind, - }, - ok: true, - }, - } - - for _, tc := range cases { - t.Run(tc.name, func(t *testing.T) { - ext := api.EnvoyExtension{ - Name: structs.BuiltinAWSLambdaExtension, - Arguments: map[string]interface{}{ - "ARN": tc.arn, - "Region": tc.region, - "PayloadPassthrough": tc.payloadPassthrough, - }, - } - - patcher, ok := makeLambdaPatcher(ext, kind) - - require.Equal(t, tc.ok, ok) - - if tc.ok { - require.Equal(t, tc.expected, patcher) - } - }) - } -} diff --git a/agent/xds/serverlessplugin/patcher.go b/agent/xds/serverlessplugin/patcher.go deleted file mode 100644 index c68533ecb..000000000 --- a/agent/xds/serverlessplugin/patcher.go +++ /dev/null @@ -1,52 +0,0 @@ -package serverlessplugin - -import ( - envoy_cluster_v3 "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3" - envoy_listener_v3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3" - envoy_route_v3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3" - - "github.com/hashicorp/consul/agent/xds/xdscommon" - "github.com/hashicorp/consul/api" -) - -// patcher is the interface that each serverless integration must implement. It -// is responsible for modifying the xDS structures based on only the state of -// the patcher. -type patcher interface { - // CanPatch determines if the patcher can mutate resources for the given api.ServiceKind - CanPatch(api.ServiceKind) bool - - // patchRoute patches a route to include the custom Envoy configuration - // PatchCluster patches a cluster to include the custom Envoy configuration - // required to integrate with the serverless integration. - PatchRoute(*envoy_route_v3.RouteConfiguration) (*envoy_route_v3.RouteConfiguration, bool, error) - - // PatchCluster patches a cluster to include the custom Envoy configuration - // required to integrate with the serverless integration. - PatchCluster(*envoy_cluster_v3.Cluster) (*envoy_cluster_v3.Cluster, bool, error) - - // PatchFilter patches an Envoy filter to include the custom Envoy - // configuration required to integrate with the serverless integration. - PatchFilter(*envoy_listener_v3.Filter) (*envoy_listener_v3.Filter, bool, error) -} - -type patchers map[api.CompoundServiceName]patcher - -func makePatcher(config xdscommon.ExtensionConfiguration) patcher { - for _, constructor := range patchConstructors { - patcher, ok := constructor(config.EnvoyExtension, config.OutgoingProxyKind()) - if ok { - return patcher - } - } - - return nil -} - -// patchConstructor is used to construct patchers based on -// xdscommon.ServiceConfig. This function contains all of the logic around -// turning Meta data into the patcher. -type patchConstructor func(extension api.EnvoyExtension, upstreamKind api.ServiceKind) (patcher, bool) - -// patchConstructors contains all patchers that getPatchers tries to create. -var patchConstructors = []patchConstructor{makeLambdaPatcher} diff --git a/agent/xds/testdata/serverless_plugin/clusters/lambda-connect-proxy-opposite-meta.latest.golden b/agent/xds/testdata/builtin_extension/clusters/lambda-connect-proxy-opposite-meta.latest.golden similarity index 100% rename from agent/xds/testdata/serverless_plugin/clusters/lambda-connect-proxy-opposite-meta.latest.golden rename to agent/xds/testdata/builtin_extension/clusters/lambda-connect-proxy-opposite-meta.latest.golden diff --git a/agent/xds/testdata/serverless_plugin/clusters/lambda-connect-proxy-with-terminating-gateway-upstream.latest.golden b/agent/xds/testdata/builtin_extension/clusters/lambda-connect-proxy-with-terminating-gateway-upstream.latest.golden similarity index 100% rename from agent/xds/testdata/serverless_plugin/clusters/lambda-connect-proxy-with-terminating-gateway-upstream.latest.golden rename to agent/xds/testdata/builtin_extension/clusters/lambda-connect-proxy-with-terminating-gateway-upstream.latest.golden diff --git a/agent/xds/testdata/serverless_plugin/clusters/lambda-connect-proxy.latest.golden b/agent/xds/testdata/builtin_extension/clusters/lambda-connect-proxy.latest.golden similarity index 100% rename from agent/xds/testdata/serverless_plugin/clusters/lambda-connect-proxy.latest.golden rename to agent/xds/testdata/builtin_extension/clusters/lambda-connect-proxy.latest.golden diff --git a/agent/xds/testdata/serverless_plugin/clusters/lambda-terminating-gateway-with-service-resolvers.latest.golden b/agent/xds/testdata/builtin_extension/clusters/lambda-terminating-gateway-with-service-resolvers.latest.golden similarity index 100% rename from agent/xds/testdata/serverless_plugin/clusters/lambda-terminating-gateway-with-service-resolvers.latest.golden rename to agent/xds/testdata/builtin_extension/clusters/lambda-terminating-gateway-with-service-resolvers.latest.golden diff --git a/agent/xds/testdata/serverless_plugin/clusters/lambda-terminating-gateway.latest.golden b/agent/xds/testdata/builtin_extension/clusters/lambda-terminating-gateway.latest.golden similarity index 100% rename from agent/xds/testdata/serverless_plugin/clusters/lambda-terminating-gateway.latest.golden rename to agent/xds/testdata/builtin_extension/clusters/lambda-terminating-gateway.latest.golden diff --git a/agent/xds/testdata/builtin_extension/clusters/lua-connect-proxy-with-terminating-gateway-upstream.latest.golden b/agent/xds/testdata/builtin_extension/clusters/lua-connect-proxy-with-terminating-gateway-upstream.latest.golden new file mode 100644 index 000000000..2e3c9ea20 --- /dev/null +++ b/agent/xds/testdata/builtin_extension/clusters/lua-connect-proxy-with-terminating-gateway-upstream.latest.golden @@ -0,0 +1,145 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.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": { + + }, + "resourceApiVersion": "V3" + } + }, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "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" + }, + "matchSubjectAltNames": [ + { + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" + } + ] + } + }, + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + } + } + }, + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + }, + "resourceApiVersion": "V3" + } + }, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "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" + }, + "matchSubjectAltNames": [ + { + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" + }, + { + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" + } + ] + } + }, + "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + } + } + }, + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "local_app", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 + } + } + } + } + ] + } + ] + } + } + ], + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/clusters/lua-inbound-applies-to-inbound.latest.golden b/agent/xds/testdata/builtin_extension/clusters/lua-inbound-applies-to-inbound.latest.golden new file mode 100644 index 000000000..2e3c9ea20 --- /dev/null +++ b/agent/xds/testdata/builtin_extension/clusters/lua-inbound-applies-to-inbound.latest.golden @@ -0,0 +1,145 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.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": { + + }, + "resourceApiVersion": "V3" + } + }, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "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" + }, + "matchSubjectAltNames": [ + { + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" + } + ] + } + }, + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + } + } + }, + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + }, + "resourceApiVersion": "V3" + } + }, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "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" + }, + "matchSubjectAltNames": [ + { + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" + }, + { + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" + } + ] + } + }, + "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + } + } + }, + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "local_app", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 + } + } + } + } + ] + } + ] + } + } + ], + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/clusters/lua-inbound-doesnt-applies-to-upstreams.latest.golden b/agent/xds/testdata/builtin_extension/clusters/lua-inbound-doesnt-applies-to-upstreams.latest.golden new file mode 100644 index 000000000..2e3c9ea20 --- /dev/null +++ b/agent/xds/testdata/builtin_extension/clusters/lua-inbound-doesnt-applies-to-upstreams.latest.golden @@ -0,0 +1,145 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.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": { + + }, + "resourceApiVersion": "V3" + } + }, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "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" + }, + "matchSubjectAltNames": [ + { + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" + } + ] + } + }, + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + } + } + }, + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + }, + "resourceApiVersion": "V3" + } + }, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "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" + }, + "matchSubjectAltNames": [ + { + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" + }, + { + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" + } + ] + } + }, + "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + } + } + }, + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "local_app", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 + } + } + } + } + ] + } + ] + } + } + ], + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/clusters/lua-outbound-applies-to-upstreams.latest.golden b/agent/xds/testdata/builtin_extension/clusters/lua-outbound-applies-to-upstreams.latest.golden new file mode 100644 index 000000000..2e3c9ea20 --- /dev/null +++ b/agent/xds/testdata/builtin_extension/clusters/lua-outbound-applies-to-upstreams.latest.golden @@ -0,0 +1,145 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.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": { + + }, + "resourceApiVersion": "V3" + } + }, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "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" + }, + "matchSubjectAltNames": [ + { + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" + } + ] + } + }, + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + } + } + }, + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + }, + "resourceApiVersion": "V3" + } + }, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "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" + }, + "matchSubjectAltNames": [ + { + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" + }, + { + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" + } + ] + } + }, + "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + } + } + }, + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "local_app", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 + } + } + } + } + ] + } + ] + } + } + ], + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/clusters/lua-outbound-doesnt-apply-to-inbound.latest.golden b/agent/xds/testdata/builtin_extension/clusters/lua-outbound-doesnt-apply-to-inbound.latest.golden new file mode 100644 index 000000000..2e3c9ea20 --- /dev/null +++ b/agent/xds/testdata/builtin_extension/clusters/lua-outbound-doesnt-apply-to-inbound.latest.golden @@ -0,0 +1,145 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.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": { + + }, + "resourceApiVersion": "V3" + } + }, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "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" + }, + "matchSubjectAltNames": [ + { + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" + } + ] + } + }, + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + } + } + }, + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + }, + "resourceApiVersion": "V3" + } + }, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "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" + }, + "matchSubjectAltNames": [ + { + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" + }, + { + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" + } + ] + } + }, + "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + } + } + }, + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "local_app", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 + } + } + } + } + ] + } + ] + } + } + ], + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/serverless_plugin/endpoints/lambda-connect-proxy-opposite-meta.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/lambda-connect-proxy-opposite-meta.latest.golden similarity index 100% rename from agent/xds/testdata/serverless_plugin/endpoints/lambda-connect-proxy-opposite-meta.latest.golden rename to agent/xds/testdata/builtin_extension/endpoints/lambda-connect-proxy-opposite-meta.latest.golden diff --git a/agent/xds/testdata/serverless_plugin/endpoints/lambda-connect-proxy-with-terminating-gateway-upstream.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/lambda-connect-proxy-with-terminating-gateway-upstream.latest.golden similarity index 100% rename from agent/xds/testdata/serverless_plugin/endpoints/lambda-connect-proxy-with-terminating-gateway-upstream.latest.golden rename to agent/xds/testdata/builtin_extension/endpoints/lambda-connect-proxy-with-terminating-gateway-upstream.latest.golden diff --git a/agent/xds/testdata/serverless_plugin/endpoints/lambda-connect-proxy.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/lambda-connect-proxy.latest.golden similarity index 100% rename from agent/xds/testdata/serverless_plugin/endpoints/lambda-connect-proxy.latest.golden rename to agent/xds/testdata/builtin_extension/endpoints/lambda-connect-proxy.latest.golden diff --git a/agent/xds/testdata/serverless_plugin/endpoints/lambda-terminating-gateway-with-service-resolvers.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/lambda-terminating-gateway-with-service-resolvers.latest.golden similarity index 100% rename from agent/xds/testdata/serverless_plugin/endpoints/lambda-terminating-gateway-with-service-resolvers.latest.golden rename to agent/xds/testdata/builtin_extension/endpoints/lambda-terminating-gateway-with-service-resolvers.latest.golden diff --git a/agent/xds/testdata/serverless_plugin/endpoints/lambda-terminating-gateway.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/lambda-terminating-gateway.latest.golden similarity index 100% rename from agent/xds/testdata/serverless_plugin/endpoints/lambda-terminating-gateway.latest.golden rename to agent/xds/testdata/builtin_extension/endpoints/lambda-terminating-gateway.latest.golden diff --git a/agent/xds/testdata/builtin_extension/endpoints/lua-connect-proxy-with-terminating-gateway-upstream.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/lua-connect-proxy-with-terminating-gateway-upstream.latest.golden new file mode 100644 index 000000000..6e4d37bc3 --- /dev/null +++ b/agent/xds/testdata/builtin_extension/endpoints/lua-connect-proxy-with-terminating-gateway-upstream.latest.golden @@ -0,0 +1,75 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 + } + } + }, + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 + }, + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 + } + } + }, + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + }, + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 + } + } + }, + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 + }, + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.20.1.2", + "portValue": 8080 + } + } + }, + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + } + ], + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/endpoints/lua-inbound-applies-to-inbound.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/lua-inbound-applies-to-inbound.latest.golden new file mode 100644 index 000000000..6e4d37bc3 --- /dev/null +++ b/agent/xds/testdata/builtin_extension/endpoints/lua-inbound-applies-to-inbound.latest.golden @@ -0,0 +1,75 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 + } + } + }, + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 + }, + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 + } + } + }, + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + }, + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 + } + } + }, + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 + }, + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.20.1.2", + "portValue": 8080 + } + } + }, + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + } + ], + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/endpoints/lua-inbound-doesnt-applies-to-upstreams.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/lua-inbound-doesnt-applies-to-upstreams.latest.golden new file mode 100644 index 000000000..6e4d37bc3 --- /dev/null +++ b/agent/xds/testdata/builtin_extension/endpoints/lua-inbound-doesnt-applies-to-upstreams.latest.golden @@ -0,0 +1,75 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 + } + } + }, + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 + }, + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 + } + } + }, + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + }, + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 + } + } + }, + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 + }, + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.20.1.2", + "portValue": 8080 + } + } + }, + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + } + ], + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/endpoints/lua-outbound-applies-to-upstreams.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/lua-outbound-applies-to-upstreams.latest.golden new file mode 100644 index 000000000..6e4d37bc3 --- /dev/null +++ b/agent/xds/testdata/builtin_extension/endpoints/lua-outbound-applies-to-upstreams.latest.golden @@ -0,0 +1,75 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 + } + } + }, + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 + }, + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 + } + } + }, + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + }, + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 + } + } + }, + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 + }, + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.20.1.2", + "portValue": 8080 + } + } + }, + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + } + ], + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/endpoints/lua-outbound-doesnt-apply-to-inbound.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/lua-outbound-doesnt-apply-to-inbound.latest.golden new file mode 100644 index 000000000..6e4d37bc3 --- /dev/null +++ b/agent/xds/testdata/builtin_extension/endpoints/lua-outbound-doesnt-apply-to-inbound.latest.golden @@ -0,0 +1,75 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 + } + } + }, + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 + }, + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 + } + } + }, + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + }, + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 + } + } + }, + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 + }, + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.20.1.2", + "portValue": 8080 + } + } + }, + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + } + ], + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/serverless_plugin/listeners/lambda-connect-proxy-opposite-meta.latest.golden b/agent/xds/testdata/builtin_extension/listeners/lambda-connect-proxy-opposite-meta.latest.golden similarity index 100% rename from agent/xds/testdata/serverless_plugin/listeners/lambda-connect-proxy-opposite-meta.latest.golden rename to agent/xds/testdata/builtin_extension/listeners/lambda-connect-proxy-opposite-meta.latest.golden diff --git a/agent/xds/testdata/serverless_plugin/listeners/lambda-connect-proxy-with-terminating-gateway-upstream.latest.golden b/agent/xds/testdata/builtin_extension/listeners/lambda-connect-proxy-with-terminating-gateway-upstream.latest.golden similarity index 100% rename from agent/xds/testdata/serverless_plugin/listeners/lambda-connect-proxy-with-terminating-gateway-upstream.latest.golden rename to agent/xds/testdata/builtin_extension/listeners/lambda-connect-proxy-with-terminating-gateway-upstream.latest.golden diff --git a/agent/xds/testdata/serverless_plugin/listeners/lambda-connect-proxy.latest.golden b/agent/xds/testdata/builtin_extension/listeners/lambda-connect-proxy.latest.golden similarity index 100% rename from agent/xds/testdata/serverless_plugin/listeners/lambda-connect-proxy.latest.golden rename to agent/xds/testdata/builtin_extension/listeners/lambda-connect-proxy.latest.golden diff --git a/agent/xds/testdata/serverless_plugin/listeners/lambda-terminating-gateway-with-service-resolvers.latest.golden b/agent/xds/testdata/builtin_extension/listeners/lambda-terminating-gateway-with-service-resolvers.latest.golden similarity index 100% rename from agent/xds/testdata/serverless_plugin/listeners/lambda-terminating-gateway-with-service-resolvers.latest.golden rename to agent/xds/testdata/builtin_extension/listeners/lambda-terminating-gateway-with-service-resolvers.latest.golden diff --git a/agent/xds/testdata/serverless_plugin/listeners/lambda-terminating-gateway.latest.golden b/agent/xds/testdata/builtin_extension/listeners/lambda-terminating-gateway.latest.golden similarity index 100% rename from agent/xds/testdata/serverless_plugin/listeners/lambda-terminating-gateway.latest.golden rename to agent/xds/testdata/builtin_extension/listeners/lambda-terminating-gateway.latest.golden diff --git a/agent/xds/testdata/builtin_extension/listeners/lua-connect-proxy-with-terminating-gateway-upstream.latest.golden b/agent/xds/testdata/builtin_extension/listeners/lua-connect-proxy-with-terminating-gateway-upstream.latest.golden new file mode 100644 index 000000000..717877fcd --- /dev/null +++ b/agent/xds/testdata/builtin_extension/listeners/lua-connect-proxy-with-terminating-gateway-upstream.latest.golden @@ -0,0 +1,152 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 9191 + } + }, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.http_connection_manager", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "statPrefix": "upstream.db.default.default.dc1", + "routeConfig": { + "name": "db", + "virtualHosts": [ + { + "name": "db.default.default.dc1", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + } + } + ] + } + ] + }, + "httpFilters": [ + { + "name": "envoy.filters.http.router", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" + } + } + ], + "tracing": { + "randomSampling": { + + } + } + } + } + ] + } + ], + "trafficDirection": "OUTBOUND" + }, + { + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", + "address": { + "socketAddress": { + "address": "127.10.10.10", + "portValue": 8181 + } + }, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + } + } + ] + } + ], + "trafficDirection": "OUTBOUND" + }, + { + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", + "address": { + "socketAddress": { + "address": "0.0.0.0", + "portValue": 9999 + } + }, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.rbac", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", + "rules": { + + }, + "statPrefix": "connect_authz" + } + }, + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "public_listener", + "cluster": "local_app" + } + } + ], + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", + "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" + } + } + }, + "requireClientCertificate": true + } + } + } + ], + "trafficDirection": "INBOUND" + } + ], + "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/listeners/lua-inbound-applies-to-inbound.latest.golden b/agent/xds/testdata/builtin_extension/listeners/lua-inbound-applies-to-inbound.latest.golden new file mode 100644 index 000000000..5b9dce5a0 --- /dev/null +++ b/agent/xds/testdata/builtin_extension/listeners/lua-inbound-applies-to-inbound.latest.golden @@ -0,0 +1,257 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 9191 + } + }, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + } + } + ] + } + ], + "trafficDirection": "OUTBOUND" + }, + { + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", + "address": { + "socketAddress": { + "address": "127.10.10.10", + "portValue": 8181 + } + }, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + } + } + ] + } + ], + "trafficDirection": "OUTBOUND" + }, + { + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", + "address": { + "socketAddress": { + "address": "0.0.0.0", + "portValue": 9999 + } + }, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.http_connection_manager", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "statPrefix": "public_listener", + "routeConfig": { + "name": "public_listener", + "virtualHosts": [ + { + "name": "public_listener", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "local_app" + } + } + ] + } + ] + }, + "httpFilters": [ + { + "name": "envoy.filters.http.rbac", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC", + "rules": { + + } + } + }, + { + "name": "envoy.filters.http.header_to_metadata", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.header_to_metadata.v3.Config", + "requestRules": [ + { + "header": "x-forwarded-client-cert", + "onHeaderPresent": { + "metadataNamespace": "consul", + "key": "trust-domain", + "regexValueRewrite": { + "pattern": { + "googleRe2": { + + }, + "regex": ".*URI=spiffe://([^/]+.[^/]+)(?:/ap/([^/]+))?/ns/([^/]+)/dc/([^/]+)/svc/([^/;,]+).*" + }, + "substitution": "\\1" + } + } + }, + { + "header": "x-forwarded-client-cert", + "onHeaderPresent": { + "metadataNamespace": "consul", + "key": "partition", + "regexValueRewrite": { + "pattern": { + "googleRe2": { + + }, + "regex": ".*URI=spiffe://([^/]+.[^/]+)(?:/ap/([^/]+))?/ns/([^/]+)/dc/([^/]+)/svc/([^/;,]+).*" + }, + "substitution": "\\2" + } + } + }, + { + "header": "x-forwarded-client-cert", + "onHeaderPresent": { + "metadataNamespace": "consul", + "key": "namespace", + "regexValueRewrite": { + "pattern": { + "googleRe2": { + + }, + "regex": ".*URI=spiffe://([^/]+.[^/]+)(?:/ap/([^/]+))?/ns/([^/]+)/dc/([^/]+)/svc/([^/;,]+).*" + }, + "substitution": "\\3" + } + } + }, + { + "header": "x-forwarded-client-cert", + "onHeaderPresent": { + "metadataNamespace": "consul", + "key": "datacenter", + "regexValueRewrite": { + "pattern": { + "googleRe2": { + + }, + "regex": ".*URI=spiffe://([^/]+.[^/]+)(?:/ap/([^/]+))?/ns/([^/]+)/dc/([^/]+)/svc/([^/;,]+).*" + }, + "substitution": "\\4" + } + } + }, + { + "header": "x-forwarded-client-cert", + "onHeaderPresent": { + "metadataNamespace": "consul", + "key": "service", + "regexValueRewrite": { + "pattern": { + "googleRe2": { + + }, + "regex": ".*URI=spiffe://([^/]+.[^/]+)(?:/ap/([^/]+))?/ns/([^/]+)/dc/([^/]+)/svc/([^/;,]+).*" + }, + "substitution": "\\5" + } + } + } + ] + } + }, + { + "name": "envoy.filters.http.lua", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua", + "inlineCode": "\nfunction envoy_on_request(request_handle)\n request_handle:headers():add(\"test\", \"test\")\nend" + } + }, + { + "name": "envoy.filters.http.router", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" + } + } + ], + "tracing": { + "randomSampling": { + + } + }, + "forwardClientCertDetails": "APPEND_FORWARD", + "setCurrentClientCertDetails": { + "subject": true, + "cert": true, + "chain": true, + "dns": true, + "uri": true + } + } + } + ], + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", + "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" + } + }, + "alpnProtocols": [ + "http/1.1" + ] + }, + "requireClientCertificate": true + } + } + } + ], + "trafficDirection": "INBOUND" + } + ], + "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/listeners/lua-inbound-doesnt-applies-to-upstreams.latest.golden b/agent/xds/testdata/builtin_extension/listeners/lua-inbound-doesnt-applies-to-upstreams.latest.golden new file mode 100644 index 000000000..717877fcd --- /dev/null +++ b/agent/xds/testdata/builtin_extension/listeners/lua-inbound-doesnt-applies-to-upstreams.latest.golden @@ -0,0 +1,152 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 9191 + } + }, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.http_connection_manager", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "statPrefix": "upstream.db.default.default.dc1", + "routeConfig": { + "name": "db", + "virtualHosts": [ + { + "name": "db.default.default.dc1", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + } + } + ] + } + ] + }, + "httpFilters": [ + { + "name": "envoy.filters.http.router", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" + } + } + ], + "tracing": { + "randomSampling": { + + } + } + } + } + ] + } + ], + "trafficDirection": "OUTBOUND" + }, + { + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", + "address": { + "socketAddress": { + "address": "127.10.10.10", + "portValue": 8181 + } + }, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + } + } + ] + } + ], + "trafficDirection": "OUTBOUND" + }, + { + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", + "address": { + "socketAddress": { + "address": "0.0.0.0", + "portValue": 9999 + } + }, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.rbac", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", + "rules": { + + }, + "statPrefix": "connect_authz" + } + }, + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "public_listener", + "cluster": "local_app" + } + } + ], + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", + "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" + } + } + }, + "requireClientCertificate": true + } + } + } + ], + "trafficDirection": "INBOUND" + } + ], + "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/listeners/lua-outbound-applies-to-upstreams.latest.golden b/agent/xds/testdata/builtin_extension/listeners/lua-outbound-applies-to-upstreams.latest.golden new file mode 100644 index 000000000..53995ae8d --- /dev/null +++ b/agent/xds/testdata/builtin_extension/listeners/lua-outbound-applies-to-upstreams.latest.golden @@ -0,0 +1,159 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 9191 + } + }, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.http_connection_manager", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "statPrefix": "upstream.db.default.default.dc1", + "routeConfig": { + "name": "db", + "virtualHosts": [ + { + "name": "db.default.default.dc1", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + } + } + ] + } + ] + }, + "httpFilters": [ + { + "name": "envoy.filters.http.lua", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua", + "inlineCode": "\nfunction envoy_on_request(request_handle)\n request_handle:headers():add(\"test\", \"test\")\nend" + } + }, + { + "name": "envoy.filters.http.router", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" + } + } + ], + "tracing": { + "randomSampling": { + + } + } + } + } + ] + } + ], + "trafficDirection": "OUTBOUND" + }, + { + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", + "address": { + "socketAddress": { + "address": "127.10.10.10", + "portValue": 8181 + } + }, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + } + } + ] + } + ], + "trafficDirection": "OUTBOUND" + }, + { + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", + "address": { + "socketAddress": { + "address": "0.0.0.0", + "portValue": 9999 + } + }, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.rbac", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", + "rules": { + + }, + "statPrefix": "connect_authz" + } + }, + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "public_listener", + "cluster": "local_app" + } + } + ], + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", + "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" + } + } + }, + "requireClientCertificate": true + } + } + } + ], + "trafficDirection": "INBOUND" + } + ], + "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/listeners/lua-outbound-doesnt-apply-to-inbound.latest.golden b/agent/xds/testdata/builtin_extension/listeners/lua-outbound-doesnt-apply-to-inbound.latest.golden new file mode 100644 index 000000000..28fe00ff2 --- /dev/null +++ b/agent/xds/testdata/builtin_extension/listeners/lua-outbound-doesnt-apply-to-inbound.latest.golden @@ -0,0 +1,250 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 9191 + } + }, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + } + } + ] + } + ], + "trafficDirection": "OUTBOUND" + }, + { + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", + "address": { + "socketAddress": { + "address": "127.10.10.10", + "portValue": 8181 + } + }, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + } + } + ] + } + ], + "trafficDirection": "OUTBOUND" + }, + { + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", + "address": { + "socketAddress": { + "address": "0.0.0.0", + "portValue": 9999 + } + }, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.http_connection_manager", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "statPrefix": "public_listener", + "routeConfig": { + "name": "public_listener", + "virtualHosts": [ + { + "name": "public_listener", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "local_app" + } + } + ] + } + ] + }, + "httpFilters": [ + { + "name": "envoy.filters.http.rbac", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC", + "rules": { + + } + } + }, + { + "name": "envoy.filters.http.header_to_metadata", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.header_to_metadata.v3.Config", + "requestRules": [ + { + "header": "x-forwarded-client-cert", + "onHeaderPresent": { + "metadataNamespace": "consul", + "key": "trust-domain", + "regexValueRewrite": { + "pattern": { + "googleRe2": { + + }, + "regex": ".*URI=spiffe://([^/]+.[^/]+)(?:/ap/([^/]+))?/ns/([^/]+)/dc/([^/]+)/svc/([^/;,]+).*" + }, + "substitution": "\\1" + } + } + }, + { + "header": "x-forwarded-client-cert", + "onHeaderPresent": { + "metadataNamespace": "consul", + "key": "partition", + "regexValueRewrite": { + "pattern": { + "googleRe2": { + + }, + "regex": ".*URI=spiffe://([^/]+.[^/]+)(?:/ap/([^/]+))?/ns/([^/]+)/dc/([^/]+)/svc/([^/;,]+).*" + }, + "substitution": "\\2" + } + } + }, + { + "header": "x-forwarded-client-cert", + "onHeaderPresent": { + "metadataNamespace": "consul", + "key": "namespace", + "regexValueRewrite": { + "pattern": { + "googleRe2": { + + }, + "regex": ".*URI=spiffe://([^/]+.[^/]+)(?:/ap/([^/]+))?/ns/([^/]+)/dc/([^/]+)/svc/([^/;,]+).*" + }, + "substitution": "\\3" + } + } + }, + { + "header": "x-forwarded-client-cert", + "onHeaderPresent": { + "metadataNamespace": "consul", + "key": "datacenter", + "regexValueRewrite": { + "pattern": { + "googleRe2": { + + }, + "regex": ".*URI=spiffe://([^/]+.[^/]+)(?:/ap/([^/]+))?/ns/([^/]+)/dc/([^/]+)/svc/([^/;,]+).*" + }, + "substitution": "\\4" + } + } + }, + { + "header": "x-forwarded-client-cert", + "onHeaderPresent": { + "metadataNamespace": "consul", + "key": "service", + "regexValueRewrite": { + "pattern": { + "googleRe2": { + + }, + "regex": ".*URI=spiffe://([^/]+.[^/]+)(?:/ap/([^/]+))?/ns/([^/]+)/dc/([^/]+)/svc/([^/;,]+).*" + }, + "substitution": "\\5" + } + } + } + ] + } + }, + { + "name": "envoy.filters.http.router", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" + } + } + ], + "tracing": { + "randomSampling": { + + } + }, + "forwardClientCertDetails": "APPEND_FORWARD", + "setCurrentClientCertDetails": { + "subject": true, + "cert": true, + "chain": true, + "dns": true, + "uri": true + } + } + } + ], + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", + "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" + } + }, + "alpnProtocols": [ + "http/1.1" + ] + }, + "requireClientCertificate": true + } + } + } + ], + "trafficDirection": "INBOUND" + } + ], + "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/serverless_plugin/routes/lambda-connect-proxy-opposite-meta.latest.golden b/agent/xds/testdata/builtin_extension/routes/lambda-connect-proxy-opposite-meta.latest.golden similarity index 100% rename from agent/xds/testdata/serverless_plugin/routes/lambda-connect-proxy-opposite-meta.latest.golden rename to agent/xds/testdata/builtin_extension/routes/lambda-connect-proxy-opposite-meta.latest.golden diff --git a/agent/xds/testdata/serverless_plugin/routes/lambda-connect-proxy-with-terminating-gateway-upstream.latest.golden b/agent/xds/testdata/builtin_extension/routes/lambda-connect-proxy-with-terminating-gateway-upstream.latest.golden similarity index 100% rename from agent/xds/testdata/serverless_plugin/routes/lambda-connect-proxy-with-terminating-gateway-upstream.latest.golden rename to agent/xds/testdata/builtin_extension/routes/lambda-connect-proxy-with-terminating-gateway-upstream.latest.golden diff --git a/agent/xds/testdata/serverless_plugin/routes/lambda-connect-proxy.latest.golden b/agent/xds/testdata/builtin_extension/routes/lambda-connect-proxy.latest.golden similarity index 100% rename from agent/xds/testdata/serverless_plugin/routes/lambda-connect-proxy.latest.golden rename to agent/xds/testdata/builtin_extension/routes/lambda-connect-proxy.latest.golden diff --git a/agent/xds/testdata/serverless_plugin/routes/lambda-terminating-gateway-with-service-resolvers.latest.golden b/agent/xds/testdata/builtin_extension/routes/lambda-terminating-gateway-with-service-resolvers.latest.golden similarity index 100% rename from agent/xds/testdata/serverless_plugin/routes/lambda-terminating-gateway-with-service-resolvers.latest.golden rename to agent/xds/testdata/builtin_extension/routes/lambda-terminating-gateway-with-service-resolvers.latest.golden diff --git a/agent/xds/testdata/serverless_plugin/routes/lambda-terminating-gateway.latest.golden b/agent/xds/testdata/builtin_extension/routes/lambda-terminating-gateway.latest.golden similarity index 100% rename from agent/xds/testdata/serverless_plugin/routes/lambda-terminating-gateway.latest.golden rename to agent/xds/testdata/builtin_extension/routes/lambda-terminating-gateway.latest.golden diff --git a/agent/xds/testdata/builtin_extension/routes/lua-connect-proxy-with-terminating-gateway-upstream.latest.golden b/agent/xds/testdata/builtin_extension/routes/lua-connect-proxy-with-terminating-gateway-upstream.latest.golden new file mode 100644 index 000000000..9c050cbe6 --- /dev/null +++ b/agent/xds/testdata/builtin_extension/routes/lua-connect-proxy-with-terminating-gateway-upstream.latest.golden @@ -0,0 +1,5 @@ +{ + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/routes/lua-inbound-applies-to-inbound.latest.golden b/agent/xds/testdata/builtin_extension/routes/lua-inbound-applies-to-inbound.latest.golden new file mode 100644 index 000000000..9c050cbe6 --- /dev/null +++ b/agent/xds/testdata/builtin_extension/routes/lua-inbound-applies-to-inbound.latest.golden @@ -0,0 +1,5 @@ +{ + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/routes/lua-inbound-doesnt-applies-to-upstreams.latest.golden b/agent/xds/testdata/builtin_extension/routes/lua-inbound-doesnt-applies-to-upstreams.latest.golden new file mode 100644 index 000000000..9c050cbe6 --- /dev/null +++ b/agent/xds/testdata/builtin_extension/routes/lua-inbound-doesnt-applies-to-upstreams.latest.golden @@ -0,0 +1,5 @@ +{ + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/routes/lua-outbound-applies-to-upstreams.latest.golden b/agent/xds/testdata/builtin_extension/routes/lua-outbound-applies-to-upstreams.latest.golden new file mode 100644 index 000000000..9c050cbe6 --- /dev/null +++ b/agent/xds/testdata/builtin_extension/routes/lua-outbound-applies-to-upstreams.latest.golden @@ -0,0 +1,5 @@ +{ + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/routes/lua-outbound-doesnt-apply-to-inbound.latest.golden b/agent/xds/testdata/builtin_extension/routes/lua-outbound-doesnt-apply-to-inbound.latest.golden new file mode 100644 index 000000000..9c050cbe6 --- /dev/null +++ b/agent/xds/testdata/builtin_extension/routes/lua-outbound-doesnt-apply-to-inbound.latest.golden @@ -0,0 +1,5 @@ +{ + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/clusters/ingress-with-chain-and-failover-to-cluster-peer.latest.golden b/agent/xds/testdata/clusters/ingress-with-chain-and-failover-to-cluster-peer.latest.golden index f21870969..f0f79211f 100644 --- a/agent/xds/testdata/clusters/ingress-with-chain-and-failover-to-cluster-peer.latest.golden +++ b/agent/xds/testdata/clusters/ingress-with-chain-and-failover-to-cluster-peer.latest.golden @@ -16,10 +16,10 @@ } }, "connectTimeout": "33s", + "lbPolicy": "CLUSTER_PROVIDED", "outlierDetection": { - }, - "lbPolicy": "CLUSTER_PROVIDED" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", diff --git a/agent/xds/testdata/clusters/ingress-with-chain-and-failover.latest.golden b/agent/xds/testdata/clusters/ingress-with-chain-and-failover.latest.golden index 13293226e..b677b081c 100644 --- a/agent/xds/testdata/clusters/ingress-with-chain-and-failover.latest.golden +++ b/agent/xds/testdata/clusters/ingress-with-chain-and-failover.latest.golden @@ -16,10 +16,10 @@ } }, "connectTimeout": "33s", + "lbPolicy": "CLUSTER_PROVIDED", "outlierDetection": { - }, - "lbPolicy": "CLUSTER_PROVIDED" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", diff --git a/agent/xds/testdata/clusters/ingress-with-defaults-passive-health-check.latest.golden b/agent/xds/testdata/clusters/ingress-with-defaults-passive-health-check.latest.golden index e380bccb1..fbbcc9856 100644 --- a/agent/xds/testdata/clusters/ingress-with-defaults-passive-health-check.latest.golden +++ b/agent/xds/testdata/clusters/ingress-with-defaults-passive-health-check.latest.golden @@ -25,9 +25,9 @@ ] }, "outlierDetection": { - "consecutive5xx": 10, - "interval": "5s", - "enforcingConsecutive5xx": 80 + "consecutive5xx": 10, + "interval": "5s", + "enforcingConsecutive5xx": 80 }, "commonLbConfig": { "healthyPanicThreshold": { diff --git a/agent/xds/testdata/clusters/ingress-with-overwrite-defaults-passive-health-check.latest.golden b/agent/xds/testdata/clusters/ingress-with-overwrite-defaults-passive-health-check.latest.golden index 8fb725c90..6c9e0802a 100644 --- a/agent/xds/testdata/clusters/ingress-with-overwrite-defaults-passive-health-check.latest.golden +++ b/agent/xds/testdata/clusters/ingress-with-overwrite-defaults-passive-health-check.latest.golden @@ -24,8 +24,8 @@ ] }, "outlierDetection": { - "interval": "8s", - "enforcingConsecutive5xx": 50 + "interval": "8s", + "enforcingConsecutive5xx": 50 }, "commonLbConfig": { "healthyPanicThreshold": { diff --git a/agent/xds/testdata/clusters/ingress-with-service-passive-health-check.latest.golden b/agent/xds/testdata/clusters/ingress-with-service-passive-health-check.latest.golden index 9242cfba7..892846151 100644 --- a/agent/xds/testdata/clusters/ingress-with-service-passive-health-check.latest.golden +++ b/agent/xds/testdata/clusters/ingress-with-service-passive-health-check.latest.golden @@ -23,8 +23,8 @@ ] }, "outlierDetection": { - "consecutive5xx": 10, - "interval": "5s" + "consecutive5xx": 10, + "interval": "5s" }, "commonLbConfig": { "healthyPanicThreshold": { diff --git a/agent/xds/testdata/clusters/ingress-with-tcp-chain-double-failover-through-local-gateway-triggered.latest.golden b/agent/xds/testdata/clusters/ingress-with-tcp-chain-double-failover-through-local-gateway-triggered.latest.golden index 1bec354e7..5c4efef3d 100644 --- a/agent/xds/testdata/clusters/ingress-with-tcp-chain-double-failover-through-local-gateway-triggered.latest.golden +++ b/agent/xds/testdata/clusters/ingress-with-tcp-chain-double-failover-through-local-gateway-triggered.latest.golden @@ -17,10 +17,10 @@ } }, "connectTimeout": "33s", + "lbPolicy": "CLUSTER_PROVIDED", "outlierDetection": { - }, - "lbPolicy": "CLUSTER_PROVIDED" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", diff --git a/agent/xds/testdata/clusters/ingress-with-tcp-chain-double-failover-through-local-gateway.latest.golden b/agent/xds/testdata/clusters/ingress-with-tcp-chain-double-failover-through-local-gateway.latest.golden index 1bec354e7..5c4efef3d 100644 --- a/agent/xds/testdata/clusters/ingress-with-tcp-chain-double-failover-through-local-gateway.latest.golden +++ b/agent/xds/testdata/clusters/ingress-with-tcp-chain-double-failover-through-local-gateway.latest.golden @@ -17,10 +17,10 @@ } }, "connectTimeout": "33s", + "lbPolicy": "CLUSTER_PROVIDED", "outlierDetection": { - }, - "lbPolicy": "CLUSTER_PROVIDED" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", diff --git a/agent/xds/testdata/clusters/ingress-with-tcp-chain-double-failover-through-remote-gateway-triggered.latest.golden b/agent/xds/testdata/clusters/ingress-with-tcp-chain-double-failover-through-remote-gateway-triggered.latest.golden index 1bec354e7..5c4efef3d 100644 --- a/agent/xds/testdata/clusters/ingress-with-tcp-chain-double-failover-through-remote-gateway-triggered.latest.golden +++ b/agent/xds/testdata/clusters/ingress-with-tcp-chain-double-failover-through-remote-gateway-triggered.latest.golden @@ -17,10 +17,10 @@ } }, "connectTimeout": "33s", + "lbPolicy": "CLUSTER_PROVIDED", "outlierDetection": { - }, - "lbPolicy": "CLUSTER_PROVIDED" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", diff --git a/agent/xds/testdata/clusters/ingress-with-tcp-chain-double-failover-through-remote-gateway.latest.golden b/agent/xds/testdata/clusters/ingress-with-tcp-chain-double-failover-through-remote-gateway.latest.golden index 1bec354e7..5c4efef3d 100644 --- a/agent/xds/testdata/clusters/ingress-with-tcp-chain-double-failover-through-remote-gateway.latest.golden +++ b/agent/xds/testdata/clusters/ingress-with-tcp-chain-double-failover-through-remote-gateway.latest.golden @@ -17,10 +17,10 @@ } }, "connectTimeout": "33s", + "lbPolicy": "CLUSTER_PROVIDED", "outlierDetection": { - }, - "lbPolicy": "CLUSTER_PROVIDED" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", diff --git a/agent/xds/testdata/clusters/ingress-with-tcp-chain-failover-through-local-gateway-triggered.latest.golden b/agent/xds/testdata/clusters/ingress-with-tcp-chain-failover-through-local-gateway-triggered.latest.golden index 1795b2569..7bec8f6fe 100644 --- a/agent/xds/testdata/clusters/ingress-with-tcp-chain-failover-through-local-gateway-triggered.latest.golden +++ b/agent/xds/testdata/clusters/ingress-with-tcp-chain-failover-through-local-gateway-triggered.latest.golden @@ -16,10 +16,10 @@ } }, "connectTimeout": "33s", + "lbPolicy": "CLUSTER_PROVIDED", "outlierDetection": { - }, - "lbPolicy": "CLUSTER_PROVIDED" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", diff --git a/agent/xds/testdata/clusters/ingress-with-tcp-chain-failover-through-local-gateway.latest.golden b/agent/xds/testdata/clusters/ingress-with-tcp-chain-failover-through-local-gateway.latest.golden index 1795b2569..7bec8f6fe 100644 --- a/agent/xds/testdata/clusters/ingress-with-tcp-chain-failover-through-local-gateway.latest.golden +++ b/agent/xds/testdata/clusters/ingress-with-tcp-chain-failover-through-local-gateway.latest.golden @@ -16,10 +16,10 @@ } }, "connectTimeout": "33s", + "lbPolicy": "CLUSTER_PROVIDED", "outlierDetection": { - }, - "lbPolicy": "CLUSTER_PROVIDED" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", diff --git a/agent/xds/testdata/clusters/ingress-with-tcp-chain-failover-through-remote-gateway-triggered.latest.golden b/agent/xds/testdata/clusters/ingress-with-tcp-chain-failover-through-remote-gateway-triggered.latest.golden index 1795b2569..7bec8f6fe 100644 --- a/agent/xds/testdata/clusters/ingress-with-tcp-chain-failover-through-remote-gateway-triggered.latest.golden +++ b/agent/xds/testdata/clusters/ingress-with-tcp-chain-failover-through-remote-gateway-triggered.latest.golden @@ -16,10 +16,10 @@ } }, "connectTimeout": "33s", + "lbPolicy": "CLUSTER_PROVIDED", "outlierDetection": { - }, - "lbPolicy": "CLUSTER_PROVIDED" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", diff --git a/agent/xds/testdata/clusters/ingress-with-tcp-chain-failover-through-remote-gateway.latest.golden b/agent/xds/testdata/clusters/ingress-with-tcp-chain-failover-through-remote-gateway.latest.golden index 1795b2569..7bec8f6fe 100644 --- a/agent/xds/testdata/clusters/ingress-with-tcp-chain-failover-through-remote-gateway.latest.golden +++ b/agent/xds/testdata/clusters/ingress-with-tcp-chain-failover-through-remote-gateway.latest.golden @@ -16,10 +16,10 @@ } }, "connectTimeout": "33s", + "lbPolicy": "CLUSTER_PROVIDED", "outlierDetection": { - }, - "lbPolicy": "CLUSTER_PROVIDED" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", diff --git a/agent/xds/testdata/listeners/custom-trace-listener.latest.golden b/agent/xds/testdata/listeners/custom-trace-listener.latest.golden index 95c1aa63c..fb23d2644 100644 --- a/agent/xds/testdata/listeners/custom-trace-listener.latest.golden +++ b/agent/xds/testdata/listeners/custom-trace-listener.latest.golden @@ -99,6 +99,94 @@ } } }, + { + "name": "envoy.filters.http.header_to_metadata", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.header_to_metadata.v3.Config", + "requestRules": [ + { + "header": "x-forwarded-client-cert", + "onHeaderPresent": { + "metadataNamespace": "consul", + "key": "trust-domain", + "regexValueRewrite": { + "pattern": { + "googleRe2": { + + }, + "regex": ".*URI=spiffe://([^/]+.[^/]+)(?:/ap/([^/]+))?/ns/([^/]+)/dc/([^/]+)/svc/([^/;,]+).*" + }, + "substitution": "\\1" + } + } + }, + { + "header": "x-forwarded-client-cert", + "onHeaderPresent": { + "metadataNamespace": "consul", + "key": "partition", + "regexValueRewrite": { + "pattern": { + "googleRe2": { + + }, + "regex": ".*URI=spiffe://([^/]+.[^/]+)(?:/ap/([^/]+))?/ns/([^/]+)/dc/([^/]+)/svc/([^/;,]+).*" + }, + "substitution": "\\2" + } + } + }, + { + "header": "x-forwarded-client-cert", + "onHeaderPresent": { + "metadataNamespace": "consul", + "key": "namespace", + "regexValueRewrite": { + "pattern": { + "googleRe2": { + + }, + "regex": ".*URI=spiffe://([^/]+.[^/]+)(?:/ap/([^/]+))?/ns/([^/]+)/dc/([^/]+)/svc/([^/;,]+).*" + }, + "substitution": "\\3" + } + } + }, + { + "header": "x-forwarded-client-cert", + "onHeaderPresent": { + "metadataNamespace": "consul", + "key": "datacenter", + "regexValueRewrite": { + "pattern": { + "googleRe2": { + + }, + "regex": ".*URI=spiffe://([^/]+.[^/]+)(?:/ap/([^/]+))?/ns/([^/]+)/dc/([^/]+)/svc/([^/;,]+).*" + }, + "substitution": "\\4" + } + } + }, + { + "header": "x-forwarded-client-cert", + "onHeaderPresent": { + "metadataNamespace": "consul", + "key": "service", + "regexValueRewrite": { + "pattern": { + "googleRe2": { + + }, + "regex": ".*URI=spiffe://([^/]+.[^/]+)(?:/ap/([^/]+))?/ns/([^/]+)/dc/([^/]+)/svc/([^/;,]+).*" + }, + "substitution": "\\5" + } + } + } + ] + } + }, { "name": "envoy.filters.http.router", "typedConfig": { diff --git a/agent/xds/testdata/listeners/grpc-public-listener.latest.golden b/agent/xds/testdata/listeners/grpc-public-listener.latest.golden index 04493913f..22bf9854c 100644 --- a/agent/xds/testdata/listeners/grpc-public-listener.latest.golden +++ b/agent/xds/testdata/listeners/grpc-public-listener.latest.golden @@ -126,14 +126,6 @@ }, "http2ProtocolOptions": { - }, - "forwardClientCertDetails": "APPEND_FORWARD", - "setCurrentClientCertDetails": { - "subject": true, - "cert": true, - "chain": true, - "dns": true, - "uri": true } } } diff --git a/agent/xds/testdata/listeners/http-listener-with-timeouts.latest.golden b/agent/xds/testdata/listeners/http-listener-with-timeouts.latest.golden index a3c58e2ab..f44314911 100644 --- a/agent/xds/testdata/listeners/http-listener-with-timeouts.latest.golden +++ b/agent/xds/testdata/listeners/http-listener-with-timeouts.latest.golden @@ -101,6 +101,94 @@ } } }, + { + "name": "envoy.filters.http.header_to_metadata", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.header_to_metadata.v3.Config", + "requestRules": [ + { + "header": "x-forwarded-client-cert", + "onHeaderPresent": { + "metadataNamespace": "consul", + "key": "trust-domain", + "regexValueRewrite": { + "pattern": { + "googleRe2": { + + }, + "regex": ".*URI=spiffe://([^/]+.[^/]+)(?:/ap/([^/]+))?/ns/([^/]+)/dc/([^/]+)/svc/([^/;,]+).*" + }, + "substitution": "\\1" + } + } + }, + { + "header": "x-forwarded-client-cert", + "onHeaderPresent": { + "metadataNamespace": "consul", + "key": "partition", + "regexValueRewrite": { + "pattern": { + "googleRe2": { + + }, + "regex": ".*URI=spiffe://([^/]+.[^/]+)(?:/ap/([^/]+))?/ns/([^/]+)/dc/([^/]+)/svc/([^/;,]+).*" + }, + "substitution": "\\2" + } + } + }, + { + "header": "x-forwarded-client-cert", + "onHeaderPresent": { + "metadataNamespace": "consul", + "key": "namespace", + "regexValueRewrite": { + "pattern": { + "googleRe2": { + + }, + "regex": ".*URI=spiffe://([^/]+.[^/]+)(?:/ap/([^/]+))?/ns/([^/]+)/dc/([^/]+)/svc/([^/;,]+).*" + }, + "substitution": "\\3" + } + } + }, + { + "header": "x-forwarded-client-cert", + "onHeaderPresent": { + "metadataNamespace": "consul", + "key": "datacenter", + "regexValueRewrite": { + "pattern": { + "googleRe2": { + + }, + "regex": ".*URI=spiffe://([^/]+.[^/]+)(?:/ap/([^/]+))?/ns/([^/]+)/dc/([^/]+)/svc/([^/;,]+).*" + }, + "substitution": "\\4" + } + } + }, + { + "header": "x-forwarded-client-cert", + "onHeaderPresent": { + "metadataNamespace": "consul", + "key": "service", + "regexValueRewrite": { + "pattern": { + "googleRe2": { + + }, + "regex": ".*URI=spiffe://([^/]+.[^/]+)(?:/ap/([^/]+))?/ns/([^/]+)/dc/([^/]+)/svc/([^/;,]+).*" + }, + "substitution": "\\5" + } + } + } + ] + } + }, { "name": "envoy.filters.http.router", "typedConfig": { diff --git a/agent/xds/testdata/listeners/http-public-listener.latest.golden b/agent/xds/testdata/listeners/http-public-listener.latest.golden index c7a70d337..28fe00ff2 100644 --- a/agent/xds/testdata/listeners/http-public-listener.latest.golden +++ b/agent/xds/testdata/listeners/http-public-listener.latest.golden @@ -99,6 +99,94 @@ } } }, + { + "name": "envoy.filters.http.header_to_metadata", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.header_to_metadata.v3.Config", + "requestRules": [ + { + "header": "x-forwarded-client-cert", + "onHeaderPresent": { + "metadataNamespace": "consul", + "key": "trust-domain", + "regexValueRewrite": { + "pattern": { + "googleRe2": { + + }, + "regex": ".*URI=spiffe://([^/]+.[^/]+)(?:/ap/([^/]+))?/ns/([^/]+)/dc/([^/]+)/svc/([^/;,]+).*" + }, + "substitution": "\\1" + } + } + }, + { + "header": "x-forwarded-client-cert", + "onHeaderPresent": { + "metadataNamespace": "consul", + "key": "partition", + "regexValueRewrite": { + "pattern": { + "googleRe2": { + + }, + "regex": ".*URI=spiffe://([^/]+.[^/]+)(?:/ap/([^/]+))?/ns/([^/]+)/dc/([^/]+)/svc/([^/;,]+).*" + }, + "substitution": "\\2" + } + } + }, + { + "header": "x-forwarded-client-cert", + "onHeaderPresent": { + "metadataNamespace": "consul", + "key": "namespace", + "regexValueRewrite": { + "pattern": { + "googleRe2": { + + }, + "regex": ".*URI=spiffe://([^/]+.[^/]+)(?:/ap/([^/]+))?/ns/([^/]+)/dc/([^/]+)/svc/([^/;,]+).*" + }, + "substitution": "\\3" + } + } + }, + { + "header": "x-forwarded-client-cert", + "onHeaderPresent": { + "metadataNamespace": "consul", + "key": "datacenter", + "regexValueRewrite": { + "pattern": { + "googleRe2": { + + }, + "regex": ".*URI=spiffe://([^/]+.[^/]+)(?:/ap/([^/]+))?/ns/([^/]+)/dc/([^/]+)/svc/([^/;,]+).*" + }, + "substitution": "\\4" + } + } + }, + { + "header": "x-forwarded-client-cert", + "onHeaderPresent": { + "metadataNamespace": "consul", + "key": "service", + "regexValueRewrite": { + "pattern": { + "googleRe2": { + + }, + "regex": ".*URI=spiffe://([^/]+.[^/]+)(?:/ap/([^/]+))?/ns/([^/]+)/dc/([^/]+)/svc/([^/;,]+).*" + }, + "substitution": "\\5" + } + } + } + ] + } + }, { "name": "envoy.filters.http.router", "typedConfig": { diff --git a/agent/xds/testdata/listeners/http2-public-listener.latest.golden b/agent/xds/testdata/listeners/http2-public-listener.latest.golden index cf6f0150a..cf4e8c776 100644 --- a/agent/xds/testdata/listeners/http2-public-listener.latest.golden +++ b/agent/xds/testdata/listeners/http2-public-listener.latest.golden @@ -99,6 +99,94 @@ } } }, + { + "name": "envoy.filters.http.header_to_metadata", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.header_to_metadata.v3.Config", + "requestRules": [ + { + "header": "x-forwarded-client-cert", + "onHeaderPresent": { + "metadataNamespace": "consul", + "key": "trust-domain", + "regexValueRewrite": { + "pattern": { + "googleRe2": { + + }, + "regex": ".*URI=spiffe://([^/]+.[^/]+)(?:/ap/([^/]+))?/ns/([^/]+)/dc/([^/]+)/svc/([^/;,]+).*" + }, + "substitution": "\\1" + } + } + }, + { + "header": "x-forwarded-client-cert", + "onHeaderPresent": { + "metadataNamespace": "consul", + "key": "partition", + "regexValueRewrite": { + "pattern": { + "googleRe2": { + + }, + "regex": ".*URI=spiffe://([^/]+.[^/]+)(?:/ap/([^/]+))?/ns/([^/]+)/dc/([^/]+)/svc/([^/;,]+).*" + }, + "substitution": "\\2" + } + } + }, + { + "header": "x-forwarded-client-cert", + "onHeaderPresent": { + "metadataNamespace": "consul", + "key": "namespace", + "regexValueRewrite": { + "pattern": { + "googleRe2": { + + }, + "regex": ".*URI=spiffe://([^/]+.[^/]+)(?:/ap/([^/]+))?/ns/([^/]+)/dc/([^/]+)/svc/([^/;,]+).*" + }, + "substitution": "\\3" + } + } + }, + { + "header": "x-forwarded-client-cert", + "onHeaderPresent": { + "metadataNamespace": "consul", + "key": "datacenter", + "regexValueRewrite": { + "pattern": { + "googleRe2": { + + }, + "regex": ".*URI=spiffe://([^/]+.[^/]+)(?:/ap/([^/]+))?/ns/([^/]+)/dc/([^/]+)/svc/([^/;,]+).*" + }, + "substitution": "\\4" + } + } + }, + { + "header": "x-forwarded-client-cert", + "onHeaderPresent": { + "metadataNamespace": "consul", + "key": "service", + "regexValueRewrite": { + "pattern": { + "googleRe2": { + + }, + "regex": ".*URI=spiffe://([^/]+.[^/]+)(?:/ap/([^/]+))?/ns/([^/]+)/dc/([^/]+)/svc/([^/;,]+).*" + }, + "substitution": "\\5" + } + } + } + ] + } + }, { "name": "envoy.filters.http.router", "typedConfig": { diff --git a/agent/xds/testdata/routes/ingress-with-chain-and-router.latest.golden b/agent/xds/testdata/routes/ingress-with-chain-and-router.latest.golden index 17c660358..ffe731399 100644 --- a/agent/xds/testdata/routes/ingress-with-chain-and-router.latest.golden +++ b/agent/xds/testdata/routes/ingress-with-chain-and-router.latest.golden @@ -275,7 +275,7 @@ "timeout": "33s" } }, - { + { "match": { "prefix": "/idle-timeout" }, diff --git a/agent/xds/xdscommon/xdscommon.go b/agent/xds/xdscommon/xdscommon.go index 7ed2d6eff..26670b4b6 100644 --- a/agent/xds/xdscommon/xdscommon.go +++ b/agent/xds/xdscommon/xdscommon.go @@ -26,8 +26,30 @@ const ( // ListenerType is the TypeURL for Listener discovery responses. ListenerType = apiTypePrefix + "envoy.config.listener.v3.Listener" + + // PublicListenerName is the name we give the public listener in Envoy config. + PublicListenerName = "public_listener" + + // LocalAppClusterName is the name we give the local application "cluster" in + // Envoy config. Note that all cluster names may collide with service names + // since we want cluster names and service names to match to enable nice + // metrics correlation without massaging prefixes on cluster names. + // + // We should probably make this more unlikely to collide however changing it + // potentially breaks upgrade compatibility without restarting all Envoy's as + // it will no longer match their existing cluster name. Changing this will + // affect metrics output so could break dashboards (for local app traffic). + // + // We should probably just make it configurable if anyone actually has + // services named "local_app" in the future. + LocalAppClusterName = "local_app" ) +type EnvoyExtension interface { + Extend(*IndexedResources, ExtensionConfiguration) (*IndexedResources, error) + Validate(ExtensionConfiguration) error +} + type IndexedResources struct { // Index is a map of typeURL => resourceName => resource Index map[string]map[string]proto.Message diff --git a/api/config_entry.go b/api/config_entry.go index 0b905a182..8649e16ea 100644 --- a/api/config_entry.go +++ b/api/config_entry.go @@ -28,6 +28,11 @@ const ( MeshConfigMesh string = "mesh" ) +const ( + BuiltinAWSLambdaExtension string = "builtin/aws/lambda" + BuiltinLuaExtension string = "builtin/lua" +) + type ConfigEntry interface { GetKind() string GetName() string diff --git a/test/integration/connect/envoy/case-cross-peers-http/alpha/setup.sh b/test/integration/connect/envoy/case-cross-peers-http/alpha/setup.sh index 2a8edf8c7..d25840b74 100644 --- a/test/integration/connect/envoy/case-cross-peers-http/alpha/setup.sh +++ b/test/integration/connect/envoy/case-cross-peers-http/alpha/setup.sh @@ -25,6 +25,31 @@ services = [ ] ' +upsert_config_entry alpha ' +Kind = "service-defaults" +Name = "s2" +Protocol = "http" +EnvoyExtensions = [ + { + Name = "builtin/lua", + Arguments = { + ProxyType = "connect-proxy" + Listener = "inbound" + Script = <<-EOF +function envoy_on_request(request_handle) + meta = request_handle:streamInfo():dynamicMetadata() + m = meta:get("consul") + request_handle:headers():add("x-consul-service", m["service"]) + request_handle:headers():add("x-consul-namespace", m["namespace"]) + request_handle:headers():add("x-consul-datacenter", m["datacenter"]) + request_handle:headers():add("x-consul-trust-domain", m["trust-domain"]) +end + EOF + } + } +] +' + register_services alpha gen_envoy_bootstrap s2 19002 alpha diff --git a/test/integration/connect/envoy/case-cross-peers-http/primary/verify.bats b/test/integration/connect/envoy/case-cross-peers-http/primary/verify.bats index 7ae3901d9..81b9d1014 100644 --- a/test/integration/connect/envoy/case-cross-peers-http/primary/verify.bats +++ b/test/integration/connect/envoy/case-cross-peers-http/primary/verify.bats @@ -55,3 +55,16 @@ load helpers @test "s1 upstream made 1 connection to s2" { assert_envoy_metric_at_least 127.0.0.1:19000 "cluster.s2.default.primary-to-alpha.external.*cx_total" 1 } + +@test "test lua adding a header" { + run retry_default curl -s -f \ + "localhost:5000/debug?env=dump" + + + [ "$status" == "0" ] + + echo "$output" | grep -E "X-Consul-Service: s1" + echo "$output" | grep -E "X-Consul-Datacenter: primary" + echo "$output" | grep -E "X-Consul-Namespace: default" + echo "$output" | grep -E "X-Consul-Trust-Domain: (\w+-){4}\w+.consul" +} diff --git a/test/integration/connect/envoy/case-http/verify.bats b/test/integration/connect/envoy/case-http/verify.bats index b322205c0..646928aaf 100644 --- a/test/integration/connect/envoy/case-http/verify.bats +++ b/test/integration/connect/envoy/case-http/verify.bats @@ -65,7 +65,7 @@ load helpers echo "PUB = $PUB" echo "UPS = $UPS" - [ "$PUB" = "envoy.filters.http.rbac,envoy.filters.http.router" ] + [ "$PUB" = "envoy.filters.http.rbac,envoy.filters.http.header_to_metadata,envoy.filters.http.router" ] [ "$UPS" = "envoy.filters.http.router" ] } @@ -85,5 +85,5 @@ load helpers echo "HTTP_FILTERS = $HTTP_FILTERS" echo "PUB = $PUB" - [ "$PUB" = "envoy.filters.http.rbac,envoy.filters.http.router" ] + [ "$PUB" = "envoy.filters.http.rbac,envoy.filters.http.header_to_metadata,envoy.filters.http.router" ] } diff --git a/test/integration/connect/envoy/case-lua/capture.sh b/test/integration/connect/envoy/case-lua/capture.sh new file mode 100644 index 000000000..1a11f7d5e --- /dev/null +++ b/test/integration/connect/envoy/case-lua/capture.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +snapshot_envoy_admin localhost:19000 s1 primary || true +snapshot_envoy_admin localhost:19001 s2 primary || true diff --git a/test/integration/connect/envoy/case-lua/service_s1.hcl b/test/integration/connect/envoy/case-lua/service_s1.hcl new file mode 100644 index 000000000..0d8957c00 --- /dev/null +++ b/test/integration/connect/envoy/case-lua/service_s1.hcl @@ -0,0 +1,16 @@ +services { + name = "s1" + port = 8080 + connect { + sidecar_service { + proxy { + upstreams = [ + { + destination_name = "s2" + local_bind_port = 5000 + } + ] + } + } + } +} diff --git a/test/integration/connect/envoy/case-lua/service_s2.hcl b/test/integration/connect/envoy/case-lua/service_s2.hcl new file mode 100644 index 000000000..9c23e79c7 --- /dev/null +++ b/test/integration/connect/envoy/case-lua/service_s2.hcl @@ -0,0 +1,5 @@ +services { + name = "s2" + port = 8181 + connect { sidecar_service {} } +} diff --git a/test/integration/connect/envoy/case-lua/setup.sh b/test/integration/connect/envoy/case-lua/setup.sh new file mode 100644 index 000000000..ee88be1f2 --- /dev/null +++ b/test/integration/connect/envoy/case-lua/setup.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +set -eEuo pipefail + +upsert_config_entry primary ' +Kind = "service-defaults" +Name = "s2" +Protocol = "http" +EnvoyExtensions = [ + { + Name = "builtin/lua", + Arguments = { + ProxyType = "connect-proxy" + Listener = "inbound" + Script = <<-EOF +function envoy_on_request(request_handle) + meta = request_handle:streamInfo():dynamicMetadata() + m = meta:get("consul") + request_handle:headers():add("x-consul-service", m["service"]) + request_handle:headers():add("x-consul-namespace", m["namespace"]) + request_handle:headers():add("x-consul-datacenter", m["datacenter"]) + request_handle:headers():add("x-consul-trust-domain", m["trust-domain"]) +end + EOF + } + } +] +' + +register_services primary + +gen_envoy_bootstrap s1 19000 primary +gen_envoy_bootstrap s2 19001 primary diff --git a/test/integration/connect/envoy/case-lua/vars.sh b/test/integration/connect/envoy/case-lua/vars.sh new file mode 100644 index 000000000..433e50c1b --- /dev/null +++ b/test/integration/connect/envoy/case-lua/vars.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +export REQUIRED_SERVICES="s1 s1-sidecar-proxy s2 s2-sidecar-proxy" diff --git a/test/integration/connect/envoy/case-lua/verify.bats b/test/integration/connect/envoy/case-lua/verify.bats new file mode 100644 index 000000000..762f8f1c3 --- /dev/null +++ b/test/integration/connect/envoy/case-lua/verify.bats @@ -0,0 +1,39 @@ +#!/usr/bin/env bats + +load helpers + +@test "s1 proxy admin is up on :19000" { + retry_default curl -f -s localhost:19000/stats -o /dev/null +} + +@test "s2 proxy admin is up on :19001" { + retry_default curl -f -s localhost:19001/stats -o /dev/null +} + +@test "s1 proxy listener should be up and have right cert" { + assert_proxy_presents_cert_uri localhost:21000 s1 +} + +@test "s2 proxy listener should be up and have right cert" { + assert_proxy_presents_cert_uri localhost:21001 s2 +} + +@test "s2 proxy should be healthy" { + assert_service_has_healthy_instances s2 1 +} + +@test "s1 upstream should have healthy endpoints for s2" { + assert_upstream_has_endpoints_in_status 127.0.0.1:19000 s2.default.primary HEALTHY 1 +} + +@test "test lua adding a header" { + run retry_default curl -s -f \ + "localhost:5000/debug?env=dump" + + [ "$status" == "0" ] + + echo "$output" | grep -E "X-Consul-Service: s1" + echo "$output" | grep -E "X-Consul-Datacenter: primary" + echo "$output" | grep -E "X-Consul-Namespace: default" + echo "$output" | grep -E "X-Consul-Trust-Domain: (\w+-){4}\w+.consul" +}