Fix a bug with disco chain config entry fetching (#17078)

Before this change, we were not fetching service resolvers (and therefore
service defaults) configuration entries for services on members of sameness
groups.
This commit is contained in:
Eric Haberkorn 2023-04-21 09:18:32 -04:00 committed by GitHub
parent e76795dc08
commit e61ba07fa1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 63 additions and 49 deletions

View File

@ -1558,10 +1558,10 @@ func readDiscoveryChainConfigEntriesTxn(
todoResolvers = make(map[structs.ServiceID]struct{}) todoResolvers = make(map[structs.ServiceID]struct{})
todoDefaults = make(map[structs.ServiceID]struct{}) todoDefaults = make(map[structs.ServiceID]struct{})
todoPeers = make(map[string]struct{}) todoPeers = make(map[string]struct{})
todoSamenessGroups = make(map[string]struct{})
) )
sid := structs.NewServiceID(serviceName, entMeta) sid := structs.NewServiceID(serviceName, entMeta)
peerEntMeta := structs.DefaultEnterpriseMetaInPartition(entMeta.PartitionOrDefault())
// At every step we'll need service and proxy defaults. // At every step we'll need service and proxy defaults.
todoDefaults[sid] = struct{}{} todoDefaults[sid] = struct{}{}
@ -1628,6 +1628,31 @@ func readDiscoveryChainConfigEntriesTxn(
} }
} }
processSamenessGroup := func(sg *structs.SamenessGroupConfigEntry, resolverID structs.ServiceID) error {
if sg == nil {
return nil
}
res.SamenessGroups[sg.Name] = sg
for _, peer := range sg.RelatedPeers() {
todoPeers[peer] = struct{}{}
}
for _, m := range sg.AllMembers() {
if m.Peer != "" {
continue
}
// Disco chains preserve the name and namespace from the resolver.
em := acl.NewEnterpriseMetaWithPartition(m.Partition, resolverID.NamespaceOrDefault())
s := structs.NewServiceID(resolverID.ID, &em)
todoResolvers[s] = struct{}{}
}
return nil
}
for { for {
resolverID, ok := anyKey(todoResolvers) resolverID, ok := anyKey(todoResolvers)
if !ok { if !ok {
@ -1650,12 +1675,23 @@ func readDiscoveryChainConfigEntriesTxn(
maxIdx = idx maxIdx = idx
} }
res.Resolvers[resolverID] = resolver
if resolver == nil { if resolver == nil {
res.Resolvers[resolverID] = nil idx, sg, err := getDefaultSamenessGroup(tx, ws, resolverID.PartitionOrDefault())
continue if err != nil {
return 0, nil, err
}
if idx > maxIdx {
maxIdx = idx
}
processSamenessGroup(sg, resolverID)
if resolverID == sid {
res.DefaultSamenessGroup = sg
} }
res.Resolvers[resolverID] = resolver continue
}
for _, svc := range resolver.ListRelatedServices() { for _, svc := range resolver.ListRelatedServices() {
todoResolvers[svc] = struct{}{} todoResolvers[svc] = struct{}{}
@ -1665,8 +1701,22 @@ func readDiscoveryChainConfigEntriesTxn(
todoPeers[peer] = struct{}{} todoPeers[peer] = struct{}{}
} }
// We fetch sameness groups here rather than in another loop because we need the resolvers
// for services in different partitions of the local datacenter.
for _, sg := range resolver.RelatedSamenessGroups() { for _, sg := range resolver.RelatedSamenessGroups() {
todoSamenessGroups[sg] = struct{}{} if _, ok := res.SamenessGroups[sg]; ok {
continue
}
idx, entry, err := getSamenessGroupConfigEntryTxn(tx, ws, sg, overrides, peerEntMeta.PartitionOrDefault())
if err != nil {
return 0, nil, err
}
if idx > maxIdx {
maxIdx = idx
}
processSamenessGroup(entry, resolverID)
} }
} }
@ -1709,42 +1759,6 @@ func readDiscoveryChainConfigEntriesTxn(
res.Services[svcID] = entry res.Services[svcID] = entry
} }
peerEntMeta := structs.DefaultEnterpriseMetaInPartition(entMeta.PartitionOrDefault())
for sg := range todoSamenessGroups {
idx, entry, err := getSamenessGroupConfigEntryTxn(tx, ws, sg, overrides, peerEntMeta.PartitionOrDefault())
if err != nil {
return 0, nil, err
}
if idx > maxIdx {
maxIdx = idx
}
if entry == nil {
continue
}
for _, peer := range entry.RelatedPeers() {
todoPeers[peer] = struct{}{}
}
res.SamenessGroups[sg] = entry
}
if r := res.Resolvers[sid]; r == nil {
idx, sg, err := getDefaultSamenessGroup(tx, ws, sid.PartitionOrDefault())
if err != nil {
return 0, nil, err
}
if idx > maxIdx {
maxIdx = idx
}
if sg != nil {
res.DefaultSamenessGroup = sg
res.SamenessGroups[sg.Name] = sg
for _, peer := range sg.RelatedPeers() {
todoPeers[peer] = struct{}{}
}
}
}
for peerName := range todoPeers { for peerName := range todoPeers {
q := Query{ q := Query{
Value: peerName, Value: peerName,

View File

@ -71,6 +71,6 @@ func (s *SamenessGroupConfigEntry) MarshalJSON() ([]byte, error) {
} }
type SamenessGroupMember struct { type SamenessGroupMember struct {
Partition string Partition string `json:",omitempty"`
Peer string Peer string `json:",omitempty"`
} }

View File

@ -16,8 +16,8 @@ type SamenessGroupConfigEntry struct {
} }
type SamenessGroupMember struct { type SamenessGroupMember struct {
Partition string Partition string `json:",omitempty"`
Peer string Peer string `json:",omitempty"`
} }
func (s *SamenessGroupConfigEntry) GetKind() string { return s.Kind } func (s *SamenessGroupConfigEntry) GetKind() string { return s.Kind }