acl: sso auth method event stream (#15280)

This PR implements SSO auth method support in the event stream.

This PR is part of the SSO work captured under ☂️ ticket #13120.
This commit is contained in:
Piotr Kazmierczak
2022-11-21 10:06:05 +01:00
committed by GitHub
parent 4703f55d6d
commit fee85dac79
3 changed files with 99 additions and 11 deletions

View File

@@ -29,6 +29,8 @@ var MsgTypeEvents = map[structs.MessageType]string{
structs.ACLPolicyUpsertRequestType: structs.TypeACLPolicyUpserted,
structs.ACLRolesDeleteByIDRequestType: structs.TypeACLRoleDeleted,
structs.ACLRolesUpsertRequestType: structs.TypeACLRoleUpserted,
structs.ACLAuthMethodsUpsertRequestType: structs.TypeACLAuthMethodUpserted,
structs.ACLAuthMethodsDeleteRequestType: structs.TypeACLAuthMethodDeleted,
structs.ServiceRegistrationUpsertRequestType: structs.TypeServiceRegistration,
structs.ServiceRegistrationDeleteByIDRequestType: structs.TypeServiceDeregistration,
structs.ServiceRegistrationDeleteByNodeIDRequestType: structs.TypeServiceDeregistration,
@@ -91,6 +93,18 @@ func eventFromChange(change memdb.Change) (structs.Event, bool) {
ACLRole: before,
},
}, true
case TableACLAuthMethods:
before, ok := change.Before.(*structs.ACLAuthMethod)
if !ok {
return structs.Event{}, false
}
return structs.Event{
Topic: structs.TopicACLAuthMethod,
Key: before.Name,
Payload: &structs.ACLAuthMethodEvent{
AuthMethod: before,
},
}, true
case "nodes":
before, ok := change.Before.(*structs.Node)
if !ok {
@@ -163,6 +177,18 @@ func eventFromChange(change memdb.Change) (structs.Event, bool) {
ACLRole: after,
},
}, true
case TableACLAuthMethods:
after, ok := change.After.(*structs.ACLAuthMethod)
if !ok {
return structs.Event{}, false
}
return structs.Event{
Topic: structs.TopicACLAuthMethod,
Key: after.Name,
Payload: &structs.ACLAuthMethodEvent{
AuthMethod: after,
},
}, true
case "evals":
after, ok := change.After.(*structs.Evaluation)
if !ok {

View File

@@ -10,6 +10,7 @@ import (
"github.com/hashicorp/nomad/helper/uuid"
"github.com/hashicorp/nomad/nomad/mock"
"github.com/hashicorp/nomad/nomad/structs"
"github.com/shoenig/test/must"
"github.com/stretchr/testify/require"
)
@@ -1051,6 +1052,58 @@ func Test_eventsFromChanges_ACLRole(t *testing.T) {
require.Equal(t, aclRole, eventPayload.ACLRole)
}
func Test_eventsFromChanges_ACLAuthMethod(t *testing.T) {
ci.Parallel(t)
testState := TestStateStoreCfg(t, TestStateStorePublisher(t))
defer testState.StopEventBroker()
// Generate a test ACL auth method
authMethod := mock.ACLAuthMethod()
// Upsert the auth method straight into state
writeTxn := testState.db.WriteTxn(10)
updated, err := testState.upsertACLAuthMethodTxn(10, writeTxn, authMethod)
must.True(t, updated)
must.NoError(t, err)
writeTxn.Txn.Commit()
// Pull the events from the stream.
upsertChange := Changes{Changes: writeTxn.Changes(), Index: 10, MsgType: structs.ACLAuthMethodsUpsertRequestType}
receivedChange := eventsFromChanges(writeTxn, upsertChange)
must.NotNil(t, receivedChange)
// Check the event, and its payload are what we are expecting.
must.Len(t, 1, receivedChange.Events)
must.Eq(t, structs.TopicACLAuthMethod, receivedChange.Events[0].Topic)
must.Eq(t, authMethod.Name, receivedChange.Events[0].Key)
must.Eq(t, structs.TypeACLAuthMethodUpserted, receivedChange.Events[0].Type)
must.Eq(t, uint64(10), receivedChange.Events[0].Index)
eventPayload := receivedChange.Events[0].Payload.(*structs.ACLAuthMethodEvent)
must.Eq(t, authMethod, eventPayload.AuthMethod)
// Delete the previously upserted auth method
deleteTxn := testState.db.WriteTxn(20)
must.NoError(t, testState.deleteACLAuthMethodTxn(deleteTxn, authMethod.Name))
must.NoError(t, deleteTxn.Insert(tableIndex, &IndexEntry{TableACLAuthMethods, 20}))
deleteTxn.Txn.Commit()
// Pull the events from the stream.
deleteChange := Changes{Changes: deleteTxn.Changes(), Index: 20, MsgType: structs.ACLAuthMethodsDeleteRequestType}
receivedDeleteChange := eventsFromChanges(deleteTxn, deleteChange)
must.NotNil(t, receivedDeleteChange)
// Check the event, and its payload are what we are expecting.
must.Len(t, 1, receivedDeleteChange.Events)
must.Eq(t, structs.TopicACLAuthMethod, receivedDeleteChange.Events[0].Topic)
must.Eq(t, authMethod.Name, receivedDeleteChange.Events[0].Key)
must.Eq(t, structs.TypeACLAuthMethodDeleted, receivedDeleteChange.Events[0].Type)
must.Eq(t, uint64(20), receivedDeleteChange.Events[0].Index)
eventPayload = receivedChange.Events[0].Payload.(*structs.ACLAuthMethodEvent)
must.Eq(t, authMethod, eventPayload.AuthMethod)
}
func requireNodeRegistrationEventEqual(t *testing.T, want, got structs.Event) {
t.Helper()

View File

@@ -16,16 +16,17 @@ type EventStreamWrapper struct {
type Topic string
const (
TopicDeployment Topic = "Deployment"
TopicEvaluation Topic = "Evaluation"
TopicAllocation Topic = "Allocation"
TopicJob Topic = "Job"
TopicNode Topic = "Node"
TopicACLPolicy Topic = "ACLPolicy"
TopicACLToken Topic = "ACLToken"
TopicACLRole Topic = "ACLRole"
TopicService Topic = "Service"
TopicAll Topic = "*"
TopicDeployment Topic = "Deployment"
TopicEvaluation Topic = "Evaluation"
TopicAllocation Topic = "Allocation"
TopicJob Topic = "Job"
TopicNode Topic = "Node"
TopicACLPolicy Topic = "ACLPolicy"
TopicACLToken Topic = "ACLToken"
TopicACLRole Topic = "ACLRole"
TopicACLAuthMethod Topic = "ACLAuthMethod"
TopicService Topic = "Service"
TopicAll Topic = "*"
TypeNodeRegistration = "NodeRegistration"
TypeNodeDeregistration = "NodeDeregistration"
@@ -49,6 +50,8 @@ const (
TypeACLPolicyUpserted = "ACLPolicyUpserted"
TypeACLRoleDeleted = "ACLRoleDeleted"
TypeACLRoleUpserted = "ACLRoleUpserted"
TypeACLAuthMethodUpserted = "ACLAuthMethodUpserted"
TypeACLAuthMethodDeleted = "ACLAuthMethodDeleted"
TypeServiceRegistration = "ServiceRegistration"
TypeServiceDeregistration = "ServiceDeregistration"
)
@@ -155,8 +158,14 @@ type ACLPolicyEvent struct {
ACLPolicy *ACLPolicy
}
// ACLRoleStreamEvent holds a newly updated or delete ACL role to be used as an
// ACLRoleStreamEvent holds a newly updated or deleted ACL role to be used as an
// event within the event stream.
type ACLRoleStreamEvent struct {
ACLRole *ACLRole
}
// ACLAuthMethodEvent holds a newly updated or deleted ACL auth method to be
// used as an event in the event stream.
type ACLAuthMethodEvent struct {
AuthMethod *ACLAuthMethod
}