Skip to content

Commit ab1bf78

Browse files
authored
feat(api): search workflow handler (#5175)
1 parent e8b6d4d commit ab1bf78

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+1771
-696
lines changed

engine/api/api_routes.go

+2
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,8 @@ func (api *API) InitRouter() {
408408
r.Handle("/group/{permGroupName}/worker/model", Scope(sdk.AuthConsumerScopeWorkerModel), r.GET(api.getWorkerModelsForGroupHandler))
409409

410410
// Workflows
411+
412+
r.Handle("/workflow/search", Scope(sdk.AuthConsumerScopeProject), r.GET(api.getSearchWorkflowHandler))
411413
r.Handle("/workflow/hook", Scope(sdk.AuthConsumerScopeHooks), r.GET(api.getWorkflowHooksHandler))
412414
r.Handle("/workflow/hook/model/{model}", ScopeNone(), r.GET(api.getWorkflowHookModelHandler), r.POST(api.postWorkflowHookModelHandler, NeedAdmin(true)), r.PUT(api.putWorkflowHookModelHandler, NeedAdmin(true)))
413415

engine/api/application.go

-2
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,6 @@ func loadApplicationUsage(ctx context.Context, db gorp.SqlExecutor, projKey, app
161161
}
162162
usage.Workflows = wf
163163

164-
// TODO: add usage of pipelines and environments
165-
166164
return usage, nil
167165
}
168166

engine/api/application/dao.go

+12
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import (
55
"database/sql"
66
"time"
77

8+
"github.com/lib/pq"
9+
810
"github.com/go-gorp/gorp"
911

1012
"github.com/ovh/cds/engine/api/database/gorpmapping"
@@ -238,6 +240,16 @@ func LoadAll(db gorp.SqlExecutor, key string, opts ...LoadOptionFunc) ([]sdk.App
238240
return getAll(context.Background(), db, opts, query)
239241
}
240242

243+
// LoadAllByIDs returns all applications
244+
func LoadAllByIDs(db gorp.SqlExecutor, ids []int64, opts ...LoadOptionFunc) ([]sdk.Application, error) {
245+
query := gorpmapping.NewQuery(`
246+
SELECT application.*
247+
FROM application
248+
WHERE application.id = ANY($1)
249+
ORDER BY application.name ASC`).Args(pq.Int64Array(ids))
250+
return getAll(context.Background(), db, opts, query)
251+
}
252+
241253
// LoadAllNames returns all application names
242254
func LoadAllNames(db gorp.SqlExecutor, projID int64) (sdk.IDNames, error) {
243255
query := `

engine/api/ascode/dao.go

+16
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import (
44
"context"
55
"database/sql"
66

7+
"github.com/lib/pq"
8+
79
"github.com/go-gorp/gorp"
810

911
"github.com/ovh/cds/engine/api/database/gorpmapping"
@@ -28,6 +30,20 @@ func LoadEventByWorkflowIDAndPullRequest(ctx context.Context, db gorp.SqlExecuto
2830
return &event, nil
2931
}
3032

33+
func LoadEventsByWorkflowIDs(ctx context.Context, db gorp.SqlExecutor, workflowIDs []int64) ([]sdk.AsCodeEvent, error) {
34+
query := gorpmapping.NewQuery("SELECT * FROM as_code_events where workflow_id = ANY($1)").Args(pq.Int64Array(workflowIDs))
35+
var events []dbAsCodeEvents
36+
if err := gorpmapping.GetAll(ctx, db, query, &events); err != nil {
37+
return nil, sdk.WrapError(err, "Unable to load as code events")
38+
}
39+
40+
asCodeEvents := make([]sdk.AsCodeEvent, len(events))
41+
for i := range events {
42+
asCodeEvents[i] = sdk.AsCodeEvent(events[i])
43+
}
44+
return asCodeEvents, nil
45+
}
46+
3147
// LoadEventsByWorkflowID returns as code events for the given workflow.
3248
func LoadEventsByWorkflowID(ctx context.Context, db gorp.SqlExecutor, workflowID int64) ([]sdk.AsCodeEvent, error) {
3349
query := gorpmapping.NewQuery(`

engine/api/environment/environment.go

+39
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,45 @@ import (
1212
"github.com/ovh/cds/sdk"
1313
)
1414

15+
// LoadAllByIDs load all environment
16+
func LoadAllByIDs(db gorp.SqlExecutor, ids []int64) ([]sdk.Environment, error) {
17+
var envs []sdk.Environment
18+
19+
query := `SELECT environment.id, environment.name, environment.last_modified, environment.from_repository, project.projectkey
20+
FROM environment
21+
JOIN project ON project.id = environment.project_id
22+
WHERE environment.id = ANY($1)
23+
ORDER by environment.name`
24+
rows, err := db.Query(query, pq.Int64Array(ids))
25+
if err != nil {
26+
if err == sql.ErrNoRows {
27+
return envs, sdk.WithStack(sdk.ErrNoEnvironment)
28+
}
29+
return envs, sdk.WithStack(err)
30+
}
31+
defer rows.Close()
32+
33+
for rows.Next() {
34+
var env sdk.Environment
35+
var lastModified time.Time
36+
var projectKey string
37+
if err := rows.Scan(&env.ID, &env.Name, &lastModified, &env.FromRepository, &projectKey); err != nil {
38+
return envs, sdk.WithStack(err)
39+
}
40+
env.LastModified = lastModified.Unix()
41+
env.ProjectKey = projectKey
42+
envs = append(envs, env)
43+
}
44+
rows.Close()
45+
46+
for i := range envs {
47+
if err := loadDependencies(db, &envs[i]); err != nil {
48+
return envs, err
49+
}
50+
}
51+
return envs, nil
52+
}
53+
1554
// LoadEnvironments load all environment from the given project
1655
func LoadEnvironments(db gorp.SqlExecutor, projectKey string) ([]sdk.Environment, error) {
1756
var envs []sdk.Environment

engine/api/group/gorp_model.go

+1
Original file line numberDiff line numberDiff line change
@@ -99,5 +99,6 @@ func init() {
9999
gorpmapping.New(group{}, "group", true, "id"),
100100
gorpmapping.New(LinkGroupUser{}, "group_authentified_user", true, "id"),
101101
gorpmapping.New(LinkGroupProject{}, "project_group", true, "id"),
102+
gorpmapping.New(LinkWorkflowGroupPermission{}, "workflow_perm", false),
102103
)
103104
}

engine/api/group/node_group.go

+17-11
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,22 @@ import (
55
"strings"
66

77
"github.com/go-gorp/gorp"
8+
"github.com/lib/pq"
9+
810
"github.com/ovh/cds/sdk"
911
)
1012

1113
// LoadGroupsByNode retrieves all groups related to a node
12-
func LoadGroupsByNode(db gorp.SqlExecutor, nodeID int64) ([]sdk.GroupPermission, error) {
13-
query := `SELECT "group".id,"group".name,workflow_node_group.role
14+
func LoadGroupsByNode(db gorp.SqlExecutor, nodeID []int64) (map[int64][]sdk.GroupPermission, error) {
15+
query := `SELECT workflow_node_id, "group".id,"group".name,workflow_node_group.role
1416
FROM "group"
15-
JOIN project_group ON "group".id = project_group.group_id
16-
JOIN workflow_perm ON workflow_perm.project_group_id = project_group.id
17-
JOIN workflow_node_group ON workflow_node_group.workflow_group_id = workflow_perm.id
18-
WHERE workflow_node_group.workflow_node_id = $1
17+
JOIN project_group ON "group".id = project_group.group_id
18+
JOIN workflow_perm ON workflow_perm.project_group_id = project_group.id
19+
JOIN workflow_node_group ON workflow_node_group.workflow_group_id = workflow_perm.id
20+
WHERE workflow_node_group.workflow_node_id = ANY($1)
1921
ORDER BY "group".name ASC`
2022

21-
rows, err := db.Query(query, nodeID)
23+
rows, err := db.Query(query, pq.Int64Array(nodeID))
2224
if err != nil {
2325
if err == sql.ErrNoRows {
2426
return nil, nil
@@ -27,19 +29,23 @@ func LoadGroupsByNode(db gorp.SqlExecutor, nodeID int64) ([]sdk.GroupPermission,
2729
}
2830
defer rows.Close()
2931

30-
var groups []sdk.GroupPermission
32+
var mapGroups = make(map[int64][]sdk.GroupPermission)
3133
for rows.Next() {
3234
var group sdk.Group
3335
var perm int
34-
if err := rows.Scan(&group.ID, &group.Name, &perm); err != nil {
35-
return groups, sdk.WithStack(err)
36+
var nodeID int64
37+
if err := rows.Scan(&nodeID, &group.ID, &group.Name, &perm); err != nil {
38+
return nil, sdk.WithStack(err)
3639
}
40+
41+
var groups = mapGroups[nodeID]
3742
groups = append(groups, sdk.GroupPermission{
3843
Group: group,
3944
Permission: perm,
4045
})
46+
mapGroups[nodeID] = groups
4147
}
42-
return groups, nil
48+
return mapGroups, nil
4349
}
4450

4551
// InsertGroupsInNode Link the given groups and the given environment

engine/api/group/workflow_group.go

+42-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ import (
66
"strings"
77

88
"github.com/go-gorp/gorp"
9+
"github.com/lib/pq"
910

11+
"github.com/ovh/cds/engine/api/database/gorpmapping"
1012
"github.com/ovh/cds/sdk"
1113
)
1214

@@ -148,14 +150,52 @@ func checkAtLeastOneGroupWithWriteRoleOnWorkflow(db gorp.SqlExecutor, wID int64)
148150
return nb > 0, err
149151
}
150152

153+
type LinkWorkflowGroupPermission struct {
154+
WorkflowID int64 `db:"workflow_id"`
155+
GroupID int64 `db:"group_id"`
156+
GroupName string `db:"group_name"`
157+
Role int `db:"role"`
158+
}
159+
160+
// LoadWorkflowGroupsByWorkflowIDs returns a map with key: workflowID and value the slite of groups
161+
func LoadWorkflowGroupsByWorkflowIDs(db gorp.SqlExecutor, workflowIDs []int64) (map[int64][]sdk.GroupPermission, error) {
162+
result := make(map[int64][]sdk.GroupPermission, len(workflowIDs))
163+
query := gorpmapping.NewQuery(`
164+
SELECT workflow_perm.workflow_id, "group".id as "group_id", "group".name as "group_name", workflow_perm.role
165+
FROM "group"
166+
JOIN project_group ON project_group.group_id = "group".id
167+
JOIN workflow_perm ON workflow_perm.project_group_id = project_group.id
168+
WHERE workflow_perm.workflow_id = ANY($1)
169+
ORDER BY workflow_perm.workflow_id, "group".name ASC
170+
`).Args(pq.Int64Array(workflowIDs))
171+
var dbResultSet = []LinkWorkflowGroupPermission{}
172+
if err := gorpmapping.GetAll(context.Background(), db, query, &dbResultSet); err != nil {
173+
return nil, err
174+
}
175+
176+
for _, row := range dbResultSet {
177+
perms := result[row.WorkflowID]
178+
perms = append(perms, sdk.GroupPermission{
179+
Permission: row.Role,
180+
Group: sdk.Group{
181+
ID: row.GroupID,
182+
Name: row.GroupName,
183+
},
184+
})
185+
result[row.WorkflowID] = perms
186+
}
187+
188+
return result, nil
189+
}
190+
151191
// LoadWorkflowGroups load groups for a workflow
152192
func LoadWorkflowGroups(db gorp.SqlExecutor, workflowID int64) ([]sdk.GroupPermission, error) {
153193
wgs := []sdk.GroupPermission{}
154194

155195
query := `SELECT "group".id, "group".name, workflow_perm.role
156196
FROM "group"
157-
JOIN project_group ON project_group.group_id = "group".id
158-
JOIN workflow_perm ON workflow_perm.project_group_id = project_group.id
197+
JOIN project_group ON project_group.group_id = "group".id
198+
JOIN workflow_perm ON workflow_perm.project_group_id = project_group.id
159199
WHERE workflow_perm.workflow_id = $1
160200
ORDER BY "group".name ASC`
161201
rows, errq := db.Query(query, workflowID)

engine/api/integration/dao_project_integration.go

+8
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package integration
33
import (
44
"context"
55

6+
"github.com/lib/pq"
7+
68
"github.com/go-gorp/gorp"
79

810
"github.com/ovh/cds/engine/api/database/gorpmapping"
@@ -153,6 +155,12 @@ func LoadIntegrationsByProjectID(db gorp.SqlExecutor, id int64) ([]sdk.ProjectIn
153155
return loadAll(db, query)
154156
}
155157

158+
// LoadIntegrationsByIDs load integration integrations by id
159+
func LoadIntegrationsByIDs(db gorp.SqlExecutor, ids []int64) ([]sdk.ProjectIntegration, error) {
160+
query := gorpmapping.NewQuery("SELECT * from project_integration WHERE id = ANY($1)").Args(pq.Int64Array(ids))
161+
return loadAll(db, query)
162+
}
163+
156164
// InsertIntegration inserts a integration
157165
func InsertIntegration(db gorp.SqlExecutor, pp *sdk.ProjectIntegration) error {
158166
oldConfig := pp.Config.Clone()

engine/api/notification/user.go

+1
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ func GetUserWorkflowEvents(ctx context.Context, db gorp.SqlExecutor, store cache
120120
if err != nil {
121121
log.Error(ctx, "notification.GetUserWorkflowEvents> unable to handle event %+v: %v", jn, err)
122122
}
123+
log.Debug("GetUserWorkflowEvents> will send mail notifications: %+v", notif)
123124
go sendMailNotif(ctx, notif)
124125
}
125126
}

engine/api/permission/dao.go

+28
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,41 @@ import (
66
"strings"
77

88
"github.com/go-gorp/gorp"
9+
"github.com/lib/pq"
910

1011
"github.com/ovh/cds/engine/api/database/gorpmapping"
1112
"github.com/ovh/cds/engine/api/group"
1213
"github.com/ovh/cds/engine/api/observability"
1314
"github.com/ovh/cds/sdk"
1415
)
1516

17+
func LoadWorkflowMaxLevelPermissionByWorkflowIDs(ctx context.Context, db gorp.SqlExecutor, workflowIDs []int64, groupIDs []int64) (sdk.EntitiesPermissions, error) {
18+
_, end := observability.Span(ctx, "permission.LoadWorkflowMaxLevelPermissionByWorkflowIDs")
19+
defer end()
20+
21+
query := `
22+
SELECT workflow.id::text, max(workflow_perm.role)
23+
FROM workflow_perm
24+
JOIN workflow ON workflow.id = workflow_perm.workflow_id
25+
JOIN project ON project.id = workflow.project_id
26+
JOIN project_group ON project_group.id = workflow_perm.project_group_id
27+
WHERE project_group.project_id = project.id
28+
AND workflow.id = ANY($1)
29+
AND project_group.group_id = ANY($2)
30+
GROUP BY workflow.id, workflow.name`
31+
32+
rows, err := db.Query(query, pq.Int64Array(workflowIDs), pq.Int64Array(groupIDs))
33+
if err == sql.ErrNoRows {
34+
return nil, nil
35+
}
36+
if err != nil {
37+
return nil, sdk.WithStack(err)
38+
}
39+
defer rows.Close()
40+
41+
return scanPermissions(rows)
42+
}
43+
1644
func LoadWorkflowMaxLevelPermission(ctx context.Context, db gorp.SqlExecutor, projectKey string, workflowNames []string, groupIDs []int64) (sdk.EntitiesPermissions, error) {
1745
_, end := observability.Span(ctx, "permission.LoadWorkflowMaxLevelPermission")
1846
defer end()

engine/api/pipeline/pipeline.go

+32
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"time"
88

99
"github.com/go-gorp/gorp"
10+
"github.com/lib/pq"
1011

1112
"github.com/ovh/cds/engine/api/database/gorpmapping"
1213
"github.com/ovh/cds/engine/api/group"
@@ -239,6 +240,37 @@ func DeletePipeline(ctx context.Context, db gorp.SqlExecutor, pipelineID int64)
239240
return nil
240241
}
241242

243+
// LoadAllByIDs loads all pipelines
244+
func LoadAllByIDs(db gorp.SqlExecutor, ids []int64, loadDependencies bool) ([]sdk.Pipeline, error) {
245+
var pips []sdk.Pipeline
246+
query := `SELECT id, name, description, project_id, last_modified, from_repository
247+
FROM pipeline
248+
WHERE id = ANY($1)
249+
ORDER BY pipeline.name`
250+
251+
if _, err := db.Select(&pips, query, pq.Int64Array(ids)); err != nil {
252+
if err == sql.ErrNoRows {
253+
return nil, nil
254+
}
255+
return nil, sdk.WithStack(err)
256+
}
257+
258+
for i := range pips {
259+
if loadDependencies {
260+
if err := LoadPipelineStage(context.TODO(), db, &pips[i]); err != nil {
261+
return nil, err
262+
}
263+
}
264+
params, err := GetAllParametersInPipeline(context.TODO(), db, pips[i].ID)
265+
if err != nil {
266+
return nil, err
267+
}
268+
pips[i].Parameter = params
269+
}
270+
271+
return pips, nil
272+
}
273+
242274
// LoadPipelines loads all pipelines in a project
243275
func LoadPipelines(db gorp.SqlExecutor, projectID int64, loadDependencies bool) ([]sdk.Pipeline, error) {
244276
var pips []sdk.Pipeline

engine/api/repositories_manager.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -557,7 +557,7 @@ func (api *API) attachRepositoriesManagerHandler() service.Handler {
557557
wfDB.WorkflowData.Node.Context.DefaultPayload = defaultPayload
558558

559559
if err := workflow.Update(ctx, db, api.Cache, *proj, wfDB, workflow.UpdateOptions{DisableHookManagement: true}); err != nil {
560-
return sdk.WrapError(err, "cannot update node context %d", wf.WorkflowData.Node.Context.ID)
560+
return sdk.WrapError(err, "cannot update node context %d", wfDB.WorkflowData.Node.Context.ID)
561561
}
562562

563563
event.PublishWorkflowUpdate(ctx, proj.Key, *wfDB, *wfOld, getAPIConsumer(ctx))

0 commit comments

Comments
 (0)