-
Notifications
You must be signed in to change notification settings - Fork 152
/
job_addhook.go
133 lines (114 loc) · 3.53 KB
/
job_addhook.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
package survey
import (
"context"
"errors"
"fmt"
"github.com/AlecAivazis/survey/v2"
"github.com/raystack/optimus/client/local/model"
"github.com/raystack/optimus/internal/models"
"github.com/raystack/optimus/sdk/plugin"
)
// JobAddHookSurvey defines survey for job add hook
type JobAddHookSurvey struct {
jobSurvey *JobSurvey
}
// NewJobAddHookSurvey initializes job add hook survey
func NewJobAddHookSurvey() *JobAddHookSurvey {
return &JobAddHookSurvey{
jobSurvey: NewJobSurvey(),
}
}
// AskToAddHook asks questions to add hook to a job
func (j *JobAddHookSurvey) AskToAddHook(pluginRepo *models.PluginRepository, jobSpec *model.JobSpec) (*model.JobSpec, error) {
newJobSpec := *jobSpec
availableHookNames := j.getAvailableHookNames(pluginRepo)
if len(availableHookNames) == 0 {
return nil, errors.New("no supported hook plugin found")
}
selectedHookName, err := j.askToSelectHook(availableHookNames)
if err != nil {
return nil, err
}
if j.isSelectedHookAlreadyInJob(jobSpec, selectedHookName) {
return nil, fmt.Errorf("hook %s already exists for this job", selectedHookName)
}
selectedHook, err := pluginRepo.GetByName(selectedHookName)
if err != nil {
return nil, err
}
var config map[string]string
if cliMod := selectedHook.GetSurveyMod(); cliMod != nil {
ctx := context.Background()
hookAnswers, err := j.askHookQuestions(ctx, cliMod, jobSpec.Name)
if err != nil {
return nil, err
}
config, err = j.getHookConfig(cliMod, hookAnswers)
if err != nil {
return nil, err
}
}
// TODO: remove the golint exception below
newJobSpec.Hooks = append(jobSpec.Hooks, model.JobSpecHook{ //nolint:gocritic
Name: selectedHook.Info().Name,
Config: config,
})
return &newJobSpec, nil
}
func (*JobAddHookSurvey) getHookConfig(cliMod plugin.CommandLineMod, answers plugin.Answers) (map[string]string, error) {
ctx := context.Background()
configRequest := plugin.DefaultConfigRequest{Answers: answers}
generatedConfigResponse, err := cliMod.DefaultConfig(ctx, configRequest)
if err != nil {
return nil, err
}
config := map[string]string{}
if generatedConfigResponse != nil {
for _, cfg := range generatedConfigResponse.Config {
config[cfg.Name] = cfg.Value
}
}
return config, nil
}
func (*JobAddHookSurvey) getAvailableHookNames(pluginRepo *models.PluginRepository) []string {
var output []string
for _, hook := range pluginRepo.GetHooks() {
output = append(output, hook.Info().Name)
}
return output
}
func (*JobAddHookSurvey) askToSelectHook(options []string) (string, error) {
question := &survey.Select{
Message: "Select hook to attach?",
Options: options,
}
var answer string
if err := survey.AskOne(question, &answer); err != nil {
return "", err
}
return answer, nil
}
func (*JobAddHookSurvey) isSelectedHookAlreadyInJob(jobSpec *model.JobSpec, selectedHookName string) bool {
for _, hook := range jobSpec.Hooks {
if hook.Name == selectedHookName {
return true
}
}
return false
}
func (j *JobAddHookSurvey) askHookQuestions(ctx context.Context, cliMod plugin.CommandLineMod, jobName string) (plugin.Answers, error) {
questionRequest := plugin.GetQuestionsRequest{JobName: jobName}
questionResponse, err := cliMod.GetQuestions(ctx, questionRequest)
if err != nil {
return nil, err
}
answers := plugin.Answers{}
for _, question := range questionResponse.Questions { //nolint: gocritic
responseAnswer, err := j.jobSurvey.askCliModSurveyQuestion(ctx, cliMod, question)
if err != nil {
return nil, err
}
answers = append(answers, responseAnswer...)
}
return answers, nil
}