open-nomad/nomad/state/events.go

213 lines
5.7 KiB
Go

package state
import (
memdb "github.com/hashicorp/go-memdb"
"github.com/hashicorp/nomad/nomad/structs"
)
var MsgTypeEvents = map[structs.MessageType]string{
structs.NodeRegisterRequestType: structs.TypeNodeRegistration,
structs.NodeDeregisterRequestType: structs.TypeNodeDeregistration,
structs.UpsertNodeEventsType: structs.TypeNodeEvent,
structs.EvalUpdateRequestType: structs.TypeEvalUpdated,
structs.AllocClientUpdateRequestType: structs.TypeAllocationUpdated,
structs.JobRegisterRequestType: structs.TypeJobRegistered,
structs.AllocUpdateRequestType: structs.TypeAllocationUpdated,
structs.NodeUpdateStatusRequestType: structs.TypeNodeEvent,
structs.JobDeregisterRequestType: structs.TypeJobDeregistered,
structs.JobBatchDeregisterRequestType: structs.TypeJobBatchDeregistered,
structs.AllocUpdateDesiredTransitionRequestType: structs.TypeAllocationUpdateDesiredStatus,
structs.NodeUpdateEligibilityRequestType: structs.TypeNodeDrain,
structs.NodeUpdateDrainRequestType: structs.TypeNodeDrain,
structs.BatchNodeUpdateDrainRequestType: structs.TypeNodeDrain,
structs.DeploymentStatusUpdateRequestType: structs.TypeDeploymentUpdate,
structs.DeploymentPromoteRequestType: structs.TypeDeploymentPromotion,
structs.DeploymentAllocHealthRequestType: structs.TypeDeploymentAllocHealth,
structs.ApplyPlanResultsRequestType: structs.TypePlanResult,
structs.ACLTokenDeleteRequestType: structs.TypeACLTokenDeleted,
structs.ACLTokenUpsertRequestType: structs.TypeACLTokenUpserted,
structs.ACLPolicyDeleteRequestType: structs.TypeACLPolicyDeleted,
structs.ACLPolicyUpsertRequestType: structs.TypeACLPolicyUpserted,
}
func eventsFromChanges(tx ReadTxn, changes Changes) *structs.Events {
eventType, ok := MsgTypeEvents[changes.MsgType]
if !ok {
return nil
}
var events []structs.Event
for _, change := range changes.Changes {
if event, ok := eventFromChange(change); ok {
event.Type = eventType
event.Index = changes.Index
events = append(events, event)
}
}
return &structs.Events{Index: changes.Index, Events: events}
}
func eventFromChange(change memdb.Change) (structs.Event, bool) {
if change.Deleted() {
switch change.Table {
case "acl_token":
before, ok := change.Before.(*structs.ACLToken)
if !ok {
return structs.Event{}, false
}
return structs.Event{
Topic: structs.TopicACLToken,
Key: before.AccessorID,
Payload: structs.ACLTokenEvent{
ACLToken: before,
},
}, true
case "acl_policy":
before, ok := change.Before.(*structs.ACLPolicy)
if !ok {
return structs.Event{}, false
}
return structs.Event{
Topic: structs.TopicACLPolicy,
Key: before.Name,
Payload: structs.ACLPolicyEvent{
ACLPolicy: before,
},
}, true
case "nodes":
before, ok := change.Before.(*structs.Node)
if !ok {
return structs.Event{}, false
}
// Node secret ID should not be included
node := before.Copy()
node.SecretID = ""
return structs.Event{
Topic: structs.TopicNode,
Key: node.ID,
Payload: &structs.NodeStreamEvent{
Node: node,
},
}, true
}
return structs.Event{}, false
}
switch change.Table {
case "acl_token":
after, ok := change.After.(*structs.ACLToken)
if !ok {
return structs.Event{}, false
}
return structs.Event{
Topic: structs.TopicACLToken,
Key: after.AccessorID,
Payload: structs.ACLTokenEvent{
ACLToken: after,
},
}, true
case "acl_policy":
after, ok := change.After.(*structs.ACLPolicy)
if !ok {
return structs.Event{}, false
}
return structs.Event{
Topic: structs.TopicACLPolicy,
Key: after.Name,
Payload: structs.ACLPolicyEvent{
ACLPolicy: after,
},
}, true
case "evals":
after, ok := change.After.(*structs.Evaluation)
if !ok {
return structs.Event{}, false
}
return structs.Event{
Topic: structs.TopicEvaluation,
Key: after.ID,
FilterKeys: []string{
after.JobID,
after.DeploymentID,
},
Namespace: after.Namespace,
Payload: &structs.EvaluationEvent{
Evaluation: after,
},
}, true
case "allocs":
after, ok := change.After.(*structs.Allocation)
if !ok {
return structs.Event{}, false
}
alloc := after.Copy()
filterKeys := []string{
alloc.JobID,
alloc.DeploymentID,
}
// remove job info to help keep size of alloc event down
alloc.Job = nil
return structs.Event{
Topic: structs.TopicAllocation,
Key: after.ID,
FilterKeys: filterKeys,
Namespace: after.Namespace,
Payload: &structs.AllocationEvent{
Allocation: alloc,
},
}, true
case "jobs":
after, ok := change.After.(*structs.Job)
if !ok {
return structs.Event{}, false
}
return structs.Event{
Topic: structs.TopicJob,
Key: after.ID,
Namespace: after.Namespace,
Payload: &structs.JobEvent{
Job: after,
},
}, true
case "nodes":
after, ok := change.After.(*structs.Node)
if !ok {
return structs.Event{}, false
}
// Node secret ID should not be included
node := after.Copy()
node.SecretID = ""
return structs.Event{
Topic: structs.TopicNode,
Key: node.ID,
Payload: &structs.NodeStreamEvent{
Node: node,
},
}, true
case "deployment":
after, ok := change.After.(*structs.Deployment)
if !ok {
return structs.Event{}, false
}
return structs.Event{
Topic: structs.TopicDeployment,
Key: after.ID,
Namespace: after.Namespace,
FilterKeys: []string{after.JobID},
Payload: &structs.DeploymentEvent{
Deployment: after,
},
}, true
}
return structs.Event{}, false
}