Consul is a distributed, highly available, and data center aware solution to connect and configure applications across dynamic, distributed infrastructure.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

209 lines
7.0 KiB

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package configentry
import (
"github.com/hashicorp/consul/agent/structs"
"github.com/hashicorp/consul/proto/private/pbpeering"
)
// DiscoveryChainSet is a wrapped set of raw cross-referenced config entries
// necessary for the DiscoveryChain.Get RPC process.
//
// None of these are defaulted.
type DiscoveryChainSet struct {
Routers map[structs.ServiceID]*structs.ServiceRouterConfigEntry
Splitters map[structs.ServiceID]*structs.ServiceSplitterConfigEntry
Resolvers map[structs.ServiceID]*structs.ServiceResolverConfigEntry
Services map[structs.ServiceID]*structs.ServiceConfigEntry
Peers map[string]*pbpeering.Peering
DefaultSamenessGroup *structs.SamenessGroupConfigEntry
SamenessGroups map[string]*structs.SamenessGroupConfigEntry
ProxyDefaults map[string]*structs.ProxyConfigEntry
}
func NewDiscoveryChainSet() *DiscoveryChainSet {
return &DiscoveryChainSet{
Routers: make(map[structs.ServiceID]*structs.ServiceRouterConfigEntry),
Splitters: make(map[structs.ServiceID]*structs.ServiceSplitterConfigEntry),
Resolvers: make(map[structs.ServiceID]*structs.ServiceResolverConfigEntry),
Services: make(map[structs.ServiceID]*structs.ServiceConfigEntry),
Peers: make(map[string]*pbpeering.Peering),
ProxyDefaults: make(map[string]*structs.ProxyConfigEntry),
SamenessGroups: make(map[string]*structs.SamenessGroupConfigEntry),
}
}
func (e *DiscoveryChainSet) GetRouter(sid structs.ServiceID) *structs.ServiceRouterConfigEntry {
if e.Routers != nil {
return e.Routers[sid]
}
return nil
}
func (e *DiscoveryChainSet) GetSplitter(sid structs.ServiceID) *structs.ServiceSplitterConfigEntry {
if e.Splitters != nil {
return e.Splitters[sid]
}
return nil
}
func (e *DiscoveryChainSet) GetResolver(sid structs.ServiceID) *structs.ServiceResolverConfigEntry {
if e.Resolvers != nil {
return e.Resolvers[sid]
}
return nil
}
func (e *DiscoveryChainSet) GetService(sid structs.ServiceID) *structs.ServiceConfigEntry {
if e.Services != nil {
return e.Services[sid]
}
return nil
}
func (e *DiscoveryChainSet) GetSamenessGroup(name string) *structs.SamenessGroupConfigEntry {
if e.SamenessGroups != nil {
return e.SamenessGroups[name]
}
return nil
}
func (e *DiscoveryChainSet) GetDefaultSamenessGroup() *structs.SamenessGroupConfigEntry {
return e.DefaultSamenessGroup
}
func (e *DiscoveryChainSet) GetProxyDefaults(partition string) *structs.ProxyConfigEntry {
if e.ProxyDefaults != nil {
return e.ProxyDefaults[partition]
}
return nil
}
// AddRouters adds router configs. Convenience function for testing.
func (e *DiscoveryChainSet) AddRouters(entries ...*structs.ServiceRouterConfigEntry) {
if e.Routers == nil {
e.Routers = make(map[structs.ServiceID]*structs.ServiceRouterConfigEntry)
}
for _, entry := range entries {
e.Routers[structs.NewServiceID(entry.Name, &entry.EnterpriseMeta)] = entry
}
}
// AddSplitters adds splitter configs. Convenience function for testing.
func (e *DiscoveryChainSet) AddSplitters(entries ...*structs.ServiceSplitterConfigEntry) {
if e.Splitters == nil {
e.Splitters = make(map[structs.ServiceID]*structs.ServiceSplitterConfigEntry)
}
for _, entry := range entries {
e.Splitters[structs.NewServiceID(entry.Name, entry.GetEnterpriseMeta())] = entry
}
}
// AddResolvers adds resolver configs. Convenience function for testing.
func (e *DiscoveryChainSet) AddResolvers(entries ...*structs.ServiceResolverConfigEntry) {
if e.Resolvers == nil {
e.Resolvers = make(map[structs.ServiceID]*structs.ServiceResolverConfigEntry)
}
for _, entry := range entries {
e.Resolvers[structs.NewServiceID(entry.Name, entry.GetEnterpriseMeta())] = entry
}
}
// AddServices adds service configs. Convenience function for testing.
func (e *DiscoveryChainSet) AddServices(entries ...*structs.ServiceConfigEntry) {
if e.Services == nil {
e.Services = make(map[structs.ServiceID]*structs.ServiceConfigEntry)
}
for _, entry := range entries {
e.Services[structs.NewServiceID(entry.Name, entry.GetEnterpriseMeta())] = entry
}
}
// AddSamenessGroup adds a sameness group. Convenience function for testing.
func (e *DiscoveryChainSet) AddSamenessGroup(entries ...*structs.SamenessGroupConfigEntry) {
if e.SamenessGroups == nil {
e.SamenessGroups = make(map[string]*structs.SamenessGroupConfigEntry)
}
for _, entry := range entries {
e.SamenessGroups[entry.Name] = entry
}
}
// SetDefaultSamenessGroup sets the default sameness group. Convenience function for testing.
func (e *DiscoveryChainSet) SetDefaultSamenessGroup(entry *structs.SamenessGroupConfigEntry) {
if e.SamenessGroups == nil {
e.SamenessGroups = make(map[string]*structs.SamenessGroupConfigEntry)
}
if entry == nil {
return
}
e.SamenessGroups[entry.Name] = entry
e.DefaultSamenessGroup = entry
}
// AddProxyDefaults adds proxy-defaults configs. Convenience function for testing.
func (e *DiscoveryChainSet) AddProxyDefaults(entries ...*structs.ProxyConfigEntry) {
if e.ProxyDefaults == nil {
e.ProxyDefaults = make(map[string]*structs.ProxyConfigEntry)
}
for _, entry := range entries {
e.ProxyDefaults[entry.PartitionOrDefault()] = entry
}
}
// AddPeers adds cluster peers. Convenience function for testing.
func (e *DiscoveryChainSet) AddPeers(entries ...*pbpeering.Peering) {
if e.Peers == nil {
e.Peers = make(map[string]*pbpeering.Peering)
}
for _, entry := range entries {
e.Peers[entry.Name] = entry
}
}
// AddEntries adds generic configs. Convenience function for testing. Panics on
// operator error.
func (e *DiscoveryChainSet) AddEntries(entries ...structs.ConfigEntry) {
for _, rawEntry := range entries {
switch entry := rawEntry.(type) {
case *structs.ServiceRouterConfigEntry:
e.AddRouters(entry)
case *structs.ServiceSplitterConfigEntry:
e.AddSplitters(entry)
case *structs.ServiceResolverConfigEntry:
e.AddResolvers(entry)
case *structs.ServiceConfigEntry:
e.AddServices(entry)
case *structs.SamenessGroupConfigEntry:
if entry.DefaultForFailover {
e.DefaultSamenessGroup = entry
}
e.AddSamenessGroup(entry)
case *structs.ProxyConfigEntry:
if entry.GetName() != structs.ProxyConfigGlobal {
panic("the only supported proxy-defaults name is '" + structs.ProxyConfigGlobal + "'")
}
e.AddProxyDefaults(entry)
default:
panic("unhandled config entry kind: " + entry.GetKind())
}
}
}
// IsEmpty returns true if there are no config entries at all in the response.
// You should prefer this over IsChainEmpty() in most cases.
func (e *DiscoveryChainSet) IsEmpty() bool {
return e.IsChainEmpty() && len(e.Services) == 0 && len(e.ProxyDefaults) == 0
}
// IsChainEmpty returns true if there are no service-routers,
// service-splitters, or service-resolvers that are present. These config
// entries are the primary parts of the discovery chain.
func (e *DiscoveryChainSet) IsChainEmpty() bool {
return len(e.Routers) == 0 && len(e.Splitters) == 0 && len(e.Resolvers) == 0 && e.DefaultSamenessGroup == nil
}