forked from FeLvi-zzz/tentez
-
Notifications
You must be signed in to change notification settings - Fork 0
/
tentez.go
131 lines (105 loc) · 2.43 KB
/
tentez.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
package tentez
import (
"fmt"
"strings"
)
type Tentez interface {
Plan() error
Apply(isForce bool) error
Get() (map[TargetType]TargetsData, error)
Rollback(hasPause bool) error
}
type tentez struct {
Targets map[TargetType]Targets
Steps []Step
config Config
}
func New(targets map[TargetType]Targets, steps []Step) (tentez, error) {
config, err := newConfig()
if err != nil {
return tentez{}, err
}
return tentez{
Targets: targets,
Steps: steps,
config: config,
}, nil
}
func (t tentez) Apply(isForce bool) (err error) {
for i, step := range t.Steps {
fmt.Fprintf(t.config.io.out, "\n%d / %d steps\n", i+1, len(t.Steps))
switch step.Type {
case StepTypePause:
pause(t.config)
case StepTypeSleep:
sleep(step.SleepSeconds, t.config)
case StepTypeSwitch:
err = execSwitch(t.Targets, step.Weight, isForce, t.config)
default:
return fmt.Errorf(`unknown step type "%s"`, step.Type)
}
if err != nil {
return err
}
fmt.Fprintln(t.config.io.out, "")
}
fmt.Fprintln(t.config.io.out, "Apply complete!")
return nil
}
func (t tentez) Plan() error {
var output strings.Builder
fmt.Fprintln(&output, "Plan:")
targetNames := getTargetNames(t.Targets)
for i, step := range t.Steps {
fmt.Fprintf(&output, "%d. ", i+1)
switch step.Type {
case StepTypePause:
fmt.Fprintln(&output, "pause")
case StepTypeSwitch:
weight := step.Weight
fmt.Fprintf(&output, "switch old:new = %d:%d\n", weight.Old, weight.New)
for _, name := range targetNames {
fmt.Fprintf(&output, " - %s\n", name)
}
case StepTypeSleep:
fmt.Fprintf(&output, "sleep %ds\n", step.SleepSeconds)
default:
return fmt.Errorf(`unknown step type "%s"`, step.Type)
}
}
fmt.Fprintf(t.config.io.out, output.String())
return nil
}
func (t tentez) Get() (targetsMap map[TargetType]TargetsData, err error) {
mapData := map[TargetType]TargetsData{}
for targetType, targetResources := range t.Targets {
data, err := targetResources.fetchData(t.config)
if err != nil {
return nil, err
}
if data == nil {
continue
}
mapData[targetType] = data
}
return mapData, nil
}
func (t tentez) Rollback(hasPause bool) (err error) {
t.Steps = []Step{}
if hasPause {
t.Steps = append(t.Steps, Step{
Type: StepTypePause,
})
}
t.Steps = append(t.Steps, Step{
Type: StepTypeSwitch,
Weight: Weight{
Old: 100,
New: 0,
},
})
if err = t.Plan(); err != nil {
return err
}
return t.Apply(true)
}