diff --git a/agent/consul/state/acl.go b/agent/consul/state/acl.go index 8efc284dd8..003a6230c1 100644 --- a/agent/consul/state/acl.go +++ b/agent/consul/state/acl.go @@ -738,7 +738,7 @@ func (s *Store) ACLTokenGetBySecret(ws memdb.WatchSet, secret string, entMeta *s // ACLTokenGetByAccessor is used to look up an existing ACL token by its AccessorID. func (s *Store) ACLTokenGetByAccessor(ws memdb.WatchSet, accessor string, entMeta *structs.EnterpriseMeta) (uint64, *structs.ACLToken, error) { - return s.aclTokenGet(ws, accessor, "accessor", entMeta) + return s.aclTokenGet(ws, accessor, indexAccessor, entMeta) } // aclTokenGet looks up a token using one of the indexes provided @@ -761,7 +761,7 @@ func (s *Store) ACLTokenBatchGet(ws memdb.WatchSet, accessors []string) (uint64, tokens := make(structs.ACLTokens, 0) for _, accessor := range accessors { - token, err := aclTokenGetTxn(tx, ws, accessor, "accessor", nil) + token, err := aclTokenGetTxn(tx, ws, accessor, indexAccessor, nil) if err != nil { return 0, nil, fmt.Errorf("failed acl token lookup: %v", err) } @@ -968,7 +968,7 @@ func (s *Store) ACLTokenDeleteBySecret(idx uint64, secret string, entMeta *struc // ACLTokenDeleteByAccessor is used to remove an existing ACL from the state store. If // the ACL does not exist this is a no-op and no error is returned. func (s *Store) ACLTokenDeleteByAccessor(idx uint64, accessor string, entMeta *structs.EnterpriseMeta) error { - return s.aclTokenDelete(idx, accessor, "accessor", entMeta) + return s.aclTokenDelete(idx, accessor, indexAccessor, entMeta) } func (s *Store) ACLTokenBatchDelete(idx uint64, tokenIDs []string) error { @@ -976,7 +976,7 @@ func (s *Store) ACLTokenBatchDelete(idx uint64, tokenIDs []string) error { defer tx.Abort() for _, tokenID := range tokenIDs { - if err := aclTokenDeleteTxn(tx, idx, tokenID, "accessor", nil); err != nil { + if err := aclTokenDeleteTxn(tx, idx, tokenID, indexAccessor, nil); err != nil { return err } } diff --git a/agent/consul/state/acl_schema.go b/agent/consul/state/acl_schema.go index bbab26a1e9..5ec9eb6643 100644 --- a/agent/consul/state/acl_schema.go +++ b/agent/consul/state/acl_schema.go @@ -16,6 +16,7 @@ const ( tableACLBindingRules = "acl-binding-rules" tableACLAuthMethods = "acl-auth-methods" + indexAccessor = "accessor" indexPolicies = "policies" indexRoles = "roles" indexAuthMethod = "authmethod" @@ -27,13 +28,14 @@ func tokensTableSchema() *memdb.TableSchema { return &memdb.TableSchema{ Name: tableACLTokens, Indexes: map[string]*memdb.IndexSchema{ - "accessor": { - Name: "accessor", + indexAccessor: { + Name: indexAccessor, // DEPRECATED (ACL-Legacy-Compat) - we should not AllowMissing here once legacy compat is removed AllowMissing: true, Unique: true, - Indexer: &memdb.UUIDFieldIndex{ - Field: "AccessorID", + Indexer: indexerSingle{ + readIndex: readIndex(indexFromUUIDString), + writeIndex: writeIndex(indexAccessorIDFromACLToken), }, }, indexID: { @@ -289,3 +291,36 @@ func authMethodsTableSchema() *memdb.TableSchema { }, } } + +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) + if err != nil { + return nil, err + } + var b indexBuilder + b.Raw(uuid) + 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 == "" { + return nil, errMissingValueForIndex + } + + uuid, err := uuidStringToBytes(p.AccessorID) + if err != nil { + return nil, err + } + var b indexBuilder + b.Raw(uuid) + return b.Bytes(), nil +}