open-consul/troubleshoot/proxy/upstreams.go

121 lines
2.8 KiB
Go

package troubleshoot
import (
envoy_admin_v3 "github.com/envoyproxy/go-control-plane/envoy/admin/v3"
envoy_listener_v3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
envoy_resource_v3 "github.com/envoyproxy/go-control-plane/pkg/resource/v3"
"github.com/hashicorp/consul/envoyextensions/extensioncommon"
"google.golang.org/protobuf/proto"
)
type UpstreamIP struct {
IPs []string
IsVirtual bool
ClusterNames map[string]struct{}
}
func (t *Troubleshoot) GetUpstreams() ([]string, []UpstreamIP, error) {
upstream_envoy_ids := []string{}
upstream_ips := []UpstreamIP{}
err := t.GetEnvoyConfigDump()
if err != nil {
return nil, nil, err
}
for _, cfg := range t.envoyConfigDump.Configs {
switch cfg.TypeUrl {
case listeners:
lcd := &envoy_admin_v3.ListenersConfigDump{}
err := proto.Unmarshal(cfg.GetValue(), lcd)
if err != nil {
return nil, nil, err
}
for _, listener := range lcd.GetDynamicListeners() {
eid := envoyID(listener.Name)
if eid != "" && eid != "public_listener" &&
eid != "outbound_listener" && eid != "inbound_listener" {
upstream_envoy_ids = append(upstream_envoy_ids, eid)
} else if eid == "outbound_listener" {
l := &envoy_listener_v3.Listener{}
err = proto.Unmarshal(listener.GetActiveState().GetListener().GetValue(), l)
if err != nil {
return nil, nil, err
}
upstream_ips, err = getUpstreamIPsFromFilterChain(l.GetFilterChains())
if err != nil {
return nil, nil, err
}
}
}
}
}
return upstream_envoy_ids, upstream_ips, nil
}
func getUpstreamIPsFromFilterChain(filterChains []*envoy_listener_v3.FilterChain) ([]UpstreamIP, error) {
if filterChains == nil {
return []UpstreamIP{}, nil
}
upstreamIPs := []UpstreamIP{}
for _, fc := range filterChains {
if fc.GetFilters() == nil {
continue
}
if fc.GetFilterChainMatch() == nil {
continue
}
if fc.GetFilterChainMatch().GetPrefixRanges() == nil {
continue
}
cidrs := fc.GetFilterChainMatch().GetPrefixRanges()
ips := []string{}
for _, cidr := range cidrs {
ips = append(ips, cidr.AddressPrefix)
}
for _, filter := range fc.GetFilters() {
isVirtual := false
if filter.GetTypedConfig() == nil {
continue
}
clusterNames := map[string]struct{}{}
if config := envoy_resource_v3.GetHTTPConnectionManager(filter); config != nil {
isVirtual = true
cfg := config.GetRouteConfig()
clusterNames = extensioncommon.RouteClusterNames(cfg)
}
if config := extensioncommon.GetTCPProxy(filter); config != nil {
if config.GetCluster() != "" {
clusterNames[config.GetCluster()] = struct{}{}
}
}
upstreamIPs = append(upstreamIPs, UpstreamIP{
IPs: ips,
IsVirtual: isVirtual,
ClusterNames: clusterNames,
})
}
}
return upstreamIPs, nil
}