Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: artifact api refactoring #4137

Merged
merged 37 commits into from
Nov 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
a0c5a10
wip
gireesh-devtron Oct 19, 2023
4f80365
wip
gireesh-devtron Oct 19, 2023
29d5e8c
ci type parent artifats fetched
gireesh-devtron Oct 19, 2023
6beb311
commented not required data
gireesh-devtron Oct 19, 2023
0d0ed18
almost done, optimise TODOs
gireesh-devtron Oct 19, 2023
673570d
pagination done for OSS
gireesh-devtron Oct 19, 2023
d043980
calling V2 function in resthandler
gireesh-devtron Oct 19, 2023
2bf1cd3
bug fix for no deployment triggered on the pipeline and query fix for…
gireesh-devtron Oct 20, 2023
d78a097
query fix for emptyexclude artifacts ids
gireesh-devtron Oct 20, 2023
89351cf
code review comments
kripanshdevtron Oct 20, 2023
4787091
searchstring refactor fix
gireesh-devtron Oct 26, 2023
53532cf
added rollback API V2 in
gireesh-devtron Oct 27, 2023
4357070
added artifact createdOn time
gireesh-devtron Oct 30, 2023
73bcb32
pagination fix
gireesh-devtron Oct 30, 2023
dc61990
fix
gireesh-devtron Oct 30, 2023
0ba2890
delete redundant ids
gireesh-devtron Oct 30, 2023
15cd7bc
setting data source value
gireesh-devtron Oct 31, 2023
d282ca2
sql script
gireesh-devtron Oct 31, 2023
686ba66
queries optimised and created queryBuilder for getting artifacts list
gireesh-devtron Nov 1, 2023
f5a9425
sync oss code
gireesh-devtron Nov 1, 2023
851c7f4
optimise getting git-triggers logic
gireesh-devtron Nov 1, 2023
b2fbcfb
fix
gireesh-devtron Nov 1, 2023
1c96fe5
merge main
gireesh-devtron Nov 3, 2023
469d1a3
totalcount fix
gireesh-devtron Nov 3, 2023
84b3911
offset validation
gireesh-devtron Nov 3, 2023
fa09e81
Merge branch 'main' into artifact-api-refactoring
gireesh-devtron Nov 7, 2023
542bd77
enterprise sync
ShashwatDadhich Nov 10, 2023
26ff795
offset issue
gireesh-devtron Nov 10, 2023
cc152f4
query change
gireesh-devtron Nov 10, 2023
47be577
query change
gireesh-devtron Nov 10, 2023
92aac1d
fix
gireesh-devtron Nov 10, 2023
13c60fb
fix
gireesh-devtron Nov 10, 2023
13f2188
parenthesis fix
gireesh-devtron Nov 15, 2023
3afdff9
update script
gireesh-devtron Nov 15, 2023
ce54447
Merge branch 'main' into artifact-api-refactoring
gireesh-devtron Nov 15, 2023
8515920
make like query part conditional
gireesh-devtron Nov 15, 2023
1611a0f
make const of empty like regex
gireesh-devtron Nov 15, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions api/bean/ValuesOverrideRequest.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,26 @@ type TriggerEvent struct {
TriggeredBy int32
TriggerdAt time.Time
}

type ArtifactsListFilterOptions struct {
//list filter data
Limit int
Offset int
SearchString string
Order string

//self stage data
PipelineId int
StageType WorkflowType

//parent satge data
ParentCdId int
ParentId int
ParentStageType WorkflowType

//excludeArtifactIds
ExcludeArtifactIds []int

//excludeWfRunners
ExcludeWfrIds []int
}
51 changes: 47 additions & 4 deletions api/restHandler/app/DeploymentPipelineRestHandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -1176,7 +1176,34 @@ func (handler PipelineConfigRestHandlerImpl) GetArtifactsByCDPipeline(w http.Res
}
stage := r.URL.Query().Get("stage")
if len(stage) == 0 {
stage = "PRE"
stage = pipeline.WorklowTypePre
}
searchString := ""
search := r.URL.Query().Get("search")
if len(search) != 0 {
searchString = search
}

offset := 0
limit := 10
offsetQueryParam := r.URL.Query().Get("offset")
if offsetQueryParam != "" {
offset, err = strconv.Atoi(offsetQueryParam)
if err != nil || offset < 0 {
handler.Logger.Errorw("request err, GetArtifactsForRollback", "err", err, "offsetQueryParam", offsetQueryParam)
common.WriteJsonResp(w, err, "invalid offset", http.StatusBadRequest)
return
}
}

sizeQueryParam := r.URL.Query().Get("size")
if sizeQueryParam != "" {
limit, err = strconv.Atoi(sizeQueryParam)
if err != nil {
handler.Logger.Errorw("request err, GetArtifactsForRollback", "err", err, "sizeQueryParam", sizeQueryParam)
common.WriteJsonResp(w, err, "invalid size", http.StatusBadRequest)
return
}
}
handler.Logger.Infow("request payload, GetArtifactsByCDPipeline", "cdPipelineId", cdPipelineId, "stage", stage)

Expand Down Expand Up @@ -1207,8 +1234,17 @@ func (handler PipelineConfigRestHandlerImpl) GetArtifactsByCDPipeline(w http.Res
return
}
//rbac block ends here

ciArtifactResponse, err := handler.pipelineBuilder.RetrieveArtifactsByCDPipeline(pipeline, bean2.WorkflowType(stage))
var ciArtifactResponse *bean.CiArtifactResponse
if handler.pipelineRestHandlerEnvConfig.UseArtifactListApiV2 {
artifactsListFilterOptions := &bean2.ArtifactsListFilterOptions{
Limit: limit,
Offset: offset,
SearchString: searchString,
}
ciArtifactResponse, err = handler.pipelineBuilder.RetrieveArtifactsByCDPipelineV2(pipeline, bean2.WorkflowType(stage), artifactsListFilterOptions)
} else {
ciArtifactResponse, err = handler.pipelineBuilder.RetrieveArtifactsByCDPipeline(pipeline, bean2.WorkflowType(stage))
}
if err != nil {
handler.Logger.Errorw("service err, GetArtifactsByCDPipeline", "err", err, "cdPipelineId", cdPipelineId, "stage", stage)
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
Expand Down Expand Up @@ -1431,6 +1467,8 @@ func (handler PipelineConfigRestHandlerImpl) GetArtifactsForRollback(w http.Resp
common.WriteJsonResp(w, err, "invalid size", http.StatusBadRequest)
return
}
searchString := r.URL.Query().Get("search")

//rbac block starts from here
object := handler.enforcerUtil.GetAppRBACName(app.AppName)
if ok := handler.enforcer.Enforce(token, casbin.ResourceApplications, casbin.ActionGet, object); !ok {
Expand All @@ -1444,9 +1482,14 @@ func (handler PipelineConfigRestHandlerImpl) GetArtifactsForRollback(w http.Resp
}
//rbac block ends here
//rbac for edit tags access
var ciArtifactResponse bean.CiArtifactResponse
triggerAccess := handler.enforcer.Enforce(token, casbin.ResourceApplications, casbin.ActionTrigger, object)
if handler.pipelineRestHandlerEnvConfig.UseArtifactListApiV2 {
ciArtifactResponse, err = handler.pipelineBuilder.FetchArtifactForRollbackV2(cdPipelineId, app.Id, offset, limit, searchString, app, deploymentPipeline)
} else {
ciArtifactResponse, err = handler.pipelineBuilder.FetchArtifactForRollback(cdPipelineId, app.Id, offset, limit, searchString)
}

ciArtifactResponse, err := handler.pipelineBuilder.FetchArtifactForRollback(cdPipelineId, app.Id, offset, limit)
if err != nil {
handler.Logger.Errorw("service err, GetArtifactsForRollback", "err", err, "cdPipelineId", cdPipelineId)
common.WriteJsonResp(w, err, "unable to fetch artifacts", http.StatusInternalServerError)
Expand Down
12 changes: 12 additions & 0 deletions api/restHandler/app/PipelineConfigRestHandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"context"
"encoding/json"
"fmt"
"github.com/caarlos0/env"
"github.com/devtron-labs/devtron/api/restHandler/common"
"github.com/devtron-labs/devtron/client/gitSensor"
"github.com/devtron-labs/devtron/internal/sql/repository/helper"
Expand Down Expand Up @@ -62,6 +63,10 @@ import (
"gopkg.in/go-playground/validator.v9"
)

type PipelineRestHandlerEnvConfig struct {
UseArtifactListApiV2 bool `env:"USE_ARTIFACT_LISTING_API_V2"`
}

type DevtronAppRestHandler interface {
CreateApp(w http.ResponseWriter, r *http.Request)
DeleteApp(w http.ResponseWriter, r *http.Request)
Expand Down Expand Up @@ -124,6 +129,7 @@ type PipelineConfigRestHandlerImpl struct {
argoUserService argo.ArgoUserService
imageTaggingService pipeline.ImageTaggingService
deploymentTemplateService generateManifest.DeploymentTemplateService
pipelineRestHandlerEnvConfig *PipelineRestHandlerEnvConfig
}

func NewPipelineRestHandlerImpl(pipelineBuilder pipeline.PipelineBuilder, Logger *zap.SugaredLogger,
Expand All @@ -148,6 +154,11 @@ func NewPipelineRestHandlerImpl(pipelineBuilder pipeline.PipelineBuilder, Logger
scanResultRepository security.ImageScanResultRepository, gitProviderRepo repository.GitProviderRepository,
argoUserService argo.ArgoUserService, ciPipelineMaterialRepository pipelineConfig.CiPipelineMaterialRepository,
imageTaggingService pipeline.ImageTaggingService) *PipelineConfigRestHandlerImpl {
envConfig := &PipelineRestHandlerEnvConfig{}
err := env.Parse(envConfig)
if err != nil {
Logger.Errorw("error in parsing PipelineRestHandlerEnvConfig", "err", err)
}
return &PipelineConfigRestHandlerImpl{
pipelineBuilder: pipelineBuilder,
Logger: Logger,
Expand Down Expand Up @@ -178,6 +189,7 @@ func NewPipelineRestHandlerImpl(pipelineBuilder pipeline.PipelineBuilder, Logger
ciPipelineMaterialRepository: ciPipelineMaterialRepository,
imageTaggingService: imageTaggingService,
deploymentTemplateService: deploymentTemplateService,
pipelineRestHandlerEnvConfig: envConfig,
}
}

Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ require (
github.com/prometheus/procfs v0.8.0 // indirect
github.com/robfig/cron v1.2.0 // indirect
github.com/russross/blackfriday v1.5.2 // indirect
github.com/samber/lo v1.38.1 // indirect
github.com/sergi/go-diff v1.1.0 // indirect
github.com/shopspring/decimal v1.2.0 // indirect
github.com/sirupsen/logrus v1.9.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1038,6 +1038,8 @@ github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM=
github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA=
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
github.com/sanity-io/litter v1.2.0/go.mod h1:JF6pZUFgu2Q0sBZ+HSV35P8TVPI1TTzEwyu9FXAw2W4=
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
Expand Down
117 changes: 116 additions & 1 deletion internal/sql/repository/CiArtifactRepository.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,15 @@ import (
"go.uber.org/zap"
)

type CiArtifactWithExtraData struct {
CiArtifact
PayloadSchema string
TotalCount int
TriggeredBy int32
StartedOn time.Time
CdWorkflowRunnerId int
}

type CiArtifact struct {
tableName struct{} `sql:"ci_artifact" pg:",discard_unknown_columns"`
Id int `sql:"id,pk"`
Expand Down Expand Up @@ -59,7 +68,7 @@ type CiArtifactRepository interface {
GetArtifactParentCiAndWorkflowDetailsByIds(ids []int) ([]*CiArtifact, error)
GetByWfId(wfId int) (artifact *CiArtifact, err error)
GetArtifactsByCDPipeline(cdPipelineId, limit int, parentId int, parentType bean.WorkflowType) ([]*CiArtifact, error)

GetArtifactsByCDPipelineV3(listingFilterOpts *bean.ArtifactsListFilterOptions) ([]*CiArtifact, int, error)
GetLatestArtifactTimeByCiPipelineIds(ciPipelineIds []int) ([]*CiArtifact, error)
GetLatestArtifactTimeByCiPipelineId(ciPipelineId int) (*CiArtifact, error)
GetArtifactsByCDPipelineV2(cdPipelineId int) ([]CiArtifact, error)
Expand All @@ -72,6 +81,8 @@ type CiArtifactRepository interface {
GetByIds(ids []int) ([]*CiArtifact, error)
GetArtifactByCdWorkflowId(cdWorkflowId int) (artifact *CiArtifact, err error)
GetArtifactsByParentCiWorkflowId(parentCiWorkflowId int) ([]string, error)
FetchArtifactsByCdPipelineIdV2(listingFilterOptions bean.ArtifactsListFilterOptions) ([]CiArtifactWithExtraData, int, error)
FindArtifactByListFilter(listingFilterOptions *bean.ArtifactsListFilterOptions) ([]CiArtifact, int, error)
}

type CiArtifactRepositoryImpl struct {
Expand Down Expand Up @@ -240,6 +251,68 @@ func (impl CiArtifactRepositoryImpl) GetArtifactsByCDPipeline(cdPipelineId, limi
return artifactsAll, err
}

func (impl CiArtifactRepositoryImpl) GetArtifactsByCDPipelineV3(listingFilterOpts *bean.ArtifactsListFilterOptions) ([]*CiArtifact, int, error) {

if listingFilterOpts.ParentStageType != bean.CI_WORKFLOW_TYPE && listingFilterOpts.ParentStageType != bean.WEBHOOK_WORKFLOW_TYPE {
return nil, 0, nil
}

artifactsResp := make([]*CiArtifactWithExtraData, 0, listingFilterOpts.Limit)
var artifacts []*CiArtifact
totalCount := 0
finalQuery := BuildQueryForParentTypeCIOrWebhook(*listingFilterOpts)
_, err := impl.dbConnection.Query(&artifactsResp, finalQuery)
if err != nil {
return nil, totalCount, err
}
artifacts = make([]*CiArtifact, len(artifactsResp))
for i, _ := range artifactsResp {
artifacts[i] = &artifactsResp[i].CiArtifact
totalCount = artifactsResp[i].TotalCount
}

if len(artifacts) == 0 {
return artifacts, totalCount, nil
}
artifacts, err = impl.setDeployedDataInArtifacts(artifacts)
return artifacts, totalCount, err
}

func (impl CiArtifactRepositoryImpl) setDeployedDataInArtifacts(artifacts []*CiArtifact) ([]*CiArtifact, error) {
//processing
artifactsMap := make(map[int]*CiArtifact)
artifactsIds := make([]int, 0, len(artifacts))
for _, artifact := range artifacts {
artifactsMap[artifact.Id] = artifact
artifactsIds = append(artifactsIds, artifact.Id)
}

//(this will fetch all the artifacts that were deployed on the given pipeline atleast once in new->old deployed order)
artifactsDeployed := make([]*CiArtifact, 0, len(artifactsIds))
query := " SELECT cia.id,pco.created_on AS created_on " +
" FROM ci_artifact cia" +
" INNER JOIN pipeline_config_override pco ON pco.ci_artifact_id=cia.id" +
" WHERE pco.pipeline_id = ? " +
" AND cia.id IN (?) " +
" ORDER BY pco.id desc;"

_, err := impl.dbConnection.Query(&artifactsDeployed, query, pg.In(artifactsIds))
if err != nil {
return artifacts, nil
}

//set deployed time and latest deployed artifact
for _, deployedArtifact := range artifactsDeployed {
artifactId := deployedArtifact.Id
if _, ok := artifactsMap[artifactId]; ok {
artifactsMap[artifactId].Deployed = true
artifactsMap[artifactId].DeployedTime = deployedArtifact.CreatedOn
}
}

return artifacts, nil
}

func (impl CiArtifactRepositoryImpl) GetLatestArtifactTimeByCiPipelineIds(ciPipelineIds []int) ([]*CiArtifact, error) {
artifacts := make([]*CiArtifact, 0)
query := "select cws.pipeline_id, cws.created_on from " +
Expand Down Expand Up @@ -582,3 +655,45 @@ func (impl CiArtifactRepositoryImpl) GetArtifactsByParentCiWorkflowId(parentCiWo
}
return artifacts, err
}

func (impl CiArtifactRepositoryImpl) FindArtifactByListFilter(listingFilterOptions *bean.ArtifactsListFilterOptions) ([]CiArtifact, int, error) {

var ciArtifactsResp []CiArtifactWithExtraData
var ciArtifacts []CiArtifact
totalCount := 0
finalQuery := BuildQueryForArtifactsForCdStage(*listingFilterOptions)
_, err := impl.dbConnection.Query(&ciArtifactsResp, finalQuery)
if err == pg.ErrNoRows || len(ciArtifactsResp) == 0 {
return ciArtifacts, totalCount, nil
}
artifactIds := make([]int, len(ciArtifactsResp))
for i, af := range ciArtifactsResp {
artifactIds[i] = af.Id
totalCount = af.TotalCount
}

err = impl.dbConnection.
Model(&ciArtifacts).
Where("id IN (?) ", pg.In(artifactIds)).
Select()

if err == pg.ErrNoRows {
return ciArtifacts, totalCount, nil
}
return ciArtifacts, totalCount, err
}

func (impl CiArtifactRepositoryImpl) FetchArtifactsByCdPipelineIdV2(listingFilterOptions bean.ArtifactsListFilterOptions) ([]CiArtifactWithExtraData, int, error) {
var wfrList []CiArtifactWithExtraData
totalCount := 0
finalQuery := BuildQueryForArtifactsForRollback(listingFilterOptions)
_, err := impl.dbConnection.Query(&wfrList, finalQuery)
if err != nil && err != pg.ErrNoRows {
impl.logger.Errorw("error in getting Wfrs and ci artifacts by pipelineId", "err", err, "pipelineId", listingFilterOptions.PipelineId)
return nil, totalCount, err
}
if len(wfrList) > 0 {
totalCount = wfrList[0].TotalCount
}
return wfrList, totalCount, nil
}
Loading
Loading