Update filter chain creation for sidecar/ingress listeners (#11245)

The duo of `makeUpstreamFilterChainForDiscoveryChain` and `makeListenerForDiscoveryChain` were really hard to reason about, and led to concealing a bug in their branching logic. There were several issues here:

- They tried to accomplish too much: determining filter name, cluster name, and whether RDS should be used. 
- They embedded logic to handle significantly different kinds of upstream listeners (passthrough, prepared query, typical services, and catch-all)
- They needed to coalesce different data sources (Upstream and CompiledDiscoveryChain)

Rather than handling all of those tasks inside of these functions, this PR pulls out the RDS/clusterName/filterName logic.

This refactor also fixed a bug with the handling of [UpstreamDefaults](https://www.consul.io/docs/connect/config-entries/service-defaults#defaults). These defaults get stored as UpstreamConfig in the proxy snapshot with a DestinationName of "*", since they apply to all upstreams. However, this wildcard destination name must not be used when creating the name of the associated upstream cluster. The coalescing logic in the original functions here was in some situations creating clusters with a `*.` prefix, which is not a valid destination.
This commit is contained in:
Freddy 2021-11-09 14:43:51 -07:00 committed by GitHub
parent ab55e230bd
commit eb2b40b22d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 289 additions and 266 deletions

3
.changelog/11245.txt Normal file
View File

@ -0,0 +1,3 @@
```release-note:bug
connect: fix issue with attempting to generate an invalid upstream cluster from UpstreamConfig.Defaults.
```

View File

@ -114,11 +114,12 @@ func copyProxyConfig(ns *structs.NodeService) (structs.ConnectProxyConfig, error
for idx := range proxyCfg.Upstreams { for idx := range proxyCfg.Upstreams {
us := &proxyCfg.Upstreams[idx] us := &proxyCfg.Upstreams[idx]
if us.DestinationType != structs.UpstreamDestTypePreparedQuery && us.DestinationNamespace == "" { if us.DestinationType != structs.UpstreamDestTypePreparedQuery && us.DestinationNamespace == "" {
// default the upstreams target namespace to the namespace of the proxy // default the upstreams target namespace and partition to those of the proxy
// doing this here prevents needing much more complex logic a bunch of other // doing this here prevents needing much more complex logic a bunch of other
// places and makes tracking these upstreams simpler as we can dedup them // places and makes tracking these upstreams simpler as we can dedup them
// with the maps tracking upstream ids being watched. // with the maps tracking upstream ids being watched.
proxyCfg.Upstreams[idx].DestinationNamespace = ns.EnterpriseMeta.NamespaceOrDefault() proxyCfg.Upstreams[idx].DestinationNamespace = ns.EnterpriseMeta.NamespaceOrDefault()
proxyCfg.Upstreams[idx].DestinationPartition = ns.EnterpriseMeta.PartitionOrDefault()
} }
} }

View File

@ -1686,6 +1686,7 @@ func TestState_WatchesAndUpdates(t *testing.T) {
db.String(): { db.String(): {
DestinationName: "db", DestinationName: "db",
DestinationNamespace: structs.IntentionDefaultNamespace, DestinationNamespace: structs.IntentionDefaultNamespace,
DestinationPartition: structs.IntentionDefaultNamespace,
}, },
} }
require.Equal(t, expectUpstreams, snap.ConnectProxy.UpstreamConfig) require.Equal(t, expectUpstreams, snap.ConnectProxy.UpstreamConfig)

View File

@ -107,17 +107,31 @@ func (s *ResourceGenerator) listenersFromSnapshotConnectProxy(cfgSnap *proxycfg.
continue continue
} }
// RDS, Envoy's Route Discovery Service, is only used for HTTP services with a customized discovery chain.
useRDS := chain.Protocol != "tcp" && !chain.IsDefault()
var clusterName string
if !useRDS {
// When not using RDS we must generate a cluster name to attach to the filter chain.
// With RDS, cluster names get attached to the dynamic routes instead.
target, err := simpleChainTarget(chain)
if err != nil {
return nil, err
}
clusterName = CustomizeClusterName(target.Name, chain)
}
filterName := fmt.Sprintf("%s.%s.%s.%s", chain.ServiceName, chain.Namespace, chain.Partition, chain.Datacenter)
// Generate the upstream listeners for when they are explicitly set with a local bind port or socket path // Generate the upstream listeners for when they are explicitly set with a local bind port or socket path
if outboundListener == nil || (upstreamCfg != nil && upstreamCfg.HasLocalPortOrSocket()) { if upstreamCfg != nil && upstreamCfg.HasLocalPortOrSocket() {
filterChain, err := s.makeUpstreamFilterChainForDiscoveryChain( filterChain, err := s.makeUpstreamFilterChain(filterChainOpts{
id, routeName: id,
"", clusterName: clusterName,
cfg.Protocol, filterName: filterName,
upstreamCfg, protocol: cfg.Protocol,
chain, useRDS: useRDS,
cfgSnap, })
nil,
)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -135,15 +149,14 @@ func (s *ResourceGenerator) listenersFromSnapshotConnectProxy(cfgSnap *proxycfg.
// The rest of this loop is used exclusively for transparent proxies. // The rest of this loop is used exclusively for transparent proxies.
// Below we create a filter chain per upstream, rather than a listener per upstream // Below we create a filter chain per upstream, rather than a listener per upstream
// as we do for explicit upstreams above. // as we do for explicit upstreams above.
filterChain, err := s.makeUpstreamFilterChainForDiscoveryChain(
id, filterChain, err := s.makeUpstreamFilterChain(filterChainOpts{
"", routeName: id,
cfg.Protocol, clusterName: clusterName,
upstreamCfg, filterName: filterName,
chain, protocol: cfg.Protocol,
cfgSnap, useRDS: useRDS,
nil, })
)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -188,17 +201,13 @@ func (s *ResourceGenerator) listenersFromSnapshotConnectProxy(cfgSnap *proxycfg.
DestinationPartition: sn.PartitionOrDefault(), DestinationPartition: sn.PartitionOrDefault(),
} }
filterChain, err := s.makeUpstreamFilterChainForDiscoveryChain( filterName := fmt.Sprintf("%s.%s.%s.%s", u.DestinationName, u.DestinationNamespace, u.DestinationPartition, cfgSnap.Datacenter)
"",
"passthrough~"+passthrough.SNI,
// TODO(tproxy) This should use the protocol configured on the upstream's config entry filterChain, err := s.makeUpstreamFilterChain(filterChainOpts{
"tcp", clusterName: "passthrough~" + passthrough.SNI,
&u, filterName: filterName,
nil, protocol: "tcp",
cfgSnap, })
nil,
)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -219,15 +228,11 @@ func (s *ResourceGenerator) listenersFromSnapshotConnectProxy(cfgSnap *proxycfg.
if cfgSnap.ConnectProxy.MeshConfig == nil || if cfgSnap.ConnectProxy.MeshConfig == nil ||
!cfgSnap.ConnectProxy.MeshConfig.TransparentProxy.MeshDestinationsOnly { !cfgSnap.ConnectProxy.MeshConfig.TransparentProxy.MeshDestinationsOnly {
filterChain, err := s.makeUpstreamFilterChainForDiscoveryChain( filterChain, err := s.makeUpstreamFilterChain(filterChainOpts{
"", clusterName: OriginalDestinationClusterName,
OriginalDestinationClusterName, filterName: OriginalDestinationClusterName,
"tcp", protocol: "tcp",
nil, })
nil,
cfgSnap,
nil,
)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -268,15 +273,13 @@ func (s *ResourceGenerator) listenersFromSnapshotConnectProxy(cfgSnap *proxycfg.
upstreamListener := makeListener(id, u, envoy_core_v3.TrafficDirection_OUTBOUND) upstreamListener := makeListener(id, u, envoy_core_v3.TrafficDirection_OUTBOUND)
filterChain, err := s.makeUpstreamFilterChainForDiscoveryChain( filterChain, err := s.makeUpstreamFilterChain(filterChainOpts{
id, // TODO (SNI partition) add partition for upstream SNI
"", clusterName: connect.UpstreamSNI(u, "", cfgSnap.Datacenter, cfgSnap.Roots.TrustDomain),
cfg.Protocol, filterName: id,
u, routeName: id,
nil, protocol: cfg.Protocol,
cfgSnap, })
nil,
)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -1212,112 +1215,32 @@ func (s *ResourceGenerator) makeMeshGatewayListener(name, addr string, port int,
return l, nil return l, nil
} }
func (s *ResourceGenerator) makeUpstreamFilterChainForDiscoveryChain( type filterChainOpts struct {
id string, routeName string
overrideCluster string, clusterName string
protocol string, filterName string
u *structs.Upstream, protocol string
chain *structs.CompiledDiscoveryChain, useRDS bool
cfgSnap *proxycfg.ConfigSnapshot, tlsContext *envoy_tls_v3.DownstreamTlsContext
tlsContext *envoy_tls_v3.DownstreamTlsContext, }
) (*envoy_listener_v3.FilterChain, error) {
// TODO (freddy) Make this actually legible
useRDS := true
var ( func (s *ResourceGenerator) makeUpstreamFilterChain(opts filterChainOpts) (*envoy_listener_v3.FilterChain, error) {
clusterName string filter, err := makeListenerFilter(listenerFilterOpts{
destination, datacenter, partition, namespace string useRDS: opts.useRDS,
) protocol: opts.protocol,
filterName: opts.filterName,
// TODO (SNI partition) add partition for SNI routeName: opts.routeName,
if chain != nil { cluster: opts.clusterName,
destination, datacenter, partition, namespace = chain.ServiceName, chain.Datacenter, chain.Partition, chain.Namespace statPrefix: "upstream.",
} })
if (chain == nil || chain.IsDefault()) && u != nil {
useRDS = false
if datacenter == "" {
datacenter = u.Datacenter
}
if datacenter == "" {
datacenter = cfgSnap.Datacenter
}
if destination == "" {
destination = u.DestinationName
}
if partition == "" {
partition = u.DestinationPartition
}
if namespace == "" {
namespace = u.DestinationNamespace
}
sni := connect.UpstreamSNI(u, "", datacenter, cfgSnap.Roots.TrustDomain)
clusterName = CustomizeClusterName(sni, chain)
} else {
if protocol == "tcp" && chain != nil {
useRDS = false
startNode := chain.Nodes[chain.StartNode]
if startNode == nil {
return nil, fmt.Errorf("missing first node in compiled discovery chain for: %s", chain.ServiceName)
}
if startNode.Type != structs.DiscoveryGraphNodeTypeResolver {
return nil, fmt.Errorf("unexpected first node in discovery chain using protocol=%q: %s", protocol, startNode.Type)
}
targetID := startNode.Resolver.Target
target := chain.Targets[targetID]
clusterName = CustomizeClusterName(target.Name, chain)
}
}
// Default the namespace to match how SNIs are generated
if namespace == "" {
namespace = structs.IntentionDefaultNamespace
}
// Default the partition to match how SNIs are generated
if partition == "" {
partition = structs.IntentionDefaultNamespace
}
filterName := fmt.Sprintf("%s.%s.%s.%s", destination, namespace, partition, datacenter)
if u != nil && u.DestinationType == structs.UpstreamDestTypePreparedQuery {
// Avoid encoding dc and namespace for prepared queries.
// Those are defined in the query itself and are not available here.
filterName = id
}
if overrideCluster != "" {
useRDS = false
clusterName = overrideCluster
if destination == "" {
filterName = overrideCluster
}
}
opts := listenerFilterOpts{
useRDS: useRDS,
protocol: protocol,
filterName: filterName,
routeName: id,
cluster: clusterName,
statPrefix: "upstream.",
routePath: "",
ingressGateway: false,
httpAuthzFilter: nil,
}
filter, err := makeListenerFilter(opts)
if err != nil {
return nil, err
}
transportSocket, err := makeDownstreamTLSTransportSocket(tlsContext)
if err != nil { if err != nil {
return nil, err return nil, err
} }
transportSocket, err := makeDownstreamTLSTransportSocket(opts.tlsContext)
if err != nil {
return nil, err
}
return &envoy_listener_v3.FilterChain{ return &envoy_listener_v3.FilterChain{
Filters: []*envoy_listener_v3.Filter{ Filters: []*envoy_listener_v3.Filter{
filter, filter,
@ -1326,111 +1249,19 @@ func (s *ResourceGenerator) makeUpstreamFilterChainForDiscoveryChain(
}, nil }, nil
} }
// TODO(freddy) Replace in favor of new function above. Currently in use for ingress gateways. // simpleChainTarget returns the discovery target for a chain with a single node.
func (s *ResourceGenerator) makeUpstreamListenerForDiscoveryChain( // A chain can have a single target if it is for a TCP service or an HTTP service without
u *structs.Upstream, // multiple splits/routes/failovers.
address string, func simpleChainTarget(chain *structs.CompiledDiscoveryChain) (*structs.DiscoveryTarget, error) {
chain *structs.CompiledDiscoveryChain, startNode := chain.Nodes[chain.StartNode]
cfgSnap *proxycfg.ConfigSnapshot, if startNode == nil {
tlsContext *envoy_tls_v3.DownstreamTlsContext, return nil, fmt.Errorf("missing first node in compiled discovery chain for: %s", chain.ServiceName)
) (proto.Message, error) {
// Best understanding is this only makes sense for port listeners....
if u.LocalBindSocketPath != "" {
return nil, fmt.Errorf("makeUpstreamListenerForDiscoveryChain not supported for unix domain sockets %s %+v",
address, u)
} }
if startNode.Type != structs.DiscoveryGraphNodeTypeResolver {
upstreamID := u.Identifier() return nil, fmt.Errorf("expected discovery chain with single node, found unexpected start node: %s", startNode.Type)
l := makePortListenerWithDefault(upstreamID, address, u.LocalBindPort, envoy_core_v3.TrafficDirection_OUTBOUND)
cfg := s.getAndModifyUpstreamConfigForListener(upstreamID, u, chain)
if cfg.EnvoyListenerJSON != "" {
return makeListenerFromUserConfig(cfg.EnvoyListenerJSON)
} }
targetID := startNode.Resolver.Target
useRDS := true return chain.Targets[targetID], nil
var (
clusterName string
destination, datacenter, partition, namespace string
)
if chain == nil || chain.IsDefault() {
useRDS = false
dc := u.Datacenter
if dc == "" {
dc = cfgSnap.Datacenter
}
destination, datacenter, partition, namespace = u.DestinationName, dc, u.DestinationPartition, u.DestinationNamespace
sni := connect.UpstreamSNI(u, "", dc, cfgSnap.Roots.TrustDomain)
clusterName = CustomizeClusterName(sni, chain)
} else {
destination, datacenter, partition, namespace = chain.ServiceName, chain.Datacenter, chain.Partition, chain.Namespace
if cfg.Protocol == "tcp" {
useRDS = false
startNode := chain.Nodes[chain.StartNode]
if startNode == nil {
return nil, fmt.Errorf("missing first node in compiled discovery chain for: %s", chain.ServiceName)
}
if startNode.Type != structs.DiscoveryGraphNodeTypeResolver {
return nil, fmt.Errorf("unexpected first node in discovery chain using protocol=%q: %s", cfg.Protocol, startNode.Type)
}
targetID := startNode.Resolver.Target
target := chain.Targets[targetID]
clusterName = CustomizeClusterName(target.Name, chain)
}
}
// Default the namespace to match how SNIs are generated
if namespace == "" {
namespace = structs.IntentionDefaultNamespace
}
// Default the partition to match how SNIs are generated
if partition == "" {
partition = structs.IntentionDefaultNamespace
}
filterName := fmt.Sprintf("%s.%s.%s.%s", destination, namespace, partition, datacenter)
if u.DestinationType == structs.UpstreamDestTypePreparedQuery {
// Avoid encoding dc and namespace for prepared queries.
// Those are defined in the query itself and are not available here.
filterName = upstreamID
}
opts := listenerFilterOpts{
useRDS: useRDS,
protocol: cfg.Protocol,
filterName: filterName,
routeName: upstreamID,
cluster: clusterName,
statPrefix: "upstream.",
routePath: "",
httpAuthzFilter: nil,
}
filter, err := makeListenerFilter(opts)
if err != nil {
return nil, err
}
transportSocket, err := makeDownstreamTLSTransportSocket(tlsContext)
if err != nil {
return nil, err
}
l.FilterChains = []*envoy_listener_v3.FilterChain{
{
Filters: []*envoy_listener_v3.Filter{
filter,
},
TransportSocket: transportSocket,
},
}
return l, nil
} }
func (s *ResourceGenerator) getAndModifyUpstreamConfigForListener(id string, u *structs.Upstream, chain *structs.CompiledDiscoveryChain) structs.UpstreamConfig { func (s *ResourceGenerator) getAndModifyUpstreamConfigForListener(id string, u *structs.Upstream, chain *structs.CompiledDiscoveryChain) structs.UpstreamConfig {

View File

@ -2,7 +2,6 @@ package xds
import ( import (
"fmt" "fmt"
envoy_core_v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" 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_listener_v3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
envoy_tls_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/tls/v3" envoy_tls_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/tls/v3"
@ -54,19 +53,47 @@ func (s *ResourceGenerator) makeIngressGatewayListeners(address string, cfgSnap
id := u.Identifier() id := u.Identifier()
chain := cfgSnap.IngressGateway.DiscoveryChain[id] chain := cfgSnap.IngressGateway.DiscoveryChain[id]
if chain == nil {
// Wait until a chain is present in the snapshot.
continue
}
var upstreamListener proto.Message cfg := s.getAndModifyUpstreamConfigForListener(id, &u, chain)
upstreamListener, err := s.makeUpstreamListenerForDiscoveryChain(
&u, // RDS, Envoy's Route Discovery Service, is only used for HTTP services with a customized discovery chain.
address, // TODO(freddy): Why can the protocol of the listener be overridden here?
chain, useRDS := cfg.Protocol != "tcp" && !chain.IsDefault()
cfgSnap,
tlsContext, var clusterName string
) if !useRDS {
// When not using RDS we must generate a cluster name to attach to the filter chain.
// With RDS, cluster names get attached to the dynamic routes instead.
target, err := simpleChainTarget(chain)
if err != nil {
return nil, err
}
clusterName = CustomizeClusterName(target.Name, chain)
}
filterName := fmt.Sprintf("%s.%s.%s.%s", chain.ServiceName, chain.Namespace, chain.Partition, chain.Datacenter)
l := makePortListenerWithDefault(id, address, u.LocalBindPort, envoy_core_v3.TrafficDirection_OUTBOUND)
filterChain, err := s.makeUpstreamFilterChain(filterChainOpts{
routeName: id,
useRDS: useRDS,
clusterName: clusterName,
filterName: filterName,
protocol: cfg.Protocol,
tlsContext: tlsContext,
})
if err != nil { if err != nil {
return nil, err return nil, err
} }
resources = append(resources, upstreamListener) l.FilterChains = []*envoy_listener_v3.FilterChain{
filterChain,
}
resources = append(resources, l)
} else { } else {
// If multiple upstreams share this port, make a special listener for the protocol. // If multiple upstreams share this port, make a special listener for the protocol.
listener := makePortListener(listenerKey.Protocol, address, listenerKey.Port, envoy_core_v3.TrafficDirection_OUTBOUND) listener := makePortListener(listenerKey.Protocol, address, listenerKey.Port, envoy_core_v3.TrafficDirection_OUTBOUND)

View File

@ -259,6 +259,23 @@ func TestListenersFromSnapshot(t *testing.T) {
create: proxycfg.TestConfigSnapshotDiscoveryChainWithFailoverThroughLocalGateway, create: proxycfg.TestConfigSnapshotDiscoveryChainWithFailoverThroughLocalGateway,
setup: nil, setup: nil,
}, },
{
name: "connect-proxy-upstream-defaults",
create: proxycfg.TestConfigSnapshot,
setup: func(snap *proxycfg.ConfigSnapshot) {
for _, v := range snap.ConnectProxy.UpstreamConfig {
// Prepared queries do not get centrally configured upstream defaults merged into them.
if v.DestinationType == structs.UpstreamDestTypePreparedQuery {
continue
}
// Represent upstream config as if it came from centrally configured upstream defaults.
// The name/namespace must not make it onto the cluster name attached to the outbound listener.
v.CentrallyConfigured = true
v.DestinationNamespace = structs.WildcardSpecifier
v.DestinationName = structs.WildcardSpecifier
}
},
},
{ {
name: "expose-paths-local-app-paths", name: "expose-paths-local-app-paths",
create: proxycfg.TestConfigSnapshotExposeConfig, create: proxycfg.TestConfigSnapshotExposeConfig,
@ -567,7 +584,7 @@ func TestListenersFromSnapshot(t *testing.T) {
snap.IngressGateway.Upstreams = map[proxycfg.IngressListenerKey]structs.Upstreams{ snap.IngressGateway.Upstreams = map[proxycfg.IngressListenerKey]structs.Upstreams{
{Protocol: "tcp", Port: 8080}: { {Protocol: "tcp", Port: 8080}: {
{ {
DestinationName: "foo", DestinationName: "db",
LocalBindPort: 8080, LocalBindPort: 8080,
}, },
}, },
@ -640,6 +657,30 @@ func TestListenersFromSnapshot(t *testing.T) {
}, },
}, },
} }
// Every ingress upstream has an associated discovery chain in the snapshot
secureChain := discoverychain.TestCompileConfigEntries(
t,
"secure",
"default",
"default",
"dc1",
connect.TestClusterID+".consul",
nil,
)
snap.IngressGateway.DiscoveryChain["secure"] = secureChain
insecureChain := discoverychain.TestCompileConfigEntries(
t,
"insecure",
"default",
"default",
"dc1",
connect.TestClusterID+".consul",
nil,
)
snap.IngressGateway.DiscoveryChain["insecure"] = insecureChain
snap.IngressGateway.Listeners = map[proxycfg.IngressListenerKey]structs.IngressListener{ snap.IngressGateway.Listeners = map[proxycfg.IngressListenerKey]structs.IngressListener{
{Protocol: "tcp", Port: 8080}: { {Protocol: "tcp", Port: 8080}: {
Port: 8080, Port: 8080,

View File

@ -0,0 +1,119 @@
{
"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.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"
}

View File

@ -3,7 +3,7 @@
"resources": [ "resources": [
{ {
"@type": "type.googleapis.com/envoy.config.listener.v3.Listener", "@type": "type.googleapis.com/envoy.config.listener.v3.Listener",
"name": "foo:1.2.3.4:8080", "name": "db:1.2.3.4:8080",
"address": { "address": {
"socketAddress": { "socketAddress": {
"address": "1.2.3.4", "address": "1.2.3.4",
@ -17,8 +17,8 @@
"name": "envoy.filters.network.tcp_proxy", "name": "envoy.filters.network.tcp_proxy",
"typedConfig": { "typedConfig": {
"@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy",
"statPrefix": "upstream.foo.default.default.dc1", "statPrefix": "upstream.db.default.default.dc1",
"cluster": "foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul"
} }
} }
], ],