github.com/justinjmoses/evergreen@v0.0.0-20170530173719-1d50e381ff0d/alerts/alerts_activation.go (about) 1 package alerts 2 3 import ( 4 "time" 5 6 "github.com/evergreen-ci/evergreen/model" 7 "github.com/evergreen-ci/evergreen/model/alert" 8 "github.com/evergreen-ci/evergreen/model/host" 9 "github.com/evergreen-ci/evergreen/model/task" 10 "github.com/evergreen-ci/evergreen/model/version" 11 "gopkg.in/mgo.v2/bson" 12 ) 13 14 func RunLastRevisionNotFoundTrigger(proj *model.ProjectRef, v *version.Version) error { 15 ctx := triggerContext{ 16 projectRef: proj, 17 version: v, 18 } 19 trigger := LastRevisionNotFound{} 20 // only one trigger to act on for now 21 shouldExec, err := trigger.ShouldExecute(ctx) 22 if err != nil { 23 return err 24 } 25 if !shouldExec { 26 return nil 27 } 28 err = alert.EnqueueAlertRequest(&alert.AlertRequest{ 29 Id: bson.NewObjectId(), 30 Trigger: trigger.Id(), 31 VersionId: v.Id, 32 CreatedAt: time.Now(), 33 }) 34 35 if err != nil { 36 return err 37 } 38 return storeTriggerBookkeeping(ctx, []Trigger{trigger}) 39 } 40 41 // RunTaskTriggers queues alerts for any active triggers on the tasks's state change. 42 func RunTaskFailureTriggers(taskId string) error { 43 t, err := task.FindOne(task.ById(taskId)) 44 if err != nil { 45 return err 46 } 47 ctx, err := getTaskTriggerContext(t) 48 if err != nil { 49 return err 50 } 51 activeTriggers, err := getActiveTaskFailureTriggers(*ctx) 52 if err != nil { 53 return err 54 } 55 for _, trigger := range activeTriggers { 56 req := &alert.AlertRequest{ 57 Id: bson.NewObjectId(), 58 Trigger: trigger.Id(), 59 TaskId: t.Id, 60 HostId: t.HostId, 61 Execution: t.Execution, 62 BuildId: t.BuildId, 63 VersionId: t.Version, 64 ProjectId: t.Project, 65 PatchId: "", 66 CreatedAt: time.Now(), 67 } 68 err := alert.EnqueueAlertRequest(req) 69 if err != nil { 70 return err 71 } 72 err = storeTriggerBookkeeping(*ctx, []Trigger{trigger}) 73 if err != nil { 74 return err 75 } 76 } 77 return nil 78 } 79 80 func RunHostProvisionFailTriggers(h *host.Host) error { 81 ctx := triggerContext{host: h} 82 trigger := &ProvisionFailed{} 83 // only one provision failure trigger to act on for now 84 shouldExec, err := trigger.ShouldExecute(ctx) 85 if err != nil { 86 return err 87 } 88 if !shouldExec { 89 return nil 90 } 91 92 err = alert.EnqueueAlertRequest(&alert.AlertRequest{ 93 Id: bson.NewObjectId(), 94 Trigger: trigger.Id(), 95 HostId: h.Id, 96 CreatedAt: time.Now(), 97 }) 98 if err != nil { 99 return err 100 } 101 return storeTriggerBookkeeping(ctx, []Trigger{trigger}) 102 } 103 104 func RunSpawnWarningTriggers(host *host.Host) error { 105 ctx := triggerContext{host: host} 106 for _, trigger := range SpawnWarningTriggers { 107 shouldExec, err := trigger.ShouldExecute(ctx) 108 if err != nil { 109 return err 110 } 111 if shouldExec { 112 err := alert.EnqueueAlertRequest(&alert.AlertRequest{ 113 Id: bson.NewObjectId(), 114 Trigger: trigger.Id(), 115 HostId: host.Id, 116 CreatedAt: time.Now(), 117 }) 118 if err != nil { 119 return err 120 } 121 err = storeTriggerBookkeeping(ctx, []Trigger{trigger}) 122 if err != nil { 123 return err 124 } 125 } 126 } 127 return nil 128 } 129 130 func getTaskTriggerContext(t *task.Task) (*triggerContext, error) { 131 ctx := triggerContext{task: t} 132 t, err := task.FindOne(task.ByBeforeRevisionWithStatuses(t.RevisionOrderNumber, task.CompletedStatuses, t.BuildVariant, 133 t.DisplayName, t.Project). 134 Sort([]string{"-" + task.RevisionOrderNumberKey})) 135 if err != nil { 136 return nil, err 137 } 138 if t != nil { 139 ctx.previousCompleted = t 140 } 141 return &ctx, nil 142 } 143 144 // getActiveTaskTriggers returns a list of the triggers that should be executed for the given task, 145 // by testing the result of each one's ShouldExecute method. 146 func getActiveTaskFailureTriggers(ctx triggerContext) ([]Trigger, error) { 147 if ctx.task == nil { 148 return nil, nil 149 } 150 151 activeTriggers := []Trigger{} 152 for _, trigger := range AvailableTaskFailTriggers { 153 shouldExec, err := trigger.ShouldExecute(ctx) 154 if err != nil { 155 return nil, err 156 } 157 if shouldExec { 158 activeTriggers = append(activeTriggers, trigger) 159 } 160 } 161 return activeTriggers, nil 162 } 163 164 // storeTriggerBookkeeping runs through any trigger bookkeeping that must be done in order to 165 // "remember" the state of the trigger for previous executions. 166 func storeTriggerBookkeeping(ctx triggerContext, triggers []Trigger) error { 167 for _, trigger := range triggers { 168 alertRecord := trigger.CreateAlertRecord(ctx) 169 if alertRecord == nil { 170 continue 171 } 172 173 err := alertRecord.Insert() 174 if err != nil { 175 return err 176 } 177 } 178 return nil 179 }