-
Notifications
You must be signed in to change notification settings - Fork 439
/
Copy pathprocess_parameters.go
293 lines (253 loc) · 8.93 KB
/
process_parameters.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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
package workflow
import (
"context"
"fmt"
"strings"
"github.com/fsamin/go-dump"
"github.com/ovh/cds/sdk"
"github.com/ovh/cds/sdk/interpolate"
"github.com/ovh/cds/sdk/telemetry"
)
func getNodeJobRunParameters(j sdk.Job, run *sdk.WorkflowNodeRun, stage *sdk.Stage) ([]sdk.Parameter, *sdk.MultiError) {
params := run.BuildParameters
tmp := map[string]string{
"cds.stage": stage.Name,
"cds.job": j.Action.Name,
}
errm := &sdk.MultiError{}
for k, v := range tmp {
s, err := interpolate.Do(v, tmp)
if err != nil {
errm.Append(err)
continue
}
sdk.AddParameter(¶ms, k, sdk.StringParameter, s)
}
if errm.IsEmpty() {
return params, nil
}
return params, errm
}
// getBuildParameterFromNodeContext returns the parameters compute from node context (project, application, pipeline, pyaload)
func getBuildParameterFromNodeContext(proj sdk.Project, w sdk.Workflow, runContext nodeRunContext, pipelineParameters []sdk.Parameter, payload interface{}, hookEvent *sdk.WorkflowNodeRunHookEvent) ([]sdk.Parameter, error) {
tmpProj := sdk.ParametersFromProjectVariables(proj)
vars := make(map[string]string, len(tmpProj))
for k, v := range tmpProj {
vars[k] = v
}
tmpProj = sdk.ParametersFromProjectKeys(proj)
for k, v := range tmpProj {
vars[k] = v
}
// COMPUTE APPLICATION VARIABLE
if runContext.Application.ID != 0 {
vars["cds.application"] = runContext.Application.Name
tmp := sdk.ParametersFromApplicationVariables(runContext.Application)
for k, v := range tmp {
vars[k] = v
}
tmp = sdk.ParametersFromApplicationKeys(runContext.Application)
for k, v := range tmp {
vars[k] = v
}
}
// COMPUTE ENVIRONMENT VARIABLE
if runContext.Environment.ID != 0 {
vars["cds.environment"] = runContext.Environment.Name
tmp := sdk.ParametersFromEnvironmentVariables(runContext.Environment)
for k, v := range tmp {
vars[k] = v
}
tmp = sdk.ParametersFromEnvironmentKeys(runContext.Environment)
for k, v := range tmp {
vars[k] = v
}
}
// COmpute integration from workflow
for _, integ := range runContext.WorkflowProjectIntegrations {
if !sdk.AllowIntegrationInVariable(integ.ProjectIntegration.Model) {
continue
}
prefix := sdk.GetIntegrationVariablePrefix(integ.ProjectIntegration.Model)
vars["cds.integration."+prefix] = integ.ProjectIntegration.Name
tmp := sdk.ParametersFromIntegration(prefix, integ.ProjectIntegration.Config)
for k, v := range tmp {
vars[k] = v
}
tmpWkfConf := sdk.ParametersFromIntegration(prefix, integ.Config)
for k, v := range tmpWkfConf {
vars[k] = v
}
}
// COMPUTE INTEGRATION VARIABLE FROM NODE CONTEXT
for _, integ := range runContext.ProjectIntegrations {
prefix := sdk.GetIntegrationVariablePrefix(integ.Model)
vars["cds.integration."+prefix] = integ.Name
tmp := sdk.ParametersFromIntegration(prefix, integ.Config)
for k, v := range tmp {
vars[k] = v
}
if integ.Model.Deployment {
// COMPUTE DEPLOYMENT STRATEGIES VARIABLE
if runContext.Application.ID != 0 {
for pfName, pfConfig := range runContext.Application.DeploymentStrategies {
if pfName == integ.Name {
tmp := sdk.ParametersFromIntegration(prefix, pfConfig)
for k, v := range tmp {
vars[k] = v
}
}
}
}
}
}
// COMPUTE PIPELINE PARAMETER
tmpPip := sdk.ParametersFromPipelineParameters(pipelineParameters)
for k, v := range tmpPip {
vars[k] = v
}
// COMPUTE PAYLOAD
e := dump.NewDefaultEncoder()
e.Formatters = []dump.KeyFormatterFunc{dump.WithDefaultLowerCaseFormatter()}
e.ExtraFields.DetailedMap = false
e.ExtraFields.DetailedStruct = false
e.ExtraFields.Len = false
e.ExtraFields.Type = false
tmpVars, errdump := e.ToStringMap(payload)
if errdump != nil {
return nil, sdk.WrapError(errdump, "do-dump error")
}
//Merge the dumped payload with vars
vars = sdk.ParametersMapMerge(vars, tmpVars)
vars["cds.project"] = w.ProjectKey
vars["cds.workflow"] = w.Name
vars["cds.pipeline"] = runContext.Pipeline.Name
// COMPUTE VCS STRATEGY VARIABLE
if runContext.Application.RepositoryStrategy.ConnectionType != "" {
vars["git.connection.type"] = runContext.Application.RepositoryStrategy.ConnectionType
if runContext.Application.RepositoryStrategy.SSHKey != "" {
vars["git.ssh.key"] = runContext.Application.RepositoryStrategy.SSHKey
}
if runContext.Application.RepositoryStrategy.PGPKey != "" {
vars["git.pgp.key"] = runContext.Application.RepositoryStrategy.PGPKey
}
if runContext.Application.RepositoryStrategy.User != "" {
vars["git.http.user"] = runContext.Application.RepositoryStrategy.User
}
if runContext.Application.VCSServer != "" {
vars["git.server"] = runContext.Application.VCSServer
}
} else {
// remove vcs strategy variable
delete(vars, "git.ssh.key")
delete(vars, "git.pgp.key")
delete(vars, "git.http.user")
}
if hookEvent != nil {
vars["parent.project"] = hookEvent.ParentWorkflow.Key
vars["parent.run"] = fmt.Sprintf("%d", hookEvent.ParentWorkflow.Run)
vars["parent.workflow"] = hookEvent.ParentWorkflow.Name
vars["parent.outgoinghook"] = hookEvent.WorkflowNodeHookUUID
}
params := make([]sdk.Parameter, 0)
for k, v := range vars {
sdk.AddParameter(¶ms, k, sdk.StringParameter, v)
}
return params, nil
}
func getParentParameters(w *sdk.WorkflowRun, nodeRuns []*sdk.WorkflowNodeRun) ([]sdk.Parameter, error) {
params := make([]sdk.Parameter, 0, len(nodeRuns))
for _, parentNodeRun := range nodeRuns {
var nodeName string
node := w.Workflow.WorkflowData.NodeByID(parentNodeRun.WorkflowNodeID)
if node == nil {
return nil, sdk.WithStack(fmt.Errorf("unable to find node %d in workflow", parentNodeRun.WorkflowNodeID))
}
nodeName = node.Name
prefix := "workflow." + nodeName + "."
parentParams := make([]sdk.Parameter, 0, len(parentNodeRun.BuildParameters))
for _, param := range parentNodeRun.BuildParameters {
if param.Name == "" || param.Name == "cds.semver" || param.Name == "cds.release.version" ||
strings.HasPrefix(param.Name, "cds.proj") ||
strings.HasPrefix(param.Name, "cds.version") || strings.HasPrefix(param.Name, "cds.run.number") ||
strings.HasPrefix(param.Name, "cds.workflow") || strings.HasPrefix(param.Name, "job.requirement") {
continue
}
if strings.HasPrefix(param.Name, "workflow.") {
parentParams = append(parentParams, param)
continue
}
// We inherite git variables is there is more than one repositories in the whole workflow
if strings.HasPrefix(param.Name, "git.") {
parentParams = append(parentParams, param)
// Create parent param
param.Name = prefix + param.Name
parentParams = append(parentParams, param)
continue
}
if strings.HasPrefix(param.Name, "gerrit.") {
parentParams = append(parentParams, param)
continue
}
if param.Name == "payload" || strings.HasPrefix(param.Name, "cds.triggered") || strings.HasPrefix(param.Name, "cds.release") {
// keep p.Name as is
} else if param.Name == "cds.status" {
// do not use input status value for parent param
continue
} else if strings.HasPrefix(param.Name, "cds.") {
param.Name = strings.Replace(param.Name, "cds.", prefix, 1)
}
parentParams = append(parentParams, param)
}
// inject parent final status as parameter
parentParams = append(parentParams, sdk.Parameter{
Name: prefix + "status",
Type: sdk.StringParameter,
Value: parentNodeRun.Status,
})
params = append(params, parentParams...)
}
return params, nil
}
func getNodeRunBuildParameters(ctx context.Context, proj sdk.Project, wr *sdk.WorkflowRun, run *sdk.WorkflowNodeRun, runContext nodeRunContext) ([]sdk.Parameter, error) {
ctx, end := telemetry.Span(ctx, "workflow.getNodeRunBuildParameters",
telemetry.Tag(telemetry.TagWorkflow, wr.Workflow.Name),
telemetry.Tag(telemetry.TagWorkflowRun, wr.Number),
telemetry.Tag(telemetry.TagWorkflowNodeRun, run.ID),
)
defer end()
// GET PARAMETER FROM NODE CONTEXT
params, errparam := getBuildParameterFromNodeContext(proj, wr.Workflow, runContext, run.PipelineParameters, run.Payload, run.HookEvent)
if errparam != nil {
return nil, sdk.WrapError(errparam, "unable to compute node build parameters")
}
errm := &sdk.MultiError{}
//override default parameters value
tmp := sdk.ParametersToMap(params)
if wr.Version != nil {
tmp["cds.version"] = *wr.Version
} else {
tmp["cds.version"] = fmt.Sprintf("%d", run.Number)
}
tmp["cds.run"] = fmt.Sprintf("%d.%d", run.Number, run.SubNumber)
tmp["cds.run.number"] = fmt.Sprintf("%d", run.Number)
tmp["cds.run.subnumber"] = fmt.Sprintf("%d", run.SubNumber)
if wr.Workflow.TemplateInstance != nil {
tmp["cds.template.version"] = fmt.Sprintf("%d", wr.Workflow.TemplateInstance.WorkflowTemplateVersion)
}
_, next := telemetry.Span(ctx, "workflow.interpolate")
params = make([]sdk.Parameter, 0, len(tmp))
for k, v := range tmp {
s, err := interpolate.Do(v, tmp)
if err != nil {
errm.Append(err)
continue
}
sdk.AddParameter(¶ms, k, sdk.StringParameter, s)
}
next()
if errm.IsEmpty() {
return params, nil
}
return params, errm
}