Make memdb indexers generic (#13558)
We have many indexer functions in Consul which take interface{} and type assert before building the index. We can use generics to get rid of the initial plumbing and pass around functions with better defined signatures. This has two benefits: 1) Less verbosity; 2) Developers can parse the argument types to memdb schemas without having to introspect the function for the type assertion.
This commit is contained in:
parent
dc19b9f46f
commit
aaf3c051f2
|
@ -7,7 +7,7 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
memdb "github.com/hashicorp/go-memdb"
|
||||
"github.com/hashicorp/go-memdb"
|
||||
|
||||
"github.com/hashicorp/consul/acl"
|
||||
"github.com/hashicorp/consul/agent/structs"
|
||||
|
@ -209,18 +209,13 @@ func (s *Store) ACLAuthMethodUpsertValidateEnterprise(method *structs.ACLAuthMet
|
|||
return nil
|
||||
}
|
||||
|
||||
func indexAuthMethodFromACLToken(raw interface{}) ([]byte, error) {
|
||||
p, ok := raw.(*structs.ACLToken)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T for structs.ACLToken index", raw)
|
||||
}
|
||||
|
||||
if p.AuthMethod == "" {
|
||||
func indexAuthMethodFromACLToken(t *structs.ACLToken) ([]byte, error) {
|
||||
if t.AuthMethod == "" {
|
||||
return nil, errMissingValueForIndex
|
||||
}
|
||||
|
||||
var b indexBuilder
|
||||
b.String(strings.ToLower(p.AuthMethod))
|
||||
b.String(strings.ToLower(t.AuthMethod))
|
||||
|
||||
return b.Bytes(), nil
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ import (
|
|||
|
||||
"github.com/hashicorp/go-memdb"
|
||||
|
||||
"github.com/hashicorp/consul/acl"
|
||||
"github.com/hashicorp/consul/agent/structs"
|
||||
)
|
||||
|
||||
|
@ -36,18 +35,18 @@ func tokensTableSchema() *memdb.TableSchema {
|
|||
// DEPRECATED (ACL-Legacy-Compat) - we should not AllowMissing here once legacy compat is removed
|
||||
AllowMissing: true,
|
||||
Unique: true,
|
||||
Indexer: indexerSingle{
|
||||
readIndex: readIndex(indexFromUUIDString),
|
||||
writeIndex: writeIndex(indexAccessorIDFromACLToken),
|
||||
Indexer: indexerSingle[string, *structs.ACLToken]{
|
||||
readIndex: indexFromUUIDString,
|
||||
writeIndex: indexAccessorIDFromACLToken,
|
||||
},
|
||||
},
|
||||
indexID: {
|
||||
Name: indexID,
|
||||
AllowMissing: false,
|
||||
Unique: true,
|
||||
Indexer: indexerSingle{
|
||||
readIndex: readIndex(indexFromStringCaseSensitive),
|
||||
writeIndex: writeIndex(indexSecretIDFromACLToken),
|
||||
Indexer: indexerSingle[string, *structs.ACLToken]{
|
||||
readIndex: indexFromStringCaseSensitive,
|
||||
writeIndex: indexSecretIDFromACLToken,
|
||||
},
|
||||
},
|
||||
indexPolicies: {
|
||||
|
@ -55,58 +54,58 @@ func tokensTableSchema() *memdb.TableSchema {
|
|||
// Need to allow missing for the anonymous token
|
||||
AllowMissing: true,
|
||||
Unique: false,
|
||||
Indexer: indexerMulti{
|
||||
readIndex: readIndex(indexFromUUIDQuery),
|
||||
writeIndexMulti: writeIndexMulti(indexPoliciesFromACLToken),
|
||||
Indexer: indexerMulti[Query, *structs.ACLToken]{
|
||||
readIndex: indexFromUUIDQuery,
|
||||
writeIndexMulti: indexPoliciesFromACLToken,
|
||||
},
|
||||
},
|
||||
indexRoles: {
|
||||
Name: indexRoles,
|
||||
AllowMissing: true,
|
||||
Unique: false,
|
||||
Indexer: indexerMulti{
|
||||
readIndex: readIndex(indexFromUUIDQuery),
|
||||
writeIndexMulti: writeIndexMulti(indexRolesFromACLToken),
|
||||
Indexer: indexerMulti[Query, *structs.ACLToken]{
|
||||
readIndex: indexFromUUIDQuery,
|
||||
writeIndexMulti: indexRolesFromACLToken,
|
||||
},
|
||||
},
|
||||
indexAuthMethod: {
|
||||
Name: indexAuthMethod,
|
||||
AllowMissing: true,
|
||||
Unique: false,
|
||||
Indexer: indexerSingle{
|
||||
readIndex: readIndex(indexFromAuthMethodQuery),
|
||||
writeIndex: writeIndex(indexAuthMethodFromACLToken),
|
||||
Indexer: indexerSingle[AuthMethodQuery, *structs.ACLToken]{
|
||||
readIndex: indexFromAuthMethodQuery,
|
||||
writeIndex: indexAuthMethodFromACLToken,
|
||||
},
|
||||
},
|
||||
indexLocality: {
|
||||
Name: indexLocality,
|
||||
AllowMissing: false,
|
||||
Unique: false,
|
||||
Indexer: indexerSingle{
|
||||
readIndex: readIndex(indexFromBoolQuery),
|
||||
writeIndex: writeIndex(indexLocalFromACLToken),
|
||||
Indexer: indexerSingle[BoolQuery, *structs.ACLToken]{
|
||||
readIndex: indexFromBoolQuery,
|
||||
writeIndex: indexLocalFromACLToken,
|
||||
},
|
||||
},
|
||||
indexExpiresGlobal: {
|
||||
Name: indexExpiresGlobal,
|
||||
AllowMissing: true,
|
||||
Unique: false,
|
||||
Indexer: indexerSingle{
|
||||
readIndex: readIndex(indexFromTimeQuery),
|
||||
writeIndex: writeIndex(indexExpiresGlobalFromACLToken),
|
||||
Indexer: indexerSingle[*TimeQuery, *structs.ACLToken]{
|
||||
readIndex: indexFromTimeQuery,
|
||||
writeIndex: indexExpiresGlobalFromACLToken,
|
||||
},
|
||||
},
|
||||
indexExpiresLocal: {
|
||||
Name: indexExpiresLocal,
|
||||
AllowMissing: true,
|
||||
Unique: false,
|
||||
Indexer: indexerSingle{
|
||||
readIndex: readIndex(indexFromTimeQuery),
|
||||
writeIndex: writeIndex(indexExpiresLocalFromACLToken),
|
||||
Indexer: indexerSingle[*TimeQuery, *structs.ACLToken]{
|
||||
readIndex: indexFromTimeQuery,
|
||||
writeIndex: indexExpiresLocalFromACLToken,
|
||||
},
|
||||
},
|
||||
|
||||
//DEPRECATED (ACL-Legacy-Compat) - This index is only needed while we support upgrading v1 to v2 acls
|
||||
// DEPRECATED (ACL-Legacy-Compat) - This index is only needed while we support upgrading v1 to v2 acls
|
||||
// This table indexes all the ACL tokens that do not have an AccessorID
|
||||
// TODO(ACL-Legacy-Compat): remove in phase 2
|
||||
"needs-upgrade": {
|
||||
|
@ -142,7 +141,7 @@ func policiesTableSchema() *memdb.TableSchema {
|
|||
Name: indexName,
|
||||
AllowMissing: false,
|
||||
Unique: true,
|
||||
Indexer: indexerSingleWithPrefix{
|
||||
Indexer: indexerSingleWithPrefix[Query, *structs.ACLPolicy, any]{
|
||||
readIndex: indexFromQuery,
|
||||
writeIndex: indexNameFromACLPolicy,
|
||||
prefixIndex: prefixIndexFromQuery,
|
||||
|
@ -152,12 +151,7 @@ func policiesTableSchema() *memdb.TableSchema {
|
|||
}
|
||||
}
|
||||
|
||||
func indexNameFromACLPolicy(raw interface{}) ([]byte, error) {
|
||||
p, ok := raw.(*structs.ACLPolicy)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T for structs.ACLPolicy index", raw)
|
||||
}
|
||||
|
||||
func indexNameFromACLPolicy(p *structs.ACLPolicy) ([]byte, error) {
|
||||
if p.Name == "" {
|
||||
return nil, errMissingValueForIndex
|
||||
}
|
||||
|
@ -183,7 +177,7 @@ func rolesTableSchema() *memdb.TableSchema {
|
|||
Name: indexName,
|
||||
AllowMissing: false,
|
||||
Unique: true,
|
||||
Indexer: indexerSingleWithPrefix{
|
||||
Indexer: indexerSingleWithPrefix[Query, *structs.ACLRole, any]{
|
||||
readIndex: indexFromQuery,
|
||||
writeIndex: indexNameFromACLRole,
|
||||
prefixIndex: prefixIndexFromQuery,
|
||||
|
@ -194,7 +188,7 @@ func rolesTableSchema() *memdb.TableSchema {
|
|||
// Need to allow missing for the anonymous token
|
||||
AllowMissing: true,
|
||||
Unique: false,
|
||||
Indexer: indexerMulti{
|
||||
Indexer: indexerMulti[Query, *structs.ACLRole]{
|
||||
readIndex: indexFromUUIDQuery,
|
||||
writeIndexMulti: multiIndexPolicyFromACLRole,
|
||||
},
|
||||
|
@ -203,75 +197,43 @@ func rolesTableSchema() *memdb.TableSchema {
|
|||
}
|
||||
}
|
||||
|
||||
func indexNameFromACLRole(raw interface{}) ([]byte, error) {
|
||||
p, ok := raw.(*structs.ACLRole)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T for structs.ACLRole index", raw)
|
||||
}
|
||||
|
||||
if p.Name == "" {
|
||||
func indexNameFromACLRole(r *structs.ACLRole) ([]byte, error) {
|
||||
if r.Name == "" {
|
||||
return nil, errMissingValueForIndex
|
||||
}
|
||||
|
||||
var b indexBuilder
|
||||
b.String(strings.ToLower(p.Name))
|
||||
b.String(strings.ToLower(r.Name))
|
||||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
func indexFromUUIDQuery(raw interface{}) ([]byte, error) {
|
||||
q, ok := raw.(Query)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T for UUIDQuery index", raw)
|
||||
}
|
||||
func indexFromUUIDQuery(q Query) ([]byte, error) {
|
||||
return uuidStringToBytes(q.Value)
|
||||
}
|
||||
|
||||
func prefixIndexFromUUIDQuery(arg interface{}) ([]byte, error) {
|
||||
switch v := arg.(type) {
|
||||
case *acl.EnterpriseMeta:
|
||||
return nil, nil
|
||||
case acl.EnterpriseMeta:
|
||||
return nil, nil
|
||||
case Query:
|
||||
return variableLengthUUIDStringToBytes(v.Value)
|
||||
func prefixIndexFromUUIDWithPeerQuery(q Query) ([]byte, error) {
|
||||
var b indexBuilder
|
||||
peername := q.PeerOrEmpty()
|
||||
if peername == "" {
|
||||
b.String(structs.LocalPeerKeyword)
|
||||
} else {
|
||||
b.String(strings.ToLower(peername))
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("unexpected type %T for Query prefix index", arg)
|
||||
uuidBytes, err := variableLengthUUIDStringToBytes(q.Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return append(b.Bytes(), uuidBytes...), nil
|
||||
}
|
||||
|
||||
func prefixIndexFromUUIDWithPeerQuery(arg interface{}) ([]byte, error) {
|
||||
switch v := arg.(type) {
|
||||
case Query:
|
||||
var b indexBuilder
|
||||
peername := v.PeerOrEmpty()
|
||||
if peername == "" {
|
||||
b.String(structs.LocalPeerKeyword)
|
||||
} else {
|
||||
b.String(strings.ToLower(peername))
|
||||
}
|
||||
uuidBytes, err := variableLengthUUIDStringToBytes(v.Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return append(b.Bytes(), uuidBytes...), nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("unexpected type %T for Query prefix index", arg)
|
||||
}
|
||||
|
||||
func multiIndexPolicyFromACLRole(raw interface{}) ([][]byte, error) {
|
||||
role, ok := raw.(*structs.ACLRole)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T for structs.ACLRole index", raw)
|
||||
}
|
||||
|
||||
count := len(role.Policies)
|
||||
func multiIndexPolicyFromACLRole(r *structs.ACLRole) ([][]byte, error) {
|
||||
count := len(r.Policies)
|
||||
if count == 0 {
|
||||
return nil, errMissingValueForIndex
|
||||
}
|
||||
|
||||
vals := make([][]byte, 0, count)
|
||||
for _, link := range role.Policies {
|
||||
for _, link := range r.Policies {
|
||||
v, err := uuidStringToBytes(link.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -290,16 +252,16 @@ func bindingRulesTableSchema() *memdb.TableSchema {
|
|||
Name: indexID,
|
||||
AllowMissing: false,
|
||||
Unique: true,
|
||||
Indexer: indexerSingle{
|
||||
readIndex: readIndex(indexFromUUIDString),
|
||||
writeIndex: writeIndex(indexIDFromACLBindingRule),
|
||||
Indexer: indexerSingle[string, *structs.ACLBindingRule]{
|
||||
readIndex: indexFromUUIDString,
|
||||
writeIndex: indexIDFromACLBindingRule,
|
||||
},
|
||||
},
|
||||
indexAuthMethod: {
|
||||
Name: indexAuthMethod,
|
||||
AllowMissing: false,
|
||||
Unique: false,
|
||||
Indexer: indexerSingle{
|
||||
Indexer: indexerSingle[Query, *structs.ACLBindingRule]{
|
||||
readIndex: indexFromQuery,
|
||||
writeIndex: indexAuthMethodFromACLBindingRule,
|
||||
},
|
||||
|
@ -308,12 +270,8 @@ func bindingRulesTableSchema() *memdb.TableSchema {
|
|||
}
|
||||
}
|
||||
|
||||
func indexIDFromACLBindingRule(raw interface{}) ([]byte, error) {
|
||||
p, ok := raw.(*structs.ACLBindingRule)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T for structs.ACLBindingRule index", raw)
|
||||
}
|
||||
vv, err := uuidStringToBytes(p.ID)
|
||||
func indexIDFromACLBindingRule(r *structs.ACLBindingRule) ([]byte, error) {
|
||||
vv, err := uuidStringToBytes(r.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -321,27 +279,18 @@ func indexIDFromACLBindingRule(raw interface{}) ([]byte, error) {
|
|||
return vv, err
|
||||
}
|
||||
|
||||
func indexAuthMethodFromACLBindingRule(raw interface{}) ([]byte, error) {
|
||||
p, ok := raw.(*structs.ACLBindingRule)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T for structs.ACLBindingRule index", raw)
|
||||
}
|
||||
|
||||
if p.AuthMethod == "" {
|
||||
func indexAuthMethodFromACLBindingRule(r *structs.ACLBindingRule) ([]byte, error) {
|
||||
if r.AuthMethod == "" {
|
||||
return nil, errMissingValueForIndex
|
||||
}
|
||||
|
||||
var b indexBuilder
|
||||
b.String(strings.ToLower(p.AuthMethod))
|
||||
b.String(strings.ToLower(r.AuthMethod))
|
||||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
func indexFromUUIDString(raw interface{}) ([]byte, error) {
|
||||
index, ok := raw.(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T for UUID string index", raw)
|
||||
}
|
||||
uuid, err := uuidStringToBytes(index)
|
||||
func indexFromUUIDString(raw string) ([]byte, error) {
|
||||
uuid, err := uuidStringToBytes(raw)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -350,17 +299,12 @@ func indexFromUUIDString(raw interface{}) ([]byte, error) {
|
|||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
func indexAccessorIDFromACLToken(raw interface{}) ([]byte, error) {
|
||||
p, ok := raw.(*structs.ACLToken)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T for structs.ACLToken index", raw)
|
||||
}
|
||||
|
||||
if p.AccessorID == "" {
|
||||
func indexAccessorIDFromACLToken(t *structs.ACLToken) ([]byte, error) {
|
||||
if t.AccessorID == "" {
|
||||
return nil, errMissingValueForIndex
|
||||
}
|
||||
|
||||
uuid, err := uuidStringToBytes(p.AccessorID)
|
||||
uuid, err := uuidStringToBytes(t.AccessorID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -369,37 +313,23 @@ func indexAccessorIDFromACLToken(raw interface{}) ([]byte, error) {
|
|||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
func indexSecretIDFromACLToken(raw interface{}) ([]byte, error) {
|
||||
p, ok := raw.(*structs.ACLToken)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T for structs.ACLToken index", raw)
|
||||
}
|
||||
|
||||
if p.SecretID == "" {
|
||||
func indexSecretIDFromACLToken(t *structs.ACLToken) ([]byte, error) {
|
||||
if t.SecretID == "" {
|
||||
return nil, errMissingValueForIndex
|
||||
}
|
||||
|
||||
var b indexBuilder
|
||||
b.String(p.SecretID)
|
||||
b.String(t.SecretID)
|
||||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
func indexFromStringCaseSensitive(raw interface{}) ([]byte, error) {
|
||||
q, ok := raw.(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T for string prefix query", raw)
|
||||
}
|
||||
|
||||
func indexFromStringCaseSensitive(s string) ([]byte, error) {
|
||||
var b indexBuilder
|
||||
b.String(q)
|
||||
b.String(s)
|
||||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
func indexPoliciesFromACLToken(raw interface{}) ([][]byte, error) {
|
||||
token, ok := raw.(*structs.ACLToken)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T for structs.ACLToken index", raw)
|
||||
}
|
||||
func indexPoliciesFromACLToken(token *structs.ACLToken) ([][]byte, error) {
|
||||
links := token.Policies
|
||||
|
||||
numLinks := len(links)
|
||||
|
@ -420,11 +350,7 @@ func indexPoliciesFromACLToken(raw interface{}) ([][]byte, error) {
|
|||
return vals, nil
|
||||
}
|
||||
|
||||
func indexRolesFromACLToken(raw interface{}) ([][]byte, error) {
|
||||
token, ok := raw.(*structs.ACLToken)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T for structs.ACLToken index", raw)
|
||||
}
|
||||
func indexRolesFromACLToken(token *structs.ACLToken) ([][]byte, error) {
|
||||
links := token.Roles
|
||||
|
||||
numLinks := len(links)
|
||||
|
@ -445,63 +371,45 @@ func indexRolesFromACLToken(raw interface{}) ([][]byte, error) {
|
|||
return vals, nil
|
||||
}
|
||||
|
||||
func indexFromBoolQuery(raw interface{}) ([]byte, error) {
|
||||
q, ok := raw.(BoolQuery)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T for BoolQuery index", raw)
|
||||
}
|
||||
func indexFromBoolQuery(q BoolQuery) ([]byte, error) {
|
||||
var b indexBuilder
|
||||
b.Bool(q.Value)
|
||||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
func indexLocalFromACLToken(raw interface{}) ([]byte, error) {
|
||||
p, ok := raw.(*structs.ACLToken)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T for structs.ACLPolicy index", raw)
|
||||
}
|
||||
|
||||
func indexLocalFromACLToken(token *structs.ACLToken) ([]byte, error) {
|
||||
var b indexBuilder
|
||||
b.Bool(p.Local)
|
||||
b.Bool(token.Local)
|
||||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
func indexFromTimeQuery(arg interface{}) ([]byte, error) {
|
||||
p, ok := arg.(*TimeQuery)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T for TimeQuery index", arg)
|
||||
}
|
||||
|
||||
func indexFromTimeQuery(q *TimeQuery) ([]byte, error) {
|
||||
var b indexBuilder
|
||||
b.Time(p.Value)
|
||||
b.Time(q.Value)
|
||||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
func indexExpiresLocalFromACLToken(raw interface{}) ([]byte, error) {
|
||||
return indexExpiresFromACLToken(raw, true)
|
||||
func indexExpiresLocalFromACLToken(token *structs.ACLToken) ([]byte, error) {
|
||||
return indexExpiresFromACLToken(token, true)
|
||||
}
|
||||
|
||||
func indexExpiresGlobalFromACLToken(raw interface{}) ([]byte, error) {
|
||||
return indexExpiresFromACLToken(raw, false)
|
||||
func indexExpiresGlobalFromACLToken(token *structs.ACLToken) ([]byte, error) {
|
||||
return indexExpiresFromACLToken(token, false)
|
||||
}
|
||||
|
||||
func indexExpiresFromACLToken(raw interface{}, local bool) ([]byte, error) {
|
||||
p, ok := raw.(*structs.ACLToken)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T for structs.ACLToken index", raw)
|
||||
}
|
||||
if p.Local != local {
|
||||
func indexExpiresFromACLToken(t *structs.ACLToken, local bool) ([]byte, error) {
|
||||
if t.Local != local {
|
||||
return nil, errMissingValueForIndex
|
||||
}
|
||||
if !p.HasExpirationTime() {
|
||||
if !t.HasExpirationTime() {
|
||||
return nil, errMissingValueForIndex
|
||||
}
|
||||
if p.ExpirationTime.Unix() < 0 {
|
||||
return nil, fmt.Errorf("token expiration time cannot be before the unix epoch: %s", p.ExpirationTime)
|
||||
if t.ExpirationTime.Unix() < 0 {
|
||||
return nil, fmt.Errorf("token expiration time cannot be before the unix epoch: %s", t.ExpirationTime)
|
||||
}
|
||||
|
||||
var b indexBuilder
|
||||
b.Time(*p.ExpirationTime)
|
||||
b.Time(*t.ExpirationTime)
|
||||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
|
@ -513,7 +421,7 @@ func authMethodsTableSchema() *memdb.TableSchema {
|
|||
Name: indexID,
|
||||
AllowMissing: false,
|
||||
Unique: true,
|
||||
Indexer: indexerSingle{
|
||||
Indexer: indexerSingle[Query, *structs.ACLAuthMethod]{
|
||||
readIndex: indexFromQuery,
|
||||
writeIndex: indexNameFromACLAuthMethod,
|
||||
},
|
||||
|
@ -522,17 +430,12 @@ func authMethodsTableSchema() *memdb.TableSchema {
|
|||
}
|
||||
}
|
||||
|
||||
func indexNameFromACLAuthMethod(raw interface{}) ([]byte, error) {
|
||||
p, ok := raw.(*structs.ACLAuthMethod)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T for structs.ACLAuthMethod index", raw)
|
||||
}
|
||||
|
||||
if p.Name == "" {
|
||||
func indexNameFromACLAuthMethod(m *structs.ACLAuthMethod) ([]byte, error) {
|
||||
if m.Name == "" {
|
||||
return nil, errMissingValueForIndex
|
||||
}
|
||||
|
||||
var b indexBuilder
|
||||
b.String(strings.ToLower(p.Name))
|
||||
b.String(strings.ToLower(m.Name))
|
||||
return b.Bytes(), nil
|
||||
}
|
||||
|
|
|
@ -7,14 +7,14 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
memdb "github.com/hashicorp/go-memdb"
|
||||
"github.com/hashicorp/go-memdb"
|
||||
"github.com/hashicorp/go-uuid"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/hashicorp/consul/acl"
|
||||
"github.com/hashicorp/consul/agent/structs"
|
||||
"github.com/hashicorp/consul/lib"
|
||||
pbacl "github.com/hashicorp/consul/proto/pbacl"
|
||||
"github.com/hashicorp/consul/proto/pbacl"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -3702,18 +3702,18 @@ func TestTokenPoliciesIndex(t *testing.T) {
|
|||
Name: "global",
|
||||
AllowMissing: true,
|
||||
Unique: false,
|
||||
Indexer: indexerSingle{
|
||||
readIndex: readIndex(indexFromTimeQuery),
|
||||
writeIndex: writeIndex(indexExpiresGlobalFromACLToken),
|
||||
Indexer: indexerSingle[*TimeQuery, *structs.ACLToken]{
|
||||
readIndex: indexFromTimeQuery,
|
||||
writeIndex: indexExpiresGlobalFromACLToken,
|
||||
},
|
||||
}
|
||||
localIndex := &memdb.IndexSchema{
|
||||
Name: "local",
|
||||
AllowMissing: true,
|
||||
Unique: false,
|
||||
Indexer: indexerSingle{
|
||||
readIndex: readIndex(indexFromTimeQuery),
|
||||
writeIndex: writeIndex(indexExpiresLocalFromACLToken),
|
||||
Indexer: indexerSingle[*TimeQuery, *structs.ACLToken]{
|
||||
readIndex: indexFromTimeQuery,
|
||||
writeIndex: indexExpiresLocalFromACLToken,
|
||||
},
|
||||
}
|
||||
schema := &memdb.DBSchema{
|
||||
|
|
|
@ -47,7 +47,7 @@ func nodesTableSchema() *memdb.TableSchema {
|
|||
Name: indexID,
|
||||
AllowMissing: false,
|
||||
Unique: true,
|
||||
Indexer: indexerSingleWithPrefix{
|
||||
Indexer: indexerSingleWithPrefix[Query, *structs.Node, any]{
|
||||
readIndex: indexWithPeerName(indexFromQuery),
|
||||
writeIndex: indexWithPeerName(indexFromNode),
|
||||
prefixIndex: prefixIndexFromQueryWithPeer,
|
||||
|
@ -57,7 +57,7 @@ func nodesTableSchema() *memdb.TableSchema {
|
|||
Name: indexUUID,
|
||||
AllowMissing: true,
|
||||
Unique: true,
|
||||
Indexer: indexerSingleWithPrefix{
|
||||
Indexer: indexerSingleWithPrefix[Query, *structs.Node, Query]{
|
||||
readIndex: indexWithPeerName(indexFromUUIDQuery),
|
||||
writeIndex: indexWithPeerName(indexIDFromNode),
|
||||
prefixIndex: prefixIndexFromUUIDWithPeerQuery,
|
||||
|
@ -67,7 +67,7 @@ func nodesTableSchema() *memdb.TableSchema {
|
|||
Name: indexMeta,
|
||||
AllowMissing: true,
|
||||
Unique: false,
|
||||
Indexer: indexerMulti{
|
||||
Indexer: indexerMulti[KeyValueQuery, *structs.Node]{
|
||||
readIndex: indexWithPeerName(indexFromKeyValueQuery),
|
||||
writeIndexMulti: multiIndexWithPeerName(indexMetaFromNode),
|
||||
},
|
||||
|
@ -76,12 +76,7 @@ func nodesTableSchema() *memdb.TableSchema {
|
|||
}
|
||||
}
|
||||
|
||||
func indexFromNode(raw interface{}) ([]byte, error) {
|
||||
n, ok := raw.(*structs.Node)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T for structs.Node index", raw)
|
||||
}
|
||||
|
||||
func indexFromNode(n *structs.Node) ([]byte, error) {
|
||||
if n.Node == "" {
|
||||
return nil, errMissingValueForIndex
|
||||
}
|
||||
|
@ -91,12 +86,7 @@ func indexFromNode(raw interface{}) ([]byte, error) {
|
|||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
func indexIDFromNode(raw interface{}) ([]byte, error) {
|
||||
n, ok := raw.(*structs.Node)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T for structs.Node index", raw)
|
||||
}
|
||||
|
||||
func indexIDFromNode(n *structs.Node) ([]byte, error) {
|
||||
if n.ID == "" {
|
||||
return nil, errMissingValueForIndex
|
||||
}
|
||||
|
@ -109,12 +99,7 @@ func indexIDFromNode(raw interface{}) ([]byte, error) {
|
|||
return v, nil
|
||||
}
|
||||
|
||||
func indexMetaFromNode(raw interface{}) ([][]byte, error) {
|
||||
n, ok := raw.(*structs.Node)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T for structs.Node index", raw)
|
||||
}
|
||||
|
||||
func indexMetaFromNode(n *structs.Node) ([][]byte, error) {
|
||||
// NOTE: this is case-sensitive!
|
||||
|
||||
vals := make([][]byte, 0, len(n.Meta))
|
||||
|
@ -145,7 +130,7 @@ func servicesTableSchema() *memdb.TableSchema {
|
|||
Name: indexID,
|
||||
AllowMissing: false,
|
||||
Unique: true,
|
||||
Indexer: indexerSingleWithPrefix{
|
||||
Indexer: indexerSingleWithPrefix[NodeServiceQuery, *structs.ServiceNode, any]{
|
||||
readIndex: indexWithPeerName(indexFromNodeServiceQuery),
|
||||
writeIndex: indexWithPeerName(indexFromServiceNode),
|
||||
prefixIndex: prefixIndexFromQueryWithPeer,
|
||||
|
@ -155,7 +140,7 @@ func servicesTableSchema() *memdb.TableSchema {
|
|||
Name: indexNode,
|
||||
AllowMissing: false,
|
||||
Unique: false,
|
||||
Indexer: indexerSingle{
|
||||
Indexer: indexerSingle[Query, nodeIdentifier]{
|
||||
readIndex: indexWithPeerName(indexFromQuery),
|
||||
writeIndex: indexWithPeerName(indexFromNodeIdentity),
|
||||
},
|
||||
|
@ -164,7 +149,7 @@ func servicesTableSchema() *memdb.TableSchema {
|
|||
Name: indexService,
|
||||
AllowMissing: true,
|
||||
Unique: false,
|
||||
Indexer: indexerSingle{
|
||||
Indexer: indexerSingle[Query, *structs.ServiceNode]{
|
||||
readIndex: indexWithPeerName(indexFromQuery),
|
||||
writeIndex: indexWithPeerName(indexServiceNameFromServiceNode),
|
||||
},
|
||||
|
@ -173,7 +158,7 @@ func servicesTableSchema() *memdb.TableSchema {
|
|||
Name: indexConnect,
|
||||
AllowMissing: true,
|
||||
Unique: false,
|
||||
Indexer: indexerSingle{
|
||||
Indexer: indexerSingle[Query, *structs.ServiceNode]{
|
||||
readIndex: indexWithPeerName(indexFromQuery),
|
||||
writeIndex: indexWithPeerName(indexConnectNameFromServiceNode),
|
||||
},
|
||||
|
@ -182,7 +167,7 @@ func servicesTableSchema() *memdb.TableSchema {
|
|||
Name: indexKind,
|
||||
AllowMissing: false,
|
||||
Unique: false,
|
||||
Indexer: indexerSingle{
|
||||
Indexer: indexerSingle[Query, *structs.ServiceNode]{
|
||||
readIndex: indexWithPeerName(indexFromQuery),
|
||||
writeIndex: indexWithPeerName(indexKindFromServiceNode),
|
||||
},
|
||||
|
@ -191,24 +176,14 @@ func servicesTableSchema() *memdb.TableSchema {
|
|||
}
|
||||
}
|
||||
|
||||
func indexFromNodeServiceQuery(arg interface{}) ([]byte, error) {
|
||||
q, ok := arg.(NodeServiceQuery)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T for NodeServiceQuery index", arg)
|
||||
}
|
||||
|
||||
func indexFromNodeServiceQuery(q NodeServiceQuery) ([]byte, error) {
|
||||
var b indexBuilder
|
||||
b.String(strings.ToLower(q.Node))
|
||||
b.String(strings.ToLower(q.Service))
|
||||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
func indexFromServiceNode(raw interface{}) ([]byte, error) {
|
||||
n, ok := raw.(*structs.ServiceNode)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T for structs.ServiceNode index", raw)
|
||||
}
|
||||
|
||||
func indexFromServiceNode(n *structs.ServiceNode) ([]byte, error) {
|
||||
if n.Node == "" {
|
||||
return nil, errMissingValueForIndex
|
||||
}
|
||||
|
@ -219,14 +194,17 @@ func indexFromServiceNode(raw interface{}) ([]byte, error) {
|
|||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
func indexFromNodeIdentity(raw interface{}) ([]byte, error) {
|
||||
n, ok := raw.(interface {
|
||||
NodeIdentity() structs.Identity
|
||||
})
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T for index, type must provide NodeIdentity()", raw)
|
||||
}
|
||||
type nodeIdentifier interface {
|
||||
partitionIndexable
|
||||
peerIndexable
|
||||
|
||||
NodeIdentity() structs.Identity
|
||||
}
|
||||
|
||||
var _ nodeIdentifier = (*structs.HealthCheck)(nil)
|
||||
var _ nodeIdentifier = (*structs.ServiceNode)(nil)
|
||||
|
||||
func indexFromNodeIdentity(n nodeIdentifier) ([]byte, error) {
|
||||
id := n.NodeIdentity()
|
||||
if id.ID == "" {
|
||||
return nil, errMissingValueForIndex
|
||||
|
@ -237,12 +215,7 @@ func indexFromNodeIdentity(raw interface{}) ([]byte, error) {
|
|||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
func indexServiceNameFromServiceNode(raw interface{}) ([]byte, error) {
|
||||
n, ok := raw.(*structs.ServiceNode)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T for structs.ServiceNode index", raw)
|
||||
}
|
||||
|
||||
func indexServiceNameFromServiceNode(n *structs.ServiceNode) ([]byte, error) {
|
||||
if n.Node == "" {
|
||||
return nil, errMissingValueForIndex
|
||||
}
|
||||
|
@ -252,12 +225,7 @@ func indexServiceNameFromServiceNode(raw interface{}) ([]byte, error) {
|
|||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
func indexConnectNameFromServiceNode(raw interface{}) ([]byte, error) {
|
||||
n, ok := raw.(*structs.ServiceNode)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T for structs.ServiceNode index", raw)
|
||||
}
|
||||
|
||||
func indexConnectNameFromServiceNode(n *structs.ServiceNode) ([]byte, error) {
|
||||
name, ok := connectNameFromServiceNode(n)
|
||||
if !ok {
|
||||
return nil, errMissingValueForIndex
|
||||
|
@ -284,33 +252,23 @@ func connectNameFromServiceNode(sn *structs.ServiceNode) (string, bool) {
|
|||
}
|
||||
}
|
||||
|
||||
func indexKindFromServiceNode(raw interface{}) ([]byte, error) {
|
||||
n, ok := raw.(*structs.ServiceNode)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T for structs.ServiceNode index", raw)
|
||||
}
|
||||
|
||||
func indexKindFromServiceNode(n *structs.ServiceNode) ([]byte, error) {
|
||||
var b indexBuilder
|
||||
b.String(strings.ToLower(string(n.ServiceKind)))
|
||||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
// indexWithPeerName adds peer name to the index.
|
||||
func indexWithPeerName(
|
||||
fn func(interface{}) ([]byte, error),
|
||||
) func(interface{}) ([]byte, error) {
|
||||
return func(raw interface{}) ([]byte, error) {
|
||||
v, err := fn(raw)
|
||||
func indexWithPeerName[T peerIndexable](
|
||||
fn func(T) ([]byte, error),
|
||||
) func(T) ([]byte, error) {
|
||||
return func(e T) ([]byte, error) {
|
||||
v, err := fn(e)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
n, ok := raw.(peerIndexable)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("type must be peerIndexable: %T", raw)
|
||||
}
|
||||
|
||||
peername := n.PeerOrEmpty()
|
||||
peername := e.PeerOrEmpty()
|
||||
if peername == "" {
|
||||
peername = structs.LocalPeerKeyword
|
||||
}
|
||||
|
@ -322,20 +280,20 @@ func indexWithPeerName(
|
|||
}
|
||||
|
||||
// multiIndexWithPeerName adds peer name to multiple indices, and returns multiple indices.
|
||||
func multiIndexWithPeerName(
|
||||
fn func(interface{}) ([][]byte, error),
|
||||
) func(interface{}) ([][]byte, error) {
|
||||
return func(raw interface{}) ([][]byte, error) {
|
||||
func multiIndexWithPeerName[T any](
|
||||
fn func(T) ([][]byte, error),
|
||||
) func(T) ([][]byte, error) {
|
||||
return func(raw T) ([][]byte, error) {
|
||||
n, ok := any(raw).(peerIndexable)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("type must be peerIndexable: %T", raw)
|
||||
}
|
||||
|
||||
results, err := fn(raw)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
n, ok := raw.(peerIndexable)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("type must be peerIndexable: %T", raw)
|
||||
}
|
||||
|
||||
peername := n.PeerOrEmpty()
|
||||
if peername == "" {
|
||||
peername = structs.LocalPeerKeyword
|
||||
|
@ -361,7 +319,7 @@ func checksTableSchema() *memdb.TableSchema {
|
|||
Name: indexID,
|
||||
AllowMissing: false,
|
||||
Unique: true,
|
||||
Indexer: indexerSingleWithPrefix{
|
||||
Indexer: indexerSingleWithPrefix[NodeCheckQuery, *structs.HealthCheck, any]{
|
||||
readIndex: indexWithPeerName(indexFromNodeCheckQuery),
|
||||
writeIndex: indexWithPeerName(indexFromHealthCheck),
|
||||
prefixIndex: prefixIndexFromQueryWithPeer,
|
||||
|
@ -371,7 +329,7 @@ func checksTableSchema() *memdb.TableSchema {
|
|||
Name: indexStatus,
|
||||
AllowMissing: false,
|
||||
Unique: false,
|
||||
Indexer: indexerSingle{
|
||||
Indexer: indexerSingle[Query, *structs.HealthCheck]{
|
||||
readIndex: indexWithPeerName(indexFromQuery),
|
||||
writeIndex: indexWithPeerName(indexStatusFromHealthCheck),
|
||||
},
|
||||
|
@ -380,7 +338,7 @@ func checksTableSchema() *memdb.TableSchema {
|
|||
Name: indexService,
|
||||
AllowMissing: true,
|
||||
Unique: false,
|
||||
Indexer: indexerSingle{
|
||||
Indexer: indexerSingle[Query, *structs.HealthCheck]{
|
||||
readIndex: indexWithPeerName(indexFromQuery),
|
||||
writeIndex: indexWithPeerName(indexServiceNameFromHealthCheck),
|
||||
},
|
||||
|
@ -389,7 +347,7 @@ func checksTableSchema() *memdb.TableSchema {
|
|||
Name: indexNode,
|
||||
AllowMissing: true,
|
||||
Unique: false,
|
||||
Indexer: indexerSingle{
|
||||
Indexer: indexerSingle[Query, nodeIdentifier]{
|
||||
readIndex: indexWithPeerName(indexFromQuery),
|
||||
writeIndex: indexWithPeerName(indexFromNodeIdentity),
|
||||
},
|
||||
|
@ -398,7 +356,7 @@ func checksTableSchema() *memdb.TableSchema {
|
|||
Name: indexNodeService,
|
||||
AllowMissing: true,
|
||||
Unique: false,
|
||||
Indexer: indexerSingle{
|
||||
Indexer: indexerSingle[NodeServiceQuery, *structs.HealthCheck]{
|
||||
readIndex: indexWithPeerName(indexFromNodeServiceQuery),
|
||||
writeIndex: indexWithPeerName(indexNodeServiceFromHealthCheck),
|
||||
},
|
||||
|
@ -407,28 +365,18 @@ func checksTableSchema() *memdb.TableSchema {
|
|||
}
|
||||
}
|
||||
|
||||
func indexFromNodeCheckQuery(raw interface{}) ([]byte, error) {
|
||||
hc, ok := raw.(NodeCheckQuery)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T for NodeCheckQuery index", raw)
|
||||
}
|
||||
|
||||
if hc.Node == "" || hc.CheckID == "" {
|
||||
func indexFromNodeCheckQuery(q NodeCheckQuery) ([]byte, error) {
|
||||
if q.Node == "" || q.CheckID == "" {
|
||||
return nil, errMissingValueForIndex
|
||||
}
|
||||
|
||||
var b indexBuilder
|
||||
b.String(strings.ToLower(hc.Node))
|
||||
b.String(strings.ToLower(hc.CheckID))
|
||||
b.String(strings.ToLower(q.Node))
|
||||
b.String(strings.ToLower(q.CheckID))
|
||||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
func indexFromHealthCheck(raw interface{}) ([]byte, error) {
|
||||
hc, ok := raw.(*structs.HealthCheck)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T for structs.HealthCheck index", raw)
|
||||
}
|
||||
|
||||
func indexFromHealthCheck(hc *structs.HealthCheck) ([]byte, error) {
|
||||
if hc.Node == "" || hc.CheckID == "" {
|
||||
return nil, errMissingValueForIndex
|
||||
}
|
||||
|
@ -439,12 +387,7 @@ func indexFromHealthCheck(raw interface{}) ([]byte, error) {
|
|||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
func indexNodeServiceFromHealthCheck(raw interface{}) ([]byte, error) {
|
||||
hc, ok := raw.(*structs.HealthCheck)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T for structs.HealthCheck index", raw)
|
||||
}
|
||||
|
||||
func indexNodeServiceFromHealthCheck(hc *structs.HealthCheck) ([]byte, error) {
|
||||
if hc.Node == "" {
|
||||
return nil, errMissingValueForIndex
|
||||
}
|
||||
|
@ -455,12 +398,7 @@ func indexNodeServiceFromHealthCheck(raw interface{}) ([]byte, error) {
|
|||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
func indexStatusFromHealthCheck(raw interface{}) ([]byte, error) {
|
||||
hc, ok := raw.(*structs.HealthCheck)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T for structs.HealthCheck index", raw)
|
||||
}
|
||||
|
||||
func indexStatusFromHealthCheck(hc *structs.HealthCheck) ([]byte, error) {
|
||||
if hc.Status == "" {
|
||||
return nil, errMissingValueForIndex
|
||||
}
|
||||
|
@ -470,12 +408,7 @@ func indexStatusFromHealthCheck(raw interface{}) ([]byte, error) {
|
|||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
func indexServiceNameFromHealthCheck(raw interface{}) ([]byte, error) {
|
||||
hc, ok := raw.(*structs.HealthCheck)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T for structs.HealthCheck index", raw)
|
||||
}
|
||||
|
||||
func indexServiceNameFromHealthCheck(hc *structs.HealthCheck) ([]byte, error) {
|
||||
if hc.ServiceName == "" {
|
||||
return nil, errMissingValueForIndex
|
||||
}
|
||||
|
@ -761,7 +694,7 @@ func kindServiceNameTableSchema() *memdb.TableSchema {
|
|||
Name: indexID,
|
||||
AllowMissing: false,
|
||||
Unique: true,
|
||||
Indexer: indexerSingle{
|
||||
Indexer: indexerSingle[any, any]{
|
||||
readIndex: indexFromKindServiceName,
|
||||
writeIndex: indexFromKindServiceName,
|
||||
},
|
||||
|
@ -770,7 +703,7 @@ func kindServiceNameTableSchema() *memdb.TableSchema {
|
|||
Name: indexKind,
|
||||
AllowMissing: false,
|
||||
Unique: false,
|
||||
Indexer: indexerSingle{
|
||||
Indexer: indexerSingle[enterpriseIndexable, enterpriseIndexable]{
|
||||
readIndex: indexFromKindServiceNameKindOnly,
|
||||
writeIndex: indexFromKindServiceNameKindOnly,
|
||||
},
|
||||
|
@ -798,7 +731,7 @@ func (q KindServiceNameQuery) PartitionOrDefault() string {
|
|||
return q.EnterpriseMeta.PartitionOrDefault()
|
||||
}
|
||||
|
||||
func indexFromKindServiceNameKindOnly(raw interface{}) ([]byte, error) {
|
||||
func indexFromKindServiceNameKindOnly(raw enterpriseIndexable) ([]byte, error) {
|
||||
switch x := raw.(type) {
|
||||
case *KindServiceName:
|
||||
var b indexBuilder
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package state
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/go-memdb"
|
||||
|
@ -27,7 +26,7 @@ func configTableSchema() *memdb.TableSchema {
|
|||
Name: indexID,
|
||||
AllowMissing: false,
|
||||
Unique: true,
|
||||
Indexer: indexerSingleWithPrefix{
|
||||
Indexer: indexerSingleWithPrefix[any, structs.ConfigEntry, any]{
|
||||
readIndex: indexFromConfigEntryKindName,
|
||||
writeIndex: indexFromConfigEntry,
|
||||
prefixIndex: indexFromConfigEntryKindName,
|
||||
|
@ -55,12 +54,30 @@ func configTableSchema() *memdb.TableSchema {
|
|||
}
|
||||
}
|
||||
|
||||
func indexFromConfigEntry(raw interface{}) ([]byte, error) {
|
||||
c, ok := raw.(structs.ConfigEntry)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("type must be structs.ConfigEntry: %T", raw)
|
||||
}
|
||||
// configEntryIndexable is required because while structs.ConfigEntry
|
||||
// has a GetEnterpriseMeta method, it does not directly expose the
|
||||
// required NamespaceOrDefault and PartitionOrDefault methods of
|
||||
// enterpriseIndexable.
|
||||
//
|
||||
// Config entries that embed *acl.EnterpriseMeta will automatically
|
||||
// implement this interface.
|
||||
type configEntryIndexable interface {
|
||||
structs.ConfigEntry
|
||||
enterpriseIndexable
|
||||
}
|
||||
|
||||
var _ configEntryIndexable = (*structs.ExportedServicesConfigEntry)(nil)
|
||||
var _ configEntryIndexable = (*structs.IngressGatewayConfigEntry)(nil)
|
||||
var _ configEntryIndexable = (*structs.MeshConfigEntry)(nil)
|
||||
var _ configEntryIndexable = (*structs.ProxyConfigEntry)(nil)
|
||||
var _ configEntryIndexable = (*structs.ServiceConfigEntry)(nil)
|
||||
var _ configEntryIndexable = (*structs.ServiceIntentionsConfigEntry)(nil)
|
||||
var _ configEntryIndexable = (*structs.ServiceResolverConfigEntry)(nil)
|
||||
var _ configEntryIndexable = (*structs.ServiceRouterConfigEntry)(nil)
|
||||
var _ configEntryIndexable = (*structs.ServiceSplitterConfigEntry)(nil)
|
||||
var _ configEntryIndexable = (*structs.TerminatingGatewayConfigEntry)(nil)
|
||||
|
||||
func indexFromConfigEntry(c structs.ConfigEntry) ([]byte, error) {
|
||||
if c.GetName() == "" || c.GetKind() == "" {
|
||||
return nil, errMissingValueForIndex
|
||||
}
|
||||
|
@ -73,12 +90,7 @@ func indexFromConfigEntry(raw interface{}) ([]byte, error) {
|
|||
|
||||
// indexKindFromConfigEntry indexes kinds without a namespace for any config
|
||||
// entries that span all namespaces.
|
||||
func indexKindFromConfigEntry(raw interface{}) ([]byte, error) {
|
||||
c, ok := raw.(structs.ConfigEntry)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("type must be structs.ConfigEntry: %T", raw)
|
||||
}
|
||||
|
||||
func indexKindFromConfigEntry(c configEntryIndexable) ([]byte, error) {
|
||||
if c.GetKind() == "" {
|
||||
return nil, errMissingValueForIndex
|
||||
}
|
||||
|
|
|
@ -13,12 +13,7 @@ import (
|
|||
|
||||
const tableCoordinates = "coordinates"
|
||||
|
||||
func indexFromCoordinate(raw interface{}) ([]byte, error) {
|
||||
c, ok := raw.(*structs.Coordinate)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T for structs.Coordinate index", raw)
|
||||
}
|
||||
|
||||
func indexFromCoordinate(c *structs.Coordinate) ([]byte, error) {
|
||||
if c.Node == "" {
|
||||
return nil, errMissingValueForIndex
|
||||
}
|
||||
|
@ -29,12 +24,7 @@ func indexFromCoordinate(raw interface{}) ([]byte, error) {
|
|||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
func indexNodeFromCoordinate(raw interface{}) ([]byte, error) {
|
||||
c, ok := raw.(*structs.Coordinate)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T for structs.Coordinate index", raw)
|
||||
}
|
||||
|
||||
func indexNodeFromCoordinate(c *structs.Coordinate) ([]byte, error) {
|
||||
if c.Node == "" {
|
||||
return nil, errMissingValueForIndex
|
||||
}
|
||||
|
@ -44,12 +34,7 @@ func indexNodeFromCoordinate(raw interface{}) ([]byte, error) {
|
|||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
func indexFromCoordinateQuery(raw interface{}) ([]byte, error) {
|
||||
q, ok := raw.(CoordinateQuery)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T for CoordinateQuery index", raw)
|
||||
}
|
||||
|
||||
func indexFromCoordinateQuery(q CoordinateQuery) ([]byte, error) {
|
||||
if q.Node == "" {
|
||||
return nil, errMissingValueForIndex
|
||||
}
|
||||
|
@ -80,7 +65,7 @@ func coordinatesTableSchema() *memdb.TableSchema {
|
|||
Name: indexID,
|
||||
AllowMissing: false,
|
||||
Unique: true,
|
||||
Indexer: indexerSingleWithPrefix{
|
||||
Indexer: indexerSingleWithPrefix[CoordinateQuery, *structs.Coordinate, any]{
|
||||
readIndex: indexFromCoordinateQuery,
|
||||
writeIndex: indexFromCoordinate,
|
||||
prefixIndex: prefixIndexFromQueryNoNamespace,
|
||||
|
@ -90,7 +75,7 @@ func coordinatesTableSchema() *memdb.TableSchema {
|
|||
Name: indexNode,
|
||||
AllowMissing: false,
|
||||
Unique: false,
|
||||
Indexer: indexerSingle{
|
||||
Indexer: indexerSingle[Query, *structs.Coordinate]{
|
||||
readIndex: indexFromQuery,
|
||||
writeIndex: indexNodeFromCoordinate,
|
||||
},
|
||||
|
|
|
@ -15,32 +15,42 @@ import (
|
|||
// indexerSingle implements both memdb.Indexer and memdb.SingleIndexer. It may
|
||||
// be used in a memdb.IndexSchema to specify functions that generate the index
|
||||
// value for memdb.Txn operations.
|
||||
type indexerSingle struct {
|
||||
//
|
||||
// R represents the type used to generate the read index.
|
||||
// W represents the type used to generate the write index.
|
||||
type indexerSingle[R, W any] struct {
|
||||
// readIndex is used by memdb for Txn.Get, Txn.First, and other operations
|
||||
// that read data.
|
||||
readIndex
|
||||
readIndex[R]
|
||||
// writeIndex is used by memdb for Txn.Insert, Txn.Delete, for operations
|
||||
// that write data to the index.
|
||||
writeIndex
|
||||
writeIndex[W]
|
||||
}
|
||||
|
||||
// indexerMulti implements both memdb.Indexer and memdb.MultiIndexer. It may
|
||||
// be used in a memdb.IndexSchema to specify functions that generate the index
|
||||
// value for memdb.Txn operations.
|
||||
type indexerMulti struct {
|
||||
//
|
||||
// R represents the type used to generate the read index.
|
||||
// W represents the type used to generate the write index.
|
||||
type indexerMulti[R, W any] struct {
|
||||
// readIndex is used by memdb for Txn.Get, Txn.First, and other operations
|
||||
// that read data.
|
||||
readIndex
|
||||
readIndex[R]
|
||||
// writeIndexMulti is used by memdb for Txn.Insert, Txn.Delete, for operations
|
||||
// that write data to the index.
|
||||
writeIndexMulti
|
||||
writeIndexMulti[W]
|
||||
}
|
||||
|
||||
// indexerSingleWithPrefix is a indexerSingle which also supports prefix queries.
|
||||
type indexerSingleWithPrefix struct {
|
||||
readIndex
|
||||
writeIndex
|
||||
prefixIndex
|
||||
//
|
||||
// R represents the type used to generate the read index.
|
||||
// W represents the type used to generate the write index.
|
||||
// P represents the type used to generate the prefix index.
|
||||
type indexerSingleWithPrefix[R, W, P any] struct {
|
||||
readIndex[R]
|
||||
writeIndex[W]
|
||||
prefixIndex[P]
|
||||
}
|
||||
|
||||
// readIndex implements memdb.Indexer. It exists so that a function can be used
|
||||
|
@ -48,13 +58,18 @@ type indexerSingleWithPrefix struct {
|
|||
//
|
||||
// Unlike memdb.Indexer, a readIndex function accepts only a single argument. To
|
||||
// generate an index from multiple values, use a struct type with multiple fields.
|
||||
type readIndex func(arg interface{}) ([]byte, error)
|
||||
type readIndex[R any] func(arg R) ([]byte, error)
|
||||
|
||||
func (f readIndex) FromArgs(args ...interface{}) ([]byte, error) {
|
||||
func (f readIndex[R]) FromArgs(args ...interface{}) ([]byte, error) {
|
||||
if len(args) != 1 {
|
||||
return nil, fmt.Errorf("index supports only a single arg")
|
||||
}
|
||||
return f(args[0])
|
||||
arg, ok := args[0].(R)
|
||||
if !ok {
|
||||
var typ R
|
||||
return nil, fmt.Errorf("unexpected type %T, does not implement %T", args[0], typ)
|
||||
}
|
||||
return f(arg)
|
||||
}
|
||||
|
||||
var errMissingValueForIndex = fmt.Errorf("object is missing a value for this index")
|
||||
|
@ -65,10 +80,15 @@ var errMissingValueForIndex = fmt.Errorf("object is missing a value for this ind
|
|||
// Instead of a bool return value, writeIndex expects errMissingValueForIndex to
|
||||
// indicate that an index could not be build for the object. It will translate
|
||||
// this error into a false value to satisfy the memdb.SingleIndexer interface.
|
||||
type writeIndex func(raw interface{}) ([]byte, error)
|
||||
type writeIndex[W any] func(raw W) ([]byte, error)
|
||||
|
||||
func (f writeIndex) FromObject(raw interface{}) (bool, []byte, error) {
|
||||
v, err := f(raw)
|
||||
func (f writeIndex[W]) FromObject(raw interface{}) (bool, []byte, error) {
|
||||
obj, ok := raw.(W)
|
||||
if !ok {
|
||||
var typ W
|
||||
return false, nil, fmt.Errorf("unexpected type %T, does not implement %T", raw, typ)
|
||||
}
|
||||
v, err := f(obj)
|
||||
if errors.Is(err, errMissingValueForIndex) {
|
||||
return false, nil, nil
|
||||
}
|
||||
|
@ -81,10 +101,15 @@ func (f writeIndex) FromObject(raw interface{}) (bool, []byte, error) {
|
|||
// Instead of a bool return value, writeIndexMulti expects errMissingValueForIndex to
|
||||
// indicate that an index could not be build for the object. It will translate
|
||||
// this error into a false value to satisfy the memdb.MultiIndexer interface.
|
||||
type writeIndexMulti func(raw interface{}) ([][]byte, error)
|
||||
type writeIndexMulti[W any] func(raw W) ([][]byte, error)
|
||||
|
||||
func (f writeIndexMulti) FromObject(raw interface{}) (bool, [][]byte, error) {
|
||||
v, err := f(raw)
|
||||
func (f writeIndexMulti[W]) FromObject(raw interface{}) (bool, [][]byte, error) {
|
||||
obj, ok := raw.(W)
|
||||
if !ok {
|
||||
var typ W
|
||||
return false, nil, fmt.Errorf("unexpected type %T, does not implement %T", raw, typ)
|
||||
}
|
||||
v, err := f(obj)
|
||||
if errors.Is(err, errMissingValueForIndex) {
|
||||
return false, nil, nil
|
||||
}
|
||||
|
@ -93,13 +118,18 @@ func (f writeIndexMulti) FromObject(raw interface{}) (bool, [][]byte, error) {
|
|||
|
||||
// prefixIndex implements memdb.PrefixIndexer. It exists so that a function
|
||||
// can be used to provide this interface.
|
||||
type prefixIndex func(args interface{}) ([]byte, error)
|
||||
type prefixIndex[P any] func(args P) ([]byte, error)
|
||||
|
||||
func (f prefixIndex) PrefixFromArgs(args ...interface{}) ([]byte, error) {
|
||||
func (f prefixIndex[P]) PrefixFromArgs(args ...interface{}) ([]byte, error) {
|
||||
if len(args) != 1 {
|
||||
return nil, fmt.Errorf("index supports only a single arg")
|
||||
}
|
||||
return f(args[0])
|
||||
arg, ok := args[0].(P)
|
||||
if !ok {
|
||||
var typ P
|
||||
return nil, fmt.Errorf("unexpected type %T, does not implement %T", args[0], typ)
|
||||
}
|
||||
return f(arg)
|
||||
}
|
||||
|
||||
const null = "\x00"
|
||||
|
@ -159,12 +189,7 @@ var _ singleValueID = (*Query)(nil)
|
|||
var _ singleValueID = (*structs.Session)(nil)
|
||||
|
||||
// indexFromIDValue creates an index key from any struct that implements singleValueID
|
||||
func indexFromIDValueLowerCase(raw interface{}) ([]byte, error) {
|
||||
e, ok := raw.(singleValueID)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T, does not implement singleValueID", raw)
|
||||
}
|
||||
|
||||
func indexFromIDValueLowerCase(e singleValueID) ([]byte, error) {
|
||||
v := strings.ToLower(e.IDValue())
|
||||
if v == "" {
|
||||
return nil, errMissingValueForIndex
|
||||
|
@ -176,11 +201,7 @@ func indexFromIDValueLowerCase(raw interface{}) ([]byte, error) {
|
|||
}
|
||||
|
||||
// indexFromIDValue creates an index key from any struct that implements singleValueID
|
||||
func indexFromMultiValueID(raw interface{}) ([]byte, error) {
|
||||
e, ok := raw.(multiValueID)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T, does not implement multiValueID", raw)
|
||||
}
|
||||
func indexFromMultiValueID(e multiValueID) ([]byte, error) {
|
||||
var b indexBuilder
|
||||
for _, v := range e.IDValue() {
|
||||
if v == "" {
|
||||
|
|
|
@ -41,12 +41,7 @@ func kvsTableSchema() *memdb.TableSchema {
|
|||
}
|
||||
|
||||
// indexFromIDValue creates an index key from any struct that implements singleValueID
|
||||
func indexFromIDValue(raw interface{}) ([]byte, error) {
|
||||
e, ok := raw.(singleValueID)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T, does not implement singleValueID", raw)
|
||||
}
|
||||
|
||||
func indexFromIDValue(e singleValueID) ([]byte, error) {
|
||||
v := e.IDValue()
|
||||
if v == "" {
|
||||
return nil, errMissingValueForIndex
|
||||
|
|
|
@ -13,11 +13,11 @@ import (
|
|||
"github.com/hashicorp/consul/agent/structs"
|
||||
)
|
||||
|
||||
func kvsIndexer() indexerSingleWithPrefix {
|
||||
return indexerSingleWithPrefix{
|
||||
readIndex: readIndex(indexFromIDValue),
|
||||
writeIndex: writeIndex(indexFromIDValue),
|
||||
prefixIndex: prefixIndex(prefixIndexForIDValue),
|
||||
func kvsIndexer() indexerSingleWithPrefix[singleValueID, singleValueID, any] {
|
||||
return indexerSingleWithPrefix[singleValueID, singleValueID, any]{
|
||||
readIndex: indexFromIDValue,
|
||||
writeIndex: indexFromIDValue,
|
||||
prefixIndex: prefixIndexForIDValue,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,16 +27,16 @@ func peeringTableSchema() *memdb.TableSchema {
|
|||
Name: indexID,
|
||||
AllowMissing: false,
|
||||
Unique: true,
|
||||
Indexer: indexerSingle{
|
||||
readIndex: readIndex(indexFromUUIDString),
|
||||
writeIndex: writeIndex(indexIDFromPeering),
|
||||
Indexer: indexerSingle[string, *pbpeering.Peering]{
|
||||
readIndex: indexFromUUIDString,
|
||||
writeIndex: indexIDFromPeering,
|
||||
},
|
||||
},
|
||||
indexName: {
|
||||
Name: indexName,
|
||||
AllowMissing: false,
|
||||
Unique: true,
|
||||
Indexer: indexerSingleWithPrefix{
|
||||
Indexer: indexerSingleWithPrefix[Query, *pbpeering.Peering, any]{
|
||||
readIndex: indexPeeringFromQuery,
|
||||
writeIndex: indexFromPeering,
|
||||
prefixIndex: prefixIndexFromQueryNoNamespace,
|
||||
|
@ -46,7 +46,7 @@ func peeringTableSchema() *memdb.TableSchema {
|
|||
Name: indexDeleted,
|
||||
AllowMissing: false,
|
||||
Unique: false,
|
||||
Indexer: indexerSingle{
|
||||
Indexer: indexerSingle[BoolQuery, *pbpeering.Peering]{
|
||||
readIndex: indexDeletedFromBoolQuery,
|
||||
writeIndex: indexDeletedFromPeering,
|
||||
},
|
||||
|
@ -63,7 +63,7 @@ func peeringTrustBundlesTableSchema() *memdb.TableSchema {
|
|||
Name: indexID,
|
||||
AllowMissing: false,
|
||||
Unique: true,
|
||||
Indexer: indexerSingleWithPrefix{
|
||||
Indexer: indexerSingleWithPrefix[Query, *pbpeering.PeeringTrustBundle, any]{
|
||||
readIndex: indexPeeringFromQuery, // same as peering table since we'll use the query.Value
|
||||
writeIndex: indexFromPeeringTrustBundle,
|
||||
prefixIndex: prefixIndexFromQueryNoNamespace,
|
||||
|
@ -73,12 +73,7 @@ func peeringTrustBundlesTableSchema() *memdb.TableSchema {
|
|||
}
|
||||
}
|
||||
|
||||
func indexIDFromPeering(raw interface{}) ([]byte, error) {
|
||||
p, ok := raw.(*pbpeering.Peering)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T for pbpeering.Peering index", raw)
|
||||
}
|
||||
|
||||
func indexIDFromPeering(p *pbpeering.Peering) ([]byte, error) {
|
||||
if p.ID == "" {
|
||||
return nil, errMissingValueForIndex
|
||||
}
|
||||
|
@ -92,12 +87,7 @@ func indexIDFromPeering(raw interface{}) ([]byte, error) {
|
|||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
func indexDeletedFromPeering(raw interface{}) ([]byte, error) {
|
||||
p, ok := raw.(*pbpeering.Peering)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T for *pbpeering.Peering index", raw)
|
||||
}
|
||||
|
||||
func indexDeletedFromPeering(p *pbpeering.Peering) ([]byte, error) {
|
||||
var b indexBuilder
|
||||
b.Bool(!p.IsActive())
|
||||
return b.Bytes(), nil
|
||||
|
|
|
@ -10,23 +10,13 @@ import (
|
|||
"github.com/hashicorp/consul/proto/pbpeering"
|
||||
)
|
||||
|
||||
func indexPeeringFromQuery(raw interface{}) ([]byte, error) {
|
||||
q, ok := raw.(Query)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T for Query index", raw)
|
||||
}
|
||||
|
||||
func indexPeeringFromQuery(q Query) ([]byte, error) {
|
||||
var b indexBuilder
|
||||
b.String(strings.ToLower(q.Value))
|
||||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
func indexFromPeering(raw interface{}) ([]byte, error) {
|
||||
p, ok := raw.(*pbpeering.Peering)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T for structs.Peering index", raw)
|
||||
}
|
||||
|
||||
func indexFromPeering(p *pbpeering.Peering) ([]byte, error) {
|
||||
if p.Name == "" {
|
||||
return nil, errMissingValueForIndex
|
||||
}
|
||||
|
@ -36,12 +26,7 @@ func indexFromPeering(raw interface{}) ([]byte, error) {
|
|||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
func indexFromPeeringTrustBundle(raw interface{}) ([]byte, error) {
|
||||
ptb, ok := raw.(*pbpeering.PeeringTrustBundle)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T for pbpeering.PeeringTrustBundle index", raw)
|
||||
}
|
||||
|
||||
func indexFromPeeringTrustBundle(ptb *pbpeering.PeeringTrustBundle) ([]byte, error) {
|
||||
if ptb.PeerName == "" {
|
||||
return nil, errMissingValueForIndex
|
||||
}
|
||||
|
|
|
@ -60,12 +60,7 @@ func (q MultiQuery) PartitionOrDefault() string {
|
|||
|
||||
// indexFromQuery builds an index key where Query.Value is lowercase, and is
|
||||
// a required value.
|
||||
func indexFromQuery(arg interface{}) ([]byte, error) {
|
||||
q, ok := arg.(Query)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T for Query index", arg)
|
||||
}
|
||||
|
||||
func indexFromQuery(q Query) ([]byte, error) {
|
||||
var b indexBuilder
|
||||
b.String(strings.ToLower(q.Value))
|
||||
return b.Bytes(), nil
|
||||
|
@ -164,12 +159,8 @@ func (q KeyValueQuery) PartitionOrDefault() string {
|
|||
return q.EnterpriseMeta.PartitionOrDefault()
|
||||
}
|
||||
|
||||
func indexFromKeyValueQuery(arg interface{}) ([]byte, error) {
|
||||
func indexFromKeyValueQuery(q KeyValueQuery) ([]byte, error) {
|
||||
// NOTE: this is case-sensitive!
|
||||
q, ok := arg.(KeyValueQuery)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T for Query index", arg)
|
||||
}
|
||||
|
||||
var b indexBuilder
|
||||
b.String(q.Key)
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
"github.com/hashicorp/consul/agent/structs"
|
||||
)
|
||||
|
||||
func prefixIndexFromQuery(arg interface{}) ([]byte, error) {
|
||||
func prefixIndexFromQuery(arg any) ([]byte, error) {
|
||||
var b indexBuilder
|
||||
switch v := arg.(type) {
|
||||
case *acl.EnterpriseMeta:
|
||||
|
@ -29,7 +29,7 @@ func prefixIndexFromQuery(arg interface{}) ([]byte, error) {
|
|||
return nil, fmt.Errorf("unexpected type %T for Query prefix index", arg)
|
||||
}
|
||||
|
||||
func prefixIndexFromQueryWithPeer(arg interface{}) ([]byte, error) {
|
||||
func prefixIndexFromQueryWithPeer(arg any) ([]byte, error) {
|
||||
var b indexBuilder
|
||||
switch v := arg.(type) {
|
||||
case *acl.EnterpriseMeta:
|
||||
|
@ -58,12 +58,7 @@ func prefixIndexFromQueryNoNamespace(arg interface{}) ([]byte, error) {
|
|||
|
||||
// indexFromAuthMethodQuery builds an index key where Query.Value is lowercase, and is
|
||||
// a required value.
|
||||
func indexFromAuthMethodQuery(arg interface{}) ([]byte, error) {
|
||||
q, ok := arg.(AuthMethodQuery)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T for Query index", arg)
|
||||
}
|
||||
|
||||
func indexFromAuthMethodQuery(q AuthMethodQuery) ([]byte, error) {
|
||||
var b indexBuilder
|
||||
b.String(strings.ToLower(q.Value))
|
||||
return b.Bytes(), nil
|
||||
|
|
|
@ -84,7 +84,7 @@ func indexTableSchema() *memdb.TableSchema {
|
|||
Name: indexID,
|
||||
AllowMissing: false,
|
||||
Unique: true,
|
||||
Indexer: indexerSingle{
|
||||
Indexer: indexerSingle[string, *IndexEntry]{
|
||||
readIndex: indexFromString,
|
||||
writeIndex: indexNameFromIndexEntry,
|
||||
},
|
||||
|
@ -93,39 +93,37 @@ func indexTableSchema() *memdb.TableSchema {
|
|||
}
|
||||
}
|
||||
|
||||
func indexNameFromIndexEntry(raw interface{}) ([]byte, error) {
|
||||
p, ok := raw.(*IndexEntry)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T for IndexEntry index", raw)
|
||||
}
|
||||
|
||||
if p.Key == "" {
|
||||
func indexNameFromIndexEntry(e *IndexEntry) ([]byte, error) {
|
||||
if e.Key == "" {
|
||||
return nil, errMissingValueForIndex
|
||||
}
|
||||
|
||||
var b indexBuilder
|
||||
b.String(strings.ToLower(p.Key))
|
||||
b.String(strings.ToLower(e.Key))
|
||||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
func indexFromString(raw interface{}) ([]byte, error) {
|
||||
q, ok := raw.(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T for string prefix query", raw)
|
||||
}
|
||||
|
||||
func indexFromString(s string) ([]byte, error) {
|
||||
var b indexBuilder
|
||||
b.String(strings.ToLower(q))
|
||||
b.String(strings.ToLower(s))
|
||||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
func indexDeletedFromBoolQuery(raw interface{}) ([]byte, error) {
|
||||
q, ok := raw.(BoolQuery)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T for BoolQuery index", raw)
|
||||
}
|
||||
|
||||
func indexDeletedFromBoolQuery(q BoolQuery) ([]byte, error) {
|
||||
var b indexBuilder
|
||||
b.Bool(q.Value)
|
||||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
type enterpriseIndexable interface {
|
||||
partitionIndexable
|
||||
namespaceIndexable
|
||||
}
|
||||
|
||||
type partitionIndexable interface {
|
||||
PartitionOrDefault() string
|
||||
}
|
||||
|
||||
type namespaceIndexable interface {
|
||||
NamespaceOrDefault() string
|
||||
}
|
||||
|
|
|
@ -19,12 +19,7 @@ const (
|
|||
indexNodeCheck = "node_check"
|
||||
)
|
||||
|
||||
func indexFromSession(raw interface{}) ([]byte, error) {
|
||||
e, ok := raw.(*structs.Session)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T, does not implement *structs.Session", raw)
|
||||
}
|
||||
|
||||
func indexFromSession(e *structs.Session) ([]byte, error) {
|
||||
v := strings.ToLower(e.ID)
|
||||
if v == "" {
|
||||
return nil, errMissingValueForIndex
|
||||
|
@ -86,12 +81,7 @@ func sessionChecksTableSchema() *memdb.TableSchema {
|
|||
}
|
||||
|
||||
// indexNodeFromSession creates an index key from *structs.Session
|
||||
func indexNodeFromSession(raw interface{}) ([]byte, error) {
|
||||
e, ok := raw.(*structs.Session)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T, does not implement *structs.Session", raw)
|
||||
}
|
||||
|
||||
func indexNodeFromSession(e *structs.Session) ([]byte, error) {
|
||||
v := strings.ToLower(e.Node)
|
||||
if v == "" {
|
||||
return nil, errMissingValueForIndex
|
||||
|
@ -103,12 +93,7 @@ func indexNodeFromSession(raw interface{}) ([]byte, error) {
|
|||
}
|
||||
|
||||
// indexFromNodeCheckIDSession creates an index key from sessionCheck
|
||||
func indexFromNodeCheckIDSession(raw interface{}) ([]byte, error) {
|
||||
e, ok := raw.(*sessionCheck)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T, does not implement sessionCheck", raw)
|
||||
}
|
||||
|
||||
func indexFromNodeCheckIDSession(e *sessionCheck) ([]byte, error) {
|
||||
var b indexBuilder
|
||||
v := strings.ToLower(e.Node)
|
||||
if v == "" {
|
||||
|
@ -132,12 +117,7 @@ func indexFromNodeCheckIDSession(raw interface{}) ([]byte, error) {
|
|||
}
|
||||
|
||||
// indexSessionCheckFromSession creates an index key from sessionCheck
|
||||
func indexSessionCheckFromSession(raw interface{}) ([]byte, error) {
|
||||
e, ok := raw.(*sessionCheck)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T, does not implement *sessionCheck", raw)
|
||||
}
|
||||
|
||||
func indexSessionCheckFromSession(e *sessionCheck) ([]byte, error) {
|
||||
var b indexBuilder
|
||||
v := strings.ToLower(e.Session)
|
||||
if v == "" {
|
||||
|
|
|
@ -14,48 +14,44 @@ import (
|
|||
"github.com/hashicorp/consul/api"
|
||||
)
|
||||
|
||||
func sessionIndexer() indexerSingleWithPrefix {
|
||||
return indexerSingleWithPrefix{
|
||||
readIndex: readIndex(indexFromQuery),
|
||||
writeIndex: writeIndex(indexFromSession),
|
||||
prefixIndex: prefixIndex(prefixIndexFromQuery),
|
||||
func sessionIndexer() indexerSingleWithPrefix[Query, *structs.Session, any] {
|
||||
return indexerSingleWithPrefix[Query, *structs.Session, any]{
|
||||
readIndex: indexFromQuery,
|
||||
writeIndex: indexFromSession,
|
||||
prefixIndex: prefixIndexFromQuery,
|
||||
}
|
||||
}
|
||||
|
||||
func nodeSessionsIndexer() indexerSingle {
|
||||
return indexerSingle{
|
||||
readIndex: readIndex(indexFromIDValueLowerCase),
|
||||
writeIndex: writeIndex(indexNodeFromSession),
|
||||
func nodeSessionsIndexer() indexerSingle[singleValueID, *structs.Session] {
|
||||
return indexerSingle[singleValueID, *structs.Session]{
|
||||
readIndex: indexFromIDValueLowerCase,
|
||||
writeIndex: indexNodeFromSession,
|
||||
}
|
||||
}
|
||||
|
||||
func idCheckIndexer() indexerSingle {
|
||||
return indexerSingle{
|
||||
func idCheckIndexer() indexerSingle[*sessionCheck, *sessionCheck] {
|
||||
return indexerSingle[*sessionCheck, *sessionCheck]{
|
||||
readIndex: indexFromNodeCheckIDSession,
|
||||
writeIndex: indexFromNodeCheckIDSession,
|
||||
}
|
||||
}
|
||||
|
||||
func sessionCheckIndexer() indexerSingle {
|
||||
return indexerSingle{
|
||||
func sessionCheckIndexer() indexerSingle[Query, *sessionCheck] {
|
||||
return indexerSingle[Query, *sessionCheck]{
|
||||
readIndex: indexFromQuery,
|
||||
writeIndex: indexSessionCheckFromSession,
|
||||
}
|
||||
}
|
||||
|
||||
func nodeChecksIndexer() indexerSingle {
|
||||
return indexerSingle{
|
||||
func nodeChecksIndexer() indexerSingle[multiValueID, *sessionCheck] {
|
||||
return indexerSingle[multiValueID, *sessionCheck]{
|
||||
readIndex: indexFromMultiValueID,
|
||||
writeIndex: indexFromNodeCheckID,
|
||||
}
|
||||
}
|
||||
|
||||
// indexFromNodeCheckID creates an index key from a sessionCheck structure
|
||||
func indexFromNodeCheckID(raw interface{}) ([]byte, error) {
|
||||
e, ok := raw.(*sessionCheck)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T, does not implement *structs.Session", raw)
|
||||
}
|
||||
func indexFromNodeCheckID(e *sessionCheck) ([]byte, error) {
|
||||
var b indexBuilder
|
||||
v := strings.ToLower(e.Node)
|
||||
if v == "" {
|
||||
|
|
Loading…
Reference in New Issue