mirror of https://github.com/hashicorp/consul
Add subset support
parent
9f233dece2
commit
913b13f31f
|
@ -81,6 +81,16 @@ type configSnapshotTerminatingGateway struct {
|
||||||
// on the service that the caller is trying to reach.
|
// on the service that the caller is trying to reach.
|
||||||
ServiceLeaves map[structs.ServiceID]*structs.IssuedCert
|
ServiceLeaves map[structs.ServiceID]*structs.IssuedCert
|
||||||
|
|
||||||
|
// WatchedResolvers is a map of ServiceID to a cancel function.
|
||||||
|
// This cancel function is tied to the watch of resolvers for linked services.
|
||||||
|
// As with WatchedServices, resolver watches will be cancelled when services
|
||||||
|
// are no longer linked to the gateway.
|
||||||
|
WatchedResolvers map[structs.ServiceID]context.CancelFunc
|
||||||
|
|
||||||
|
// ServiceResolvers is a map of service id to an associated
|
||||||
|
// service-resolver config entry for that service.
|
||||||
|
ServiceResolvers map[structs.ServiceID]*structs.ServiceResolverConfigEntry
|
||||||
|
|
||||||
// ServiceGroups is a map of service id to the service instances of that
|
// ServiceGroups is a map of service id to the service instances of that
|
||||||
// service in the local datacenter.
|
// service in the local datacenter.
|
||||||
ServiceGroups map[structs.ServiceID]structs.CheckServiceNodes
|
ServiceGroups map[structs.ServiceID]structs.CheckServiceNodes
|
||||||
|
@ -94,7 +104,8 @@ func (c *configSnapshotTerminatingGateway) IsEmpty() bool {
|
||||||
len(c.WatchedLeaves) == 0 &&
|
len(c.WatchedLeaves) == 0 &&
|
||||||
len(c.WatchedIntentions) == 0 &&
|
len(c.WatchedIntentions) == 0 &&
|
||||||
len(c.ServiceGroups) == 0 &&
|
len(c.ServiceGroups) == 0 &&
|
||||||
len(c.WatchedServices) == 0
|
len(c.WatchedServices) == 0 &&
|
||||||
|
len(c.ServiceResolvers) == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
type configSnapshotMeshGateway struct {
|
type configSnapshotMeshGateway struct {
|
||||||
|
|
|
@ -536,8 +536,10 @@ func (s *state) initialConfigSnapshot() ConfigSnapshot {
|
||||||
snap.TerminatingGateway.WatchedServices = make(map[structs.ServiceID]context.CancelFunc)
|
snap.TerminatingGateway.WatchedServices = make(map[structs.ServiceID]context.CancelFunc)
|
||||||
snap.TerminatingGateway.WatchedLeaves = make(map[structs.ServiceID]context.CancelFunc)
|
snap.TerminatingGateway.WatchedLeaves = make(map[structs.ServiceID]context.CancelFunc)
|
||||||
snap.TerminatingGateway.WatchedIntentions = make(map[structs.ServiceID]context.CancelFunc)
|
snap.TerminatingGateway.WatchedIntentions = make(map[structs.ServiceID]context.CancelFunc)
|
||||||
|
snap.TerminatingGateway.WatchedResolvers = make(map[structs.ServiceID]context.CancelFunc)
|
||||||
snap.TerminatingGateway.ServiceLeaves = make(map[structs.ServiceID]*structs.IssuedCert)
|
snap.TerminatingGateway.ServiceLeaves = make(map[structs.ServiceID]*structs.IssuedCert)
|
||||||
snap.TerminatingGateway.ServiceGroups = make(map[structs.ServiceID]structs.CheckServiceNodes)
|
snap.TerminatingGateway.ServiceGroups = make(map[structs.ServiceID]structs.CheckServiceNodes)
|
||||||
|
snap.TerminatingGateway.ServiceResolvers = make(map[structs.ServiceID]*structs.ServiceResolverConfigEntry)
|
||||||
case structs.ServiceKindMeshGateway:
|
case structs.ServiceKindMeshGateway:
|
||||||
snap.MeshGateway.WatchedServices = make(map[structs.ServiceID]context.CancelFunc)
|
snap.MeshGateway.WatchedServices = make(map[structs.ServiceID]context.CancelFunc)
|
||||||
snap.MeshGateway.WatchedDatacenters = make(map[string]context.CancelFunc)
|
snap.MeshGateway.WatchedDatacenters = make(map[string]context.CancelFunc)
|
||||||
|
@ -983,6 +985,29 @@ func (s *state) handleUpdateTerminatingGateway(u cache.UpdateEvent, snap *Config
|
||||||
}
|
}
|
||||||
snap.TerminatingGateway.WatchedLeaves[svc.Service] = cancel
|
snap.TerminatingGateway.WatchedLeaves[svc.Service] = cancel
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Watch service resolvers for the service
|
||||||
|
// These are used to create clusters and endpoints for the service subsets
|
||||||
|
if _, ok := snap.TerminatingGateway.WatchedResolvers[svc.Service]; !ok {
|
||||||
|
ctx, cancel := context.WithCancel(s.ctx)
|
||||||
|
err := s.cache.Notify(ctx, cachetype.ConfigEntriesName, &structs.ConfigEntryQuery{
|
||||||
|
Datacenter: s.source.Datacenter,
|
||||||
|
QueryOptions: structs.QueryOptions{Token: s.token},
|
||||||
|
Kind: structs.ServiceResolver,
|
||||||
|
Name: svc.Service.ID,
|
||||||
|
EnterpriseMeta: svc.Service.EnterpriseMeta,
|
||||||
|
}, fmt.Sprintf("service-resolver:%s", svc.Service.String()), s.ch)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("failed to register watch for a service-resolver",
|
||||||
|
"service", svc.Service.String(),
|
||||||
|
"error", err,
|
||||||
|
)
|
||||||
|
cancel()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
snap.TerminatingGateway.WatchedResolvers[svc.Service] = cancel
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cancel service instance watches for services that were not in the update
|
// Cancel service instance watches for services that were not in the update
|
||||||
|
@ -1005,6 +1030,16 @@ func (s *state) handleUpdateTerminatingGateway(u cache.UpdateEvent, snap *Config
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cancel service-resolver watches for services that were not in the update
|
||||||
|
for sid, cancelFn := range snap.TerminatingGateway.WatchedResolvers {
|
||||||
|
if _, ok := svcMap[sid]; !ok {
|
||||||
|
logger.Debug("canceling watch for service-resolver", "service", sid.String())
|
||||||
|
delete(snap.TerminatingGateway.WatchedResolvers, sid)
|
||||||
|
delete(snap.TerminatingGateway.ServiceResolvers, sid)
|
||||||
|
cancelFn()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Cancel intention watches for services that were not in the update
|
// Cancel intention watches for services that were not in the update
|
||||||
for sid, cancelFn := range snap.TerminatingGateway.WatchedIntentions {
|
for sid, cancelFn := range snap.TerminatingGateway.WatchedIntentions {
|
||||||
if _, ok := svcMap[sid]; !ok {
|
if _, ok := svcMap[sid]; !ok {
|
||||||
|
@ -1044,6 +1079,18 @@ func (s *state) handleUpdateTerminatingGateway(u cache.UpdateEvent, snap *Config
|
||||||
sid := structs.ServiceIDFromString(strings.TrimPrefix(u.CorrelationID, "service-leaf:"))
|
sid := structs.ServiceIDFromString(strings.TrimPrefix(u.CorrelationID, "service-leaf:"))
|
||||||
snap.TerminatingGateway.ServiceLeaves[sid] = leaf
|
snap.TerminatingGateway.ServiceLeaves[sid] = leaf
|
||||||
|
|
||||||
|
case strings.HasPrefix(u.CorrelationID, "service-resolver:"):
|
||||||
|
configEntries, ok := u.Result.(*structs.IndexedConfigEntries)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("invalid type for response: %T", u.Result)
|
||||||
|
}
|
||||||
|
// There should only ever be one entry for a service resolver within a namespace
|
||||||
|
if len(configEntries.Entries) == 1 {
|
||||||
|
if resolver, ok := configEntries.Entries[0].(*structs.ServiceResolverConfigEntry); ok {
|
||||||
|
snap.TerminatingGateway.ServiceResolvers[structs.NewServiceID(resolver.Name, &resolver.EnterpriseMeta)] = resolver
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
case strings.HasPrefix(u.CorrelationID, "service-intentions:"):
|
case strings.HasPrefix(u.CorrelationID, "service-intentions:"):
|
||||||
// no-op: Intentions don't get stored in the snapshot, calls to ConnectAuthorize will fetch them from the cache
|
// no-op: Intentions don't get stored in the snapshot, calls to ConnectAuthorize will fetch them from the cache
|
||||||
|
|
||||||
|
|
|
@ -206,6 +206,18 @@ func genVerifyLeafWatch(expectedService string, expectedDatacenter string) verif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func genVerifyResolverWatch(expectedService, expectedDatacenter, expectedKind string) verifyWatchRequest {
|
||||||
|
return func(t testing.TB, cacheType string, request cache.Request) {
|
||||||
|
require.Equal(t, cachetype.ConfigEntriesName, cacheType)
|
||||||
|
|
||||||
|
reqReal, ok := request.(*structs.ConfigEntryQuery)
|
||||||
|
require.True(t, ok)
|
||||||
|
require.Equal(t, expectedDatacenter, reqReal.Datacenter)
|
||||||
|
require.Equal(t, expectedService, reqReal.Name)
|
||||||
|
require.Equal(t, expectedKind, reqReal.Kind)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func genVerifyIntentionWatch(expectedService string, expectedDatacenter string) verifyWatchRequest {
|
func genVerifyIntentionWatch(expectedService string, expectedDatacenter string) verifyWatchRequest {
|
||||||
return func(t testing.TB, cacheType string, request cache.Request) {
|
return func(t testing.TB, cacheType string, request cache.Request) {
|
||||||
require.Equal(t, cachetype.IntentionMatchName, cacheType)
|
require.Equal(t, cachetype.IntentionMatchName, cacheType)
|
||||||
|
@ -827,8 +839,11 @@ func TestState_WatchesAndUpdates(t *testing.T) {
|
||||||
require.True(t, snap.ConnectProxy.IsEmpty())
|
require.True(t, snap.ConnectProxy.IsEmpty())
|
||||||
require.Equal(t, indexedRoots, snap.Roots)
|
require.Equal(t, indexedRoots, snap.Roots)
|
||||||
require.Empty(t, snap.TerminatingGateway.WatchedServices)
|
require.Empty(t, snap.TerminatingGateway.WatchedServices)
|
||||||
require.Empty(t, snap.TerminatingGateway.WatchedLeaves)
|
|
||||||
require.Empty(t, snap.TerminatingGateway.ServiceGroups)
|
require.Empty(t, snap.TerminatingGateway.ServiceGroups)
|
||||||
|
require.Empty(t, snap.TerminatingGateway.WatchedLeaves)
|
||||||
|
require.Empty(t, snap.TerminatingGateway.ServiceLeaves)
|
||||||
|
require.Empty(t, snap.TerminatingGateway.WatchedResolvers)
|
||||||
|
require.Empty(t, snap.TerminatingGateway.ServiceResolvers)
|
||||||
require.Empty(t, snap.TerminatingGateway.WatchedIntentions)
|
require.Empty(t, snap.TerminatingGateway.WatchedIntentions)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -904,6 +919,10 @@ func TestState_WatchesAndUpdates(t *testing.T) {
|
||||||
require.Len(t, snap.TerminatingGateway.WatchedLeaves, 2)
|
require.Len(t, snap.TerminatingGateway.WatchedLeaves, 2)
|
||||||
require.Contains(t, snap.TerminatingGateway.WatchedLeaves, db)
|
require.Contains(t, snap.TerminatingGateway.WatchedLeaves, db)
|
||||||
require.Contains(t, snap.TerminatingGateway.WatchedLeaves, billing)
|
require.Contains(t, snap.TerminatingGateway.WatchedLeaves, billing)
|
||||||
|
|
||||||
|
require.Len(t, snap.TerminatingGateway.WatchedResolvers, 2)
|
||||||
|
require.Contains(t, snap.TerminatingGateway.WatchedResolvers, db)
|
||||||
|
require.Contains(t, snap.TerminatingGateway.WatchedResolvers, billing)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
verificationStage{
|
verificationStage{
|
||||||
|
@ -963,6 +982,41 @@ func TestState_WatchesAndUpdates(t *testing.T) {
|
||||||
require.Equal(t, snap.TerminatingGateway.ServiceLeaves[structs.NewServiceID("db", nil)], issuedCert)
|
require.Equal(t, snap.TerminatingGateway.ServiceLeaves[structs.NewServiceID("db", nil)], issuedCert)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
verificationStage{
|
||||||
|
requiredWatches: map[string]verifyWatchRequest{
|
||||||
|
"service-resolver:db": genVerifyResolverWatch("db", "dc1", structs.ServiceResolver),
|
||||||
|
},
|
||||||
|
events: []cache.UpdateEvent{
|
||||||
|
cache.UpdateEvent{
|
||||||
|
CorrelationID: "service-resolver:db",
|
||||||
|
Result: &structs.IndexedConfigEntries{
|
||||||
|
Kind: structs.ServiceResolver,
|
||||||
|
Entries: []structs.ConfigEntry{
|
||||||
|
&structs.ServiceResolverConfigEntry{
|
||||||
|
Name: "db",
|
||||||
|
Kind: structs.ServiceResolver,
|
||||||
|
Redirect: &structs.ServiceResolverRedirect{
|
||||||
|
Service: "db",
|
||||||
|
Datacenter: "dc2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Err: nil,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
verifySnapshot: func(t testing.TB, snap *ConfigSnapshot) {
|
||||||
|
want := &structs.ServiceResolverConfigEntry{
|
||||||
|
Kind: structs.ServiceResolver,
|
||||||
|
Name: "db",
|
||||||
|
Redirect: &structs.ServiceResolverRedirect{
|
||||||
|
Service: "db",
|
||||||
|
Datacenter: "dc2",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
require.Equal(t, want, snap.TerminatingGateway.ServiceResolvers[structs.NewServiceID("db", nil)])
|
||||||
|
},
|
||||||
|
},
|
||||||
verificationStage{
|
verificationStage{
|
||||||
events: []cache.UpdateEvent{
|
events: []cache.UpdateEvent{
|
||||||
cache.UpdateEvent{
|
cache.UpdateEvent{
|
||||||
|
@ -993,9 +1047,13 @@ func TestState_WatchesAndUpdates(t *testing.T) {
|
||||||
require.Len(t, snap.TerminatingGateway.WatchedLeaves, 1)
|
require.Len(t, snap.TerminatingGateway.WatchedLeaves, 1)
|
||||||
require.Contains(t, snap.TerminatingGateway.WatchedLeaves, billing)
|
require.Contains(t, snap.TerminatingGateway.WatchedLeaves, billing)
|
||||||
|
|
||||||
|
require.Len(t, snap.TerminatingGateway.WatchedResolvers, 1)
|
||||||
|
require.Contains(t, snap.TerminatingGateway.WatchedResolvers, billing)
|
||||||
|
|
||||||
// There was no update event for billing's leaf/endpoints, so length is 0
|
// There was no update event for billing's leaf/endpoints, so length is 0
|
||||||
require.Len(t, snap.TerminatingGateway.ServiceGroups, 0)
|
require.Len(t, snap.TerminatingGateway.ServiceGroups, 0)
|
||||||
require.Len(t, snap.TerminatingGateway.ServiceLeaves, 0)
|
require.Len(t, snap.TerminatingGateway.ServiceLeaves, 0)
|
||||||
|
require.Len(t, snap.TerminatingGateway.ServiceResolvers, 0)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -1475,6 +1475,12 @@ func testConfigSnapshotTerminatingGateway(t testing.T, populateServices bool) *C
|
||||||
if populateServices {
|
if populateServices {
|
||||||
web := structs.NewServiceID("web", nil)
|
web := structs.NewServiceID("web", nil)
|
||||||
webNodes := TestUpstreamNodes(t)
|
webNodes := TestUpstreamNodes(t)
|
||||||
|
webNodes[0].Service.Meta = map[string]string{
|
||||||
|
"version": "1",
|
||||||
|
}
|
||||||
|
webNodes[1].Service.Meta = map[string]string{
|
||||||
|
"version": "2",
|
||||||
|
}
|
||||||
|
|
||||||
api := structs.NewServiceID("api", nil)
|
api := structs.NewServiceID("api", nil)
|
||||||
apiNodes := TestUpstreamNodes(t)
|
apiNodes := TestUpstreamNodes(t)
|
||||||
|
|
|
@ -120,22 +120,9 @@ func makeExposeClusterName(destinationPort int) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// clustersFromSnapshotTerminatingGateway returns the xDS API representation of the "clusters"
|
// clustersFromSnapshotTerminatingGateway returns the xDS API representation of the "clusters"
|
||||||
// for a terminating gateway. This will include 1 cluster per service.
|
// for a terminating gateway. This will include 1 cluster per service and service subset.
|
||||||
func (s *Server) clustersFromSnapshotTerminatingGateway(cfgSnap *proxycfg.ConfigSnapshot) ([]proto.Message, error) {
|
func (s *Server) clustersFromSnapshotTerminatingGateway(cfgSnap *proxycfg.ConfigSnapshot) ([]proto.Message, error) {
|
||||||
clusters := make([]proto.Message, 0, len(cfgSnap.TerminatingGateway.ServiceGroups))
|
return s.clustersFromServicesAndResolvers(cfgSnap, cfgSnap.TerminatingGateway.ServiceGroups, cfgSnap.TerminatingGateway.ServiceResolvers)
|
||||||
|
|
||||||
// Generate the per-service clusters
|
|
||||||
for svc, _ := range cfgSnap.TerminatingGateway.ServiceGroups {
|
|
||||||
clusterName := connect.ServiceSNI(svc.ID, "", svc.NamespaceOrDefault(), cfgSnap.Datacenter, cfgSnap.Roots.TrustDomain)
|
|
||||||
|
|
||||||
cluster, err := s.makeGatewayCluster(clusterName, cfgSnap)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to make cluster %q for terminating-gateway: %v", cluster, err)
|
|
||||||
}
|
|
||||||
clusters = append(clusters, cluster)
|
|
||||||
}
|
|
||||||
|
|
||||||
return clusters, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// clustersFromSnapshotMeshGateway returns the xDS API representation of the "clusters"
|
// clustersFromSnapshotMeshGateway returns the xDS API representation of the "clusters"
|
||||||
|
@ -185,10 +172,26 @@ func (s *Server) clustersFromSnapshotMeshGateway(cfgSnap *proxycfg.ConfigSnapsho
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate the per-service clusters
|
// generate the per-service/subset clusters
|
||||||
for svc, _ := range cfgSnap.MeshGateway.ServiceGroups {
|
c, err := s.clustersFromServicesAndResolvers(cfgSnap, cfgSnap.MeshGateway.ServiceGroups, cfgSnap.MeshGateway.ServiceResolvers)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
clusters = append(clusters, c...)
|
||||||
|
|
||||||
|
return clusters, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) clustersFromServicesAndResolvers(
|
||||||
|
cfgSnap *proxycfg.ConfigSnapshot,
|
||||||
|
services map[structs.ServiceID]structs.CheckServiceNodes,
|
||||||
|
resolvers map[structs.ServiceID]*structs.ServiceResolverConfigEntry) ([]proto.Message, error) {
|
||||||
|
|
||||||
|
clusters := make([]proto.Message, 0, len(services))
|
||||||
|
|
||||||
|
for svc, _ := range services {
|
||||||
clusterName := connect.ServiceSNI(svc.ID, "", svc.NamespaceOrDefault(), cfgSnap.Datacenter, cfgSnap.Roots.TrustDomain)
|
clusterName := connect.ServiceSNI(svc.ID, "", svc.NamespaceOrDefault(), cfgSnap.Datacenter, cfgSnap.Roots.TrustDomain)
|
||||||
resolver, hasResolver := cfgSnap.MeshGateway.ServiceResolvers[svc]
|
resolver, hasResolver := resolvers[svc]
|
||||||
|
|
||||||
// Create the cluster for default/unnamed services
|
// Create the cluster for default/unnamed services
|
||||||
var cluster *envoy.Cluster
|
var cluster *envoy.Cluster
|
||||||
|
@ -199,7 +202,7 @@ func (s *Server) clustersFromSnapshotMeshGateway(cfgSnap *proxycfg.ConfigSnapsho
|
||||||
cluster, err = s.makeGatewayCluster(clusterName, cfgSnap)
|
cluster, err = s.makeGatewayCluster(clusterName, cfgSnap)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("failed to make %s cluster: %v", cfgSnap.Kind, err)
|
||||||
}
|
}
|
||||||
clusters = append(clusters, cluster)
|
clusters = append(clusters, cluster)
|
||||||
|
|
||||||
|
@ -211,7 +214,7 @@ func (s *Server) clustersFromSnapshotMeshGateway(cfgSnap *proxycfg.ConfigSnapsho
|
||||||
|
|
||||||
cluster, err := s.makeGatewayClusterWithConnectTimeout(clusterName, cfgSnap, resolver.ConnectTimeout)
|
cluster, err := s.makeGatewayClusterWithConnectTimeout(clusterName, cfgSnap, resolver.ConnectTimeout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("failed to make %s cluster: %v", cfgSnap.Kind, err)
|
||||||
}
|
}
|
||||||
clusters = append(clusters, cluster)
|
clusters = append(clusters, cluster)
|
||||||
}
|
}
|
||||||
|
@ -529,9 +532,9 @@ func (s *Server) makeGatewayCluster(clusterName string, cfgSnap *proxycfg.Config
|
||||||
return s.makeGatewayClusterWithConnectTimeout(clusterName, cfgSnap, 0)
|
return s.makeGatewayClusterWithConnectTimeout(clusterName, cfgSnap, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// makeGatewayClusterWithConnectTimeout initializes a mesh gateway cluster
|
// makeGatewayClusterWithConnectTimeout initializes a gateway cluster
|
||||||
// with the specified connect timeout. If the timeout is 0, the connect timeout
|
// with the specified connect timeout. If the timeout is 0, the connect timeout
|
||||||
// defaults to use the mesh gateway timeout.
|
// defaults to use the configured gateway timeout.
|
||||||
func (s *Server) makeGatewayClusterWithConnectTimeout(clusterName string, cfgSnap *proxycfg.ConfigSnapshot,
|
func (s *Server) makeGatewayClusterWithConnectTimeout(clusterName string, cfgSnap *proxycfg.ConfigSnapshot,
|
||||||
connectTimeout time.Duration) (*envoy.Cluster, error) {
|
connectTimeout time.Duration) (*envoy.Cluster, error) {
|
||||||
cfg, err := ParseGatewayConfig(cfgSnap.Proxy.Config)
|
cfg, err := ParseGatewayConfig(cfgSnap.Proxy.Config)
|
||||||
|
|
|
@ -428,6 +428,63 @@ func TestClustersFromSnapshot(t *testing.T) {
|
||||||
create: proxycfg.TestConfigSnapshotTerminatingGatewayNoServices,
|
create: proxycfg.TestConfigSnapshotTerminatingGatewayNoServices,
|
||||||
setup: nil,
|
setup: nil,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "terminating-gateway-service-subsets",
|
||||||
|
create: proxycfg.TestConfigSnapshotTerminatingGateway,
|
||||||
|
setup: func(snap *proxycfg.ConfigSnapshot) {
|
||||||
|
snap.TerminatingGateway.ServiceResolvers = map[structs.ServiceID]*structs.ServiceResolverConfigEntry{
|
||||||
|
structs.NewServiceID("web", nil): {
|
||||||
|
Kind: structs.ServiceResolver,
|
||||||
|
Name: "web",
|
||||||
|
Subsets: map[string]structs.ServiceResolverSubset{
|
||||||
|
"v1": {
|
||||||
|
Filter: "Service.Meta.Version == 1",
|
||||||
|
},
|
||||||
|
"v2": {
|
||||||
|
Filter: "Service.Meta.Version == 2",
|
||||||
|
OnlyPassing: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "terminating-gateway-ignore-extra-resolvers",
|
||||||
|
create: proxycfg.TestConfigSnapshotTerminatingGateway,
|
||||||
|
setup: func(snap *proxycfg.ConfigSnapshot) {
|
||||||
|
snap.TerminatingGateway.ServiceResolvers = map[structs.ServiceID]*structs.ServiceResolverConfigEntry{
|
||||||
|
structs.NewServiceID("web", nil): {
|
||||||
|
Kind: structs.ServiceResolver,
|
||||||
|
Name: "web",
|
||||||
|
DefaultSubset: "v2",
|
||||||
|
Subsets: map[string]structs.ServiceResolverSubset{
|
||||||
|
"v1": {
|
||||||
|
Filter: "Service.Meta.Version == 1",
|
||||||
|
},
|
||||||
|
"v2": {
|
||||||
|
Filter: "Service.Meta.Version == 2",
|
||||||
|
OnlyPassing: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
structs.NewServiceID("notfound", nil): {
|
||||||
|
Kind: structs.ServiceResolver,
|
||||||
|
Name: "notfound",
|
||||||
|
DefaultSubset: "v2",
|
||||||
|
Subsets: map[string]structs.ServiceResolverSubset{
|
||||||
|
"v1": {
|
||||||
|
Filter: "Service.Meta.Version == 1",
|
||||||
|
},
|
||||||
|
"v2": {
|
||||||
|
Filter: "Service.Meta.Version == 2",
|
||||||
|
OnlyPassing: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
|
|
|
@ -108,19 +108,7 @@ func (s *Server) filterSubsetEndpoints(subset *structs.ServiceResolverSubset, en
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) endpointsFromSnapshotTerminatingGateway(cfgSnap *proxycfg.ConfigSnapshot) ([]proto.Message, error) {
|
func (s *Server) endpointsFromSnapshotTerminatingGateway(cfgSnap *proxycfg.ConfigSnapshot) ([]proto.Message, error) {
|
||||||
resources := make([]proto.Message, 0, len(cfgSnap.TerminatingGateway.ServiceGroups))
|
return s.endpointsFromServicesAndResolvers(cfgSnap, cfgSnap.TerminatingGateway.ServiceGroups, cfgSnap.TerminatingGateway.ServiceResolvers)
|
||||||
|
|
||||||
// generate the endpoints for the linked service groups
|
|
||||||
for svc, endpoints := range cfgSnap.TerminatingGateway.ServiceGroups {
|
|
||||||
clusterName := connect.ServiceSNI(svc.ID, "", svc.NamespaceOrDefault(), cfgSnap.Datacenter, cfgSnap.Roots.TrustDomain)
|
|
||||||
|
|
||||||
group := []loadAssignmentEndpointGroup{{Endpoints: endpoints, OnlyPassing: false}}
|
|
||||||
|
|
||||||
la := makeLoadAssignment(clusterName, group, cfgSnap.Datacenter)
|
|
||||||
resources = append(resources, la)
|
|
||||||
}
|
|
||||||
|
|
||||||
return resources, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) endpointsFromSnapshotMeshGateway(cfgSnap *proxycfg.ConfigSnapshot) ([]proto.Message, error) {
|
func (s *Server) endpointsFromSnapshotMeshGateway(cfgSnap *proxycfg.ConfigSnapshot) ([]proto.Message, error) {
|
||||||
|
@ -209,38 +197,53 @@ func (s *Server) endpointsFromSnapshotMeshGateway(cfgSnap *proxycfg.ConfigSnapsh
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate the endpoints for each service and its subsets
|
// Generate the endpoints for each service and its subsets
|
||||||
for svc, endpoints := range cfgSnap.MeshGateway.ServiceGroups {
|
e, err := s.endpointsFromServicesAndResolvers(cfgSnap, cfgSnap.MeshGateway.ServiceGroups, cfgSnap.MeshGateway.ServiceResolvers)
|
||||||
clusterEndpoints := make(map[string]loadAssignmentEndpointGroup)
|
if err != nil {
|
||||||
clusterEndpoints[UnnamedSubset] = loadAssignmentEndpointGroup{Endpoints: endpoints, OnlyPassing: false}
|
return nil, err
|
||||||
|
}
|
||||||
|
resources = append(resources, e...)
|
||||||
|
|
||||||
|
return resources, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) endpointsFromServicesAndResolvers(
|
||||||
|
cfgSnap *proxycfg.ConfigSnapshot,
|
||||||
|
services map[structs.ServiceID]structs.CheckServiceNodes,
|
||||||
|
resolvers map[structs.ServiceID]*structs.ServiceResolverConfigEntry) ([]proto.Message, error) {
|
||||||
|
|
||||||
|
resources := make([]proto.Message, 0, len(services))
|
||||||
|
|
||||||
|
// generate the endpoints for the linked service groups
|
||||||
|
for svc, endpoints := range services {
|
||||||
|
clusterEndpoints := make(map[string][]loadAssignmentEndpointGroup)
|
||||||
|
clusterEndpoints[UnnamedSubset] = []loadAssignmentEndpointGroup{{Endpoints: endpoints, OnlyPassing: false}}
|
||||||
|
|
||||||
// Collect all of the loadAssignmentEndpointGroups for the various subsets. We do this before generating
|
// Collect all of the loadAssignmentEndpointGroups for the various subsets. We do this before generating
|
||||||
// the endpoints for the default/unnamed subset so that we can take into account the DefaultSubset on the
|
// the endpoints for the default/unnamed subset so that we can take into account the DefaultSubset on the
|
||||||
// service-resolver which may prevent the default/unnamed cluster from creating endpoints for all service
|
// service-resolver which may prevent the default/unnamed cluster from creating endpoints for all service
|
||||||
// instances.
|
// instances.
|
||||||
if resolver, hasResolver := cfgSnap.MeshGateway.ServiceResolvers[svc]; hasResolver {
|
if resolver, hasResolver := resolvers[svc]; hasResolver {
|
||||||
for subsetName, subset := range resolver.Subsets {
|
for subsetName, subset := range resolver.Subsets {
|
||||||
subsetEndpoints, err := s.filterSubsetEndpoints(&subset, endpoints)
|
subsetEndpoints, err := s.filterSubsetEndpoints(&subset, endpoints)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
group := loadAssignmentEndpointGroup{Endpoints: subsetEndpoints, OnlyPassing: subset.OnlyPassing}
|
groups := []loadAssignmentEndpointGroup{{Endpoints: subsetEndpoints, OnlyPassing: subset.OnlyPassing}}
|
||||||
clusterEndpoints[subsetName] = group
|
clusterEndpoints[subsetName] = groups
|
||||||
|
|
||||||
// if this subset is the default then override the unnamed subset with this configuration
|
// if this subset is the default then override the unnamed subset with this configuration
|
||||||
if subsetName == resolver.DefaultSubset {
|
if subsetName == resolver.DefaultSubset {
|
||||||
clusterEndpoints[UnnamedSubset] = group
|
clusterEndpoints[UnnamedSubset] = groups
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// now generate the load assignment for all subsets
|
// now generate the load assignment for all subsets
|
||||||
for subsetName, group := range clusterEndpoints {
|
for subsetName, groups := range clusterEndpoints {
|
||||||
clusterName := connect.ServiceSNI(svc.ID, subsetName, svc.NamespaceOrDefault(), cfgSnap.Datacenter, cfgSnap.Roots.TrustDomain)
|
clusterName := connect.ServiceSNI(svc.ID, subsetName, svc.NamespaceOrDefault(), cfgSnap.Datacenter, cfgSnap.Roots.TrustDomain)
|
||||||
la := makeLoadAssignment(
|
la := makeLoadAssignment(
|
||||||
clusterName,
|
clusterName,
|
||||||
[]loadAssignmentEndpointGroup{
|
groups,
|
||||||
group,
|
|
||||||
},
|
|
||||||
cfgSnap.Datacenter,
|
cfgSnap.Datacenter,
|
||||||
)
|
)
|
||||||
resources = append(resources, la)
|
resources = append(resources, la)
|
||||||
|
|
|
@ -466,6 +466,76 @@ func Test_endpointsFromSnapshot(t *testing.T) {
|
||||||
create: proxycfg.TestConfigSnapshotTerminatingGatewayNoServices,
|
create: proxycfg.TestConfigSnapshotTerminatingGatewayNoServices,
|
||||||
setup: nil,
|
setup: nil,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "terminating-gateway-service-subsets",
|
||||||
|
create: proxycfg.TestConfigSnapshotTerminatingGateway,
|
||||||
|
setup: func(snap *proxycfg.ConfigSnapshot) {
|
||||||
|
snap.TerminatingGateway.ServiceResolvers = map[structs.ServiceID]*structs.ServiceResolverConfigEntry{
|
||||||
|
structs.NewServiceID("web", nil): {
|
||||||
|
Kind: structs.ServiceResolver,
|
||||||
|
Name: "web",
|
||||||
|
Subsets: map[string]structs.ServiceResolverSubset{
|
||||||
|
"v1": {
|
||||||
|
Filter: "Service.Meta.version == 1",
|
||||||
|
},
|
||||||
|
"v2": {
|
||||||
|
Filter: "Service.Meta.version == 2",
|
||||||
|
OnlyPassing: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
structs.NewServiceID("web", nil): {
|
||||||
|
Kind: structs.ServiceResolver,
|
||||||
|
Name: "web",
|
||||||
|
Subsets: map[string]structs.ServiceResolverSubset{
|
||||||
|
"v1": {
|
||||||
|
Filter: "Service.Meta.version == 1",
|
||||||
|
},
|
||||||
|
"v2": {
|
||||||
|
Filter: "Service.Meta.version == 2",
|
||||||
|
OnlyPassing: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "terminating-gateway-default-service-subset",
|
||||||
|
create: proxycfg.TestConfigSnapshotTerminatingGateway,
|
||||||
|
setup: func(snap *proxycfg.ConfigSnapshot) {
|
||||||
|
snap.TerminatingGateway.ServiceResolvers = map[structs.ServiceID]*structs.ServiceResolverConfigEntry{
|
||||||
|
structs.NewServiceID("web", nil): &structs.ServiceResolverConfigEntry{
|
||||||
|
Kind: structs.ServiceResolver,
|
||||||
|
Name: "web",
|
||||||
|
DefaultSubset: "v2",
|
||||||
|
Subsets: map[string]structs.ServiceResolverSubset{
|
||||||
|
"v1": {
|
||||||
|
Filter: "Service.Meta.version == 1",
|
||||||
|
},
|
||||||
|
"v2": {
|
||||||
|
Filter: "Service.Meta.version == 2",
|
||||||
|
OnlyPassing: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
structs.NewServiceID("web", nil): &structs.ServiceResolverConfigEntry{
|
||||||
|
Kind: structs.ServiceResolver,
|
||||||
|
Name: "web",
|
||||||
|
DefaultSubset: "v2",
|
||||||
|
Subsets: map[string]structs.ServiceResolverSubset{
|
||||||
|
"v1": {
|
||||||
|
Filter: "Service.Meta.version == 1",
|
||||||
|
},
|
||||||
|
"v2": {
|
||||||
|
Filter: "Service.Meta.version == 2",
|
||||||
|
OnlyPassing: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
|
|
|
@ -562,35 +562,31 @@ func (s *Server) makeTerminatingGatewayListener(name, addr string, port int, cfg
|
||||||
}
|
}
|
||||||
l.ListenerFilters = []envoylistener.ListenerFilter{tlsInspector}
|
l.ListenerFilters = []envoylistener.ListenerFilter{tlsInspector}
|
||||||
|
|
||||||
sniCluster, err := makeSNIClusterFilter()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make a FilterChain for each linked service
|
// Make a FilterChain for each linked service
|
||||||
// Match on the cluster name,
|
// Match on the cluster name,
|
||||||
for svc, _ := range cfgSnap.TerminatingGateway.ServiceGroups {
|
for svc, _ := range cfgSnap.TerminatingGateway.ServiceGroups {
|
||||||
clusterName := connect.ServiceSNI(svc.ID, "", svc.NamespaceOrDefault(), cfgSnap.Datacenter, cfgSnap.Roots.TrustDomain)
|
clusterName := connect.ServiceSNI(svc.ID, "", svc.NamespaceOrDefault(), cfgSnap.Datacenter, cfgSnap.Roots.TrustDomain)
|
||||||
|
resolver, hasResolver := cfgSnap.TerminatingGateway.ServiceResolvers[svc]
|
||||||
|
|
||||||
// The cluster name here doesn't matter as the sni_cluster filter will fill it in for us.
|
clusterChain, err := s.sniFilterChainTerminatingGateway(name, clusterName, svc, cfgSnap)
|
||||||
tcpProxy, err := makeTCPProxyFilter(name, "", fmt.Sprintf("terminating_gateway_%s_", svc.ID))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("failed to make filter chain for cluster %q: %v", clusterName, err)
|
||||||
}
|
|
||||||
|
|
||||||
clusterChain := envoylistener.FilterChain{
|
|
||||||
FilterChainMatch: makeSNIFilterChainMatch(clusterName),
|
|
||||||
Filters: []envoylistener.Filter{
|
|
||||||
sniCluster,
|
|
||||||
tcpProxy,
|
|
||||||
},
|
|
||||||
TlsContext: &envoyauth.DownstreamTlsContext{
|
|
||||||
// TODO (gateways) (freddy) Could we get to this point and not have a leaf for the service?
|
|
||||||
CommonTlsContext: makeCommonTLSContext(cfgSnap, cfgSnap.TerminatingGateway.ServiceLeaves[svc]),
|
|
||||||
RequireClientCertificate: &types.BoolValue{Value: true},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
l.FilterChains = append(l.FilterChains, clusterChain)
|
l.FilterChains = append(l.FilterChains, clusterChain)
|
||||||
|
|
||||||
|
// if there is a service-resolver for this service then also setup subset filter chains for it
|
||||||
|
if hasResolver {
|
||||||
|
// generate 1 filter chain for each service subset
|
||||||
|
for subsetName := range resolver.Subsets {
|
||||||
|
clusterName := connect.ServiceSNI(svc.ID, subsetName, svc.NamespaceOrDefault(), cfgSnap.Datacenter, cfgSnap.Roots.TrustDomain)
|
||||||
|
|
||||||
|
clusterChain, err := s.sniFilterChainTerminatingGateway(name, clusterName, svc, cfgSnap)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to make filter chain for cluster %q: %v", clusterName, err)
|
||||||
|
}
|
||||||
|
l.FilterChains = append(l.FilterChains, clusterChain)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = injectConnectFilters(cfgSnap, token, l, false)
|
err = injectConnectFilters(cfgSnap, token, l, false)
|
||||||
|
@ -598,6 +594,31 @@ func (s *Server) makeTerminatingGatewayListener(name, addr string, port int, cfg
|
||||||
return l, nil
|
return l, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Server) sniFilterChainTerminatingGateway(listener, cluster string, service structs.ServiceID, cfgSnap *proxycfg.ConfigSnapshot) (envoylistener.FilterChain, error) {
|
||||||
|
sniCluster, err := makeSNIClusterFilter()
|
||||||
|
if err != nil {
|
||||||
|
return envoylistener.FilterChain{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// The cluster name here doesn't matter as the sni_cluster filter will fill it in for us.
|
||||||
|
tcpProxy, err := makeTCPProxyFilter(listener, "", fmt.Sprintf("terminating_gateway_%s_", service.String()))
|
||||||
|
if err != nil {
|
||||||
|
return envoylistener.FilterChain{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return envoylistener.FilterChain{
|
||||||
|
FilterChainMatch: makeSNIFilterChainMatch(cluster),
|
||||||
|
Filters: []envoylistener.Filter{
|
||||||
|
sniCluster,
|
||||||
|
tcpProxy,
|
||||||
|
},
|
||||||
|
TlsContext: &envoyauth.DownstreamTlsContext{
|
||||||
|
CommonTlsContext: makeCommonTLSContext(cfgSnap, cfgSnap.TerminatingGateway.ServiceLeaves[service]),
|
||||||
|
RequireClientCertificate: &types.BoolValue{Value: true},
|
||||||
|
},
|
||||||
|
}, err
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Server) makeMeshGatewayListener(name, addr string, port int, cfgSnap *proxycfg.ConfigSnapshot) (*envoy.Listener, error) {
|
func (s *Server) makeMeshGatewayListener(name, addr string, port int, cfgSnap *proxycfg.ConfigSnapshot) (*envoy.Listener, error) {
|
||||||
tlsInspector, err := makeTLSInspectorListenerFilter()
|
tlsInspector, err := makeTLSInspectorListenerFilter()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -329,6 +329,40 @@ func TestListenersFromSnapshot(t *testing.T) {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "terminating-gateway-service-subsets",
|
||||||
|
create: proxycfg.TestConfigSnapshotTerminatingGateway,
|
||||||
|
setup: func(snap *proxycfg.ConfigSnapshot) {
|
||||||
|
snap.TerminatingGateway.ServiceResolvers = map[structs.ServiceID]*structs.ServiceResolverConfigEntry{
|
||||||
|
structs.NewServiceID("web", nil): {
|
||||||
|
Kind: structs.ServiceResolver,
|
||||||
|
Name: "web",
|
||||||
|
Subsets: map[string]structs.ServiceResolverSubset{
|
||||||
|
"v1": {
|
||||||
|
Filter: "Service.Meta.version == 1",
|
||||||
|
},
|
||||||
|
"v2": {
|
||||||
|
Filter: "Service.Meta.version == 2",
|
||||||
|
OnlyPassing: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
structs.NewServiceID("web", nil): {
|
||||||
|
Kind: structs.ServiceResolver,
|
||||||
|
Name: "web",
|
||||||
|
Subsets: map[string]structs.ServiceResolverSubset{
|
||||||
|
"v1": {
|
||||||
|
Filter: "Service.Meta.version == 1",
|
||||||
|
},
|
||||||
|
"v2": {
|
||||||
|
Filter: "Service.Meta.version == 2",
|
||||||
|
OnlyPassing: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
|
|
71
agent/xds/testdata/clusters/terminating-gateway-ignore-extra-resolvers.golden
vendored
Normal file
71
agent/xds/testdata/clusters/terminating-gateway-ignore-extra-resolvers.golden
vendored
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
{
|
||||||
|
"versionInfo": "00000001",
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.Cluster",
|
||||||
|
"name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"type": "EDS",
|
||||||
|
"edsClusterConfig": {
|
||||||
|
"edsConfig": {
|
||||||
|
"ads": {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"connectTimeout": "5s",
|
||||||
|
"outlierDetection": {
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.Cluster",
|
||||||
|
"name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"type": "EDS",
|
||||||
|
"edsClusterConfig": {
|
||||||
|
"edsConfig": {
|
||||||
|
"ads": {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"connectTimeout": "5s",
|
||||||
|
"outlierDetection": {
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.Cluster",
|
||||||
|
"name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"type": "EDS",
|
||||||
|
"edsClusterConfig": {
|
||||||
|
"edsConfig": {
|
||||||
|
"ads": {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"connectTimeout": "5s",
|
||||||
|
"outlierDetection": {
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.Cluster",
|
||||||
|
"name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"type": "EDS",
|
||||||
|
"edsClusterConfig": {
|
||||||
|
"edsConfig": {
|
||||||
|
"ads": {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"connectTimeout": "5s",
|
||||||
|
"outlierDetection": {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"typeUrl": "type.googleapis.com/envoy.api.v2.Cluster",
|
||||||
|
"nonce": "00000001"
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
{
|
||||||
|
"versionInfo": "00000001",
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.Cluster",
|
||||||
|
"name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"type": "EDS",
|
||||||
|
"edsClusterConfig": {
|
||||||
|
"edsConfig": {
|
||||||
|
"ads": {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"connectTimeout": "5s",
|
||||||
|
"outlierDetection": {
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.Cluster",
|
||||||
|
"name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"type": "EDS",
|
||||||
|
"edsClusterConfig": {
|
||||||
|
"edsConfig": {
|
||||||
|
"ads": {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"connectTimeout": "5s",
|
||||||
|
"outlierDetection": {
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.Cluster",
|
||||||
|
"name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"type": "EDS",
|
||||||
|
"edsClusterConfig": {
|
||||||
|
"edsConfig": {
|
||||||
|
"ads": {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"connectTimeout": "5s",
|
||||||
|
"outlierDetection": {
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.Cluster",
|
||||||
|
"name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"type": "EDS",
|
||||||
|
"edsClusterConfig": {
|
||||||
|
"edsConfig": {
|
||||||
|
"ads": {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"connectTimeout": "5s",
|
||||||
|
"outlierDetection": {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"typeUrl": "type.googleapis.com/envoy.api.v2.Cluster",
|
||||||
|
"nonce": "00000001"
|
||||||
|
}
|
107
agent/xds/testdata/endpoints/terminating-gateway-default-service-subset.golden
vendored
Normal file
107
agent/xds/testdata/endpoints/terminating-gateway-default-service-subset.golden
vendored
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
{
|
||||||
|
"versionInfo": "00000001",
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment",
|
||||||
|
"clusterName": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"endpoints": [
|
||||||
|
{
|
||||||
|
"lbEndpoints": [
|
||||||
|
{
|
||||||
|
"endpoint": {
|
||||||
|
"address": {
|
||||||
|
"socketAddress": {
|
||||||
|
"address": "10.10.1.1",
|
||||||
|
"portValue": 8081
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"healthStatus": "HEALTHY",
|
||||||
|
"loadBalancingWeight": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"endpoint": {
|
||||||
|
"address": {
|
||||||
|
"socketAddress": {
|
||||||
|
"address": "10.10.1.2",
|
||||||
|
"portValue": 8081
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"healthStatus": "HEALTHY",
|
||||||
|
"loadBalancingWeight": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment",
|
||||||
|
"clusterName": "v1.web.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
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment",
|
||||||
|
"clusterName": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"endpoints": [
|
||||||
|
{
|
||||||
|
"lbEndpoints": [
|
||||||
|
{
|
||||||
|
"endpoint": {
|
||||||
|
"address": {
|
||||||
|
"socketAddress": {
|
||||||
|
"address": "10.10.1.2",
|
||||||
|
"portValue": 8080
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"healthStatus": "HEALTHY",
|
||||||
|
"loadBalancingWeight": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment",
|
||||||
|
"clusterName": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"endpoints": [
|
||||||
|
{
|
||||||
|
"lbEndpoints": [
|
||||||
|
{
|
||||||
|
"endpoint": {
|
||||||
|
"address": {
|
||||||
|
"socketAddress": {
|
||||||
|
"address": "10.10.1.2",
|
||||||
|
"portValue": 8080
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"healthStatus": "HEALTHY",
|
||||||
|
"loadBalancingWeight": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"typeUrl": "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment",
|
||||||
|
"nonce": "00000001"
|
||||||
|
}
|
|
@ -0,0 +1,119 @@
|
||||||
|
{
|
||||||
|
"versionInfo": "00000001",
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment",
|
||||||
|
"clusterName": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"endpoints": [
|
||||||
|
{
|
||||||
|
"lbEndpoints": [
|
||||||
|
{
|
||||||
|
"endpoint": {
|
||||||
|
"address": {
|
||||||
|
"socketAddress": {
|
||||||
|
"address": "10.10.1.1",
|
||||||
|
"portValue": 8081
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"healthStatus": "HEALTHY",
|
||||||
|
"loadBalancingWeight": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"endpoint": {
|
||||||
|
"address": {
|
||||||
|
"socketAddress": {
|
||||||
|
"address": "10.10.1.2",
|
||||||
|
"portValue": 8081
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"healthStatus": "HEALTHY",
|
||||||
|
"loadBalancingWeight": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment",
|
||||||
|
"clusterName": "v1.web.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
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment",
|
||||||
|
"clusterName": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"endpoints": [
|
||||||
|
{
|
||||||
|
"lbEndpoints": [
|
||||||
|
{
|
||||||
|
"endpoint": {
|
||||||
|
"address": {
|
||||||
|
"socketAddress": {
|
||||||
|
"address": "10.10.1.2",
|
||||||
|
"portValue": 8080
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"healthStatus": "HEALTHY",
|
||||||
|
"loadBalancingWeight": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment",
|
||||||
|
"clusterName": "web.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
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"typeUrl": "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment",
|
||||||
|
"nonce": "00000001"
|
||||||
|
}
|
|
@ -0,0 +1,260 @@
|
||||||
|
{
|
||||||
|
"versionInfo": "00000001",
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.Listener",
|
||||||
|
"name": "default:1.2.3.4:8443",
|
||||||
|
"address": {
|
||||||
|
"socketAddress": {
|
||||||
|
"address": "1.2.3.4",
|
||||||
|
"portValue": 8443
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"filterChains": [
|
||||||
|
{
|
||||||
|
"filterChainMatch": {
|
||||||
|
"serverNames": [
|
||||||
|
"web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"tlsContext": {
|
||||||
|
"commonTlsContext": {
|
||||||
|
"tlsParams": {
|
||||||
|
|
||||||
|
},
|
||||||
|
"tlsCertificates": [
|
||||||
|
{
|
||||||
|
"certificateChain": {
|
||||||
|
"inlineString": "-----BEGIN CERTIFICATE-----\\nMIICKDCCAc+gAwIBAgIIT/zLIOrnlRQwCgYIKoZIzj0EAwIwFTETMBEGA1UEAxMK\\nVGVzdCBDQSA4NTAeFw0yMDA0MTEwMDMxMjJaFw0zMDA0MTEwMDMxMjJaMCoxKDAm\\nBgNVBAMTH3dlYi5zdmMuZGVmYXVsdC4xMTExMTExMS5jb25zdWwwWTATBgcqhkjO\\nPQIBBggqhkjOPQMBBwNCAAR3uNYYt8amLQMfae6GpMyFaMBBkGL2ZPANmCy7nsL7\\n5kczishLb0GG1/PoNBQJW5A1Wl7uI/SE77KTThRxk3Wco4HzMIHwMA4GA1UdDwEB\\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\\nBAIwADApBgNVHQ4EIgQgYbec+6bte/VdH3M63TFVmDU0jH5461iZTsiJ1x+18iow\\nKwYDVR0jBCQwIoAgqo5xDZXH+SCNmEyBYOSyc8RlSBX3sJJrSLCtuZp5WxgwWQYD\\nVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1NTU1\\nNTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqGSM49\\nBAMCA0cAMEQCIC/xdLblMMnwXGqBn9XkdGOnUEtJW0LU+tKyen5PxRO7AiBjTefh\\n5uZU8QVs2FQTQHN0Omr4ngToHBHNwKl1Flvyqw==\\n-----END CERTIFICATE-----\\n"
|
||||||
|
},
|
||||||
|
"privateKey": {
|
||||||
|
"inlineString": "-----BEGIN EC PRIVATE KEY-----\\nMHcCAQEEIP6roctlkGz+7od7hFwaldpvbnkXmnjvpPBxyKU4NcM9oAoGCCqGSM49\\nAwEHoUQDQgAEd7jWGLfGpi0DH2nuhqTMhWjAQZBi9mTwDZgsu57C++ZHM4rIS29B\\nhtfz6DQUCVuQNVpe7iP0hO+yk04UcZN1nA==\\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
|
||||||
|
},
|
||||||
|
"filters": [
|
||||||
|
{
|
||||||
|
"name": "envoy.ext_authz",
|
||||||
|
"config": {
|
||||||
|
"grpc_service": {
|
||||||
|
"envoy_grpc": {
|
||||||
|
"cluster_name": "local_agent"
|
||||||
|
},
|
||||||
|
"initial_metadata": [
|
||||||
|
{
|
||||||
|
"key": "x-consul-token",
|
||||||
|
"value": "my-token"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"stat_prefix": "connect_authz"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "envoy.filters.network.sni_cluster"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "envoy.tcp_proxy",
|
||||||
|
"config": {
|
||||||
|
"cluster": "",
|
||||||
|
"stat_prefix": "terminating_gateway_web_default_tcp"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filterChainMatch": {
|
||||||
|
"serverNames": [
|
||||||
|
"v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"tlsContext": {
|
||||||
|
"commonTlsContext": {
|
||||||
|
"tlsParams": {
|
||||||
|
|
||||||
|
},
|
||||||
|
"tlsCertificates": [
|
||||||
|
{
|
||||||
|
"certificateChain": {
|
||||||
|
"inlineString": "-----BEGIN CERTIFICATE-----\\nMIICKDCCAc+gAwIBAgIIT/zLIOrnlRQwCgYIKoZIzj0EAwIwFTETMBEGA1UEAxMK\\nVGVzdCBDQSA4NTAeFw0yMDA0MTEwMDMxMjJaFw0zMDA0MTEwMDMxMjJaMCoxKDAm\\nBgNVBAMTH3dlYi5zdmMuZGVmYXVsdC4xMTExMTExMS5jb25zdWwwWTATBgcqhkjO\\nPQIBBggqhkjOPQMBBwNCAAR3uNYYt8amLQMfae6GpMyFaMBBkGL2ZPANmCy7nsL7\\n5kczishLb0GG1/PoNBQJW5A1Wl7uI/SE77KTThRxk3Wco4HzMIHwMA4GA1UdDwEB\\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\\nBAIwADApBgNVHQ4EIgQgYbec+6bte/VdH3M63TFVmDU0jH5461iZTsiJ1x+18iow\\nKwYDVR0jBCQwIoAgqo5xDZXH+SCNmEyBYOSyc8RlSBX3sJJrSLCtuZp5WxgwWQYD\\nVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1NTU1\\nNTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqGSM49\\nBAMCA0cAMEQCIC/xdLblMMnwXGqBn9XkdGOnUEtJW0LU+tKyen5PxRO7AiBjTefh\\n5uZU8QVs2FQTQHN0Omr4ngToHBHNwKl1Flvyqw==\\n-----END CERTIFICATE-----\\n"
|
||||||
|
},
|
||||||
|
"privateKey": {
|
||||||
|
"inlineString": "-----BEGIN EC PRIVATE KEY-----\\nMHcCAQEEIP6roctlkGz+7od7hFwaldpvbnkXmnjvpPBxyKU4NcM9oAoGCCqGSM49\\nAwEHoUQDQgAEd7jWGLfGpi0DH2nuhqTMhWjAQZBi9mTwDZgsu57C++ZHM4rIS29B\\nhtfz6DQUCVuQNVpe7iP0hO+yk04UcZN1nA==\\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
|
||||||
|
},
|
||||||
|
"filters": [
|
||||||
|
{
|
||||||
|
"name": "envoy.ext_authz",
|
||||||
|
"config": {
|
||||||
|
"grpc_service": {
|
||||||
|
"envoy_grpc": {
|
||||||
|
"cluster_name": "local_agent"
|
||||||
|
},
|
||||||
|
"initial_metadata": [
|
||||||
|
{
|
||||||
|
"key": "x-consul-token",
|
||||||
|
"value": "my-token"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"stat_prefix": "connect_authz"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "envoy.filters.network.sni_cluster"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "envoy.tcp_proxy",
|
||||||
|
"config": {
|
||||||
|
"cluster": "",
|
||||||
|
"stat_prefix": "terminating_gateway_web_default_tcp"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filterChainMatch": {
|
||||||
|
"serverNames": [
|
||||||
|
"v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"tlsContext": {
|
||||||
|
"commonTlsContext": {
|
||||||
|
"tlsParams": {
|
||||||
|
|
||||||
|
},
|
||||||
|
"tlsCertificates": [
|
||||||
|
{
|
||||||
|
"certificateChain": {
|
||||||
|
"inlineString": "-----BEGIN CERTIFICATE-----\\nMIICKDCCAc+gAwIBAgIIT/zLIOrnlRQwCgYIKoZIzj0EAwIwFTETMBEGA1UEAxMK\\nVGVzdCBDQSA4NTAeFw0yMDA0MTEwMDMxMjJaFw0zMDA0MTEwMDMxMjJaMCoxKDAm\\nBgNVBAMTH3dlYi5zdmMuZGVmYXVsdC4xMTExMTExMS5jb25zdWwwWTATBgcqhkjO\\nPQIBBggqhkjOPQMBBwNCAAR3uNYYt8amLQMfae6GpMyFaMBBkGL2ZPANmCy7nsL7\\n5kczishLb0GG1/PoNBQJW5A1Wl7uI/SE77KTThRxk3Wco4HzMIHwMA4GA1UdDwEB\\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\\nBAIwADApBgNVHQ4EIgQgYbec+6bte/VdH3M63TFVmDU0jH5461iZTsiJ1x+18iow\\nKwYDVR0jBCQwIoAgqo5xDZXH+SCNmEyBYOSyc8RlSBX3sJJrSLCtuZp5WxgwWQYD\\nVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1NTU1\\nNTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqGSM49\\nBAMCA0cAMEQCIC/xdLblMMnwXGqBn9XkdGOnUEtJW0LU+tKyen5PxRO7AiBjTefh\\n5uZU8QVs2FQTQHN0Omr4ngToHBHNwKl1Flvyqw==\\n-----END CERTIFICATE-----\\n"
|
||||||
|
},
|
||||||
|
"privateKey": {
|
||||||
|
"inlineString": "-----BEGIN EC PRIVATE KEY-----\\nMHcCAQEEIP6roctlkGz+7od7hFwaldpvbnkXmnjvpPBxyKU4NcM9oAoGCCqGSM49\\nAwEHoUQDQgAEd7jWGLfGpi0DH2nuhqTMhWjAQZBi9mTwDZgsu57C++ZHM4rIS29B\\nhtfz6DQUCVuQNVpe7iP0hO+yk04UcZN1nA==\\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
|
||||||
|
},
|
||||||
|
"filters": [
|
||||||
|
{
|
||||||
|
"name": "envoy.ext_authz",
|
||||||
|
"config": {
|
||||||
|
"grpc_service": {
|
||||||
|
"envoy_grpc": {
|
||||||
|
"cluster_name": "local_agent"
|
||||||
|
},
|
||||||
|
"initial_metadata": [
|
||||||
|
{
|
||||||
|
"key": "x-consul-token",
|
||||||
|
"value": "my-token"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"stat_prefix": "connect_authz"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "envoy.filters.network.sni_cluster"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "envoy.tcp_proxy",
|
||||||
|
"config": {
|
||||||
|
"cluster": "",
|
||||||
|
"stat_prefix": "terminating_gateway_web_default_tcp"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filterChainMatch": {
|
||||||
|
"serverNames": [
|
||||||
|
"api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"tlsContext": {
|
||||||
|
"commonTlsContext": {
|
||||||
|
"tlsParams": {
|
||||||
|
|
||||||
|
},
|
||||||
|
"tlsCertificates": [
|
||||||
|
{
|
||||||
|
"certificateChain": {
|
||||||
|
"inlineString": "-----BEGIN CERTIFICATE-----\\nMIICKjCCAc+gAwIBAgIICeaPMbQdJsswCgYIKoZIzj0EAwIwFTETMBEGA1UEAxMK\\nVGVzdCBDQSA4NTAeFw0yMDA0MTEwMDE3NTZaFw0zMDA0MTEwMDE3NTZaMCoxKDAm\\nBgNVBAMTH2FwaS5zdmMuZGVmYXVsdC4xMTExMTExMS5jb25zdWwwWTATBgcqhkjO\\nPQIBBggqhkjOPQMBBwNCAASvkFCbA1rP8NxyKAOGoLmVjwSB+dO/ncs5KqourUPw\\nbZfQEETsTaTdO5aWgkJilagD7Z1RZltWk+MGhPleo8/bo4HzMIHwMA4GA1UdDwEB\\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\\nBAIwADApBgNVHQ4EIgQgyNkAhsJy93ueCk9Bjo9DdiZB+eJq7zs4qr9tmrT5zBAw\\nKwYDVR0jBCQwIoAgJDQM9fdkMlYIa/hmjVbXie/3qNMaAS8R9dKPQ2XE05gwWQYD\\nVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1NTU1\\nNTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvYXBpMAoGCCqGSM49\\nBAMCA0kAMEYCIQDN/60bmqjeFQpHw52r63Lftuuexl6AHVDI+o7MPYzfKwIhANMJ\\n0s1qRbOUItdIC8y0Ph2woXcj2yXluiPzFT3Ij94k\\n-----END CERTIFICATE-----\\n"
|
||||||
|
},
|
||||||
|
"privateKey": {
|
||||||
|
"inlineString": "-----BEGIN EC PRIVATE KEY-----\\nMHcCAQEEIBdbcIKnjbzUBLHVQANB2P6bQf6SNOtEd6san+82wY21oAoGCCqGSM49\\nAwEHoUQDQgAEr5BQmwNaz/DccigDhqC5lY8EgfnTv53LOSqqLq1D8G2X0BBE7E2k\\n3TuWloJCYpWoA+2dUWZbVpPjBoT5XqPP2w==\\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
|
||||||
|
},
|
||||||
|
"filters": [
|
||||||
|
{
|
||||||
|
"name": "envoy.ext_authz",
|
||||||
|
"config": {
|
||||||
|
"grpc_service": {
|
||||||
|
"envoy_grpc": {
|
||||||
|
"cluster_name": "local_agent"
|
||||||
|
},
|
||||||
|
"initial_metadata": [
|
||||||
|
{
|
||||||
|
"key": "x-consul-token",
|
||||||
|
"value": "my-token"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"stat_prefix": "connect_authz"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "envoy.filters.network.sni_cluster"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "envoy.tcp_proxy",
|
||||||
|
"config": {
|
||||||
|
"cluster": "",
|
||||||
|
"stat_prefix": "terminating_gateway_api_default_tcp"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"listenerFilters": [
|
||||||
|
{
|
||||||
|
"name": "envoy.listener.tls_inspector"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"typeUrl": "type.googleapis.com/envoy.api.v2.Listener",
|
||||||
|
"nonce": "00000001"
|
||||||
|
}
|
Loading…
Reference in New Issue