diff --git a/agent/consul/state/catalog.go b/agent/consul/state/catalog.go index 2c92d7d58d..b8588f17cc 100644 --- a/agent/consul/state/catalog.go +++ b/agent/consul/state/catalog.go @@ -20,6 +20,7 @@ import ( "github.com/hashicorp/consul/api" "github.com/hashicorp/consul/lib" "github.com/hashicorp/consul/lib/maps" + "github.com/hashicorp/consul/lib/stringslice" "github.com/hashicorp/consul/types" ) @@ -1169,7 +1170,7 @@ func (s *Store) AssignManualServiceVIPs(idx uint64, psn structs.PeeredServiceNam newEntry := entry.(ServiceVirtualIP) // Check to see if the slice already contains the same ips. - if !vipSliceEqualsMapKeys(newEntry.ManualIPs, assignedIPs) { + if !stringslice.EqualMapKeys(newEntry.ManualIPs, assignedIPs) { newEntry.ManualIPs = slices.Clone(ips) newEntry.ModifyIndex = idx @@ -1193,18 +1194,6 @@ func (s *Store) AssignManualServiceVIPs(idx uint64, psn structs.PeeredServiceNam return true, maps.SliceOfKeys(modifiedEntries), nil } -func vipSliceEqualsMapKeys(a []string, b map[string]struct{}) bool { - if len(a) != len(b) { - return false - } - for _, ip := range a { - if _, ok := b[ip]; !ok { - return false - } - } - return true -} - func updateVirtualIPMaxIndexes(txn WriteTxn, idx uint64, partition, peerName string) error { // update global max index (for snapshots) if err := indexUpdateMaxTxn(txn, idx, tableServiceVirtualIPs); err != nil { diff --git a/lib/stringslice/stringslice.go b/lib/stringslice/stringslice.go index 7c32864b94..71e90dba2a 100644 --- a/lib/stringslice/stringslice.go +++ b/lib/stringslice/stringslice.go @@ -80,3 +80,17 @@ func CloneStringSlice(s []string) []string { copy(out, s) return out } + +// EqualMapKeys returns true if the slice equals the keys of +// the map ignoring any ordering. +func EqualMapKeys[V any](a []string, b map[string]V) bool { + if len(a) != len(b) { + return false + } + for _, ip := range a { + if _, ok := b[ip]; !ok { + return false + } + } + return true +} diff --git a/lib/stringslice/stringslice_test.go b/lib/stringslice/stringslice_test.go index dd25071757..b861d9c38a 100644 --- a/lib/stringslice/stringslice_test.go +++ b/lib/stringslice/stringslice_test.go @@ -63,3 +63,28 @@ func TestMergeSorted(t *testing.T) { }) } } + +func TestEqualMapKeys(t *testing.T) { + for _, tc := range []struct { + a []string + b map[string]int + same bool + }{ + // same + {nil, nil, true}, + {[]string{}, nil, true}, + {nil, map[string]int{}, true}, + {[]string{}, map[string]int{}, true}, + {[]string{"a"}, map[string]int{"a": 1}, true}, + {[]string{"b", "a"}, map[string]int{"a": 1, "b": 1}, true}, + // different + {[]string{"a"}, map[string]int{}, false}, + {[]string{}, map[string]int{"a": 1}, false}, + {[]string{"b", "a"}, map[string]int{"c": 1, "a": 1, "b": 1}, false}, + {[]string{"b", "a"}, map[string]int{"c": 1, "a": 1, "b": 1}, false}, + {[]string{"b", "a", "c"}, map[string]int{"a": 1, "b": 1}, false}, + } { + got := EqualMapKeys(tc.a, tc.b) + require.Equal(t, tc.same, got) + } +}