2023-03-28 18:39:22 +00:00
|
|
|
// Copyright (c) HashiCorp, Inc.
|
|
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
|
2021-11-16 18:04:01 +00:00
|
|
|
//go:build !consulent
|
2021-03-10 19:18:41 +00:00
|
|
|
// +build !consulent
|
|
|
|
|
|
|
|
package state
|
|
|
|
|
2022-02-22 16:36:36 +00:00
|
|
|
import (
|
2022-05-06 19:35:31 +00:00
|
|
|
"testing"
|
|
|
|
|
2022-04-05 21:10:06 +00:00
|
|
|
"github.com/hashicorp/consul/acl"
|
2022-02-22 16:36:36 +00:00
|
|
|
"github.com/hashicorp/consul/agent/configentry"
|
|
|
|
"github.com/hashicorp/consul/agent/structs"
|
2022-05-06 19:35:31 +00:00
|
|
|
"github.com/stretchr/testify/require"
|
2022-02-22 16:36:36 +00:00
|
|
|
)
|
2021-03-10 19:18:41 +00:00
|
|
|
|
|
|
|
func testIndexerTableConfigEntries() map[string]indexerTestCase {
|
|
|
|
return map[string]indexerTestCase{
|
|
|
|
indexID: {
|
|
|
|
read: indexValue{
|
2022-02-22 16:36:36 +00:00
|
|
|
source: configentry.KindName{
|
2021-03-10 19:18:41 +00:00
|
|
|
Kind: "Proxy-Defaults",
|
|
|
|
Name: "NaMe",
|
|
|
|
},
|
|
|
|
expected: []byte("proxy-defaults\x00name\x00"),
|
|
|
|
},
|
|
|
|
write: indexValue{
|
|
|
|
source: &structs.ProxyConfigEntry{Name: "NaMe"},
|
|
|
|
expected: []byte("proxy-defaults\x00name\x00"),
|
|
|
|
},
|
2021-03-31 20:21:21 +00:00
|
|
|
prefix: []indexValue{
|
|
|
|
{
|
2022-04-05 21:10:06 +00:00
|
|
|
source: acl.EnterpriseMeta{},
|
2021-03-31 20:21:21 +00:00
|
|
|
expected: nil,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
source: ConfigEntryKindQuery{Kind: "Proxy-Defaults"},
|
|
|
|
expected: []byte("proxy-defaults\x00"),
|
2021-03-10 19:18:41 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
2022-05-06 19:35:31 +00:00
|
|
|
|
2022-05-23 16:16:39 +00:00
|
|
|
func TestStore_peersForService(t *testing.T) {
|
|
|
|
queryName := "foo"
|
|
|
|
|
2022-05-06 19:35:31 +00:00
|
|
|
type testCase struct {
|
|
|
|
name string
|
2022-05-23 16:16:39 +00:00
|
|
|
write structs.ConfigEntry
|
|
|
|
expect []string
|
2022-05-06 19:35:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
cases := []testCase{
|
|
|
|
{
|
|
|
|
name: "empty everything",
|
2022-05-23 16:16:39 +00:00
|
|
|
expect: nil,
|
2022-05-06 19:35:31 +00:00
|
|
|
},
|
|
|
|
{
|
2022-05-23 16:16:39 +00:00
|
|
|
name: "service is not exported",
|
|
|
|
write: &structs.ExportedServicesConfigEntry{
|
|
|
|
Name: "default",
|
|
|
|
Services: []structs.ExportedService{
|
|
|
|
{
|
|
|
|
Name: "not-" + queryName,
|
|
|
|
Consumers: []structs.ServiceConsumer{
|
|
|
|
{
|
2022-10-04 18:46:15 +00:00
|
|
|
Peer: "zip",
|
2022-05-23 16:16:39 +00:00
|
|
|
},
|
|
|
|
},
|
2022-05-06 19:35:31 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2022-05-23 16:16:39 +00:00
|
|
|
expect: nil,
|
2022-05-06 19:35:31 +00:00
|
|
|
},
|
|
|
|
{
|
2022-05-23 16:16:39 +00:00
|
|
|
name: "wildcard name matches",
|
|
|
|
write: &structs.ExportedServicesConfigEntry{
|
|
|
|
Name: "default",
|
|
|
|
Services: []structs.ExportedService{
|
|
|
|
{
|
|
|
|
Name: "not-" + queryName,
|
|
|
|
Consumers: []structs.ServiceConsumer{
|
|
|
|
{
|
2022-10-04 18:46:15 +00:00
|
|
|
Peer: "zip",
|
2022-05-23 16:16:39 +00:00
|
|
|
},
|
|
|
|
},
|
2022-05-06 19:35:31 +00:00
|
|
|
},
|
2022-05-23 16:16:39 +00:00
|
|
|
{
|
|
|
|
Name: structs.WildcardSpecifier,
|
|
|
|
Consumers: []structs.ServiceConsumer{
|
|
|
|
{
|
2022-10-04 18:46:15 +00:00
|
|
|
Peer: "bar",
|
2022-05-23 16:16:39 +00:00
|
|
|
},
|
|
|
|
{
|
2022-10-04 18:46:15 +00:00
|
|
|
Peer: "baz",
|
2022-05-23 16:16:39 +00:00
|
|
|
},
|
|
|
|
},
|
2022-05-06 19:35:31 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2022-05-23 16:16:39 +00:00
|
|
|
expect: []string{"bar", "baz"},
|
2022-05-06 19:35:31 +00:00
|
|
|
},
|
|
|
|
{
|
2022-05-23 16:16:39 +00:00
|
|
|
name: "exact name takes precedence over wildcard",
|
|
|
|
write: &structs.ExportedServicesConfigEntry{
|
|
|
|
Name: "default",
|
|
|
|
Services: []structs.ExportedService{
|
|
|
|
{
|
|
|
|
Name: queryName,
|
|
|
|
Consumers: []structs.ServiceConsumer{
|
|
|
|
{
|
2022-10-04 18:46:15 +00:00
|
|
|
Peer: "baz",
|
2022-05-23 16:16:39 +00:00
|
|
|
},
|
|
|
|
},
|
2022-05-06 19:35:31 +00:00
|
|
|
},
|
2022-05-23 16:16:39 +00:00
|
|
|
{
|
|
|
|
Name: structs.WildcardSpecifier,
|
|
|
|
Consumers: []structs.ServiceConsumer{
|
|
|
|
{
|
2022-10-04 18:46:15 +00:00
|
|
|
Peer: "zip",
|
2022-05-23 16:16:39 +00:00
|
|
|
},
|
|
|
|
},
|
2022-05-06 19:35:31 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2022-05-23 16:16:39 +00:00
|
|
|
expect: []string{"baz"},
|
2022-05-06 19:35:31 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range cases {
|
|
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
|
|
s := testStateStore(t)
|
2022-05-23 16:16:39 +00:00
|
|
|
var lastIdx uint64
|
|
|
|
|
|
|
|
// Write the entry.
|
|
|
|
if tc.write != nil {
|
|
|
|
require.NoError(t, tc.write.Normalize())
|
|
|
|
require.NoError(t, tc.write.Validate())
|
2022-05-06 19:35:31 +00:00
|
|
|
|
2022-05-23 16:16:39 +00:00
|
|
|
lastIdx++
|
|
|
|
require.NoError(t, s.EnsureConfigEntry(lastIdx, tc.write))
|
2022-05-06 19:35:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Read the entries back.
|
|
|
|
tx := s.db.ReadTxn()
|
|
|
|
defer tx.Abort()
|
2022-05-23 16:16:39 +00:00
|
|
|
|
|
|
|
idx, peers, err := peersForServiceTxn(tx, nil, queryName, acl.DefaultEnterpriseMeta())
|
2022-05-06 19:35:31 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
2022-05-23 16:16:39 +00:00
|
|
|
// This is a little weird, but when there are no results, the index returned should be the max index for the
|
|
|
|
// config entries table so that the caller can watch for changes to it
|
|
|
|
if len(peers) == 0 {
|
|
|
|
require.Equal(t, maxIndexTxn(tx, tableConfigEntries), idx)
|
|
|
|
} else {
|
|
|
|
require.Equal(t, lastIdx, idx)
|
2022-05-06 19:35:31 +00:00
|
|
|
}
|
2022-05-23 16:16:39 +00:00
|
|
|
|
|
|
|
// Verify the result.
|
|
|
|
require.Len(t, peers, len(tc.expect))
|
|
|
|
require.Equal(t, tc.expect, peers)
|
2022-05-06 19:35:31 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|