diff --git a/agent/consul/state/acl.go b/agent/consul/state/acl.go index dde2acf9b..46a2cba45 100644 --- a/agent/consul/state/acl.go +++ b/agent/consul/state/acl.go @@ -48,7 +48,7 @@ func (s *Restore) ACLRole(role *structs.ACLRole) error { // ACLBindingRules is used when saving a snapshot func (s *Snapshot) ACLBindingRules() (memdb.ResultIterator, error) { - iter, err := s.tx.Get("acl-binding-rules", "id") + iter, err := s.tx.Get(tableACLBindingRules, "id") if err != nil { return nil, err } diff --git a/agent/consul/state/acl_oss.go b/agent/consul/state/acl_oss.go index 30315a3e9..4db789736 100644 --- a/agent/consul/state/acl_oss.go +++ b/agent/consul/state/acl_oss.go @@ -167,12 +167,12 @@ func (s *Store) ACLRoleUpsertValidateEnterprise(role *structs.ACLRole, existing func aclBindingRuleInsert(tx WriteTxn, rule *structs.ACLBindingRule) error { // insert the role into memdb - if err := tx.Insert("acl-binding-rules", rule); err != nil { + if err := tx.Insert(tableACLBindingRules, rule); err != nil { return fmt.Errorf("failed inserting acl role: %v", err) } // update the overall acl-binding-rules index - if err := indexUpdateMaxTxn(tx, rule.ModifyIndex, "acl-binding-rules"); err != nil { + if err := indexUpdateMaxTxn(tx, rule.ModifyIndex, tableACLBindingRules); err != nil { return fmt.Errorf("failed updating acl binding-rules index: %v", err) } @@ -180,32 +180,32 @@ func aclBindingRuleInsert(tx WriteTxn, rule *structs.ACLBindingRule) error { } func aclBindingRuleGetByID(tx ReadTxn, id string, _ *structs.EnterpriseMeta) (<-chan struct{}, interface{}, error) { - return tx.FirstWatch("acl-binding-rules", "id", id) + return tx.FirstWatch(tableACLBindingRules, "id", id) } func aclBindingRuleList(tx ReadTxn, _ *structs.EnterpriseMeta) (memdb.ResultIterator, error) { - return tx.Get("acl-binding-rules", "id") + return tx.Get(tableACLBindingRules, "id") } func aclBindingRuleListByAuthMethod(tx ReadTxn, method string, _ *structs.EnterpriseMeta) (memdb.ResultIterator, error) { - return tx.Get("acl-binding-rules", "authmethod", method) + return tx.Get(tableACLBindingRules, indexAuthMethod, Query{Value: method}) } func aclBindingRuleDeleteWithRule(tx WriteTxn, rule *structs.ACLBindingRule, idx uint64) error { - // remove the rule - if err := tx.Delete("acl-binding-rules", rule); err != nil { + // remove the acl-binding-rule + if err := tx.Delete(tableACLBindingRules, rule); err != nil { return fmt.Errorf("failed deleting acl binding rule: %v", err) } // update the overall acl-binding-rules index - if err := indexUpdateMaxTxn(tx, idx, "acl-binding-rules"); err != nil { + if err := indexUpdateMaxTxn(tx, idx, tableACLBindingRules); err != nil { return fmt.Errorf("failed updating acl binding rules index: %v", err) } return nil } func aclBindingRuleMaxIndex(tx ReadTxn, _ *structs.ACLBindingRule, entMeta *structs.EnterpriseMeta) uint64 { - return maxIndexTxn(tx, "acl-binding-rules") + return maxIndexTxn(tx, tableACLBindingRules) } func aclBindingRuleUpsertValidateEnterprise(tx ReadTxn, rule *structs.ACLBindingRule, existing *structs.ACLBindingRule) error { diff --git a/agent/consul/state/acl_oss_test.go b/agent/consul/state/acl_oss_test.go index c2c399bdf..8f64020e2 100644 --- a/agent/consul/state/acl_oss_test.go +++ b/agent/consul/state/acl_oss_test.go @@ -141,3 +141,22 @@ func testIndexerTableACLRoles() map[string]indexerTestCase { }, } } + +func testIndexerTableACLBindingRules() map[string]indexerTestCase { + obj := &structs.ACLBindingRule{ + ID: "123e4567-e89a-12d7-a456-426614174abc", + AuthMethod: "BinDingRuLe", + } + return map[string]indexerTestCase{ + indexAuthMethod: { + read: indexValue{ + source: Query{Value: "BinDingRuLe"}, + expected: []byte("bindingrule\x00"), + }, + write: indexValue{ + source: obj, + expected: []byte("bindingrule\x00"), + }, + }, + } +} diff --git a/agent/consul/state/acl_schema.go b/agent/consul/state/acl_schema.go index 4d8b6cb9e..d58ef0646 100644 --- a/agent/consul/state/acl_schema.go +++ b/agent/consul/state/acl_schema.go @@ -276,15 +276,30 @@ func bindingRulesTableSchema() *memdb.TableSchema { Name: indexAuthMethod, AllowMissing: false, Unique: false, - Indexer: &memdb.StringFieldIndex{ - Field: "AuthMethod", - Lowercase: true, + Indexer: indexerSingle{ + readIndex: indexFromQuery, + writeIndex: indexAuthMethodFromACLBindingRule, }, }, }, } } +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 == "" { + return nil, errMissingValueForIndex + } + + var b indexBuilder + b.String(strings.ToLower(p.AuthMethod)) + return b.Bytes(), nil +} + func authMethodsTableSchema() *memdb.TableSchema { return &memdb.TableSchema{ Name: tableACLAuthMethods, diff --git a/agent/consul/state/acl_test.go b/agent/consul/state/acl_test.go index d7f13c6f6..3f11dd125 100644 --- a/agent/consul/state/acl_test.go +++ b/agent/consul/state/acl_test.go @@ -4213,7 +4213,7 @@ func TestStateStore_ACLBindingRules_Snapshot_Restore(t *testing.T) { require.NoError(t, err) require.Equal(t, uint64(2), idx) require.ElementsMatch(t, rules, res) - require.Equal(t, uint64(2), s.maxIndex("acl-binding-rules")) + require.Equal(t, uint64(2), s.maxIndex(tableACLBindingRules)) }() } diff --git a/agent/consul/state/schema_test.go b/agent/consul/state/schema_test.go index 31dff1e69..923040814 100644 --- a/agent/consul/state/schema_test.go +++ b/agent/consul/state/schema_test.go @@ -38,9 +38,10 @@ func TestNewDBSchema_Indexers(t *testing.T) { var testcases = map[string]func() map[string]indexerTestCase{ // acl - tableACLPolicies: testIndexerTableACLPolicies, - tableACLRoles: testIndexerTableACLRoles, - tableACLTokens: testIndexerTableACLTokens, + tableACLBindingRules: testIndexerTableACLBindingRules, + tableACLPolicies: testIndexerTableACLPolicies, + tableACLRoles: testIndexerTableACLRoles, + tableACLTokens: testIndexerTableACLTokens, // catalog tableChecks: testIndexerTableChecks, tableServices: testIndexerTableServices,