From 8b987a4d59451446240cfc1cc6cacdb7101c69fe Mon Sep 17 00:00:00 2001 From: "R.B. Boyer" <4903+rboyer@users.noreply.github.com> Date: Tue, 22 Feb 2022 10:36:36 -0600 Subject: [PATCH] configentry: make a new package to hold shared config entry structs that aren't used for RPC or the FSM (#12384) First two candidates are ConfigEntryKindName and DiscoveryChainConfigEntries. --- agent/configentry/config_entry.go | 34 +++++ agent/configentry/discoverychain.go | 149 +++++++++++++++++++ agent/configentry/doc.go | 5 + agent/consul/discoverychain/compile.go | 5 +- agent/consul/discoverychain/compile_test.go | 14 +- agent/consul/discoverychain/testing.go | 6 +- agent/consul/leader_intentions_test.go | 10 +- agent/consul/state/config_entry.go | 78 ++++------ agent/consul/state/config_entry_oss.go | 3 +- agent/consul/state/config_entry_oss_test.go | 7 +- agent/consul/state/config_entry_test.go | 139 ++++++++--------- agent/structs/config_entry_discoverychain.go | 137 ----------------- 12 files changed, 310 insertions(+), 277 deletions(-) create mode 100644 agent/configentry/config_entry.go create mode 100644 agent/configentry/discoverychain.go create mode 100644 agent/configentry/doc.go diff --git a/agent/configentry/config_entry.go b/agent/configentry/config_entry.go new file mode 100644 index 0000000000..0b57514922 --- /dev/null +++ b/agent/configentry/config_entry.go @@ -0,0 +1,34 @@ +package configentry + +import ( + "github.com/hashicorp/consul/agent/structs" +) + +// KindName is a value type useful for maps. You can use: +// map[KindName]Payload +// instead of: +// map[string]map[string]Payload +type KindName struct { + Kind string + Name string + structs.EnterpriseMeta +} + +// NewKindName returns a new KindName. The EnterpriseMeta values will be +// normalized based on the kind. +// +// Any caller which modifies the EnterpriseMeta field must call Normalize +// before persisting or using the value as a map key. +func NewKindName(kind, name string, entMeta *structs.EnterpriseMeta) KindName { + ret := KindName{ + Kind: kind, + Name: name, + } + if entMeta == nil { + entMeta = structs.DefaultEnterpriseMetaInDefaultPartition() + } + + ret.EnterpriseMeta = *entMeta + ret.Normalize() + return ret +} diff --git a/agent/configentry/discoverychain.go b/agent/configentry/discoverychain.go new file mode 100644 index 0000000000..4acf3f9ff8 --- /dev/null +++ b/agent/configentry/discoverychain.go @@ -0,0 +1,149 @@ +package configentry + +import ( + "github.com/hashicorp/consul/agent/structs" +) + +// 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 + 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), + ProxyDefaults: make(map[string]*structs.ProxyConfigEntry), + } +} + +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) 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 + } +} + +// 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 + } +} + +// AddEntries adds generic configs. Convenience function for testing. Panics on +// operator error. +func (e *DiscoveryChainSet) AddEntries(entries ...structs.ConfigEntry) { + for _, entry := range entries { + switch entry.GetKind() { + case structs.ServiceRouter: + e.AddRouters(entry.(*structs.ServiceRouterConfigEntry)) + case structs.ServiceSplitter: + e.AddSplitters(entry.(*structs.ServiceSplitterConfigEntry)) + case structs.ServiceResolver: + e.AddResolvers(entry.(*structs.ServiceResolverConfigEntry)) + case structs.ServiceDefaults: + e.AddServices(entry.(*structs.ServiceConfigEntry)) + case structs.ProxyDefaults: + if entry.GetName() != structs.ProxyConfigGlobal { + panic("the only supported proxy-defaults name is '" + structs.ProxyConfigGlobal + "'") + } + e.AddProxyDefaults(entry.(*structs.ProxyConfigEntry)) + 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 +} diff --git a/agent/configentry/doc.go b/agent/configentry/doc.go new file mode 100644 index 0000000000..b7da03fcd0 --- /dev/null +++ b/agent/configentry/doc.go @@ -0,0 +1,5 @@ +// Package configentry contains structs and logic related to the Configuration +// Entry subsystem. Currently this is restricted to structs used during +// runtime, but which are not serialized to the network or disk. + +package configentry diff --git a/agent/consul/discoverychain/compile.go b/agent/consul/discoverychain/compile.go index 12de7f45d9..4f78eb8bfd 100644 --- a/agent/consul/discoverychain/compile.go +++ b/agent/consul/discoverychain/compile.go @@ -8,6 +8,7 @@ import ( "github.com/mitchellh/hashstructure" "github.com/mitchellh/mapstructure" + "github.com/hashicorp/consul/agent/configentry" "github.com/hashicorp/consul/agent/connect" "github.com/hashicorp/consul/agent/structs" ) @@ -37,7 +38,7 @@ type CompileRequest struct { // overridden for any resolver in the compiled chain. OverrideConnectTimeout time.Duration - Entries *structs.DiscoveryChainConfigEntries + Entries *configentry.DiscoveryChainSet } // Compile assembles a discovery chain in the form of a graph of nodes using @@ -131,7 +132,7 @@ type compiler struct { // config entries that are being compiled (will be mutated during compilation) // // This is an INPUT field. - entries *structs.DiscoveryChainConfigEntries + entries *configentry.DiscoveryChainSet // resolvers is initially seeded by copying the provided entries.Resolvers // map and default resolvers are added as they are needed. diff --git a/agent/consul/discoverychain/compile_test.go b/agent/consul/discoverychain/compile_test.go index 1cd5758154..94029465ee 100644 --- a/agent/consul/discoverychain/compile_test.go +++ b/agent/consul/discoverychain/compile_test.go @@ -4,13 +4,15 @@ import ( "testing" "time" + "github.com/stretchr/testify/require" + + "github.com/hashicorp/consul/agent/configentry" "github.com/hashicorp/consul/agent/connect" "github.com/hashicorp/consul/agent/structs" - "github.com/stretchr/testify/require" ) type compileTestCase struct { - entries *structs.DiscoveryChainConfigEntries + entries *configentry.DiscoveryChainSet setup func(req *CompileRequest) expect *structs.CompiledDiscoveryChain // expectIsDefault tests behavior of CompiledDiscoveryChain.IsDefault() @@ -2645,7 +2647,7 @@ func newSimpleRoute(name string, muts ...func(*structs.ServiceRoute)) structs.Se return r } -func setGlobalProxyProtocol(entries *structs.DiscoveryChainConfigEntries, protocol string) { +func setGlobalProxyProtocol(entries *configentry.DiscoveryChainSet, protocol string) { entries.AddProxyDefaults(&structs.ProxyConfigEntry{ Kind: structs.ProxyDefaults, Name: structs.ProxyConfigGlobal, @@ -2655,7 +2657,7 @@ func setGlobalProxyProtocol(entries *structs.DiscoveryChainConfigEntries, protoc }) } -func setServiceProtocol(entries *structs.DiscoveryChainConfigEntries, name, protocol string) { +func setServiceProtocol(entries *configentry.DiscoveryChainSet, name, protocol string) { entries.AddServices(&structs.ServiceConfigEntry{ Kind: structs.ServiceDefaults, Name: name, @@ -2663,8 +2665,8 @@ func setServiceProtocol(entries *structs.DiscoveryChainConfigEntries, name, prot }) } -func newEntries() *structs.DiscoveryChainConfigEntries { - return &structs.DiscoveryChainConfigEntries{ +func newEntries() *configentry.DiscoveryChainSet { + return &configentry.DiscoveryChainSet{ Routers: make(map[structs.ServiceID]*structs.ServiceRouterConfigEntry), Splitters: make(map[structs.ServiceID]*structs.ServiceSplitterConfigEntry), Resolvers: make(map[structs.ServiceID]*structs.ServiceResolverConfigEntry), diff --git a/agent/consul/discoverychain/testing.go b/agent/consul/discoverychain/testing.go index 427c38b5ee..68a75c26a9 100644 --- a/agent/consul/discoverychain/testing.go +++ b/agent/consul/discoverychain/testing.go @@ -1,9 +1,11 @@ package discoverychain import ( - "github.com/hashicorp/consul/agent/structs" "github.com/mitchellh/go-testing-interface" "github.com/stretchr/testify/require" + + "github.com/hashicorp/consul/agent/configentry" + "github.com/hashicorp/consul/agent/structs" ) func TestCompileConfigEntries(t testing.T, @@ -13,7 +15,7 @@ func TestCompileConfigEntries(t testing.T, evaluateInDatacenter string, evaluateInTrustDomain string, setup func(req *CompileRequest), entries ...structs.ConfigEntry) *structs.CompiledDiscoveryChain { - set := structs.NewDiscoveryChainConfigEntries() + set := configentry.NewDiscoveryChainSet() set.AddEntries(entries...) diff --git a/agent/consul/leader_intentions_test.go b/agent/consul/leader_intentions_test.go index e48e3aa669..b431567fc6 100644 --- a/agent/consul/leader_intentions_test.go +++ b/agent/consul/leader_intentions_test.go @@ -9,7 +9,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/hashicorp/consul/agent/consul/state" + "github.com/hashicorp/consul/agent/configentry" "github.com/hashicorp/consul/agent/structs" tokenStore "github.com/hashicorp/consul/agent/token" "github.com/hashicorp/consul/sdk/testutil/retry" @@ -535,17 +535,17 @@ func TestLeader_LegacyIntentionMigration(t *testing.T) { checkIntentions(t, s1, true, map[string]*structs.Intention{}) })) - mapifyConfigs := func(entries interface{}) map[state.ConfigEntryKindName]*structs.ServiceIntentionsConfigEntry { - m := make(map[state.ConfigEntryKindName]*structs.ServiceIntentionsConfigEntry) + mapifyConfigs := func(entries interface{}) map[configentry.KindName]*structs.ServiceIntentionsConfigEntry { + m := make(map[configentry.KindName]*structs.ServiceIntentionsConfigEntry) switch v := entries.(type) { case []*structs.ServiceIntentionsConfigEntry: for _, entry := range v { - kn := state.NewConfigEntryKindName(entry.Kind, entry.Name, &entry.EnterpriseMeta) + kn := configentry.NewKindName(entry.Kind, entry.Name, &entry.EnterpriseMeta) m[kn] = entry } case []structs.ConfigEntry: for _, entry := range v { - kn := state.NewConfigEntryKindName(entry.GetKind(), entry.GetName(), entry.GetEnterpriseMeta()) + kn := configentry.NewKindName(entry.GetKind(), entry.GetName(), entry.GetEnterpriseMeta()) m[kn] = entry.(*structs.ServiceIntentionsConfigEntry) } default: diff --git a/agent/consul/state/config_entry.go b/agent/consul/state/config_entry.go index 29e4e7aa5b..e75ed7f8b1 100644 --- a/agent/consul/state/config_entry.go +++ b/agent/consul/state/config_entry.go @@ -6,6 +6,7 @@ import ( memdb "github.com/hashicorp/go-memdb" + "github.com/hashicorp/consul/agent/configentry" "github.com/hashicorp/consul/agent/connect" "github.com/hashicorp/consul/agent/consul/discoverychain" "github.com/hashicorp/consul/agent/structs" @@ -105,7 +106,7 @@ func configEntryTxn(tx ReadTxn, ws memdb.WatchSet, kind, name string, entMeta *s idx := maxIndexTxn(tx, tableConfigEntries) // Get the existing config entry. - watchCh, existing, err := tx.FirstWatch(tableConfigEntries, "id", NewConfigEntryKindName(kind, name, entMeta)) + watchCh, existing, err := tx.FirstWatch(tableConfigEntries, "id", configentry.NewKindName(kind, name, entMeta)) if err != nil { return 0, nil, fmt.Errorf("failed config entry lookup: %s", err) } @@ -290,7 +291,7 @@ func (s *Store) DeleteConfigEntry(idx uint64, kind, name string, entMeta *struct // TODO: accept structs.ConfigEntry instead of individual fields func deleteConfigEntryTxn(tx WriteTxn, idx uint64, kind, name string, entMeta *structs.EnterpriseMeta) error { - q := NewConfigEntryKindName(kind, name, entMeta) + q := configentry.NewKindName(kind, name, entMeta) existing, err := tx.First(tableConfigEntries, indexID, q) if err != nil { return fmt.Errorf("failed config entry lookup: %s", err) @@ -370,7 +371,7 @@ func insertConfigEntryWithTxn(tx WriteTxn, idx uint64, conf structs.ConfigEntry) // to the caller that they can correct. func validateProposedConfigEntryInGraph( tx ReadTxn, - kindName ConfigEntryKindName, + kindName configentry.KindName, newEntry structs.ConfigEntry, ) error { switch kindName.Kind { @@ -403,7 +404,7 @@ func validateProposedConfigEntryInGraph( return validateProposedConfigEntryInServiceGraph(tx, kindName, newEntry) } -func checkGatewayClash(tx ReadTxn, kindName ConfigEntryKindName, otherKind string) error { +func checkGatewayClash(tx ReadTxn, kindName configentry.KindName, otherKind string) error { _, entry, err := configEntryTxn(tx, nil, otherKind, kindName.Name, &kindName.EnterpriseMeta) if err != nil { return err @@ -513,7 +514,7 @@ func (s *Store) discoveryChainSourcesTxn(tx ReadTxn, ws memdb.WatchSet, dc strin func validateProposedConfigEntryInServiceGraph( tx ReadTxn, - kindName ConfigEntryKindName, + kindName configentry.KindName, newEntry structs.ConfigEntry, ) error { // Collect all of the chains that could be affected by this change @@ -658,7 +659,7 @@ func validateProposedConfigEntryInServiceGraph( checkChains[sn.ToServiceID()] = struct{}{} } - overrides := map[ConfigEntryKindName]structs.ConfigEntry{ + overrides := map[configentry.KindName]structs.ConfigEntry{ kindName: newEntry, } @@ -738,7 +739,7 @@ func validateProposedConfigEntryInServiceGraph( func testCompileDiscoveryChain( tx ReadTxn, chainName string, - overrides map[ConfigEntryKindName]structs.ConfigEntry, + overrides map[configentry.KindName]structs.ConfigEntry, entMeta *structs.EnterpriseMeta, ) (string, *structs.DiscoveryGraphNode, error) { _, speculativeEntries, err := readDiscoveryChainConfigEntriesTxn(tx, nil, chainName, overrides, entMeta) @@ -827,7 +828,7 @@ func (s *Store) ReadDiscoveryChainConfigEntries( ws memdb.WatchSet, serviceName string, entMeta *structs.EnterpriseMeta, -) (uint64, *structs.DiscoveryChainConfigEntries, error) { +) (uint64, *configentry.DiscoveryChainSet, error) { return s.readDiscoveryChainConfigEntries(ws, serviceName, nil, entMeta) } @@ -844,9 +845,9 @@ func (s *Store) ReadDiscoveryChainConfigEntries( func (s *Store) readDiscoveryChainConfigEntries( ws memdb.WatchSet, serviceName string, - overrides map[ConfigEntryKindName]structs.ConfigEntry, + overrides map[configentry.KindName]structs.ConfigEntry, entMeta *structs.EnterpriseMeta, -) (uint64, *structs.DiscoveryChainConfigEntries, error) { +) (uint64, *configentry.DiscoveryChainSet, error) { tx := s.db.Txn(false) defer tx.Abort() return readDiscoveryChainConfigEntriesTxn(tx, ws, serviceName, overrides, entMeta) @@ -856,10 +857,10 @@ func readDiscoveryChainConfigEntriesTxn( tx ReadTxn, ws memdb.WatchSet, serviceName string, - overrides map[ConfigEntryKindName]structs.ConfigEntry, + overrides map[configentry.KindName]structs.ConfigEntry, entMeta *structs.EnterpriseMeta, -) (uint64, *structs.DiscoveryChainConfigEntries, error) { - res := structs.NewDiscoveryChainConfigEntries() +) (uint64, *configentry.DiscoveryChainSet, error) { + res := configentry.NewDiscoveryChainSet() // Note that below we always look up splitters and resolvers in pairs, even // in some circumstances where both are not strictly necessary. @@ -1063,7 +1064,7 @@ func getProxyConfigEntryTxn( tx ReadTxn, ws memdb.WatchSet, name string, - overrides map[ConfigEntryKindName]structs.ConfigEntry, + overrides map[configentry.KindName]structs.ConfigEntry, entMeta *structs.EnterpriseMeta, ) (uint64, *structs.ProxyConfigEntry, error) { idx, entry, err := configEntryWithOverridesTxn(tx, ws, structs.ProxyDefaults, name, overrides, entMeta) @@ -1088,7 +1089,7 @@ func getServiceConfigEntryTxn( tx ReadTxn, ws memdb.WatchSet, serviceName string, - overrides map[ConfigEntryKindName]structs.ConfigEntry, + overrides map[configentry.KindName]structs.ConfigEntry, entMeta *structs.EnterpriseMeta, ) (uint64, *structs.ServiceConfigEntry, error) { idx, entry, err := configEntryWithOverridesTxn(tx, ws, structs.ServiceDefaults, serviceName, overrides, entMeta) @@ -1113,7 +1114,7 @@ func getRouterConfigEntryTxn( tx ReadTxn, ws memdb.WatchSet, serviceName string, - overrides map[ConfigEntryKindName]structs.ConfigEntry, + overrides map[configentry.KindName]structs.ConfigEntry, entMeta *structs.EnterpriseMeta, ) (uint64, *structs.ServiceRouterConfigEntry, error) { idx, entry, err := configEntryWithOverridesTxn(tx, ws, structs.ServiceRouter, serviceName, overrides, entMeta) @@ -1138,7 +1139,7 @@ func getSplitterConfigEntryTxn( tx ReadTxn, ws memdb.WatchSet, serviceName string, - overrides map[ConfigEntryKindName]structs.ConfigEntry, + overrides map[configentry.KindName]structs.ConfigEntry, entMeta *structs.EnterpriseMeta, ) (uint64, *structs.ServiceSplitterConfigEntry, error) { idx, entry, err := configEntryWithOverridesTxn(tx, ws, structs.ServiceSplitter, serviceName, overrides, entMeta) @@ -1163,7 +1164,7 @@ func getResolverConfigEntryTxn( tx ReadTxn, ws memdb.WatchSet, serviceName string, - overrides map[ConfigEntryKindName]structs.ConfigEntry, + overrides map[configentry.KindName]structs.ConfigEntry, entMeta *structs.EnterpriseMeta, ) (uint64, *structs.ServiceResolverConfigEntry, error) { idx, entry, err := configEntryWithOverridesTxn(tx, ws, structs.ServiceResolver, serviceName, overrides, entMeta) @@ -1188,7 +1189,7 @@ func getServiceIntentionsConfigEntryTxn( tx ReadTxn, ws memdb.WatchSet, name string, - overrides map[ConfigEntryKindName]structs.ConfigEntry, + overrides map[configentry.KindName]structs.ConfigEntry, entMeta *structs.EnterpriseMeta, ) (uint64, *structs.ServiceIntentionsConfigEntry, error) { idx, entry, err := configEntryWithOverridesTxn(tx, ws, structs.ServiceIntentions, name, overrides, entMeta) @@ -1210,11 +1211,11 @@ func configEntryWithOverridesTxn( ws memdb.WatchSet, kind string, name string, - overrides map[ConfigEntryKindName]structs.ConfigEntry, + overrides map[configentry.KindName]structs.ConfigEntry, entMeta *structs.EnterpriseMeta, ) (uint64, structs.ConfigEntry, error) { if len(overrides) > 0 { - kn := NewConfigEntryKindName(kind, name, entMeta) + kn := configentry.NewKindName(kind, name, entMeta) kn.Normalize() entry, ok := overrides[kn] if ok { @@ -1244,7 +1245,7 @@ func protocolForService( } maxIdx = lib.MaxUint64(maxIdx, idx) - entries := structs.NewDiscoveryChainConfigEntries() + entries := configentry.NewDiscoveryChainSet() if proxyConfig != nil { entries.AddEntries(proxyConfig) } @@ -1267,37 +1268,8 @@ func protocolForService( return maxIdx, chain.Protocol, nil } -// ConfigEntryKindName is a value type useful for maps. You can use: -// map[ConfigEntryKindName]Payload -// instead of: -// map[string]map[string]Payload -type ConfigEntryKindName struct { - Kind string - Name string - structs.EnterpriseMeta -} - -// NewConfigEntryKindName returns a new ConfigEntryKindName. The EnterpriseMeta -// values will be normalized based on the kind. -// -// Any caller which modifies the EnterpriseMeta field must call Normalize before -// persisting or using the value as a map key. -func NewConfigEntryKindName(kind, name string, entMeta *structs.EnterpriseMeta) ConfigEntryKindName { - ret := ConfigEntryKindName{ - Kind: kind, - Name: name, - } - if entMeta == nil { - entMeta = structs.DefaultEnterpriseMetaInDefaultPartition() - } - - ret.EnterpriseMeta = *entMeta - ret.Normalize() - return ret -} - -func newConfigEntryQuery(c structs.ConfigEntry) ConfigEntryKindName { - return NewConfigEntryKindName(c.GetKind(), c.GetName(), c.GetEnterpriseMeta()) +func newConfigEntryQuery(c structs.ConfigEntry) configentry.KindName { + return configentry.NewKindName(c.GetKind(), c.GetName(), c.GetEnterpriseMeta()) } // ConfigEntryKindQuery is used to lookup config entries by their kind. diff --git a/agent/consul/state/config_entry_oss.go b/agent/consul/state/config_entry_oss.go index 817162d190..9c3d6c7ea8 100644 --- a/agent/consul/state/config_entry_oss.go +++ b/agent/consul/state/config_entry_oss.go @@ -9,6 +9,7 @@ import ( memdb "github.com/hashicorp/go-memdb" + "github.com/hashicorp/consul/agent/configentry" "github.com/hashicorp/consul/agent/structs" ) @@ -23,7 +24,7 @@ func indexFromConfigEntryKindName(arg interface{}) ([]byte, error) { case ConfigEntryKindQuery: b.String(strings.ToLower(n.Kind)) return b.Bytes(), nil - case ConfigEntryKindName: + case configentry.KindName: b.String(strings.ToLower(n.Kind)) b.String(strings.ToLower(n.Name)) return b.Bytes(), nil diff --git a/agent/consul/state/config_entry_oss_test.go b/agent/consul/state/config_entry_oss_test.go index 1a4af3cf91..4c6595192a 100644 --- a/agent/consul/state/config_entry_oss_test.go +++ b/agent/consul/state/config_entry_oss_test.go @@ -3,13 +3,16 @@ package state -import "github.com/hashicorp/consul/agent/structs" +import ( + "github.com/hashicorp/consul/agent/configentry" + "github.com/hashicorp/consul/agent/structs" +) func testIndexerTableConfigEntries() map[string]indexerTestCase { return map[string]indexerTestCase{ indexID: { read: indexValue{ - source: ConfigEntryKindName{ + source: configentry.KindName{ Kind: "Proxy-Defaults", Name: "NaMe", }, diff --git a/agent/consul/state/config_entry_test.go b/agent/consul/state/config_entry_test.go index ee37844fc7..8cb4d8f51d 100644 --- a/agent/consul/state/config_entry_test.go +++ b/agent/consul/state/config_entry_test.go @@ -7,6 +7,7 @@ import ( memdb "github.com/hashicorp/go-memdb" "github.com/stretchr/testify/require" + "github.com/hashicorp/consul/agent/configentry" "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/sdk/testutil" ) @@ -999,11 +1000,11 @@ func TestStore_ReadDiscoveryChainConfigEntries_Overrides(t *testing.T) { for _, tc := range []struct { name string entries []structs.ConfigEntry - expectBefore []ConfigEntryKindName - overrides map[ConfigEntryKindName]structs.ConfigEntry - expectAfter []ConfigEntryKindName + expectBefore []configentry.KindName + overrides map[configentry.KindName]structs.ConfigEntry + expectAfter []configentry.KindName expectAfterErr string - checkAfter func(t *testing.T, entrySet *structs.DiscoveryChainConfigEntries) + checkAfter func(t *testing.T, entrySet *configentry.DiscoveryChainSet) }{ { name: "mask service-defaults", @@ -1014,13 +1015,13 @@ func TestStore_ReadDiscoveryChainConfigEntries_Overrides(t *testing.T) { Protocol: "tcp", }, }, - expectBefore: []ConfigEntryKindName{ - NewConfigEntryKindName(structs.ServiceDefaults, "main", nil), + expectBefore: []configentry.KindName{ + configentry.NewKindName(structs.ServiceDefaults, "main", nil), }, - overrides: map[ConfigEntryKindName]structs.ConfigEntry{ - NewConfigEntryKindName(structs.ServiceDefaults, "main", nil): nil, + overrides: map[configentry.KindName]structs.ConfigEntry{ + configentry.NewKindName(structs.ServiceDefaults, "main", nil): nil, }, - expectAfter: []ConfigEntryKindName{ + expectAfter: []configentry.KindName{ // nothing }, }, @@ -1033,20 +1034,20 @@ func TestStore_ReadDiscoveryChainConfigEntries_Overrides(t *testing.T) { Protocol: "tcp", }, }, - expectBefore: []ConfigEntryKindName{ - NewConfigEntryKindName(structs.ServiceDefaults, "main", nil), + expectBefore: []configentry.KindName{ + configentry.NewKindName(structs.ServiceDefaults, "main", nil), }, - overrides: map[ConfigEntryKindName]structs.ConfigEntry{ - NewConfigEntryKindName(structs.ServiceDefaults, "main", nil): &structs.ServiceConfigEntry{ + overrides: map[configentry.KindName]structs.ConfigEntry{ + configentry.NewKindName(structs.ServiceDefaults, "main", nil): &structs.ServiceConfigEntry{ Kind: structs.ServiceDefaults, Name: "main", Protocol: "grpc", }, }, - expectAfter: []ConfigEntryKindName{ - NewConfigEntryKindName(structs.ServiceDefaults, "main", nil), + expectAfter: []configentry.KindName{ + configentry.NewKindName(structs.ServiceDefaults, "main", nil), }, - checkAfter: func(t *testing.T, entrySet *structs.DiscoveryChainConfigEntries) { + checkAfter: func(t *testing.T, entrySet *configentry.DiscoveryChainSet) { defaults := entrySet.GetService(structs.NewServiceID("main", nil)) require.NotNil(t, defaults) require.Equal(t, "grpc", defaults.Protocol) @@ -1066,15 +1067,15 @@ func TestStore_ReadDiscoveryChainConfigEntries_Overrides(t *testing.T) { Name: "main", }, }, - expectBefore: []ConfigEntryKindName{ - NewConfigEntryKindName(structs.ServiceDefaults, "main", nil), - NewConfigEntryKindName(structs.ServiceRouter, "main", nil), + expectBefore: []configentry.KindName{ + configentry.NewKindName(structs.ServiceDefaults, "main", nil), + configentry.NewKindName(structs.ServiceRouter, "main", nil), }, - overrides: map[ConfigEntryKindName]structs.ConfigEntry{ - NewConfigEntryKindName(structs.ServiceRouter, "main", nil): nil, + overrides: map[configentry.KindName]structs.ConfigEntry{ + configentry.NewKindName(structs.ServiceRouter, "main", nil): nil, }, - expectAfter: []ConfigEntryKindName{ - NewConfigEntryKindName(structs.ServiceDefaults, "main", nil), + expectAfter: []configentry.KindName{ + configentry.NewKindName(structs.ServiceDefaults, "main", nil), }, }, { @@ -1111,13 +1112,13 @@ func TestStore_ReadDiscoveryChainConfigEntries_Overrides(t *testing.T) { }, }, }, - expectBefore: []ConfigEntryKindName{ - NewConfigEntryKindName(structs.ServiceDefaults, "main", nil), - NewConfigEntryKindName(structs.ServiceResolver, "main", nil), - NewConfigEntryKindName(structs.ServiceRouter, "main", nil), + expectBefore: []configentry.KindName{ + configentry.NewKindName(structs.ServiceDefaults, "main", nil), + configentry.NewKindName(structs.ServiceResolver, "main", nil), + configentry.NewKindName(structs.ServiceRouter, "main", nil), }, - overrides: map[ConfigEntryKindName]structs.ConfigEntry{ - NewConfigEntryKindName(structs.ServiceRouter, "main", nil): &structs.ServiceRouterConfigEntry{ + overrides: map[configentry.KindName]structs.ConfigEntry{ + configentry.NewKindName(structs.ServiceRouter, "main", nil): &structs.ServiceRouterConfigEntry{ Kind: structs.ServiceRouter, Name: "main", Routes: []structs.ServiceRoute{ @@ -1134,12 +1135,12 @@ func TestStore_ReadDiscoveryChainConfigEntries_Overrides(t *testing.T) { }, }, }, - expectAfter: []ConfigEntryKindName{ - NewConfigEntryKindName(structs.ServiceDefaults, "main", nil), - NewConfigEntryKindName(structs.ServiceResolver, "main", nil), - NewConfigEntryKindName(structs.ServiceRouter, "main", nil), + expectAfter: []configentry.KindName{ + configentry.NewKindName(structs.ServiceDefaults, "main", nil), + configentry.NewKindName(structs.ServiceResolver, "main", nil), + configentry.NewKindName(structs.ServiceRouter, "main", nil), }, - checkAfter: func(t *testing.T, entrySet *structs.DiscoveryChainConfigEntries) { + checkAfter: func(t *testing.T, entrySet *configentry.DiscoveryChainSet) { router := entrySet.GetRouter(structs.NewServiceID("main", nil)) require.NotNil(t, router) require.Len(t, router.Routes, 1) @@ -1174,15 +1175,15 @@ func TestStore_ReadDiscoveryChainConfigEntries_Overrides(t *testing.T) { }, }, }, - expectBefore: []ConfigEntryKindName{ - NewConfigEntryKindName(structs.ServiceDefaults, "main", nil), - NewConfigEntryKindName(structs.ServiceSplitter, "main", nil), + expectBefore: []configentry.KindName{ + configentry.NewKindName(structs.ServiceDefaults, "main", nil), + configentry.NewKindName(structs.ServiceSplitter, "main", nil), }, - overrides: map[ConfigEntryKindName]structs.ConfigEntry{ - NewConfigEntryKindName(structs.ServiceSplitter, "main", nil): nil, + overrides: map[configentry.KindName]structs.ConfigEntry{ + configentry.NewKindName(structs.ServiceSplitter, "main", nil): nil, }, - expectAfter: []ConfigEntryKindName{ - NewConfigEntryKindName(structs.ServiceDefaults, "main", nil), + expectAfter: []configentry.KindName{ + configentry.NewKindName(structs.ServiceDefaults, "main", nil), }, }, { @@ -1201,12 +1202,12 @@ func TestStore_ReadDiscoveryChainConfigEntries_Overrides(t *testing.T) { }, }, }, - expectBefore: []ConfigEntryKindName{ - NewConfigEntryKindName(structs.ServiceDefaults, "main", nil), - NewConfigEntryKindName(structs.ServiceSplitter, "main", nil), + expectBefore: []configentry.KindName{ + configentry.NewKindName(structs.ServiceDefaults, "main", nil), + configentry.NewKindName(structs.ServiceSplitter, "main", nil), }, - overrides: map[ConfigEntryKindName]structs.ConfigEntry{ - NewConfigEntryKindName(structs.ServiceSplitter, "main", nil): &structs.ServiceSplitterConfigEntry{ + overrides: map[configentry.KindName]structs.ConfigEntry{ + configentry.NewKindName(structs.ServiceSplitter, "main", nil): &structs.ServiceSplitterConfigEntry{ Kind: structs.ServiceSplitter, Name: "main", Splits: []structs.ServiceSplit{ @@ -1215,11 +1216,11 @@ func TestStore_ReadDiscoveryChainConfigEntries_Overrides(t *testing.T) { }, }, }, - expectAfter: []ConfigEntryKindName{ - NewConfigEntryKindName(structs.ServiceDefaults, "main", nil), - NewConfigEntryKindName(structs.ServiceSplitter, "main", nil), + expectAfter: []configentry.KindName{ + configentry.NewKindName(structs.ServiceDefaults, "main", nil), + configentry.NewKindName(structs.ServiceSplitter, "main", nil), }, - checkAfter: func(t *testing.T, entrySet *structs.DiscoveryChainConfigEntries) { + checkAfter: func(t *testing.T, entrySet *configentry.DiscoveryChainSet) { splitter := entrySet.GetSplitter(structs.NewServiceID("main", nil)) require.NotNil(t, splitter) require.Len(t, splitter.Splits, 2) @@ -1240,13 +1241,13 @@ func TestStore_ReadDiscoveryChainConfigEntries_Overrides(t *testing.T) { Name: "main", }, }, - expectBefore: []ConfigEntryKindName{ - NewConfigEntryKindName(structs.ServiceResolver, "main", nil), + expectBefore: []configentry.KindName{ + configentry.NewKindName(structs.ServiceResolver, "main", nil), }, - overrides: map[ConfigEntryKindName]structs.ConfigEntry{ - NewConfigEntryKindName(structs.ServiceResolver, "main", nil): nil, + overrides: map[configentry.KindName]structs.ConfigEntry{ + configentry.NewKindName(structs.ServiceResolver, "main", nil): nil, }, - expectAfter: []ConfigEntryKindName{ + expectAfter: []configentry.KindName{ // nothing }, }, @@ -1258,20 +1259,20 @@ func TestStore_ReadDiscoveryChainConfigEntries_Overrides(t *testing.T) { Name: "main", }, }, - expectBefore: []ConfigEntryKindName{ - NewConfigEntryKindName(structs.ServiceResolver, "main", nil), + expectBefore: []configentry.KindName{ + configentry.NewKindName(structs.ServiceResolver, "main", nil), }, - overrides: map[ConfigEntryKindName]structs.ConfigEntry{ - NewConfigEntryKindName(structs.ServiceResolver, "main", nil): &structs.ServiceResolverConfigEntry{ + overrides: map[configentry.KindName]structs.ConfigEntry{ + configentry.NewKindName(structs.ServiceResolver, "main", nil): &structs.ServiceResolverConfigEntry{ Kind: structs.ServiceResolver, Name: "main", ConnectTimeout: 33 * time.Second, }, }, - expectAfter: []ConfigEntryKindName{ - NewConfigEntryKindName(structs.ServiceResolver, "main", nil), + expectAfter: []configentry.KindName{ + configentry.NewKindName(structs.ServiceResolver, "main", nil), }, - checkAfter: func(t *testing.T, entrySet *structs.DiscoveryChainConfigEntries) { + checkAfter: func(t *testing.T, entrySet *configentry.DiscoveryChainSet) { resolver := entrySet.GetResolver(structs.NewServiceID("main", nil)) require.NotNil(t, resolver) require.Equal(t, 33*time.Second, resolver.ConnectTimeout) @@ -1313,38 +1314,38 @@ func TestStore_ReadDiscoveryChainConfigEntries_Overrides(t *testing.T) { } } -func entrySetToKindNames(entrySet *structs.DiscoveryChainConfigEntries) []ConfigEntryKindName { - var out []ConfigEntryKindName +func entrySetToKindNames(entrySet *configentry.DiscoveryChainSet) []configentry.KindName { + var out []configentry.KindName for _, entry := range entrySet.Routers { - out = append(out, NewConfigEntryKindName( + out = append(out, configentry.NewKindName( entry.Kind, entry.Name, &entry.EnterpriseMeta, )) } for _, entry := range entrySet.Splitters { - out = append(out, NewConfigEntryKindName( + out = append(out, configentry.NewKindName( entry.Kind, entry.Name, &entry.EnterpriseMeta, )) } for _, entry := range entrySet.Resolvers { - out = append(out, NewConfigEntryKindName( + out = append(out, configentry.NewKindName( entry.Kind, entry.Name, &entry.EnterpriseMeta, )) } for _, entry := range entrySet.Services { - out = append(out, NewConfigEntryKindName( + out = append(out, configentry.NewKindName( entry.Kind, entry.Name, &entry.EnterpriseMeta, )) } for _, entry := range entrySet.ProxyDefaults { - out = append(out, NewConfigEntryKindName( + out = append(out, configentry.NewKindName( entry.Kind, entry.Name, &entry.EnterpriseMeta, diff --git a/agent/structs/config_entry_discoverychain.go b/agent/structs/config_entry_discoverychain.go index 27980a4d19..63cf843564 100644 --- a/agent/structs/config_entry_discoverychain.go +++ b/agent/structs/config_entry_discoverychain.go @@ -1333,143 +1333,6 @@ func canWriteDiscoveryChain(entry discoveryChainConfigEntry, authz acl.Authorize return true } -// DiscoveryChainConfigEntries wraps just the raw cross-referenced config -// entries. None of these are defaulted. -type DiscoveryChainConfigEntries struct { - Routers map[ServiceID]*ServiceRouterConfigEntry - Splitters map[ServiceID]*ServiceSplitterConfigEntry - Resolvers map[ServiceID]*ServiceResolverConfigEntry - Services map[ServiceID]*ServiceConfigEntry - ProxyDefaults map[string]*ProxyConfigEntry -} - -func NewDiscoveryChainConfigEntries() *DiscoveryChainConfigEntries { - return &DiscoveryChainConfigEntries{ - Routers: make(map[ServiceID]*ServiceRouterConfigEntry), - Splitters: make(map[ServiceID]*ServiceSplitterConfigEntry), - Resolvers: make(map[ServiceID]*ServiceResolverConfigEntry), - Services: make(map[ServiceID]*ServiceConfigEntry), - ProxyDefaults: make(map[string]*ProxyConfigEntry), - } -} - -func (e *DiscoveryChainConfigEntries) GetRouter(sid ServiceID) *ServiceRouterConfigEntry { - if e.Routers != nil { - return e.Routers[sid] - } - return nil -} - -func (e *DiscoveryChainConfigEntries) GetSplitter(sid ServiceID) *ServiceSplitterConfigEntry { - if e.Splitters != nil { - return e.Splitters[sid] - } - return nil -} - -func (e *DiscoveryChainConfigEntries) GetResolver(sid ServiceID) *ServiceResolverConfigEntry { - if e.Resolvers != nil { - return e.Resolvers[sid] - } - return nil -} - -func (e *DiscoveryChainConfigEntries) GetService(sid ServiceID) *ServiceConfigEntry { - if e.Services != nil { - return e.Services[sid] - } - return nil -} - -func (e *DiscoveryChainConfigEntries) GetProxyDefaults(partition string) *ProxyConfigEntry { - if e.ProxyDefaults != nil { - return e.ProxyDefaults[partition] - } - return nil -} - -// AddRouters adds router configs. Convenience function for testing. -func (e *DiscoveryChainConfigEntries) AddRouters(entries ...*ServiceRouterConfigEntry) { - if e.Routers == nil { - e.Routers = make(map[ServiceID]*ServiceRouterConfigEntry) - } - for _, entry := range entries { - e.Routers[NewServiceID(entry.Name, &entry.EnterpriseMeta)] = entry - } -} - -// AddSplitters adds splitter configs. Convenience function for testing. -func (e *DiscoveryChainConfigEntries) AddSplitters(entries ...*ServiceSplitterConfigEntry) { - if e.Splitters == nil { - e.Splitters = make(map[ServiceID]*ServiceSplitterConfigEntry) - } - for _, entry := range entries { - e.Splitters[NewServiceID(entry.Name, entry.GetEnterpriseMeta())] = entry - } -} - -// AddResolvers adds resolver configs. Convenience function for testing. -func (e *DiscoveryChainConfigEntries) AddResolvers(entries ...*ServiceResolverConfigEntry) { - if e.Resolvers == nil { - e.Resolvers = make(map[ServiceID]*ServiceResolverConfigEntry) - } - for _, entry := range entries { - e.Resolvers[NewServiceID(entry.Name, entry.GetEnterpriseMeta())] = entry - } -} - -// AddServices adds service configs. Convenience function for testing. -func (e *DiscoveryChainConfigEntries) AddServices(entries ...*ServiceConfigEntry) { - if e.Services == nil { - e.Services = make(map[ServiceID]*ServiceConfigEntry) - } - for _, entry := range entries { - e.Services[NewServiceID(entry.Name, entry.GetEnterpriseMeta())] = entry - } -} - -// AddProxyDefaults adds proxy-defaults configs. Convenience function for testing. -func (e *DiscoveryChainConfigEntries) AddProxyDefaults(entries ...*ProxyConfigEntry) { - if e.ProxyDefaults == nil { - e.ProxyDefaults = make(map[string]*ProxyConfigEntry) - } - for _, entry := range entries { - e.ProxyDefaults[entry.PartitionOrDefault()] = entry - } -} - -// AddEntries adds generic configs. Convenience function for testing. Panics on -// operator error. -func (e *DiscoveryChainConfigEntries) AddEntries(entries ...ConfigEntry) { - for _, entry := range entries { - switch entry.GetKind() { - case ServiceRouter: - e.AddRouters(entry.(*ServiceRouterConfigEntry)) - case ServiceSplitter: - e.AddSplitters(entry.(*ServiceSplitterConfigEntry)) - case ServiceResolver: - e.AddResolvers(entry.(*ServiceResolverConfigEntry)) - case ServiceDefaults: - e.AddServices(entry.(*ServiceConfigEntry)) - case ProxyDefaults: - if entry.GetName() != ProxyConfigGlobal { - panic("the only supported proxy-defaults name is '" + ProxyConfigGlobal + "'") - } - e.AddProxyDefaults(entry.(*ProxyConfigEntry)) - default: - panic("unhandled config entry kind: " + entry.GetKind()) - } - } -} - -func (e *DiscoveryChainConfigEntries) IsEmpty() bool { - return e.IsChainEmpty() && len(e.Services) == 0 && len(e.ProxyDefaults) == 0 -} - -func (e *DiscoveryChainConfigEntries) IsChainEmpty() bool { - return len(e.Routers) == 0 && len(e.Splitters) == 0 && len(e.Resolvers) == 0 -} - // DiscoveryChainRequest is used when requesting the discovery chain for a // service. type DiscoveryChainRequest struct {