github.com/hernad/nomad@v1.6.112/nomad/state/events.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: MPL-2.0 3 4 package state 5 6 import ( 7 memdb "github.com/hashicorp/go-memdb" 8 "github.com/hernad/nomad/nomad/structs" 9 ) 10 11 var MsgTypeEvents = map[structs.MessageType]string{ 12 structs.NodeRegisterRequestType: structs.TypeNodeRegistration, 13 structs.NodeDeregisterRequestType: structs.TypeNodeDeregistration, 14 structs.UpsertNodeEventsType: structs.TypeNodeEvent, 15 structs.NodePoolUpsertRequestType: structs.TypeNodePoolUpserted, 16 structs.NodePoolDeleteRequestType: structs.TypeNodePoolDeleted, 17 structs.EvalUpdateRequestType: structs.TypeEvalUpdated, 18 structs.AllocClientUpdateRequestType: structs.TypeAllocationUpdated, 19 structs.JobRegisterRequestType: structs.TypeJobRegistered, 20 structs.NodeUpdateStatusRequestType: structs.TypeNodeEvent, 21 structs.JobDeregisterRequestType: structs.TypeJobDeregistered, 22 structs.JobBatchDeregisterRequestType: structs.TypeJobBatchDeregistered, 23 structs.AllocUpdateDesiredTransitionRequestType: structs.TypeAllocationUpdateDesiredStatus, 24 structs.NodeUpdateEligibilityRequestType: structs.TypeNodeDrain, 25 structs.NodeUpdateDrainRequestType: structs.TypeNodeDrain, 26 structs.BatchNodeUpdateDrainRequestType: structs.TypeNodeDrain, 27 structs.DeploymentStatusUpdateRequestType: structs.TypeDeploymentUpdate, 28 structs.DeploymentPromoteRequestType: structs.TypeDeploymentPromotion, 29 structs.DeploymentAllocHealthRequestType: structs.TypeDeploymentAllocHealth, 30 structs.ApplyPlanResultsRequestType: structs.TypePlanResult, 31 structs.ACLTokenDeleteRequestType: structs.TypeACLTokenDeleted, 32 structs.ACLTokenUpsertRequestType: structs.TypeACLTokenUpserted, 33 structs.ACLPolicyDeleteRequestType: structs.TypeACLPolicyDeleted, 34 structs.ACLPolicyUpsertRequestType: structs.TypeACLPolicyUpserted, 35 structs.ACLRolesDeleteByIDRequestType: structs.TypeACLRoleDeleted, 36 structs.ACLRolesUpsertRequestType: structs.TypeACLRoleUpserted, 37 structs.ACLAuthMethodsUpsertRequestType: structs.TypeACLAuthMethodUpserted, 38 structs.ACLAuthMethodsDeleteRequestType: structs.TypeACLAuthMethodDeleted, 39 structs.ACLBindingRulesUpsertRequestType: structs.TypeACLBindingRuleUpserted, 40 structs.ACLBindingRulesDeleteRequestType: structs.TypeACLBindingRuleDeleted, 41 structs.ServiceRegistrationUpsertRequestType: structs.TypeServiceRegistration, 42 structs.ServiceRegistrationDeleteByIDRequestType: structs.TypeServiceDeregistration, 43 structs.ServiceRegistrationDeleteByNodeIDRequestType: structs.TypeServiceDeregistration, 44 } 45 46 func eventsFromChanges(tx ReadTxn, changes Changes) *structs.Events { 47 eventType, ok := MsgTypeEvents[changes.MsgType] 48 if !ok { 49 return nil 50 } 51 52 var events []structs.Event 53 for _, change := range changes.Changes { 54 if event, ok := eventFromChange(change); ok { 55 event.Type = eventType 56 event.Index = changes.Index 57 events = append(events, event) 58 } 59 } 60 61 return &structs.Events{Index: changes.Index, Events: events} 62 } 63 64 func eventFromChange(change memdb.Change) (structs.Event, bool) { 65 if change.Deleted() { 66 switch change.Table { 67 case "acl_token": 68 before, ok := change.Before.(*structs.ACLToken) 69 if !ok { 70 return structs.Event{}, false 71 } 72 73 return structs.Event{ 74 Topic: structs.TopicACLToken, 75 Key: before.AccessorID, 76 Payload: structs.NewACLTokenEvent(before), 77 }, true 78 case "acl_policy": 79 before, ok := change.Before.(*structs.ACLPolicy) 80 if !ok { 81 return structs.Event{}, false 82 } 83 return structs.Event{ 84 Topic: structs.TopicACLPolicy, 85 Key: before.Name, 86 Payload: &structs.ACLPolicyEvent{ 87 ACLPolicy: before, 88 }, 89 }, true 90 case TableACLRoles: 91 before, ok := change.Before.(*structs.ACLRole) 92 if !ok { 93 return structs.Event{}, false 94 } 95 return structs.Event{ 96 Topic: structs.TopicACLRole, 97 Key: before.ID, 98 FilterKeys: []string{before.Name}, 99 Payload: &structs.ACLRoleStreamEvent{ 100 ACLRole: before, 101 }, 102 }, true 103 case TableACLAuthMethods: 104 before, ok := change.Before.(*structs.ACLAuthMethod) 105 if !ok { 106 return structs.Event{}, false 107 } 108 return structs.Event{ 109 Topic: structs.TopicACLAuthMethod, 110 Key: before.Name, 111 Payload: &structs.ACLAuthMethodEvent{ 112 AuthMethod: before, 113 }, 114 }, true 115 case TableACLBindingRules: 116 before, ok := change.Before.(*structs.ACLBindingRule) 117 if !ok { 118 return structs.Event{}, false 119 } 120 return structs.Event{ 121 Topic: structs.TopicACLBindingRule, 122 Key: before.ID, 123 FilterKeys: []string{before.AuthMethod}, 124 Payload: &structs.ACLBindingRuleEvent{ 125 ACLBindingRule: before, 126 }, 127 }, true 128 case "nodes": 129 before, ok := change.Before.(*structs.Node) 130 if !ok { 131 return structs.Event{}, false 132 } 133 134 before = before.Sanitize() 135 return structs.Event{ 136 Topic: structs.TopicNode, 137 Key: before.ID, 138 Payload: &structs.NodeStreamEvent{ 139 Node: before, 140 }, 141 }, true 142 case TableNodePools: 143 before, ok := change.Before.(*structs.NodePool) 144 if !ok { 145 return structs.Event{}, false 146 } 147 return structs.Event{ 148 Topic: structs.TopicNodePool, 149 Key: before.Name, 150 Payload: &structs.NodePoolEvent{ 151 NodePool: before, 152 }, 153 }, true 154 case TableServiceRegistrations: 155 before, ok := change.Before.(*structs.ServiceRegistration) 156 if !ok { 157 return structs.Event{}, false 158 } 159 return structs.Event{ 160 Topic: structs.TopicService, 161 Key: before.ID, 162 FilterKeys: []string{ 163 before.JobID, 164 before.ServiceName, 165 }, 166 Namespace: before.Namespace, 167 Payload: &structs.ServiceRegistrationStreamEvent{ 168 Service: before, 169 }, 170 }, true 171 } 172 return structs.Event{}, false 173 } 174 175 switch change.Table { 176 case "acl_token": 177 after, ok := change.After.(*structs.ACLToken) 178 if !ok { 179 return structs.Event{}, false 180 } 181 182 return structs.Event{ 183 Topic: structs.TopicACLToken, 184 Key: after.AccessorID, 185 Payload: structs.NewACLTokenEvent(after), 186 }, true 187 case "acl_policy": 188 after, ok := change.After.(*structs.ACLPolicy) 189 if !ok { 190 return structs.Event{}, false 191 } 192 return structs.Event{ 193 Topic: structs.TopicACLPolicy, 194 Key: after.Name, 195 Payload: &structs.ACLPolicyEvent{ 196 ACLPolicy: after, 197 }, 198 }, true 199 case TableACLRoles: 200 after, ok := change.After.(*structs.ACLRole) 201 if !ok { 202 return structs.Event{}, false 203 } 204 return structs.Event{ 205 Topic: structs.TopicACLRole, 206 Key: after.ID, 207 FilterKeys: []string{after.Name}, 208 Payload: &structs.ACLRoleStreamEvent{ 209 ACLRole: after, 210 }, 211 }, true 212 case TableACLAuthMethods: 213 after, ok := change.After.(*structs.ACLAuthMethod) 214 if !ok { 215 return structs.Event{}, false 216 } 217 return structs.Event{ 218 Topic: structs.TopicACLAuthMethod, 219 Key: after.Name, 220 Payload: &structs.ACLAuthMethodEvent{ 221 AuthMethod: after, 222 }, 223 }, true 224 case TableACLBindingRules: 225 after, ok := change.After.(*structs.ACLBindingRule) 226 if !ok { 227 return structs.Event{}, false 228 } 229 return structs.Event{ 230 Topic: structs.TopicACLBindingRule, 231 Key: after.ID, 232 FilterKeys: []string{after.AuthMethod}, 233 Payload: &structs.ACLBindingRuleEvent{ 234 ACLBindingRule: after, 235 }, 236 }, true 237 case "evals": 238 after, ok := change.After.(*structs.Evaluation) 239 if !ok { 240 return structs.Event{}, false 241 } 242 return structs.Event{ 243 Topic: structs.TopicEvaluation, 244 Key: after.ID, 245 FilterKeys: []string{ 246 after.JobID, 247 after.DeploymentID, 248 }, 249 Namespace: after.Namespace, 250 Payload: &structs.EvaluationEvent{ 251 Evaluation: after, 252 }, 253 }, true 254 case "allocs": 255 after, ok := change.After.(*structs.Allocation) 256 if !ok { 257 return structs.Event{}, false 258 } 259 alloc := after.Copy() 260 261 filterKeys := []string{ 262 alloc.JobID, 263 alloc.DeploymentID, 264 } 265 266 // remove job info to help keep size of alloc event down 267 alloc.Job = nil 268 269 return structs.Event{ 270 Topic: structs.TopicAllocation, 271 Key: after.ID, 272 FilterKeys: filterKeys, 273 Namespace: after.Namespace, 274 Payload: &structs.AllocationEvent{ 275 Allocation: alloc, 276 }, 277 }, true 278 case "jobs": 279 after, ok := change.After.(*structs.Job) 280 if !ok { 281 return structs.Event{}, false 282 } 283 return structs.Event{ 284 Topic: structs.TopicJob, 285 Key: after.ID, 286 Namespace: after.Namespace, 287 Payload: &structs.JobEvent{ 288 Job: after, 289 }, 290 }, true 291 case "nodes": 292 after, ok := change.After.(*structs.Node) 293 if !ok { 294 return structs.Event{}, false 295 } 296 297 after = after.Sanitize() 298 return structs.Event{ 299 Topic: structs.TopicNode, 300 Key: after.ID, 301 Payload: &structs.NodeStreamEvent{ 302 Node: after, 303 }, 304 }, true 305 case TableNodePools: 306 after, ok := change.After.(*structs.NodePool) 307 if !ok { 308 return structs.Event{}, false 309 } 310 return structs.Event{ 311 Topic: structs.TopicNodePool, 312 Key: after.Name, 313 Payload: &structs.NodePoolEvent{ 314 NodePool: after, 315 }, 316 }, true 317 case "deployment": 318 after, ok := change.After.(*structs.Deployment) 319 if !ok { 320 return structs.Event{}, false 321 } 322 return structs.Event{ 323 Topic: structs.TopicDeployment, 324 Key: after.ID, 325 Namespace: after.Namespace, 326 FilterKeys: []string{after.JobID}, 327 Payload: &structs.DeploymentEvent{ 328 Deployment: after, 329 }, 330 }, true 331 case TableServiceRegistrations: 332 after, ok := change.After.(*structs.ServiceRegistration) 333 if !ok { 334 return structs.Event{}, false 335 } 336 return structs.Event{ 337 Topic: structs.TopicService, 338 Key: after.ID, 339 FilterKeys: []string{ 340 after.JobID, 341 after.ServiceName, 342 }, 343 Namespace: after.Namespace, 344 Payload: &structs.ServiceRegistrationStreamEvent{ 345 Service: after, 346 }, 347 }, true 348 } 349 350 return structs.Event{}, false 351 }