-
Notifications
You must be signed in to change notification settings - Fork 78
/
taskutils.go
117 lines (100 loc) · 3.21 KB
/
taskutils.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package taskutils
import (
"context"
"time"
"github.com/juju/errors"
"github.com/loopfz/gadgeto/zesty"
"github.com/ovh/utask/models/resolution"
"github.com/ovh/utask/models/task"
"github.com/ovh/utask/models/tasktemplate"
"github.com/ovh/utask/pkg/auth"
"github.com/ovh/utask/pkg/constants"
)
// CreateTask creates a task with the given inputs, and creates a resolution if autorunnable
func CreateTask(c context.Context, dbp zesty.DBProvider, tt *tasktemplate.TaskTemplate, watcherUsernames []string, watcherGroups []string, resolverUsernames []string, resolverGroups []string, input map[string]interface{}, b *task.Batch, comment string, delay *string, tags map[string]string) (*task.Task, error) {
reqUsername := auth.GetIdentity(c)
reqGroups := auth.GetGroups(c)
if tt.Blocked {
return nil, errors.NewNotValid(nil, "Template not available (blocked)")
}
delayed := delay != nil
t, err := task.Create(dbp, tt, reqUsername, reqGroups, watcherUsernames, watcherGroups, resolverUsernames, resolverGroups, input, tags, b, delayed)
if err != nil {
return nil, err
}
if comment != "" {
com, err := task.CreateComment(dbp, t, reqUsername, comment)
if err != nil {
return nil, err
}
t.Comments = []*task.Comment{com}
}
if !tt.IsAutoRunnable() && tt.AllowAllResolverUsernames {
return nil, errors.Errorf("invalid tasktemplate: %q should be auto_runnable", tt.Name)
} else if !tt.IsAutoRunnable() {
t.NotifyValidationRequired(tt)
return t, nil
}
// task is AutoRunnable, creating resolution
admin := auth.IsAdmin(c) == nil
requester := (auth.IsRequester(c, t) == nil && tt.AllowAllResolverUsernames)
resolutionManager := auth.IsResolutionManager(c, tt, t, nil) == nil
if !requester && !resolutionManager && !admin {
t.NotifyValidationRequired(tt)
return t, nil
}
var delayUntil *time.Time
if delay != nil {
delayDuration, err := time.ParseDuration(*delay)
if err != nil {
return nil, errors.NewNotValid(err, "delay")
}
delayTime := time.Now().Add(delayDuration)
delayUntil = &delayTime
}
resolution, err := resolution.Create(dbp, t, nil, reqUsername, true, delayUntil)
if err != nil {
return nil, err
}
if resolution != nil {
t.Resolution = &resolution.PublicID
}
return t, nil
}
func ShouldResumeParentTask(dbp zesty.DBProvider, t *task.Task) (*task.Task, error) {
switch t.State {
case task.StateDone, task.StateWontfix, task.StateCancelled:
default:
return nil, nil
}
if t.Tags == nil {
return nil, nil
}
parentTaskID, ok := t.Tags[constants.SubtaskTagParentTaskID]
if !ok {
return nil, nil
}
parentTask, err := task.LoadFromPublicID(dbp, parentTaskID)
if err != nil {
return nil, err
}
switch parentTask.State {
case task.StateBlocked, task.StateRunning, task.StateWaiting:
default:
// not allowed to resume a parent task that is not either Waiting, Running or Blocked.
// Todo state should not be runned as it might need manual resolution from a granted resolver
return nil, nil
}
if parentTask.Resolution == nil {
return nil, nil
}
r, err := resolution.LoadFromPublicID(dbp, *parentTask.Resolution)
if err != nil {
return nil, err
}
switch r.State {
case resolution.StateCrashed, resolution.StatePaused:
return nil, nil
}
return parentTask, nil
}