/
before_run_check.go
134 lines (112 loc) · 4 KB
/
before_run_check.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
// Copyright (c) 2021 Terminus, Inc.
//
// This program is free software: you can use, redistribute, and/or modify
// it under the terms of the GNU Affero General Public License, version 3
// or later ("AGPL"), as published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package precheck_before_pop
import (
"fmt"
"github.com/erda-project/erda/apistructs"
"github.com/erda-project/erda/bundle"
"github.com/erda-project/erda/modules/pipeline/dbclient"
"github.com/erda-project/erda/pkg/parser/pipelineyml"
"github.com/erda-project/erda/pkg/pipeline_network_hook_client"
)
const CheckResultSuccess = "success"
const CheckResultFailed = "failed"
const HookType = "before-run-check"
type HttpBeforeCheckRun struct {
PipelineID uint64
Bdl *bundle.Bundle
DBClient *dbclient.Client
}
type RetryOption struct {
IntervalSecond uint64 `json:"intervalSecond"`
IntervalMillisecond uint64 `json:"intervalMillisecond"`
}
type CheckRunResult struct {
CheckResult string `json:"checkResult"`
RetryOption RetryOption `json:"retryOption"`
Message string `json:"message"`
}
type CheckRunResultRequest struct {
Hook string `json:"hook"`
Labels map[string]interface{} `json:"labels"`
Source string `json:"source"`
PipelineYamlName string `json:"pipelineYamlName"`
PipelineYamlContent string `json:"pipelineYamlContent"`
}
type CheckRunResultResponse struct {
apistructs.Header
CheckRunResult CheckRunResult `json:"data"`
}
type HookBeforeCheckRun interface {
CheckRun() (*CheckRunResult, error)
GetPipelineWithTasks()
}
// filter out the corresponding type of hook
func (beforeCheckRun *HttpBeforeCheckRun) matchHookType(lifecycle []*pipelineyml.NetworkHookInfo) []*pipelineyml.NetworkHookInfo {
var result []*pipelineyml.NetworkHookInfo
for _, v := range lifecycle {
if v.Hook == HookType {
result = append(result, v)
}
}
return result
}
func (beforeCheckRun HttpBeforeCheckRun) CheckRun() (result *CheckRunResult, err error) {
if beforeCheckRun.PipelineID <= 0 {
return nil, fmt.Errorf("pipelineID can not empty")
}
pipelineWithTasks, err := beforeCheckRun.DBClient.GetPipelineWithTasks(beforeCheckRun.PipelineID)
if err != nil {
return nil, err
}
yml, err := pipelineyml.New(
[]byte(pipelineWithTasks.Pipeline.PipelineYml),
)
if err != nil {
return nil, err
}
// if the network hook is not specified
//the network hook will be passed by success
matchInfo := beforeCheckRun.matchHookType(yml.Spec().Lifecycle)
if matchInfo == nil {
return &CheckRunResult{
CheckResult: CheckResultSuccess,
}, nil
}
pipeline := pipelineWithTasks.Pipeline
for _, info := range matchInfo {
var checkRunResultRequest CheckRunResultRequest
checkRunResultRequest.Hook = info.Hook
checkRunResultRequest.PipelineYamlContent = pipeline.PipelineYml
checkRunResultRequest.Source = pipeline.PipelineSource.String()
checkRunResultRequest.PipelineYamlName = pipeline.PipelineYmlName
checkRunResultRequest.Labels = map[string]interface{}{}
checkRunResultRequest.Labels["pipelineID"] = pipeline.ID
checkRunResultRequest.Labels["pipelineLabels"] = info.Labels
var response CheckRunResultResponse
err := pipeline_network_hook_client.PostLifecycleHookHttpClient(info.Client, checkRunResultRequest, &response)
if err != nil {
return nil, err
}
if !response.Success {
return nil, fmt.Errorf("response is empty or response not success")
}
// return directly if there is an failed
if response.CheckRunResult.CheckResult == CheckResultFailed {
return &response.CheckRunResult, nil
}
}
return &CheckRunResult{
CheckResult: CheckResultSuccess,
}, nil
}