-
Notifications
You must be signed in to change notification settings - Fork 173
/
plan.go
159 lines (136 loc) · 4.21 KB
/
plan.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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
package main
import (
"fmt"
"log"
"net/url"
"sort"
"strconv"
"strings"
"time"
"github.com/logrusorgru/aurora"
)
// decisionType type representing type of Decision for console output
type decisionType int
const (
create decisionType = iota + 1
change
delete
noop
ignored
)
var decisionColor = map[decisionType]aurora.Color{
create: aurora.GreenFg,
change: aurora.BrownFg,
delete: aurora.RedFg,
noop: aurora.CyanFg,
ignored: aurora.GrayFg,
}
// orderedDecision type representing a Decision and it's priority weight
type orderedDecision struct {
Description string
Priority int
Type decisionType
}
// orderedCommand type representing a Command and it's priority weight and the targeted release from the desired state
type orderedCommand struct {
Command command
Priority int
targetRelease *release
}
// plan type representing the plan of actions to make the desired state come true.
type plan struct {
Commands []orderedCommand
Decisions []orderedDecision
Created time.Time
}
// createPlan initializes an empty plan
func createPlan() plan {
p := plan{
Commands: []orderedCommand{},
Decisions: []orderedDecision{},
Created: time.Now().UTC(),
}
return p
}
// addCommand adds a command type to the plan
func (p *plan) addCommand(cmd command, priority int, r *release) {
oc := orderedCommand{
Command: cmd,
Priority: priority,
targetRelease: r,
}
p.Commands = append(p.Commands, oc)
}
// addDecision adds a decision type to the plan
func (p *plan) addDecision(decision string, priority int, decisionType decisionType) {
od := orderedDecision{
Description: decision,
Priority: priority,
Type: decisionType,
}
p.Decisions = append(p.Decisions, od)
}
// execPlan executes the commands (actions) which were added to the plan.
func (p plan) execPlan() {
p.sortPlan()
if len(p.Commands) > 0 {
log.Println("INFO: Executing the plan ... ")
} else {
log.Println("INFO: Nothing to execute ... ")
}
for _, cmd := range p.Commands {
log.Println("INFO: " + cmd.Command.Description)
if exitCode, msg, _ := cmd.Command.exec(debug, verbose); exitCode != 0 {
var errorMsg string
if errorMsg = msg; !verbose {
errorMsg = strings.Split(msg, "---")[0]
}
logError(fmt.Sprintf("Command returned with exit code: %d. And error message: %s ", exitCode, errorMsg))
} else {
log.Println(style.Cyan(msg))
if cmd.targetRelease != nil && !dryRun {
labelResource(cmd.targetRelease)
}
log.Println("INFO: finished " + cmd.Command.Description)
if _, err := url.ParseRequestURI(s.Settings.SlackWebhook); err == nil {
notifySlack(cmd.Command.Description+" ... SUCCESS!", s.Settings.SlackWebhook, false, true)
}
}
}
}
// printPlanCmds prints the actual commands that will be executed as part of a plan.
func (p plan) printPlanCmds() {
fmt.Println("Printing the commands of the current plan ...")
for _, cmd := range p.Commands {
fmt.Println(cmd.Command.Args[1])
}
}
// printPlan prints the decisions made in a plan.
func (p plan) printPlan() {
log.Println("----------------------")
log.Println(style.Bold(style.Blue("INFO: Plan generated at: " + p.Created.Format("Mon Jan _2 2006 15:04:05"))))
for _, decision := range p.Decisions {
log.Println(style.Colorize(decision.Description+" -- priority: "+strconv.Itoa(decision.Priority), decisionColor[decision.Type]))
}
}
// sendPlanToSlack sends the description of plan commands to slack if a webhook is provided.
func (p plan) sendPlanToSlack() {
if _, err := url.ParseRequestURI(s.Settings.SlackWebhook); err == nil {
str := ""
for _, c := range p.Commands {
str = str + c.Command.Description + "\n"
}
notifySlack(strings.TrimRight(str, "\n"), s.Settings.SlackWebhook, false, false)
}
}
// sortPlan sorts the slices of commands and decisions based on priorities
// the lower the priority value the earlier a command should be attempted
func (p plan) sortPlan() {
log.Println("INFO: sorting the commands in the plan based on priorities (order flags) ... ")
sort.SliceStable(p.Commands, func(i, j int) bool {
return p.Commands[i].Priority < p.Commands[j].Priority
})
sort.SliceStable(p.Decisions, func(i, j int) bool {
return p.Decisions[i].Priority < p.Decisions[j].Priority
})
}