2023-03-28 18:39:22 +00:00
|
|
|
// Copyright (c) HashiCorp, Inc.
|
|
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
|
2022-02-22 16:36:36 +00:00
|
|
|
package configentry
|
|
|
|
|
|
|
|
import (
|
|
|
|
"github.com/hashicorp/consul/agent/structs"
|
2023-03-10 17:59:47 +00:00
|
|
|
"github.com/hashicorp/consul/proto/private/pbpeering"
|
2022-02-22 16:36:36 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// 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 {
|
2023-03-31 18:35:56 +00:00
|
|
|
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
|
2022-02-22 16:36:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func NewDiscoveryChainSet() *DiscoveryChainSet {
|
|
|
|
return &DiscoveryChainSet{
|
2023-03-17 14:48:06 +00:00
|
|
|
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),
|
2022-02-22 16:36:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2023-03-20 13:12:37 +00:00
|
|
|
func (e *DiscoveryChainSet) GetSamenessGroup(name string) *structs.SamenessGroupConfigEntry {
|
|
|
|
if e.SamenessGroups != nil {
|
|
|
|
return e.SamenessGroups[name]
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-03-31 18:35:56 +00:00
|
|
|
func (e *DiscoveryChainSet) GetDefaultSamenessGroup() *structs.SamenessGroupConfigEntry {
|
|
|
|
return e.DefaultSamenessGroup
|
|
|
|
}
|
|
|
|
|
2022-02-22 16:36:36 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-31 18:35:56 +00:00
|
|
|
// AddSamenessGroup adds a sameness group. Convenience function for testing.
|
2023-03-20 13:12:37 +00:00
|
|
|
func (e *DiscoveryChainSet) AddSamenessGroup(entries ...*structs.SamenessGroupConfigEntry) {
|
2023-03-31 18:35:56 +00:00
|
|
|
if e.SamenessGroups == nil {
|
2023-03-20 13:12:37 +00:00
|
|
|
e.SamenessGroups = make(map[string]*structs.SamenessGroupConfigEntry)
|
|
|
|
}
|
|
|
|
for _, entry := range entries {
|
|
|
|
e.SamenessGroups[entry.Name] = entry
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-31 18:35:56 +00:00
|
|
|
// 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
|
|
|
|
}
|
|
|
|
|
2022-02-22 16:36:36 +00:00
|
|
|
// 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
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-10 17:59:47 +00:00
|
|
|
// 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
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-02-22 16:36:36 +00:00
|
|
|
// AddEntries adds generic configs. Convenience function for testing. Panics on
|
|
|
|
// operator error.
|
|
|
|
func (e *DiscoveryChainSet) AddEntries(entries ...structs.ConfigEntry) {
|
2023-03-31 18:35:56 +00:00
|
|
|
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:
|
2022-02-22 16:36:36 +00:00
|
|
|
if entry.GetName() != structs.ProxyConfigGlobal {
|
|
|
|
panic("the only supported proxy-defaults name is '" + structs.ProxyConfigGlobal + "'")
|
|
|
|
}
|
2023-03-31 18:35:56 +00:00
|
|
|
e.AddProxyDefaults(entry)
|
2022-02-22 16:36:36 +00:00
|
|
|
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 {
|
2023-03-31 18:35:56 +00:00
|
|
|
return len(e.Routers) == 0 && len(e.Splitters) == 0 && len(e.Resolvers) == 0 && e.DefaultSamenessGroup == nil
|
2022-02-22 16:36:36 +00:00
|
|
|
}
|