Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
fsamin committed May 14, 2020
1 parent 66c9c07 commit 9c1ff8f
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 77 deletions.
2 changes: 1 addition & 1 deletion engine/api/repositories_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,7 @@ func (api *API) attachRepositoriesManagerHandler() service.Handler {
wfDB.WorkflowData.Node.Context.DefaultPayload = defaultPayload

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

event.PublishWorkflowUpdate(ctx, proj.Key, *wfDB, *wfOld, getAPIConsumer(ctx))
Expand Down
2 changes: 0 additions & 2 deletions engine/api/router_middleware_auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,6 @@ func (api *API) jwtMiddleware(ctx context.Context, w http.ResponseWriter, req *h
ctx, end := observability.Span(ctx, "router.jwtMiddleware")
defer end()

log.Debug("jwtMiddleware> try to find a jwt token in cookie or header")

var jwtRaw string
var jwtFromCookie bool
// Try to get the jwt from the cookie firstly then from the authorization bearer header, a XSRF token with cookie
Expand Down
2 changes: 1 addition & 1 deletion engine/api/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -932,7 +932,7 @@ func (api *API) getTemplateUsageHandler() service.Handler {
mProjectIDs[ps[i].ID] = struct{}{}
}

filteredWorkflow := []sdk.Workflow{}
filteredWorkflow := []sdk.WorkflowName{}
for i := range wfs {
if _, ok := mProjectIDs[wfs[i].ProjectID]; ok {
filteredWorkflow = append(filteredWorkflow, wfs[i])
Expand Down
22 changes: 10 additions & 12 deletions engine/api/workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ func (api *API) getWorkflowsHandler() service.Handler {
opts.Filters.Repository = filterByRepo
}

opts.Loaders.WithFavoritesForUserID = getAPIConsumer(ctx).AuthentifiedUserID

groupIDS := getAPIConsumer(ctx).GetGroupIDs()
opts.Filters.GroupIDs = groupIDS
if isMaintainer(ctx) {
Expand Down Expand Up @@ -98,24 +100,20 @@ func (api *API) getWorkflowHandler() service.Handler {
}

opts := workflow.LoadOptions{
Minimal: minimal, // if true, load only data from table workflow, not pipelines, app, env...
DeepPipeline: withDeepPipelines,
WithIcon: !withoutIcons,
WithLabels: withLabels,
WithAsCodeUpdateEvent: withAsCodeEvents,
WithIntegrations: true,
WithTemplate: withTemplate,
Minimal: minimal, // if true, load only data from table workflow, not pipelines, app, env...
DeepPipeline: withDeepPipelines,
WithIcon: !withoutIcons,
WithLabels: withLabels,
WithAsCodeUpdateEvent: withAsCodeEvents,
WithIntegrations: true,
WithTemplate: withTemplate,
WithFavoritesForUserID: getAPIConsumer(ctx).AuthentifiedUserID,
}
w1, err := workflow.Load(ctx, api.mustDB(), api.Cache, *proj, name, opts)
if err != nil {
return sdk.WrapError(err, "cannot load workflow %s", name)
}

w1.Favorite, err = workflow.IsFavorite(api.mustDB(), w1, getAPIConsumer(ctx).AuthentifiedUserID)
if err != nil {
return err
}

if withUsage {
usage, err := loadWorkflowUsage(api.mustDB(), w1.ID)
if err != nil {
Expand Down
102 changes: 47 additions & 55 deletions engine/api/workflow/dao.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,14 @@ func LoadAllByIDs(ctx context.Context, db gorp.SqlExecutor, ids []int64) (sdk.Wo

// LoadOptions custom option for loading workflow
type LoadOptions struct {
Minimal bool
DeepPipeline bool
WithLabels bool
WithIcon bool
WithAsCodeUpdateEvent bool
WithIntegrations bool
WithTemplate bool
Minimal bool
DeepPipeline bool
WithLabels bool
WithIcon bool
WithAsCodeUpdateEvent bool
WithIntegrations bool
WithTemplate bool
WithFavoritesForUserID string
}

// UpdateOptions is option to parse a workflow
Expand Down Expand Up @@ -257,6 +258,7 @@ func Load(ctx context.Context, db gorp.SqlExecutor, store cache.Store, proj sdk.
loadOpts.Loaders.WithApplications = true
loadOpts.Loaders.WithEnvironments = true
loadOpts.Loaders.WithIntegrations = true
loadOpts.Loaders.WithFavoritesForUserID = opts.WithFavoritesForUserID

if opts.WithIcon {
loadOpts.Loaders.WithIcon = true
Expand Down Expand Up @@ -294,6 +296,7 @@ func Load(ctx context.Context, db gorp.SqlExecutor, store cache.Store, proj sdk.
}

// LoadAndLockByID loads a workflow
// TODO
func LoadAndLockByID(ctx context.Context, db gorp.SqlExecutor, store cache.Store, proj sdk.Project, id int64, opts LoadOptions) (*sdk.Workflow, error) {
query := `
select *
Expand All @@ -311,6 +314,7 @@ func LoadAndLockByID(ctx context.Context, db gorp.SqlExecutor, store cache.Store
}

// LoadByID loads a workflow
// TODO
func LoadByID(ctx context.Context, db gorp.SqlExecutor, store cache.Store, proj sdk.Project, id int64, opts LoadOptions) (*sdk.Workflow, error) {
query := `
select *
Expand All @@ -327,85 +331,64 @@ func LoadByID(ctx context.Context, db gorp.SqlExecutor, store cache.Store, proj
return res, nil
}

// LoadByPipelineName loads a workflow for a given project key and pipeline name (ie. checking permissions)
func LoadByPipelineName(ctx context.Context, db gorp.SqlExecutor, projectKey string, pipName string) (sdk.Workflows, error) {
dbRes := Workflows{}
query := gorpmapping.NewQuery(`select distinct workflow.*, project.projectkey
// LoadByPipelineName loads a workflow for a given project key and pipeline name
func LoadByPipelineName(ctx context.Context, db gorp.SqlExecutor, projectKey string, pipName string) ([]sdk.WorkflowName, error) {
query := `SELECT distinct workflow.*, project.projectkey as "project_key", project.id as "project_id"
from workflow
join project on project.id = workflow.project_id
join w_node on w_node.workflow_id = workflow.id
join w_node_context on w_node_context.node_id = w_node.id
join pipeline on pipeline.id = w_node_context.pipeline_id
where project.projectkey = $1 and pipeline.name = $2
and workflow.to_delete = false
order by workflow.name asc`).Args(projectKey, pipName)

if err := gorpmapping.GetAll(ctx, db, query, &dbRes); err != nil {
return nil, sdk.WrapError(err, "Unable to load workflows for project %s and pipeline %s", projectKey, pipName)
}

return dbRes.Get(), nil
order by workflow.name asc`
var result []sdk.WorkflowName // This struct is not registered as a gorpmapping entity so we can't use gorpmapping.Query
_, err := db.Select(&result, query, projectKey, pipName)
return result, sdk.WithStack(err)
}

// LoadByApplicationName loads a workflow for a given project key and application name (ie. checking permissions)
func LoadByApplicationName(ctx context.Context, db gorp.SqlExecutor, projectKey string, appName string) (sdk.Workflows, error) {
dbRes := Workflows{}
query := gorpmapping.NewQuery(`
select distinct workflow.*, project.projectkey
// LoadByApplicationName loads a workflow for a given project key and application name
func LoadByApplicationName(ctx context.Context, db gorp.SqlExecutor, projectKey string, appName string) ([]sdk.WorkflowName, error) {
query := `SELECT distinct workflow.*, project.projectkey as "project_key", project.id as "project_id"
from workflow
join project on project.id = workflow.project_id
join w_node on w_node.workflow_id = workflow.id
join w_node_context on w_node_context.node_id = w_node.id
join application on w_node_context.application_id = application.id
where project.projectkey = $1 and application.name = $2
and workflow.to_delete = false
order by workflow.name asc`).Args(projectKey, appName)

if err := gorpmapping.GetAll(ctx, db, query, &dbRes); err != nil {
return nil, sdk.WrapError(err, "Unable to load workflows for project %s and application %s", projectKey, appName)
}

return dbRes.Get(), nil
order by workflow.name asc`
var result []sdk.WorkflowName // This struct is not registered as a gorpmapping entity so we can't use gorpmapping.Query
_, err := db.Select(&result, query, projectKey, appName)
return result, sdk.WithStack(err)
}

// LoadByEnvName loads a workflow for a given project key and environment name (ie. checking permissions)
func LoadByEnvName(ctx context.Context, db gorp.SqlExecutor, projectKey string, envName string) (sdk.Workflows, error) {
dbRes := Workflows{}
query := gorpmapping.NewQuery(`
select distinct workflow.*, project.projectkey
func LoadByEnvName(ctx context.Context, db gorp.SqlExecutor, projectKey string, envName string) ([]sdk.WorkflowName, error) {
query := `SELECT distinct workflow.*, project.projectkey as "project_key", project.id as "project_id"
from workflow
join project on project.id = workflow.project_id
join w_node on w_node.workflow_id = workflow.id
join w_node_context on w_node_context.node_id = w_node.id
join environment on w_node_context.environment_id = environment.id
where project.projectkey = $1 and environment.name = $2
and workflow.to_delete = false
order by workflow.name asc`).Args(projectKey, envName)

if err := gorpmapping.GetAll(ctx, db, query, &dbRes); err != nil {
return nil, sdk.WrapError(err, "Unable to load workflows for project %s and environment %s", projectKey, envName)
}

return dbRes.Get(), nil
}

func loadByWorkflowTemplateID(ctx context.Context, db gorp.SqlExecutor, query gorpmapping.Query) (sdk.Workflows, error) {
var dbRes Workflows
if err := gorpmapping.GetAll(ctx, db, query, &dbRes); err != nil {
return nil, err
}
return dbRes.Get(), nil
order by workflow.name asc`
var result []sdk.WorkflowName // This struct is not registered as a gorpmapping entity so we can't use gorpmapping.Query
_, err := db.Select(&result, query, projectKey, envName)
return result, sdk.WithStack(err)
}

// LoadByWorkflowTemplateID load all workflows linked to a workflow template but without loading workflow details
func LoadByWorkflowTemplateID(ctx context.Context, db gorp.SqlExecutor, templateID int64) (sdk.Workflows, error) {
query := gorpmapping.NewQuery(`
SELECT workflow.*, project.projectkey
// LoadByWorkflowTemplateID load all workflow names linked to a workflow template
func LoadByWorkflowTemplateID(ctx context.Context, db gorp.SqlExecutor, templateID int64) ([]sdk.WorkflowName, error) {
query := `SELECT distinct workflow.*, project.projectkey as "project_key", project.id as "project_id"
FROM workflow
JOIN workflow_template_instance ON workflow_template_instance.workflow_id = workflow.id
JOIN project on project.id = workflow.project_id
WHERE workflow_template_instance.workflow_template_id = $1 AND workflow.to_delete = false`).Args(templateID)
return loadByWorkflowTemplateID(ctx, db, query)
WHERE workflow_template_instance.workflow_template_id = $1 AND workflow.to_delete = false`
var result []sdk.WorkflowName // This struct is not registered as a gorpmapping entity so we can't use gorpmapping.Query
_, err := db.Select(&result, query, templateID)
return result, sdk.WithStack(err)
}

func load(ctx context.Context, db gorp.SqlExecutor, proj sdk.Project, opts LoadOptions, query string, args ...interface{}) (*sdk.Workflow, error) {
Expand Down Expand Up @@ -518,6 +501,15 @@ func IsFavorite(db gorp.SqlExecutor, w *sdk.Workflow, uID string) (bool, error)
return count > 0, nil
}

// UserFavoriteWorkflowIDs returns the list of workflow ID
func UserFavoriteWorkflowIDs(db gorp.SqlExecutor, uID string) ([]int64, error) {
var result []int64
if _, err := db.Select(&result, "SELECT workflow_id FROM workflow_favorite WHERE authentified_user_id = $1", uID); err != nil {
return nil, sdk.WithStack(err)
}
return result, nil
}

// Insert inserts a new workflow
func Insert(ctx context.Context, db gorp.SqlExecutor, store cache.Store, proj sdk.Project, w *sdk.Workflow) error {
if err := CompleteWorkflow(ctx, db, w, proj, LoadOptions{}); err != nil {
Expand Down
25 changes: 23 additions & 2 deletions engine/api/workflow/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ type LoadAllWorkflowsOptionsLoaders struct {
WithTemplate bool
WithNotifications bool
WithLabels bool
WithAudits bool
WithFavoritesForUserID string
}

type LoadAllWorkflowsOptions struct {
Expand Down Expand Up @@ -216,6 +218,13 @@ func (opt LoadAllWorkflowsOptions) GetLoaders() []gorpmapping.GetOptionFunc {
})
}

if opt.Loaders.WithFavoritesForUserID != "" {
loaders = append(loaders, func(db gorp.SqlExecutor, i interface{}) error {
ws := i.(*[]Workflow)
return opt.withFavorites(db, ws, opt.Loaders.WithFavoritesForUserID)
})
}

loaders = append(loaders, func(db gorp.SqlExecutor, i interface{}) error {
ws := i.(*[]Workflow)
return opt.withGroups(db, ws)
Expand Down Expand Up @@ -531,8 +540,6 @@ func (opt LoadAllWorkflowsOptions) withLabels(db gorp.SqlExecutor, ws *[]Workflo
return err
}

log.Debug("withLabels> %+v => %+v", ids, labels)

for x := range *ws {
w := &(*ws)[x]
for _, label := range labels {
Expand All @@ -545,6 +552,20 @@ func (opt LoadAllWorkflowsOptions) withLabels(db gorp.SqlExecutor, ws *[]Workflo
return nil
}

func (opt LoadAllWorkflowsOptions) withFavorites(db gorp.SqlExecutor, ws *[]Workflow, userID string) error {
workflowIDs, err := UserFavoriteWorkflowIDs(db, userID)
if err != nil {
return err
}

for x := range *ws {
w := &(*ws)[x]
w.Favorite = sdk.IsInInt64Array(w.ID, workflowIDs)
}

return nil
}

func LoadAllWorkflows(ctx context.Context, db gorp.SqlExecutor, opts LoadAllWorkflowsOptions) (sdk.Workflows, error) {
t0 := time.Now()

Expand Down
8 changes: 4 additions & 4 deletions sdk/usage.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ package sdk

// Usage is type to represent usage of each type
type Usage struct {
Workflows []Workflow `json:"workflows,omitempty"`
Environments []Environment `json:"environments,omitempty"`
Pipelines []Pipeline `json:"pipelines,omitempty"`
Applications []Application `json:"applications,omitempty"`
Workflows []WorkflowName `json:"workflows,omitempty"`
Environments []Environment `json:"environments,omitempty"`
Pipelines []Pipeline `json:"pipelines,omitempty"`
Applications []Application `json:"applications,omitempty"`
}
7 changes: 7 additions & 0 deletions sdk/workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ const (
// ColorRegexp represent the regexp for a format to hexadecimal color
var ColorRegexp = regexp.MustCompile(`^#\w{3,8}$`)

type WorkflowName struct {
ID int64 `json:"id" db:"id" cli:"-"`
Name string `json:"name" db:"name" cli:"name,key"`
ProjectKey string `json:"project_key" db:"project_key" cli:"project_key"`
ProjectID int64 `json:"project_id" db:"project_id" cli:"-"`
}

//Workflow represents a pipeline based workflow
type Workflow struct {
ID int64 `json:"id" db:"id" cli:"-"`
Expand Down

0 comments on commit 9c1ff8f

Please sign in to comment.