consul/agent/xds/serverlessplugin/patcher.go

95 lines
2.9 KiB
Go

package serverlessplugin
import (
envoy_cluster_v3 "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3"
envoy_listener_v3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
envoy_route_v3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3"
"github.com/hashicorp/consul/agent/xds/xdscommon"
"github.com/hashicorp/consul/api"
)
// patcher is the interface that each serverless integration must implement. It
// is responsible for modifying the xDS structures based on only the state of
// the patcher.
type patcher interface {
// CanPatch determines if the patcher can mutate resources for the given api.ServiceKind
CanPatch(api.ServiceKind) bool
// patchRoute patches a route to include the custom Envoy configuration
// PatchCluster patches a cluster to include the custom Envoy configuration
// required to integrate with the serverless integration.
PatchRoute(*envoy_route_v3.RouteConfiguration) (*envoy_route_v3.RouteConfiguration, bool, error)
// PatchCluster patches a cluster to include the custom Envoy configuration
// required to integrate with the serverless integration.
PatchCluster(*envoy_cluster_v3.Cluster) (*envoy_cluster_v3.Cluster, bool, error)
// PatchFilter patches an Envoy filter to include the custom Envoy
// configuration required to integrate with the serverless integration.
PatchFilter(*envoy_listener_v3.Filter) (*envoy_listener_v3.Filter, bool, error)
}
type patchers map[api.CompoundServiceName]patcher
// 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 {
for _, constructor := range patchConstructors {
patcher, ok := constructor(serviceConfig)
if ok {
return patcher
}
}
return nil
}
// patchConstructor is used to construct patchers based on
// xdscommon.ServiceConfig. This function contains all of the logic around
// turning Meta data into the patcher.
type patchConstructor func(xdscommon.ServiceConfig) (patcher, bool)
// patchConstructors contains all patchers that getPatchers tries to create.
var patchConstructors = []patchConstructor{makeLambdaPatcher}