From ba4ee6e67c024af357679a6789f3be434fe2bed8 Mon Sep 17 00:00:00 2001 From: Dhia Ayachi Date: Fri, 10 Sep 2021 16:56:56 -0400 Subject: [PATCH] convert `indexAuthMethod` index to use `indexerSingle` (#11014) * convert `Roles` index to use `indexerSingle` * fix oss build * split authmethod write indexer to oss and ent * add auth method unit tests --- agent/consul/state/acl_oss.go | 19 ++++++++++++++++++- agent/consul/state/acl_oss_test.go | 13 +++++++++++++ agent/consul/state/acl_schema.go | 6 +++--- agent/consul/state/query.go | 18 ++++++++++++++++++ agent/consul/state/query_oss.go | 13 +++++++++++++ 5 files changed, 65 insertions(+), 4 deletions(-) diff --git a/agent/consul/state/acl_oss.go b/agent/consul/state/acl_oss.go index 815212a0a9..faa9d0cb59 100644 --- a/agent/consul/state/acl_oss.go +++ b/agent/consul/state/acl_oss.go @@ -4,6 +4,7 @@ package state import ( "fmt" + "strings" memdb "github.com/hashicorp/go-memdb" @@ -94,7 +95,7 @@ func aclTokenListByRole(tx ReadTxn, role string, _ *structs.EnterpriseMeta) (mem } func aclTokenListByAuthMethod(tx ReadTxn, authMethod string, _, _ *structs.EnterpriseMeta) (memdb.ResultIterator, error) { - return tx.Get(tableACLTokens, "authmethod", authMethod) + return tx.Get(tableACLTokens, indexAuthMethod, AuthMethodQuery{Value: authMethod}) } func aclTokenDeleteWithToken(tx WriteTxn, token *structs.ACLToken, idx uint64) error { @@ -273,3 +274,19 @@ func aclAuthMethodUpsertValidateEnterprise(_ ReadTxn, method *structs.ACLAuthMet func (s *Store) ACLAuthMethodUpsertValidateEnterprise(method *structs.ACLAuthMethod, existing *structs.ACLAuthMethod) error { 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 == "" { + return nil, errMissingValueForIndex + } + + var b indexBuilder + b.String(strings.ToLower(p.AuthMethod)) + + return b.Bytes(), nil +} diff --git a/agent/consul/state/acl_oss_test.go b/agent/consul/state/acl_oss_test.go index 29eed374ad..c2c399bdf5 100644 --- a/agent/consul/state/acl_oss_test.go +++ b/agent/consul/state/acl_oss_test.go @@ -49,6 +49,7 @@ func testIndexerTableACLTokens() map[string]indexerTestCase { Roles: []structs.ACLTokenRoleLink{ {ID: roleID1}, {ID: roleID2}, }, + AuthMethod: "test-Auth-Method", } encodedPID1 := []byte{0x12, 0x3e, 0x45, 0x67, 0xe8, 0x9a, 0x12, 0xd7, 0xa4, 0x56, 0x42, 0x66, 0x14, 0x17, 0x40, 0x01} encodedPID2 := []byte{0x12, 0x3e, 0x45, 0x67, 0xe8, 0x9a, 0x12, 0xd7, 0xa4, 0x56, 0x42, 0x66, 0x14, 0x17, 0x40, 0x02} @@ -79,6 +80,18 @@ func testIndexerTableACLTokens() map[string]indexerTestCase { expected: [][]byte{encodedRID1, encodedRID2}, }, }, + indexAuthMethod: { + read: indexValue{ + source: AuthMethodQuery{ + Value: "test-Auth-Method", + }, + expected: []byte("test-auth-method\x00"), + }, + write: indexValue{ + source: obj, + expected: []byte("test-auth-method\x00"), + }, + }, } } diff --git a/agent/consul/state/acl_schema.go b/agent/consul/state/acl_schema.go index 3ef2c1fa08..fae87af887 100644 --- a/agent/consul/state/acl_schema.go +++ b/agent/consul/state/acl_schema.go @@ -70,9 +70,9 @@ func tokensTableSchema() *memdb.TableSchema { Name: indexAuthMethod, AllowMissing: true, Unique: false, - Indexer: &memdb.StringFieldIndex{ - Field: "AuthMethod", - Lowercase: false, + Indexer: indexerSingle{ + readIndex: readIndex(indexFromAuthMethodQuery), + writeIndex: writeIndex(indexAuthMethodFromACLToken), }, }, indexLocal: { diff --git a/agent/consul/state/query.go b/agent/consul/state/query.go index 3dba99a4eb..d264e98aae 100644 --- a/agent/consul/state/query.go +++ b/agent/consul/state/query.go @@ -128,3 +128,21 @@ func indexFromKeyValueQuery(arg interface{}) ([]byte, error) { b.String(q.Value) return b.Bytes(), nil } + +type AuthMethodQuery struct { + Value string + AuthMethodEntMeta structs.EnterpriseMeta + structs.EnterpriseMeta +} + +// NamespaceOrDefault exists because structs.EnterpriseMeta uses a pointer +// receiver for this method. Remove once that is fixed. +func (q AuthMethodQuery) NamespaceOrDefault() string { + return q.EnterpriseMeta.NamespaceOrDefault() +} + +// PartitionOrDefault exists because structs.EnterpriseMeta uses a pointer +// receiver for this method. Remove once that is fixed. +func (q AuthMethodQuery) PartitionOrDefault() string { + return q.EnterpriseMeta.PartitionOrDefault() +} diff --git a/agent/consul/state/query_oss.go b/agent/consul/state/query_oss.go index 98091f0f17..0b36a461cd 100644 --- a/agent/consul/state/query_oss.go +++ b/agent/consul/state/query_oss.go @@ -42,3 +42,16 @@ func prefixIndexFromServiceNameAsString(arg interface{}) ([]byte, error) { return nil, fmt.Errorf("unexpected type %T for Query prefix index", arg) } + +// 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) + } + + var b indexBuilder + b.String(strings.ToLower(q.Value)) + return b.Bytes(), nil +}