convert `Roles` index to use `indexerMulti` (#11013)

* convert `Roles` index to use `indexerMulti`

* add role test in oss

* fix oss to use the right index func

* preallocate slice
This commit is contained in:
Dhia Ayachi 2021-09-10 16:04:33 -04:00 committed by GitHub
parent f3f0654038
commit 6cac30aa22
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 50 additions and 53 deletions

View File

@ -11,57 +11,6 @@ import (
pbacl "github.com/hashicorp/consul/proto/pbacl" pbacl "github.com/hashicorp/consul/proto/pbacl"
) )
type TokenRolesIndex struct {
}
func (s *TokenRolesIndex) FromObject(obj interface{}) (bool, [][]byte, error) {
token, ok := obj.(*structs.ACLToken)
if !ok {
return false, nil, fmt.Errorf("object is not an ACLToken")
}
links := token.Roles
numLinks := len(links)
if numLinks == 0 {
return false, nil, nil
}
vals := make([][]byte, 0, numLinks)
for _, link := range links {
vals = append(vals, []byte(link.ID+"\x00"))
}
return true, vals, nil
}
func (s *TokenRolesIndex) FromArgs(args ...interface{}) ([]byte, error) {
if len(args) != 1 {
return nil, fmt.Errorf("must provide only a single argument")
}
arg, ok := args[0].(string)
if !ok {
return nil, fmt.Errorf("argument must be a string: %#v", args[0])
}
// Add the null character as a terminator
arg += "\x00"
return []byte(arg), nil
}
func (s *TokenRolesIndex) PrefixFromArgs(args ...interface{}) ([]byte, error) {
val, err := s.FromArgs(args...)
if err != nil {
return nil, err
}
// Strip the null terminator, the rest is a prefix
n := len(val)
if n > 0 {
return val[:n-1], nil
}
return val, nil
}
type TokenExpirationIndex struct { type TokenExpirationIndex struct {
LocalFilter bool LocalFilter bool
} }

View File

@ -90,7 +90,7 @@ func aclTokenListByPolicy(tx ReadTxn, policy string, _ *structs.EnterpriseMeta)
} }
func aclTokenListByRole(tx ReadTxn, role string, _ *structs.EnterpriseMeta) (memdb.ResultIterator, error) { func aclTokenListByRole(tx ReadTxn, role string, _ *structs.EnterpriseMeta) (memdb.ResultIterator, error) {
return tx.Get(tableACLTokens, "roles", role) return tx.Get(tableACLTokens, indexRoles, Query{Value: role})
} }
func aclTokenListByAuthMethod(tx ReadTxn, authMethod string, _, _ *structs.EnterpriseMeta) (memdb.ResultIterator, error) { func aclTokenListByAuthMethod(tx ReadTxn, authMethod string, _, _ *structs.EnterpriseMeta) (memdb.ResultIterator, error) {

View File

@ -37,15 +37,23 @@ func testIndexerTableACLPolicies() map[string]indexerTestCase {
func testIndexerTableACLTokens() map[string]indexerTestCase { func testIndexerTableACLTokens() map[string]indexerTestCase {
policyID1 := "123e4567-e89a-12d7-a456-426614174001" policyID1 := "123e4567-e89a-12d7-a456-426614174001"
policyID2 := "123e4567-e89a-12d7-a456-426614174002" policyID2 := "123e4567-e89a-12d7-a456-426614174002"
roleID1 := "123e4567-e89a-12d7-a457-426614174001"
roleID2 := "123e4567-e89a-12d7-a457-426614174002"
obj := &structs.ACLToken{ obj := &structs.ACLToken{
AccessorID: "123e4567-e89a-12d7-a456-426614174abc", AccessorID: "123e4567-e89a-12d7-a456-426614174abc",
SecretID: "123e4567-e89a-12d7-a456-426614174abd", SecretID: "123e4567-e89a-12d7-a456-426614174abd",
Policies: []structs.ACLTokenPolicyLink{ Policies: []structs.ACLTokenPolicyLink{
{ID: policyID1}, {ID: policyID2}, {ID: policyID1}, {ID: policyID2},
}, },
Roles: []structs.ACLTokenRoleLink{
{ID: roleID1}, {ID: roleID2},
},
} }
encodedPID1 := []byte{0x12, 0x3e, 0x45, 0x67, 0xe8, 0x9a, 0x12, 0xd7, 0xa4, 0x56, 0x42, 0x66, 0x14, 0x17, 0x40, 0x01} 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} encodedPID2 := []byte{0x12, 0x3e, 0x45, 0x67, 0xe8, 0x9a, 0x12, 0xd7, 0xa4, 0x56, 0x42, 0x66, 0x14, 0x17, 0x40, 0x02}
encodedRID1 := []byte{0x12, 0x3e, 0x45, 0x67, 0xe8, 0x9a, 0x12, 0xd7, 0xa4, 0x57, 0x42, 0x66, 0x14, 0x17, 0x40, 0x1}
encodedRID2 := []byte{0x12, 0x3e, 0x45, 0x67, 0xe8, 0x9a, 0x12, 0xd7, 0xa4, 0x57, 0x42, 0x66, 0x14, 0x17, 0x40, 0x2}
return map[string]indexerTestCase{ return map[string]indexerTestCase{
indexPolicies: { indexPolicies: {
read: indexValue{ read: indexValue{
@ -59,6 +67,18 @@ func testIndexerTableACLTokens() map[string]indexerTestCase {
expected: [][]byte{encodedPID1, encodedPID2}, expected: [][]byte{encodedPID1, encodedPID2},
}, },
}, },
indexRoles: {
read: indexValue{
source: Query{
Value: roleID1,
},
expected: encodedRID1,
},
writeMulti: indexValueMulti{
source: obj,
expected: [][]byte{encodedRID1, encodedRID2},
},
},
} }
} }

View File

@ -61,7 +61,10 @@ func tokensTableSchema() *memdb.TableSchema {
Name: indexRoles, Name: indexRoles,
AllowMissing: true, AllowMissing: true,
Unique: false, Unique: false,
Indexer: &TokenRolesIndex{}, Indexer: indexerMulti{
readIndex: readIndex(indexFromUUIDQuery),
writeIndexMulti: writeIndexMulti(indexRolesFromACLToken),
},
}, },
indexAuthMethod: { indexAuthMethod: {
Name: indexAuthMethod, Name: indexAuthMethod,
@ -378,3 +381,28 @@ func indexPoliciesFromACLToken(raw interface{}) ([][]byte, error) {
return vals, nil 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)
}
links := token.Roles
numLinks := len(links)
if numLinks == 0 {
return nil, errMissingValueForIndex
}
vals := make([][]byte, numLinks)
for i, link := range links {
id, err := uuidStringToBytes(link.ID)
if err != nil {
return nil, err
}
vals[i] = id
}
return vals, nil
}