mirror of https://github.com/hashicorp/consul
113 lines
3.2 KiB
Go
113 lines
3.2 KiB
Go
// Copyright 2018 Envoyproxy Authors
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package cache
|
|
|
|
import (
|
|
"github.com/gogo/protobuf/proto"
|
|
|
|
"github.com/envoyproxy/go-control-plane/envoy/api/v2"
|
|
hcm "github.com/envoyproxy/go-control-plane/envoy/config/filter/network/http_connection_manager/v2"
|
|
"github.com/envoyproxy/go-control-plane/pkg/util"
|
|
)
|
|
|
|
// Resource is the base interface for the xDS payload.
|
|
type Resource interface {
|
|
proto.Message
|
|
Equal(interface{}) bool
|
|
}
|
|
|
|
// Resource types in xDS v2.
|
|
const (
|
|
typePrefix = "type.googleapis.com/envoy.api.v2."
|
|
EndpointType = typePrefix + "ClusterLoadAssignment"
|
|
ClusterType = typePrefix + "Cluster"
|
|
RouteType = typePrefix + "RouteConfiguration"
|
|
ListenerType = typePrefix + "Listener"
|
|
|
|
// AnyType is used only by ADS
|
|
AnyType = ""
|
|
)
|
|
|
|
var (
|
|
// ResponseTypes are supported response types.
|
|
ResponseTypes = []string{
|
|
EndpointType,
|
|
ClusterType,
|
|
RouteType,
|
|
ListenerType,
|
|
}
|
|
)
|
|
|
|
// GetResourceName returns the resource name for a valid xDS response type.
|
|
func GetResourceName(res Resource) string {
|
|
switch v := res.(type) {
|
|
case *v2.ClusterLoadAssignment:
|
|
return v.GetClusterName()
|
|
case *v2.Cluster:
|
|
return v.GetName()
|
|
case *v2.RouteConfiguration:
|
|
return v.GetName()
|
|
case *v2.Listener:
|
|
return v.GetName()
|
|
default:
|
|
return ""
|
|
}
|
|
}
|
|
|
|
// GetResourceReferences returns the names for dependent resources (EDS cluster
|
|
// names for CDS, RDS routes names for LDS).
|
|
func GetResourceReferences(resources map[string]Resource) map[string]bool {
|
|
out := make(map[string]bool)
|
|
for _, res := range resources {
|
|
if res == nil {
|
|
continue
|
|
}
|
|
switch v := res.(type) {
|
|
case *v2.ClusterLoadAssignment:
|
|
// no dependencies
|
|
case *v2.Cluster:
|
|
// for EDS type, use cluster name or ServiceName override
|
|
if v.Type == v2.Cluster_EDS {
|
|
if v.EdsClusterConfig != nil && v.EdsClusterConfig.ServiceName != "" {
|
|
out[v.EdsClusterConfig.ServiceName] = true
|
|
} else {
|
|
out[v.Name] = true
|
|
}
|
|
}
|
|
case *v2.RouteConfiguration:
|
|
// References to clusters in both routes (and listeners) are not included
|
|
// in the result, because the clusters are retrieved in bulk currently,
|
|
// and not by name.
|
|
case *v2.Listener:
|
|
// extract route configuration names from HTTP connection manager
|
|
for _, chain := range v.FilterChains {
|
|
for _, filter := range chain.Filters {
|
|
if filter.Name != util.HTTPConnectionManager {
|
|
continue
|
|
}
|
|
|
|
config := &hcm.HttpConnectionManager{}
|
|
if util.StructToMessage(filter.Config, config) == nil && config != nil {
|
|
if rds, ok := config.RouteSpecifier.(*hcm.HttpConnectionManager_Rds); ok && rds != nil && rds.Rds != nil {
|
|
out[rds.Rds.RouteConfigName] = true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return out
|
|
}
|