Skip to content

fix: Fix scanning optimisation #6683

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

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
68 changes: 45 additions & 23 deletions api/restHandler/ImageScanRestHandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/devtron-labs/devtron/pkg/policyGovernance/security/imageScanning"
securityBean "github.com/devtron-labs/devtron/pkg/policyGovernance/security/imageScanning/bean"
security2 "github.com/devtron-labs/devtron/pkg/policyGovernance/security/imageScanning/repository"
"github.com/devtron-labs/devtron/util/sliceUtil"
"net/http"
"strconv"

Expand Down Expand Up @@ -104,6 +105,45 @@ func (impl ImageScanRestHandlerImpl) ScanExecutionList(w http.ResponseWriter, r
return
}
token := r.Header.Get("token")
isSuperAdmin := false
if ok := impl.enforcer.Enforce(token, casbin.ResourceGlobal, casbin.ActionGet, "*"); ok {
isSuperAdmin = true
}
var ids []int
if isSuperAdmin {
ids = sliceUtil.NewSliceFromFuncExec(filteredDeployInfoList, func(item *security2.ImageScanDeployInfo) int {
return item.Id
})
} else {
ids, err = impl.getAuthorisedImageScanDeployInfoIds(token, filteredDeployInfoList)
if err != nil {
impl.logger.Errorw("error in getting authorised image scan deploy info ids", "err", err)
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
return
}
}

if len(ids) == 0 {
responseList := make([]*securityBean.ImageScanHistoryResponse, 0)
common.WriteJsonResp(w, nil, &securityBean.ImageScanHistoryListingResponse{ImageScanHistoryResponse: responseList}, http.StatusOK)
return
}

results, err := impl.imageScanService.FetchScanExecutionListing(request, ids)
if err != nil {
impl.logger.Errorw("service err, ScanExecutionList", "err", err, "payload", request)
if util.IsErrNoRows(err) {
responseList := make([]*securityBean.ImageScanHistoryResponse, 0)
common.WriteJsonResp(w, nil, &securityBean.ImageScanHistoryListingResponse{ImageScanHistoryResponse: responseList}, http.StatusOK)
} else {
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
}
return
}
common.WriteJsonResp(w, err, results, http.StatusOK)
}

func (impl ImageScanRestHandlerImpl) getAuthorisedImageScanDeployInfoIds(token string, filteredDeployInfoList []*security2.ImageScanDeployInfo) ([]int, error) {
var ids []int
var appRBACObjects []string
var envRBACObjects []string
Expand All @@ -119,8 +159,8 @@ func (impl ImageScanRestHandlerImpl) ScanExecutionList(w http.ResponseWriter, r

appObjects, envObjects, appIdtoApp, envIdToEnv, err := impl.enforcerUtil.GetAppAndEnvRBACNamesByAppAndEnvIds(IdToAppEnvPairs)
if err != nil {
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
return
impl.logger.Errorw("error in getting app and env rbac objects", "err", err)
return nil, err
}

for _, item := range filteredDeployInfoList {
Expand All @@ -136,8 +176,8 @@ func (impl ImageScanRestHandlerImpl) ScanExecutionList(w http.ResponseWriter, r
} else if item.ScanObjectMetaId > 0 && (item.ObjectType == ObjectTypePod) {
environments, err := impl.environmentService.GetByClusterId(item.ClusterId)
if err != nil {
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
return
impl.logger.Errorw("error in getting environments for cluster", "clusterId", item.ClusterId, "err", err)
return nil, err
}
for _, environment := range environments {
podObject := environment.EnvironmentIdentifier
Expand All @@ -163,25 +203,7 @@ func (impl ImageScanRestHandlerImpl) ScanExecutionList(w http.ResponseWriter, r
}
}
}

if ids == nil || len(ids) == 0 {
responseList := make([]*securityBean.ImageScanHistoryResponse, 0)
common.WriteJsonResp(w, nil, &securityBean.ImageScanHistoryListingResponse{ImageScanHistoryResponse: responseList}, http.StatusOK)
return
}

results, err := impl.imageScanService.FetchScanExecutionListing(request, ids)
if err != nil {
impl.logger.Errorw("service err, ScanExecutionList", "err", err, "payload", request)
if util.IsErrNoRows(err) {
responseList := make([]*securityBean.ImageScanHistoryResponse, 0)
common.WriteJsonResp(w, nil, &securityBean.ImageScanHistoryListingResponse{ImageScanHistoryResponse: responseList}, http.StatusOK)
} else {
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
}
return
}
common.WriteJsonResp(w, err, results, http.StatusOK)
return ids, nil
}

func (impl ImageScanRestHandlerImpl) FetchExecutionDetail(w http.ResponseWriter, r *http.Request) {
Expand Down
34 changes: 22 additions & 12 deletions internal/sql/repository/pipelineConfig/CdWorfkflowRepository.go
Original file line number Diff line number Diff line change
Expand Up @@ -774,31 +774,41 @@ func (impl *CdWorkflowRepositoryImpl) FindDeployedCdWorkflowRunnersByPipelineId(
}

func (impl *CdWorkflowRepositoryImpl) FindLatestCdWorkflowRunnerArtifactMetadataForAppAndEnvIds(appVsEnvIdMap map[int][]int, runnerType apiBean.WorkflowType) ([]*cdWorkflow.CdWorkflowRunnerArtifactMetadata, error) {
var allRunners []*cdWorkflow.CdWorkflowRunnerArtifactMetadata
var runners []*cdWorkflow.CdWorkflowRunnerArtifactMetadata

// Prepare the (app_id, env_id) tuple list for the query
tupleList := make([]interface{}, 0, len(appVsEnvIdMap))
for appId, envIds := range appVsEnvIdMap {
for _, envId := range envIds {
tupleList = append(tupleList, []interface{}{appId, envId})
}
}
if len(tupleList) == 0 {
return nil, nil
}

query := `
WITH RankedData AS (
SELECT
p.app_id AS "app_id",
p.environment_id AS "env_id",
p.deleted AS "deleted",
p.deleted AS "deleted",
wf.ci_artifact_id AS "ci_artifact_id",
ci_artifact.parent_ci_artifact AS "parent_ci_artifact",
ci_artifact.scanned AS "scanned",
ROW_NUMBER() OVER (PARTITION BY p.app_id, p.environment_id ORDER BY cd_workflow_runner.id DESC) AS rn
FROM cd_workflow_runner INNER JOIN cd_workflow wf ON wf.id = cd_workflow_runner.cd_workflow_id
INNER JOIN pipeline p ON p.id = wf.pipeline_id
INNER JOIN ci_artifact ON ci_artifact.id = wf.ci_artifact_id
WHERE cd_workflow_runner.workflow_type = ? AND p.app_id = ? AND p.environment_id IN (?))
WHERE cd_workflow_runner.workflow_type = ?
AND (p.app_id, p.environment_id) IN ( ? )
)
SELECT "app_id","env_id","ci_artifact_id","parent_ci_artifact","scanned" FROM RankedData WHERE rn = 1 and deleted= false;
`
for appId, envIds := range appVsEnvIdMap {
var runners []*cdWorkflow.CdWorkflowRunnerArtifactMetadata
_, err := impl.dbConnection.Query(&runners, query, runnerType, appId, pg.In(envIds))
if err != nil {
impl.logger.Errorw("error in getting cdWfrs by appId and envIds and runner type", "appVsEnvIdMap", appVsEnvIdMap, "err", err)
return nil, err
}
allRunners = append(allRunners, runners...)
_, err := impl.dbConnection.Query(&runners, query, runnerType, pg.In(tupleList))
if err != nil {
impl.logger.Errorw("error in getting cdWfrs by appId and envIds and runner type", "appVsEnvIdMap", appVsEnvIdMap, "err", err)
return nil, err
}
return allRunners, nil
return runners, nil
}
2 changes: 1 addition & 1 deletion wire_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading