mirror of https://github.com/status-im/consul.git
[OSS] extensions: refactor PluginConfiguration into a more generic type ExtensionConfiguration (#15846)
* extensions: refactor PluginConfiguration into a more generic type ExtensionConfiguration Also: * adds endpoints configuration to lambda golden tests * uses string constant for builtin/aws/lambda Co-authored-by: Eric <eric@haberkorn.co>
This commit is contained in:
parent
f5e01f8c6b
commit
c7ef04c597
|
@ -952,7 +952,7 @@ func TestConfigSnapshotTerminatingGatewayWithLambdaService(t testing.T, extraUpd
|
|||
ProxyConfig: map[string]interface{}{"protocol": "http"},
|
||||
EnvoyExtensions: []structs.EnvoyExtension{
|
||||
{
|
||||
Name: "builtin/aws/lambda",
|
||||
Name: structs.BuiltinAWSLambdaExtension,
|
||||
Arguments: map[string]interface{}{
|
||||
"ARN": "lambda-arn",
|
||||
"PayloadPassthrough": true,
|
||||
|
|
|
@ -25,6 +25,12 @@ func setupTestVariationConfigEntriesAndSnapshot(
|
|||
|
||||
dbChain := setupTestVariationDiscoveryChain(t, variation, additionalEntries...)
|
||||
|
||||
nodes := TestUpstreamNodes(t, "db")
|
||||
if variation == "register-to-terminating-gateway" {
|
||||
for _, node := range nodes {
|
||||
node.Service.Kind = structs.ServiceKindTerminatingGateway
|
||||
}
|
||||
}
|
||||
events := []UpdateEvent{
|
||||
{
|
||||
CorrelationID: "discovery-chain:" + dbUID.String(),
|
||||
|
@ -35,7 +41,7 @@ func setupTestVariationConfigEntriesAndSnapshot(
|
|||
{
|
||||
CorrelationID: "upstream-target:" + dbChain.ID() + ":" + dbUID.String(),
|
||||
Result: &structs.IndexedCheckServiceNodes{
|
||||
Nodes: TestUpstreamNodes(t, "db"),
|
||||
Nodes: nodes,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -207,6 +213,7 @@ func setupTestVariationConfigEntriesAndSnapshot(
|
|||
case "grpc-router":
|
||||
case "chain-and-router":
|
||||
case "lb-resolver":
|
||||
case "register-to-terminating-gateway":
|
||||
default:
|
||||
t.Fatalf("unexpected variation: %q", variation)
|
||||
return nil
|
||||
|
@ -229,6 +236,7 @@ func setupTestVariationDiscoveryChain(
|
|||
switch variation {
|
||||
case "default":
|
||||
// no config entries
|
||||
case "register-to-terminating-gateway":
|
||||
case "simple-with-overrides":
|
||||
compileSetup = func(req *discoverychain.CompileRequest) {
|
||||
req.OverrideMeshGateway.Mode = structs.MeshGatewayModeLocal
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/consul/api"
|
||||
"github.com/miekg/dns"
|
||||
|
||||
"github.com/hashicorp/go-multierror"
|
||||
|
@ -56,6 +57,10 @@ var AllConfigEntryKinds = []string{
|
|||
ExportedServices,
|
||||
}
|
||||
|
||||
const (
|
||||
BuiltinAWSLambdaExtension string = "builtin/aws/lambda"
|
||||
)
|
||||
|
||||
// ConfigEntry is the interface for centralized configuration stored in Raft.
|
||||
// Currently only service-defaults and proxy-defaults are supported.
|
||||
type ConfigEntry interface {
|
||||
|
@ -293,10 +298,23 @@ type EnvoyExtension struct {
|
|||
Required bool
|
||||
Arguments map[string]interface{}
|
||||
}
|
||||
type EnvoyExtensions []EnvoyExtension
|
||||
|
||||
func (es EnvoyExtensions) ToAPI() []api.EnvoyExtension {
|
||||
extensions := make([]api.EnvoyExtension, len(es))
|
||||
for i, e := range es {
|
||||
extensions[i] = api.EnvoyExtension{
|
||||
Name: e.Name,
|
||||
Required: e.Required,
|
||||
Arguments: e.Arguments,
|
||||
}
|
||||
}
|
||||
return extensions
|
||||
}
|
||||
|
||||
func builtInExtension(name string) bool {
|
||||
extensions := map[string]struct{}{
|
||||
"builtin/aws/lambda": {},
|
||||
BuiltinAWSLambdaExtension: {},
|
||||
}
|
||||
|
||||
_, ok := extensions[name]
|
||||
|
|
|
@ -2732,7 +2732,7 @@ func TestServiceConfigEntry(t *testing.T) {
|
|||
Protocol: "http",
|
||||
EnvoyExtensions: []EnvoyExtension{
|
||||
{
|
||||
Name: "builtin/aws/lambda",
|
||||
Name: BuiltinAWSLambdaExtension,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -251,9 +251,17 @@ func (s *Server) processDelta(stream ADSDeltaStream, reqCh <-chan *envoy_discove
|
|||
s.ResourceMapMutateFn(newResourceMap)
|
||||
}
|
||||
|
||||
newResourceMap, err = serverlessplugin.MutateIndexedResources(newResourceMap, xdscommon.MakePluginConfiguration(cfgSnap))
|
||||
if err != nil {
|
||||
return status.Errorf(codes.Unavailable, "failed to patch xDS resources in the serverless plugin: %v", err)
|
||||
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 := populateChildIndexMap(newResourceMap); err != nil {
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"testing"
|
||||
|
||||
envoy_cluster_v3 "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3"
|
||||
envoy_endpoint_v3 "github.com/envoyproxy/go-control-plane/envoy/config/endpoint/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/golang/protobuf/proto"
|
||||
|
@ -45,7 +46,7 @@ func TestServerlessPluginFromSnapshot(t *testing.T) {
|
|||
Protocol: "http",
|
||||
EnvoyExtensions: []structs.EnvoyExtension{
|
||||
{
|
||||
Name: "builtin/aws/lambda",
|
||||
Name: structs.BuiltinAWSLambdaExtension,
|
||||
Arguments: map[string]interface{}{
|
||||
"ARN": "lambda-arn",
|
||||
"PayloadPassthrough": payloadPassthrough,
|
||||
|
@ -67,6 +68,13 @@ func TestServerlessPluginFromSnapshot(t *testing.T) {
|
|||
return proxycfg.TestConfigSnapshotDiscoveryChain(t, "default", nil, nil, makeServiceDefaults(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))
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "lambda-connect-proxy-opposite-meta",
|
||||
create: func(t testinf.T) *proxycfg.ConfigSnapshot {
|
||||
|
@ -107,8 +115,17 @@ func TestServerlessPluginFromSnapshot(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
|
||||
indexedResources := indexResources(g.Logger, res)
|
||||
newResourceMap, err := serverlessplugin.MutateIndexedResources(indexedResources, xdscommon.MakePluginConfiguration(snap))
|
||||
require.NoError(t, err)
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
entities := []struct {
|
||||
name string
|
||||
|
@ -142,6 +159,15 @@ func TestServerlessPluginFromSnapshot(t *testing.T) {
|
|||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "endpoints",
|
||||
key: xdscommon.EndpointType,
|
||||
sorter: func(msgs []proto.Message) func(int, int) bool {
|
||||
return func(i, j int) bool {
|
||||
return msgs[i].(*envoy_endpoint_v3.ClusterLoadAssignment).ClusterName < msgs[j].(*envoy_endpoint_v3.ClusterLoadAssignment).ClusterName
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, entity := range entities {
|
||||
|
|
|
@ -14,9 +14,9 @@ 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/xdscommon"
|
||||
"github.com/hashicorp/consul/api"
|
||||
)
|
||||
|
||||
|
@ -30,22 +30,15 @@ type lambdaPatcher struct {
|
|||
|
||||
var _ patcher = (*lambdaPatcher)(nil)
|
||||
|
||||
func makeLambdaPatcher(serviceConfig xdscommon.ServiceConfig) (patcher, bool) {
|
||||
func makeLambdaPatcher(ext api.EnvoyExtension, upstreamKind api.ServiceKind) (patcher, bool) {
|
||||
var patcher lambdaPatcher
|
||||
|
||||
// TODO this is a hack. We should iterate through the extensions outside of here
|
||||
if len(serviceConfig.EnvoyExtensions) == 0 {
|
||||
if ext.Name != structs.BuiltinAWSLambdaExtension {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// TODO this is a hack. We should iterate through the extensions outside of here
|
||||
extension := serviceConfig.EnvoyExtensions[0]
|
||||
if extension.Name != "builtin/aws/lambda" {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// TODO this fails when types aren't encode properly. We need to check this earlier in the Validate RPC.
|
||||
err := mapstructure.Decode(extension.Arguments, &patcher)
|
||||
// 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
|
||||
}
|
||||
|
@ -58,7 +51,7 @@ func makeLambdaPatcher(serviceConfig xdscommon.ServiceConfig) (patcher, bool) {
|
|||
return nil, false
|
||||
}
|
||||
|
||||
patcher.Kind = serviceConfig.Kind
|
||||
patcher.Kind = upstreamKind
|
||||
|
||||
return patcher, true
|
||||
}
|
||||
|
|
|
@ -3,9 +3,9 @@ package serverlessplugin
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/consul/agent/structs"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/hashicorp/consul/agent/xds/xdscommon"
|
||||
"github.com/hashicorp/consul/api"
|
||||
)
|
||||
|
||||
|
@ -50,21 +50,16 @@ func TestMakeLambdaPatcher(t *testing.T) {
|
|||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
config := xdscommon.ServiceConfig{
|
||||
Kind: kind,
|
||||
EnvoyExtensions: []api.EnvoyExtension{
|
||||
{
|
||||
Name: "builtin/aws/lambda",
|
||||
Arguments: map[string]interface{}{
|
||||
"ARN": tc.arn,
|
||||
"Region": tc.region,
|
||||
"PayloadPassthrough": tc.payloadPassthrough,
|
||||
},
|
||||
},
|
||||
ext := api.EnvoyExtension{
|
||||
Name: structs.BuiltinAWSLambdaExtension,
|
||||
Arguments: map[string]interface{}{
|
||||
"ARN": tc.arn,
|
||||
"Region": tc.region,
|
||||
"PayloadPassthrough": tc.payloadPassthrough,
|
||||
},
|
||||
}
|
||||
|
||||
patcher, ok := makeLambdaPatcher(config)
|
||||
patcher, ok := makeLambdaPatcher(ext, kind)
|
||||
|
||||
require.Equal(t, tc.ok, ok)
|
||||
|
||||
|
|
|
@ -32,51 +32,9 @@ type patcher interface {
|
|||
|
||||
type patchers map[api.CompoundServiceName]patcher
|
||||
|
||||
// getPatcherBySNI gets the patcher for the associated SNI.
|
||||
func getPatcherBySNI(config xdscommon.PluginConfiguration, sni string) patcher {
|
||||
serviceName, ok := config.SNIToServiceName[sni]
|
||||
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
serviceConfig, ok := config.ServiceConfigs[serviceName]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
p := makePatcher(serviceConfig)
|
||||
if p == nil || !p.CanPatch(config.Kind) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
// getPatcherByEnvoyID gets the patcher for the associated envoy id.
|
||||
func getPatcherByEnvoyID(config xdscommon.PluginConfiguration, envoyID string) patcher {
|
||||
serviceName, ok := config.EnvoyIDToServiceName[envoyID]
|
||||
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
serviceConfig, ok := config.ServiceConfigs[serviceName]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
p := makePatcher(serviceConfig)
|
||||
if p == nil || !p.CanPatch(config.Kind) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func makePatcher(serviceConfig xdscommon.ServiceConfig) patcher {
|
||||
func makePatcher(config xdscommon.ExtensionConfiguration) patcher {
|
||||
for _, constructor := range patchConstructors {
|
||||
patcher, ok := constructor(serviceConfig)
|
||||
patcher, ok := constructor(config.EnvoyExtension, config.OutgoingProxyKind())
|
||||
if ok {
|
||||
return patcher
|
||||
}
|
||||
|
@ -88,7 +46,7 @@ func makePatcher(serviceConfig xdscommon.ServiceConfig) patcher {
|
|||
// 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(xdscommon.ServiceConfig) (patcher, bool)
|
||||
type patchConstructor func(extension api.EnvoyExtension, upstreamKind api.ServiceKind) (patcher, bool)
|
||||
|
||||
// patchConstructors contains all patchers that getPatchers tries to create.
|
||||
var patchConstructors = []patchConstructor{makeLambdaPatcher}
|
||||
|
|
|
@ -1,105 +0,0 @@
|
|||
package serverlessplugin
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/hashicorp/consul/agent/xds/xdscommon"
|
||||
"github.com/hashicorp/consul/api"
|
||||
)
|
||||
|
||||
func TestGetPatcherBySNI(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
sni string
|
||||
kind api.ServiceKind
|
||||
expected patcher
|
||||
config *xdscommon.PluginConfiguration
|
||||
}{
|
||||
{
|
||||
name: "no sni match",
|
||||
sni: "not-matching",
|
||||
},
|
||||
{
|
||||
name: "no patcher",
|
||||
config: &xdscommon.PluginConfiguration{},
|
||||
sni: "lambda-sni",
|
||||
},
|
||||
{
|
||||
name: "no kind match",
|
||||
kind: api.ServiceKindIngressGateway,
|
||||
sni: "lambda-sni",
|
||||
},
|
||||
{
|
||||
name: "full match",
|
||||
sni: "lambda-sni",
|
||||
kind: api.ServiceKindTerminatingGateway,
|
||||
expected: lambdaPatcher{
|
||||
ARN: "arn",
|
||||
Region: "region",
|
||||
PayloadPassthrough: false,
|
||||
Kind: api.ServiceKindTerminatingGateway,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
config := sampleConfig()
|
||||
config.Kind = tc.kind
|
||||
if tc.config != nil {
|
||||
config = *tc.config
|
||||
}
|
||||
patcher := getPatcherBySNI(config, tc.sni)
|
||||
|
||||
if tc.expected == nil {
|
||||
require.Empty(t, patcher)
|
||||
} else {
|
||||
require.Equal(t, tc.expected, patcher)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
lambdaService = api.CompoundServiceName{Name: "lambda"}
|
||||
disabledLambdaService = api.CompoundServiceName{Name: "disabled-lambda"}
|
||||
invalidLambdaService = api.CompoundServiceName{Name: "invalid-lambda"}
|
||||
)
|
||||
|
||||
func sampleConfig() xdscommon.PluginConfiguration {
|
||||
return xdscommon.PluginConfiguration{
|
||||
Kind: api.ServiceKindTerminatingGateway,
|
||||
ServiceConfigs: map[api.CompoundServiceName]xdscommon.ServiceConfig{
|
||||
lambdaService: {
|
||||
Kind: api.ServiceKindTerminatingGateway,
|
||||
EnvoyExtensions: []api.EnvoyExtension{
|
||||
{
|
||||
Name: "builtin/aws/lambda",
|
||||
Arguments: map[string]interface{}{
|
||||
"ARN": "arn",
|
||||
"Region": "region",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
disabledLambdaService: {
|
||||
Kind: api.ServiceKindTerminatingGateway,
|
||||
// No extension.
|
||||
},
|
||||
invalidLambdaService: {
|
||||
Kind: api.ServiceKindTerminatingGateway,
|
||||
EnvoyExtensions: []api.EnvoyExtension{
|
||||
{
|
||||
Name: "builtin/aws/lambda",
|
||||
Arguments: map[string]interface{}{}, // ARN, etc missing
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
SNIToServiceName: map[string]api.CompoundServiceName{
|
||||
"lambda-sni": lambdaService,
|
||||
},
|
||||
}
|
||||
}
|
|
@ -14,19 +14,32 @@ import (
|
|||
"github.com/hashicorp/consul/api"
|
||||
)
|
||||
|
||||
// MutateIndexedResources updates indexed xDS structures to include patches for
|
||||
// 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 MutateIndexedResources(resources *xdscommon.IndexedResources, config xdscommon.PluginConfiguration) (*xdscommon.IndexedResources, error) {
|
||||
func Extend(resources *xdscommon.IndexedResources, config xdscommon.ExtensionConfiguration) (*xdscommon.IndexedResources, error) {
|
||||
var resultErr error
|
||||
|
||||
switch config.Kind {
|
||||
case api.ServiceKindTerminatingGateway, api.ServiceKindConnectProxy:
|
||||
default:
|
||||
return resources, resultErr
|
||||
return resources, nil
|
||||
}
|
||||
|
||||
if !config.IsUpstream() {
|
||||
return resources, nil
|
||||
}
|
||||
|
||||
patcher := makePatcher(config)
|
||||
if patcher == nil {
|
||||
return resources, nil
|
||||
}
|
||||
|
||||
if !patcher.CanPatch(config.Kind) {
|
||||
return resources, nil
|
||||
}
|
||||
|
||||
for _, indexType := range []string{
|
||||
|
@ -37,8 +50,7 @@ func MutateIndexedResources(resources *xdscommon.IndexedResources, config xdscom
|
|||
for nameOrSNI, msg := range resources.Index[indexType] {
|
||||
switch resource := msg.(type) {
|
||||
case *envoy_cluster_v3.Cluster:
|
||||
patcher := getPatcherBySNI(config, nameOrSNI)
|
||||
if patcher == nil {
|
||||
if !config.MatchesUpstreamServiceSNI(nameOrSNI) {
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -52,7 +64,7 @@ func MutateIndexedResources(resources *xdscommon.IndexedResources, config xdscom
|
|||
}
|
||||
|
||||
case *envoy_listener_v3.Listener:
|
||||
newListener, patched, err := patchListener(config, resource)
|
||||
newListener, patched, err := patchListener(config, resource, patcher)
|
||||
if err != nil {
|
||||
resultErr = multierror.Append(resultErr, fmt.Errorf("error patching listener: %w", err))
|
||||
continue
|
||||
|
@ -62,8 +74,7 @@ func MutateIndexedResources(resources *xdscommon.IndexedResources, config xdscom
|
|||
}
|
||||
|
||||
case *envoy_route_v3.RouteConfiguration:
|
||||
patcher := getPatcherBySNI(config, nameOrSNI)
|
||||
if patcher == nil {
|
||||
if !config.MatchesUpstreamServiceSNI(nameOrSNI) {
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -85,17 +96,17 @@ func MutateIndexedResources(resources *xdscommon.IndexedResources, config xdscom
|
|||
return resources, resultErr
|
||||
}
|
||||
|
||||
func patchListener(config xdscommon.PluginConfiguration, l *envoy_listener_v3.Listener) (proto.Message, bool, error) {
|
||||
func patchListener(config xdscommon.ExtensionConfiguration, l *envoy_listener_v3.Listener, p patcher) (proto.Message, bool, error) {
|
||||
switch config.Kind {
|
||||
case api.ServiceKindTerminatingGateway:
|
||||
return patchTerminatingGatewayListener(config, l)
|
||||
return patchTerminatingGatewayListener(config, l, p)
|
||||
case api.ServiceKindConnectProxy:
|
||||
return patchConnectProxyListener(config, l)
|
||||
return patchConnectProxyListener(config, l, p)
|
||||
}
|
||||
return l, false, nil
|
||||
}
|
||||
|
||||
func patchTerminatingGatewayListener(config xdscommon.PluginConfiguration, l *envoy_listener_v3.Listener) (proto.Message, bool, error) {
|
||||
func patchTerminatingGatewayListener(config xdscommon.ExtensionConfiguration, l *envoy_listener_v3.Listener, p patcher) (proto.Message, bool, error) {
|
||||
var resultErr error
|
||||
patched := false
|
||||
for _, filterChain := range l.FilterChains {
|
||||
|
@ -105,16 +116,14 @@ func patchTerminatingGatewayListener(config xdscommon.PluginConfiguration, l *en
|
|||
continue
|
||||
}
|
||||
|
||||
patcher := getPatcherBySNI(config, sni)
|
||||
|
||||
if patcher == nil {
|
||||
if !config.MatchesUpstreamServiceSNI(sni) {
|
||||
continue
|
||||
}
|
||||
|
||||
var filters []*envoy_listener_v3.Filter
|
||||
|
||||
for _, filter := range filterChain.Filters {
|
||||
newFilter, ok, err := patcher.PatchFilter(filter)
|
||||
newFilter, ok, err := p.PatchFilter(filter)
|
||||
|
||||
if err != nil {
|
||||
resultErr = multierror.Append(resultErr, fmt.Errorf("error patching listener filter: %w", err))
|
||||
|
@ -131,7 +140,7 @@ func patchTerminatingGatewayListener(config xdscommon.PluginConfiguration, l *en
|
|||
return l, patched, resultErr
|
||||
}
|
||||
|
||||
func patchConnectProxyListener(config xdscommon.PluginConfiguration, l *envoy_listener_v3.Listener) (proto.Message, bool, error) {
|
||||
func patchConnectProxyListener(config xdscommon.ExtensionConfiguration, l *envoy_listener_v3.Listener, p patcher) (proto.Message, bool, error) {
|
||||
var resultErr error
|
||||
|
||||
envoyID := ""
|
||||
|
@ -139,8 +148,7 @@ func patchConnectProxyListener(config xdscommon.PluginConfiguration, l *envoy_li
|
|||
envoyID = l.Name[:i]
|
||||
}
|
||||
|
||||
patcher := getPatcherByEnvoyID(config, envoyID)
|
||||
if patcher == nil {
|
||||
if envoyID != config.EnvoyID() {
|
||||
return l, false, nil
|
||||
}
|
||||
|
||||
|
@ -150,7 +158,7 @@ func patchConnectProxyListener(config xdscommon.PluginConfiguration, l *envoy_li
|
|||
var filters []*envoy_listener_v3.Filter
|
||||
|
||||
for _, filter := range filterChain.Filters {
|
||||
newFilter, ok, err := patcher.PatchFilter(filter)
|
||||
newFilter, ok, err := p.PatchFilter(filter)
|
||||
if err != nil {
|
||||
resultErr = multierror.Append(resultErr, fmt.Errorf("error patching listener filter: %w", err))
|
||||
filters = append(filters, filter)
|
||||
|
|
|
@ -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"
|
||||
}
|
75
agent/xds/testdata/serverless_plugin/endpoints/lambda-connect-proxy-opposite-meta.latest.golden
vendored
Normal file
75
agent/xds/testdata/serverless_plugin/endpoints/lambda-connect-proxy-opposite-meta.latest.golden
vendored
Normal file
|
@ -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"
|
||||
}
|
|
@ -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"
|
||||
}
|
75
agent/xds/testdata/serverless_plugin/endpoints/lambda-connect-proxy.latest.golden
vendored
Normal file
75
agent/xds/testdata/serverless_plugin/endpoints/lambda-connect-proxy.latest.golden
vendored
Normal file
|
@ -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"
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
{
|
||||
"versionInfo": "00000001",
|
||||
"resources": [
|
||||
{
|
||||
"@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment",
|
||||
"clusterName": "canary1.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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment",
|
||||
"clusterName": "canary2.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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"@type": "type.googleapis.com/envoy.config.endpoint.v3.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.config.endpoint.v3.ClusterLoadAssignment",
|
||||
"nonce": "00000001"
|
||||
}
|
41
agent/xds/testdata/serverless_plugin/endpoints/lambda-terminating-gateway.latest.golden
vendored
Normal file
41
agent/xds/testdata/serverless_plugin/endpoints/lambda-terminating-gateway.latest.golden
vendored
Normal file
|
@ -0,0 +1,41 @@
|
|||
{
|
||||
"versionInfo": "00000001",
|
||||
"resources": [
|
||||
{
|
||||
"@type": "type.googleapis.com/envoy.config.endpoint.v3.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.config.endpoint.v3.ClusterLoadAssignment",
|
||||
"nonce": "00000001"
|
||||
}
|
|
@ -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"
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"versionInfo": "00000001",
|
||||
"typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration",
|
||||
"nonce": "00000001"
|
||||
}
|
|
@ -60,35 +60,65 @@ type ServiceConfig struct {
|
|||
EnvoyExtensions []api.EnvoyExtension
|
||||
}
|
||||
|
||||
// PluginConfiguration is passed into Envoy plugins. It should depend on the
|
||||
// API client rather than the structs package because the API client is meant
|
||||
// to be public.
|
||||
type PluginConfiguration struct {
|
||||
// ServiceConfigs is a mapping from service names to the data Envoy plugins
|
||||
// need to override the default Envoy configurations.
|
||||
ServiceConfigs map[api.CompoundServiceName]ServiceConfig
|
||||
// ExtensionConfiguration is the configuration for an extension attached to a service on the local proxy. Currently, it
|
||||
// is only created for the local proxy's upstream service if the upstream service has an extension configured. In the
|
||||
// future it will also include information about the service local to the local proxy as well. It should depend on the
|
||||
// API client rather than the structs package because the API client is meant to be public.
|
||||
type ExtensionConfiguration struct {
|
||||
// EnvoyExtension is the extension that will patch Envoy resources.
|
||||
EnvoyExtension api.EnvoyExtension
|
||||
|
||||
// SNIToServiceName is a mapping from SNIs to service names. This allows
|
||||
// Envoy plugins to easily convert from an SNI Envoy resource name to the
|
||||
// associated service's CompoundServiceName
|
||||
SNIToServiceName map[string]api.CompoundServiceName
|
||||
// ServiceName is the name of the service the EnvoyExtension is being applied to. It could be the local service or
|
||||
// an upstream of the local service.
|
||||
ServiceName api.CompoundServiceName
|
||||
|
||||
// EnvoyIDToServiceName is a mapping from EnvoyIDs to service names. This allows
|
||||
// Envoy plugins to easily convert from an EnvoyID Envoy resource name to the
|
||||
// associated service's CompoundServiceName
|
||||
EnvoyIDToServiceName map[string]api.CompoundServiceName
|
||||
// Upstreams will only be configured on the ExtensionConfiguration if the EnvoyExtension is being applied to an
|
||||
// upstream. If there are no Upstreams, then EnvoyExtension is being applied to the local service's resources.
|
||||
Upstreams map[api.CompoundServiceName]UpstreamData
|
||||
|
||||
// Kind is mode the local Envoy proxy is running in. For now, only
|
||||
// Kind is mode the local Envoy proxy is running in. For now, only connect proxy and
|
||||
// terminating gateways are supported.
|
||||
Kind api.ServiceKind
|
||||
}
|
||||
|
||||
// MakePluginConfiguration generates the configuration that will be sent to
|
||||
// Envoy plugins.
|
||||
func MakePluginConfiguration(cfgSnap *proxycfg.ConfigSnapshot) PluginConfiguration {
|
||||
serviceConfigs := make(map[api.CompoundServiceName]ServiceConfig)
|
||||
sniMappings := make(map[string]api.CompoundServiceName)
|
||||
envoyIDMappings := make(map[string]api.CompoundServiceName)
|
||||
// UpstreamData has the SNI, EnvoyID, and OutgoingProxyKind of the upstream services for the local proxy and this data
|
||||
// is used to choose which Envoy resources to patch.
|
||||
type UpstreamData struct {
|
||||
// SNI is the SNI header used to reach an upstream service.
|
||||
SNI map[string]struct{}
|
||||
// EnvoyID is the envoy ID of an upstream service, structured <service> or <partition>/<ns>/<service> when using a
|
||||
// non-default namespace or partition.
|
||||
EnvoyID string
|
||||
// OutgoingProxyKind is the type of proxy of the upstream service. However, if the upstream is "typical" this will
|
||||
// be set to "connect-proxy" instead.
|
||||
OutgoingProxyKind api.ServiceKind
|
||||
}
|
||||
|
||||
func (ec ExtensionConfiguration) IsUpstream() bool {
|
||||
_, ok := ec.Upstreams[ec.ServiceName]
|
||||
return ok
|
||||
}
|
||||
|
||||
func (ec ExtensionConfiguration) MatchesUpstreamServiceSNI(sni string) bool {
|
||||
u := ec.Upstreams[ec.ServiceName]
|
||||
_, match := u.SNI[sni]
|
||||
return match
|
||||
}
|
||||
|
||||
func (ec ExtensionConfiguration) EnvoyID() string {
|
||||
u := ec.Upstreams[ec.ServiceName]
|
||||
return u.EnvoyID
|
||||
}
|
||||
|
||||
func (ec ExtensionConfiguration) OutgoingProxyKind() api.ServiceKind {
|
||||
u := ec.Upstreams[ec.ServiceName]
|
||||
return u.OutgoingProxyKind
|
||||
}
|
||||
|
||||
func GetExtensionConfigurations(cfgSnap *proxycfg.ConfigSnapshot) map[api.CompoundServiceName][]ExtensionConfiguration {
|
||||
extensionsMap := make(map[api.CompoundServiceName][]api.EnvoyExtension)
|
||||
upstreamMap := make(map[api.CompoundServiceName]UpstreamData)
|
||||
var kind api.ServiceKind
|
||||
|
||||
trustDomain := ""
|
||||
if cfgSnap.Roots != nil {
|
||||
|
@ -97,70 +127,91 @@ func MakePluginConfiguration(cfgSnap *proxycfg.ConfigSnapshot) PluginConfigurati
|
|||
|
||||
switch cfgSnap.Kind {
|
||||
case structs.ServiceKindConnectProxy:
|
||||
connectProxies := make(map[proxycfg.UpstreamID]struct{})
|
||||
kind = api.ServiceKindConnectProxy
|
||||
outgoingKindByService := make(map[api.CompoundServiceName]api.ServiceKind)
|
||||
for uid, upstreamData := range cfgSnap.ConnectProxy.WatchedUpstreamEndpoints {
|
||||
sn := upstreamIDToCompoundServiceName(uid)
|
||||
|
||||
for _, serviceNodes := range upstreamData {
|
||||
// Lambdas and likely other integrations won't be attached to nodes.
|
||||
// After agentless, we may need to reconsider this.
|
||||
if len(serviceNodes) == 0 {
|
||||
connectProxies[uid] = struct{}{}
|
||||
}
|
||||
for _, serviceNode := range serviceNodes {
|
||||
if serviceNode.Service.Kind == structs.ServiceKindTypical || serviceNode.Service.Kind == structs.ServiceKindConnectProxy {
|
||||
connectProxies[uid] = struct{}{}
|
||||
if serviceNode.Service == nil {
|
||||
continue
|
||||
}
|
||||
// Store the upstream's kind, and for ServiceKindTypical we don't do anything because we'll default
|
||||
// any unset upstreams to ServiceKindConnectProxy below.
|
||||
switch serviceNode.Service.Kind {
|
||||
case structs.ServiceKindTypical:
|
||||
default:
|
||||
outgoingKindByService[sn] = api.ServiceKind(serviceNode.Service.Kind)
|
||||
}
|
||||
// We only need the kind from one instance, so break once we find it.
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(peering): consider PeerUpstreamEndpoints in addition to DiscoveryChain
|
||||
|
||||
// These are the discovery chains for upstreams which have the Envoy Extensions applied to the local service.
|
||||
for uid, dc := range cfgSnap.ConnectProxy.DiscoveryChain {
|
||||
if _, ok := connectProxies[uid]; !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
serviceConfigs[upstreamIDToCompoundServiceName(uid)] = ServiceConfig{
|
||||
Kind: api.ServiceKindConnectProxy,
|
||||
EnvoyExtensions: convertEnvoyExtensions(dc.EnvoyExtensions),
|
||||
}
|
||||
|
||||
compoundServiceName := upstreamIDToCompoundServiceName(uid)
|
||||
extensionsMap[compoundServiceName] = convertEnvoyExtensions(dc.EnvoyExtensions)
|
||||
|
||||
meta := uid.EnterpriseMeta
|
||||
sni := connect.ServiceSNI(uid.Name, "", meta.NamespaceOrDefault(), meta.PartitionOrDefault(), cfgSnap.Datacenter, trustDomain)
|
||||
sniMappings[sni] = compoundServiceName
|
||||
envoyIDMappings[uid.EnvoyID()] = compoundServiceName
|
||||
}
|
||||
case structs.ServiceKindTerminatingGateway:
|
||||
for svc, c := range cfgSnap.TerminatingGateway.ServiceConfigs {
|
||||
compoundServiceName := serviceNameToCompoundServiceName(svc)
|
||||
serviceConfigs[compoundServiceName] = ServiceConfig{
|
||||
EnvoyExtensions: convertEnvoyExtensions(c.EnvoyExtensions),
|
||||
Kind: api.ServiceKindTerminatingGateway,
|
||||
outgoingKind, ok := outgoingKindByService[compoundServiceName]
|
||||
if !ok {
|
||||
outgoingKind = api.ServiceKindConnectProxy
|
||||
}
|
||||
|
||||
sni := connect.ServiceSNI(svc.Name, "", svc.NamespaceOrDefault(), svc.PartitionOrDefault(), cfgSnap.Datacenter, trustDomain)
|
||||
sniMappings[sni] = compoundServiceName
|
||||
upstreamMap[compoundServiceName] = UpstreamData{
|
||||
SNI: map[string]struct{}{sni: {}},
|
||||
EnvoyID: uid.EnvoyID(),
|
||||
OutgoingProxyKind: outgoingKind,
|
||||
}
|
||||
}
|
||||
case structs.ServiceKindTerminatingGateway:
|
||||
kind = api.ServiceKindTerminatingGateway
|
||||
for svc, c := range cfgSnap.TerminatingGateway.ServiceConfigs {
|
||||
compoundServiceName := serviceNameToCompoundServiceName(svc)
|
||||
extensionsMap[compoundServiceName] = convertEnvoyExtensions(c.EnvoyExtensions)
|
||||
|
||||
sni := connect.ServiceSNI(svc.Name, "", svc.NamespaceOrDefault(), svc.PartitionOrDefault(), cfgSnap.Datacenter, trustDomain)
|
||||
envoyID := proxycfg.NewUpstreamIDFromServiceName(svc)
|
||||
envoyIDMappings[envoyID.EnvoyID()] = compoundServiceName
|
||||
|
||||
snis := map[string]struct{}{sni: {}}
|
||||
|
||||
resolver, hasResolver := cfgSnap.TerminatingGateway.ServiceResolvers[svc]
|
||||
if hasResolver {
|
||||
for subsetName := range resolver.Subsets {
|
||||
sni := connect.ServiceSNI(svc.Name, subsetName, svc.NamespaceOrDefault(), svc.PartitionOrDefault(), cfgSnap.Datacenter, trustDomain)
|
||||
sniMappings[sni] = compoundServiceName
|
||||
snis[sni] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
upstreamMap[compoundServiceName] = UpstreamData{
|
||||
SNI: snis,
|
||||
EnvoyID: envoyID.EnvoyID(),
|
||||
OutgoingProxyKind: api.ServiceKindTerminatingGateway,
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return PluginConfiguration{
|
||||
ServiceConfigs: serviceConfigs,
|
||||
SNIToServiceName: sniMappings,
|
||||
EnvoyIDToServiceName: envoyIDMappings,
|
||||
Kind: api.ServiceKind(cfgSnap.Kind),
|
||||
extensionConfigurationsMap := make(map[api.CompoundServiceName][]ExtensionConfiguration)
|
||||
for svc, exts := range extensionsMap {
|
||||
extensionConfigurationsMap[svc] = []ExtensionConfiguration{}
|
||||
for _, ext := range exts {
|
||||
extCfg := ExtensionConfiguration{
|
||||
EnvoyExtension: ext,
|
||||
Kind: kind,
|
||||
ServiceName: svc,
|
||||
Upstreams: upstreamMap,
|
||||
}
|
||||
extensionConfigurationsMap[svc] = append(extensionConfigurationsMap[svc], extCfg)
|
||||
}
|
||||
}
|
||||
|
||||
return extensionConfigurationsMap
|
||||
}
|
||||
|
||||
func serviceNameToCompoundServiceName(svc structs.ServiceName) api.CompoundServiceName {
|
||||
|
@ -179,16 +230,6 @@ func upstreamIDToCompoundServiceName(uid proxycfg.UpstreamID) api.CompoundServic
|
|||
}
|
||||
}
|
||||
|
||||
func convertEnvoyExtensions(structExtensions []structs.EnvoyExtension) []api.EnvoyExtension {
|
||||
var extensions []api.EnvoyExtension
|
||||
|
||||
for _, e := range structExtensions {
|
||||
extensions = append(extensions, api.EnvoyExtension{
|
||||
Name: e.Name,
|
||||
Required: e.Required,
|
||||
Arguments: e.Arguments,
|
||||
})
|
||||
}
|
||||
|
||||
return extensions
|
||||
func convertEnvoyExtensions(structExtensions structs.EnvoyExtensions) []api.EnvoyExtension {
|
||||
return structExtensions.ToAPI()
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ import (
|
|||
"github.com/hashicorp/consul/api"
|
||||
)
|
||||
|
||||
func TestMakePluginConfiguration_TerminatingGateway(t *testing.T) {
|
||||
func TestGetExtensionConfigurations_TerminatingGateway(t *testing.T) {
|
||||
snap := proxycfg.TestConfigSnapshotTerminatingGatewayWithLambdaServiceAndServiceResolvers(t)
|
||||
|
||||
webService := api.CompoundServiceName{
|
||||
|
@ -37,52 +37,62 @@ func TestMakePluginConfiguration_TerminatingGateway(t *testing.T) {
|
|||
Partition: "default",
|
||||
}
|
||||
|
||||
expected := PluginConfiguration{
|
||||
Kind: api.ServiceKindTerminatingGateway,
|
||||
ServiceConfigs: map[api.CompoundServiceName]ServiceConfig{
|
||||
webService: {
|
||||
Kind: api.ServiceKindTerminatingGateway,
|
||||
EnvoyExtensions: []api.EnvoyExtension{
|
||||
{
|
||||
Name: "builtin/aws/lambda",
|
||||
Arguments: map[string]interface{}{
|
||||
"ARN": "lambda-arn",
|
||||
"PayloadPassthrough": true,
|
||||
"Region": "us-east-1",
|
||||
},
|
||||
expected := map[api.CompoundServiceName][]ExtensionConfiguration{
|
||||
apiService: {},
|
||||
cacheService: {},
|
||||
dbService: {},
|
||||
webService: {
|
||||
{
|
||||
EnvoyExtension: api.EnvoyExtension{
|
||||
Name: structs.BuiltinAWSLambdaExtension,
|
||||
Arguments: map[string]interface{}{
|
||||
"ARN": "lambda-arn",
|
||||
"PayloadPassthrough": true,
|
||||
"Region": "us-east-1",
|
||||
},
|
||||
},
|
||||
ServiceName: webService,
|
||||
Upstreams: map[api.CompoundServiceName]UpstreamData{
|
||||
apiService: {
|
||||
SNI: map[string]struct{}{
|
||||
"api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul": {},
|
||||
},
|
||||
EnvoyID: "api",
|
||||
OutgoingProxyKind: "terminating-gateway",
|
||||
},
|
||||
cacheService: {
|
||||
SNI: map[string]struct{}{
|
||||
"cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul": {},
|
||||
},
|
||||
EnvoyID: "cache",
|
||||
OutgoingProxyKind: "terminating-gateway",
|
||||
},
|
||||
dbService: {
|
||||
SNI: map[string]struct{}{
|
||||
"db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul": {},
|
||||
},
|
||||
EnvoyID: "db",
|
||||
OutgoingProxyKind: "terminating-gateway",
|
||||
},
|
||||
webService: {
|
||||
SNI: map[string]struct{}{
|
||||
"canary1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul": {},
|
||||
"canary2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul": {},
|
||||
"web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul": {},
|
||||
},
|
||||
EnvoyID: "web",
|
||||
OutgoingProxyKind: "terminating-gateway",
|
||||
},
|
||||
},
|
||||
},
|
||||
apiService: {
|
||||
Kind: api.ServiceKindTerminatingGateway,
|
||||
},
|
||||
cacheService: {
|
||||
Kind: api.ServiceKindTerminatingGateway,
|
||||
},
|
||||
dbService: {
|
||||
Kind: api.ServiceKindTerminatingGateway,
|
||||
},
|
||||
},
|
||||
SNIToServiceName: map[string]api.CompoundServiceName{
|
||||
"api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul": apiService,
|
||||
"cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul": cacheService,
|
||||
"db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul": dbService,
|
||||
"web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul": webService,
|
||||
"canary1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul": webService,
|
||||
"canary2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul": webService,
|
||||
},
|
||||
EnvoyIDToServiceName: map[string]api.CompoundServiceName{
|
||||
"web": webService,
|
||||
"db": dbService,
|
||||
"cache": cacheService,
|
||||
"api": apiService,
|
||||
},
|
||||
}
|
||||
|
||||
require.Equal(t, expected, MakePluginConfiguration(snap))
|
||||
require.Equal(t, expected, GetExtensionConfigurations(snap))
|
||||
}
|
||||
|
||||
func TestMakePluginConfiguration_ConnectProxy(t *testing.T) {
|
||||
func TestGetExtensionConfigurations_ConnectProxy(t *testing.T) {
|
||||
dbService := api.CompoundServiceName{
|
||||
Name: "db",
|
||||
Partition: "default",
|
||||
|
@ -90,7 +100,7 @@ func TestMakePluginConfiguration_ConnectProxy(t *testing.T) {
|
|||
}
|
||||
envoyExtensions := []structs.EnvoyExtension{
|
||||
{
|
||||
Name: "builtin/aws/lambda",
|
||||
Name: structs.BuiltinAWSLambdaExtension,
|
||||
Arguments: map[string]interface{}{
|
||||
"ARN": "lambda-arn",
|
||||
"PayloadPassthrough": true,
|
||||
|
@ -106,22 +116,75 @@ func TestMakePluginConfiguration_ConnectProxy(t *testing.T) {
|
|||
EnvoyExtensions: envoyExtensions,
|
||||
}
|
||||
|
||||
snap := proxycfg.TestConfigSnapshotDiscoveryChain(t, "default", nil, nil, serviceDefaults)
|
||||
expected := PluginConfiguration{
|
||||
Kind: api.ServiceKindConnectProxy,
|
||||
ServiceConfigs: map[api.CompoundServiceName]ServiceConfig{
|
||||
dbService: {
|
||||
Kind: api.ServiceKindConnectProxy,
|
||||
EnvoyExtensions: convertEnvoyExtensions(envoyExtensions),
|
||||
snapConnect := proxycfg.TestConfigSnapshotDiscoveryChain(t, "default", nil, nil, serviceDefaults)
|
||||
snapTermGw := proxycfg.TestConfigSnapshotDiscoveryChain(t, "register-to-terminating-gateway", nil, nil, serviceDefaults)
|
||||
|
||||
type testCase struct {
|
||||
snapshot *proxycfg.ConfigSnapshot
|
||||
expected map[api.CompoundServiceName][]ExtensionConfiguration
|
||||
}
|
||||
cases := map[string]testCase{
|
||||
"connect proxy upstream": {
|
||||
snapshot: snapConnect,
|
||||
expected: map[api.CompoundServiceName][]ExtensionConfiguration{
|
||||
dbService: {
|
||||
{
|
||||
EnvoyExtension: api.EnvoyExtension{
|
||||
Name: structs.BuiltinAWSLambdaExtension,
|
||||
Arguments: map[string]interface{}{
|
||||
"ARN": "lambda-arn",
|
||||
"PayloadPassthrough": true,
|
||||
"Region": "us-east-1",
|
||||
},
|
||||
},
|
||||
ServiceName: dbService,
|
||||
Upstreams: map[api.CompoundServiceName]UpstreamData{
|
||||
dbService: {
|
||||
SNI: map[string]struct{}{
|
||||
"db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul": {},
|
||||
},
|
||||
EnvoyID: "db",
|
||||
OutgoingProxyKind: "connect-proxy",
|
||||
},
|
||||
},
|
||||
Kind: api.ServiceKindConnectProxy,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
SNIToServiceName: map[string]api.CompoundServiceName{
|
||||
"db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul": dbService,
|
||||
},
|
||||
EnvoyIDToServiceName: map[string]api.CompoundServiceName{
|
||||
"db": dbService,
|
||||
"terminating gateway upstream": {
|
||||
snapshot: snapTermGw,
|
||||
expected: map[api.CompoundServiceName][]ExtensionConfiguration{
|
||||
dbService: {
|
||||
{
|
||||
EnvoyExtension: api.EnvoyExtension{
|
||||
Name: structs.BuiltinAWSLambdaExtension,
|
||||
Arguments: map[string]interface{}{
|
||||
"ARN": "lambda-arn",
|
||||
"PayloadPassthrough": true,
|
||||
"Region": "us-east-1",
|
||||
},
|
||||
},
|
||||
ServiceName: dbService,
|
||||
Upstreams: map[api.CompoundServiceName]UpstreamData{
|
||||
dbService: {
|
||||
SNI: map[string]struct{}{
|
||||
"db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul": {},
|
||||
},
|
||||
EnvoyID: "db",
|
||||
OutgoingProxyKind: "terminating-gateway",
|
||||
},
|
||||
},
|
||||
Kind: api.ServiceKindConnectProxy,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
require.Equal(t, expected, MakePluginConfiguration(snap))
|
||||
for name, tc := range cases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
require.Equal(t, tc.expected, GetExtensionConfigurations(tc.snapshot))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue