8000 fix(api): not allow to resynchronize pipeline on as code workflow #48… · ovh/cds@bea8a05 · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Commit bea8a05

Browse files
bnjjjyesnault
authored andcommitted
fix(api): not allow to resynchronize pipeline on as code workflow #4806 (#4828)
Signed-off-by: Benjamin Coenen <5719034+bnjjj@users.noreply.github.com>
1 parent c724a8e commit bea8a05

File tree

3 files changed

+167
-0
lines changed

3 files changed

+167
-0
lines changed

engine/api/workflow_run.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,14 @@ func (api *API) resyncWorkflowRunHandler() service.Handler {
277277
return sdk.WrapError(err, "unable to load projet")
278278
}
279279

280+
wf, err := workflow.Load(ctx, api.mustDB(), api.Cache, proj, name, deprecatedGetUser(ctx), workflow.LoadOptions{Minimal: true, DeepPipeline: false})
281+
if err != nil {
282+
return sdk.WrapError(err, "cannot load workflow %s/%s", key, name)
283+
}
284+
if wf.FromRepository != "" {
285+
return sdk.ErrWorkflowAsCodeResync
286+
}
287+
280288
run, err := workflow.LoadRun(ctx, api.mustDB(), key, name, number, workflow.LoadRunOptions{})
281289
if err != nil {
282290
return sdk.WrapError(err, "Unable to load last workflow run [%s/%d]", name, number)

engine/api/workflow_run_test.go

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -962,6 +962,162 @@ func Test_resyncWorkflowRunHandler(t *testing.T) {
962962
assert.Equal(t, "New awesome stage", workflowRun.Workflow.Pipelines[pip.ID].Stages[0].Name)
963963
}
964964

965+
func Test_resyncWorkflowRunHandlerError(t *testing.T) {
966+
api, db, router, end := newTestAPI(t, bootstrap.InitiliazeDB)
967+
defer end()
968+
u, pass := assets.InsertAdminUser(db)
969+
key := sdk.RandomString(10)
970+
proj := assets.InsertTestProject(t, db, api.Cache, key, key, u)
971+
972+
//First pipeline
973+
pip := sdk.Pipeline{
974+
ProjectID: proj.ID,
975+
ProjectKey: proj.Key,
976+
Name: "pip1",
977+
}
978+
test.NoError(t, pipeline.InsertPipeline(db, api.Cache, proj, &pip, u))
979+
980+
s := sdk.NewStage("stage 1")
981+
s.Enabled = true
982+
s.PipelineID = pip.ID
983+
pipeline.InsertStage(db, s)
984+
j := &sdk.Job{
985+
Enabled: true,
986+
Action: sdk.Action{
987+
Enabled: true,
988+
},
989+
}
990+
pipeline.InsertJob(db, j, s.ID, &pip)
991+
s.Jobs = append(s.Jobs, *j)
992+
993+
pip.Stages = append(pip.Stages, *s)
994+
995+
pipeline.InsertStage(db, s)
996+
j = &sdk.Job{
997+
Enabled: true,
998+
Action: sdk.Action{
999+
Enabled: true,
1000+
},
1001+
}
1002+
s.Jobs = append(s.Jobs, *j)
1003+
1004+
// Create Application
1005+
app := sdk.Application{
1006+
Name: sdk.RandomString(10),
1007+
ProjectID: proj.ID,
1008+
RepositoryFullname: "foo/myrepo",
1009+
VCSServer: "github",
1010+
}
1011+
assert.NoError(t, application.Insert(db, api.Cache, proj, &app, u))
1012+
assert.NoError(t, repositoriesmanager.InsertForApplication(db, &app, proj.Key))
1013+
1014+
w := sdk.Workflow{
1015+
Name: "test_1",
1016+
ProjectID: proj.ID,
1017+
ProjectKey: proj.Key,
1018+
FromRepository: "foo/myrepo",
1019+
WorkflowData: &sdk.WorkflowData{
1020+
Node: sdk.Node{
1021+
Name: "root",
1022+
Type: sdk.NodeTypePipeline,
1023+
Context: &sdk.NodeContext{
1024+
PipelineID: pip.ID,
1025+
ApplicationID: app.ID,
1026+
},
1027+
Triggers: []sdk.NodeTrigger{
1028+
{
1029+
ChildNode: sdk.Node{
1030+
Name: "child",
1031+
Type: sdk.NodeTypePipeline,
1032+
Context: &sdk.NodeContext{
1033+
PipelineID: pip.ID,
1034+
},
1035+
},
1036+
},
1037+
},
1038+
},
1039+
},
1040+
}
1041+
1042+
proj2, errP := project.Load(api.mustDB(), api.Cache, proj.Key, u, project.LoadOptions.WithPipelines, project.LoadOptions.WithGroups, project.LoadOptions.WithIntegrations)
1043+
test.NoError(t, errP)
1044+
1045+
test.NoError(t, workflow.Insert(db, api.Cache, &w, proj2, u))
1046+
w1, err := workflow.Load(context.TODO(), db, api.Cache, proj2, "test_1", u, workflow.LoadOptions{})
1047+
test.NoError(t, err)
1048+
1049+
//Prepare request
1050+
vars := map[string]string{
1051+
"key": proj.Key,
1052+
"permWorkflowName": w1.Name,
1053+
}
1054+
uri := router.GetRoute("POST", api.postWorkflowRunHandler, vars)
1055+
test.NotEmpty(t, uri)
1056+
1057+
opts := &sdk.WorkflowRunPostHandlerOption{
1058+
Manual: &sdk.WorkflowNodeRunManual{
1059+
Payload: map[string]string{
1060+
"git.branch": "master",
1061+
},
1062+
},
1063+
}
1064+
req := assets.NewAuthentifiedRequest(t, u, pass, "POST", uri, opts)
1065+
1066+
//Do the request
1067+
rec := httptest.NewRecorder()
1068+
router.Mux.ServeHTTP(rec, req)
1069+
assert.Equal(t, 202, rec.Code)
1070+
1071+
wr := &sdk.WorkflowRun{}
1072+
test.NoError(t, json.Unmarshal(rec.Body.Bytes(), wr))
1073+
assert.Equal(t, int64(1), wr.Number)
1074+
1075+
cpt := 0
1076+
for {
1077+
varsGet := map[string]string{
1078+
"key": proj.Key,
1079+
"permWorkflowName": w1.Name,
1080+
"number": "1",
1081+
}
1082+
uriGet := router.GetRoute("GET", api.getWorkflowRunHandler, varsGet)
1083+
reqGet := assets.NewAuthentifiedRequest(t, u, pass, "GET", uriGet, nil)
1084+
recGet := httptest.NewRecorder()
1085+
router.Mux.ServeHTTP(recGet, reqGet)
1086+
1087+
var wrGet sdk.WorkflowRun
1088+
assert.NoError(t, json.Unmarshal(recGet.Body.Bytes(), &wrGet))
1089+
1090+
if wrGet.Status != sdk.StatusPending.String() {
1091+
assert.Equal(t, sdk.StatusBuilding.String(), wrGet.Status)
1092+
break
1093+
}
1094+
t.Logf("workflow run response %+v\n", wrGet)
1095+
cpt++
1096+
if cpt > 10 {
1097+
break
1098+
}
1099+
}
1100+
1101+
pip.Stages[0].Name = "New awesome stage"
1102+
errS := pipeline.UpdateStage(db, &pip.Stages[0])
1103+
test.NoError(t, errS)
1104+
1105+
//Prepare request
1106+
vars = map[string]string{
1107+
"key": proj.Key,
1108+
"permWorkflowName": w1.Name,
1109+
"number": fmt.Sprintf("%d", wr.Number),
1110+
}
1111+
uri = router.GetRoute("POST", api.resyncWorkflowRunHandler, vars)
1112+
test.NotEmpty(t, uri)
1113+
req = assets.NewAuthentifiedRequest(t, u, pass, "POST", uri, nil)
1114+
1115+
//Do the request
1116+
rec = httptest.NewRecorder()
1117+
router.Mux.ServeHTTP(rec, req)
1118+
assert.Equal(t, 403, rec.Code)
1119+
}
1120+
9651121
func Test_postWorkflowRunHandler(t *testing.T) {
9661122
api, db, router, end := newTestAPI(t, bootstrap.InitiliazeDB)
9671123
defer end()

sdk/error.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ var (
198198
ErrBadBrokerConfiguration = Error{ID: 181, Status: http.StatusBadRequest}
199199
ErrInvalidJobRequirementNetworkAccess = Error{ID: 182, Status: http.StatusBadRequest}
200200
ErrInvalidWorkerModelNamePattern = Error{ID: 183, Status: http.StatusBadRequest}
201+
ErrWorkflowAsCodeResync = Error{ID: 184, Status: http.StatusForbidden}
201202
)
202203

203204
var errorsAmericanEnglish = map[int]string{
@@ -378,6 +379,7 @@ var errorsAmericanEnglish = map[int]string{
378379
ErrIntegrationtNotFound.ID: "integration not found",
379380
ErrBadBrokerConfiguration.ID: "Cannot connect to the broker of your event integration. Check your configuration",
380381
ErrInvalidJobRequirementNetworkAccess.ID: "Invalid job requirement: network requirement must contains ':'. Example: golang.org:http, golang.org:443",
382+
ErrWorkflowAsCodeResync.ID: "You cannot resynchronize an as-code workflow",
381383
}
382384

383385
var errorsFrench = map[int]string{
@@ -557,6 +559,7 @@ var errorsFrench = map[int]string{
557559
ErrEnvironmentNotFound.ID: "l'environnement n'existe pas",
558560
ErrBadBrokerConfiguration.ID: "Impossible de se connecter à votre intégration de type évènement. Veuillez vérifier votre configuration",
559561
ErrInvalidJobRequirementNetworkAccess.ID: "Pré-requis de job invalide: Le pré-requis network doit contenir un ':'. Exemple: golang.org:http, golang.org:443",
562+
ErrWorkflowAsCodeResync.ID: "Impossible de resynchroniser un workflow en mode as-code",
560563
}
561564

562565
var errorsLanguages = []map[int]string{

0 commit comments

Comments
 (0)
0