Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
d85886e
introduction to feasibility
Shivam-nagar23 Apr 1, 2024
6b731eb
Merge branch 'main' into feat-release-feasibility
Shivam-nagar23 Apr 1, 2024
38d6d07
moved feasibility in trigger/devtronApps
Shivam-nagar23 Apr 1, 2024
0569c31
feasibility refactorings
Shivam-nagar23 Apr 1, 2024
78f0ad0
Merge branch 'main' into feat-release-feasibility
Shivam-nagar23 Apr 2, 2024
db7f772
refactoring and feasibility manager
Shivam-nagar23 Apr 2, 2024
2231ce7
Merge branch 'main' into feat-release-feasibility
Shivam-nagar23 Apr 3, 2024
1ce9703
removing vulnerability changes
Shivam-nagar23 Apr 3, 2024
c4910f0
vulnerability checks retract
Shivam-nagar23 Apr 3, 2024
fdab43d
dry run removed
Shivam-nagar23 Apr 3, 2024
70c1df2
dry run checks removed
Shivam-nagar23 Apr 3, 2024
5e60445
refactoring
Shivam-nagar23 Apr 3, 2024
dd19181
removing unnecessary code
Shivam-nagar23 Apr 3, 2024
ea0345f
comments
Shivam-nagar23 Apr 4, 2024
bd354a0
Merge branch 'main' into feat-release-feasibility
Shivam-nagar23 Apr 5, 2024
6ffad39
Merge branch 'main' of github.com:devtron-labs/devtron into feat-rele…
Shivam-nagar23 Apr 5, 2024
f7d4f45
Merge branch 'main' into feat-release-feasibility
Shivam-nagar23 Apr 8, 2024
b33c308
trigger request
Shivam-nagar23 Apr 8, 2024
b6e673a
main-merge
Shivam-nagar23 Apr 8, 2024
733a975
Merge branch 'main' into feat-release-feasibility
Shivam-nagar23 Apr 22, 2024
b3512d8
Merge branch 'main' into feat-release-feasibility
Shivam-nagar23 Apr 24, 2024
2572773
Merge branch 'main' into feat-release-feasibility
Shivam-nagar23 Apr 25, 2024
fc2341e
Merge branch 'main' into feat-release-feasibility
Shivam-nagar23 Apr 26, 2024
0628648
Merge branch 'main' into feat-release-feasibility
Shivam-nagar23 Apr 29, 2024
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
4 changes: 4 additions & 0 deletions internal/constants/InternalErrorCode.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ const (

GitHostCreateFailedAlreadyExists string = "9001"
GitHostCreateFailedInDb string = "9002"

// feasibility errors
OperationPerformError string = "10001"
VulnerabilityFound string = "10002"
)

var AppAlreadyExists = &ErrorCode{"4001", "application %s already exists"}
Expand Down
10 changes: 10 additions & 0 deletions pkg/cluster/EnvironmentService.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ type EnvironmentService interface {
GetCombinedEnvironmentListForDropDown(token string, isActionUserSuperAdmin bool, auth func(email string, object []string) map[string]bool) ([]*bean2.ClusterEnvDto, error)
GetCombinedEnvironmentListForDropDownByClusterIds(token string, clusterIds []int, auth func(token string, object string) bool) ([]*bean2.ClusterEnvDto, error)
HandleErrorInClusterConnections(clusters []*ClusterBean, respMap map[int]error, clusterExistInDb bool)
GetDetailsById(envId int) (*repository.Environment, error)
}

type EnvironmentServiceImpl struct {
Expand Down Expand Up @@ -743,3 +744,12 @@ func (impl EnvironmentServiceImpl) Delete(deleteReq *bean2.EnvironmentBean, user
func (impl EnvironmentServiceImpl) HandleErrorInClusterConnections(clusters []*ClusterBean, respMap map[int]error, clusterExistInDb bool) {
impl.clusterService.HandleErrorInClusterConnections(clusters, respMap, clusterExistInDb)
}

func (impl EnvironmentServiceImpl) GetDetailsById(envId int) (*repository.Environment, error) {
envDetails, err := impl.environmentRepository.FindById(envId)
if err != nil {
impl.logger.Errorw("error encountered in GetDetailsById", "envId", envId, "err", err)
return nil, err
}
return envDetails, nil
}
41 changes: 3 additions & 38 deletions pkg/deployment/trigger/devtronApps/PreStageTriggerService.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ import (
gitSensorClient "github.com/devtron-labs/devtron/client/gitSensor"
"github.com/devtron-labs/devtron/internal/sql/repository"
"github.com/devtron-labs/devtron/internal/sql/repository/pipelineConfig"
"github.com/devtron-labs/devtron/internal/sql/repository/security"
"github.com/devtron-labs/devtron/internal/util"
bean4 "github.com/devtron-labs/devtron/pkg/bean"
repository2 "github.com/devtron-labs/devtron/pkg/cluster/repository"
adapter2 "github.com/devtron-labs/devtron/pkg/deployment/trigger/devtronApps/adapter"
"github.com/devtron-labs/devtron/pkg/deployment/trigger/devtronApps/bean"
"github.com/devtron-labs/devtron/pkg/imageDigestPolicy"
"github.com/devtron-labs/devtron/pkg/pipeline"
Expand Down Expand Up @@ -193,7 +193,8 @@ func (impl *TriggerServiceImpl) getEnvAndNsIfRunStageInEnv(ctx context.Context,
func (impl *TriggerServiceImpl) checkVulnerabilityStatusAndFailWfIfNeeded(ctx context.Context, artifact *repository.CiArtifact,
cdPipeline *pipelineConfig.Pipeline, runner *pipelineConfig.CdWorkflowRunner, triggeredBy int32) error {
//checking vulnerability for the selected image
isVulnerable, err := impl.GetArtifactVulnerabilityStatus(artifact, cdPipeline, ctx)
vulnerabilityCheckRequest := adapter2.GetVulnerabilityCheckRequest(cdPipeline, artifact.ImageDigest)
isVulnerable, err := impl.imageScanService.GetArtifactVulnerabilityStatus(ctx, vulnerabilityCheckRequest)
if err != nil {
impl.logger.Errorw("error in getting Artifact vulnerability status, TriggerPreStage", "err", err)
return err
Expand Down Expand Up @@ -860,42 +861,6 @@ func (impl *TriggerServiceImpl) getSourceCiPipelineForArtifact(ciPipeline pipeli
return sourceCiPipeline, nil
}

func (impl *TriggerServiceImpl) GetArtifactVulnerabilityStatus(artifact *repository.CiArtifact, cdPipeline *pipelineConfig.Pipeline, ctx context.Context) (bool, error) {
isVulnerable := false
if len(artifact.ImageDigest) > 0 {
var cveStores []*security.CveStore
_, span := otel.Tracer("orchestrator").Start(ctx, "scanResultRepository.FindByImageDigest")
imageScanResult, err := impl.scanResultRepository.FindByImageDigest(artifact.ImageDigest)
span.End()
if err != nil && err != pg.ErrNoRows {
impl.logger.Errorw("error fetching image digest", "digest", artifact.ImageDigest, "err", err)
return false, err
}
for _, item := range imageScanResult {
cveStores = append(cveStores, &item.CveStore)
}
_, span = otel.Tracer("orchestrator").Start(ctx, "cvePolicyRepository.GetBlockedCVEList")
if cdPipeline.Environment.ClusterId == 0 {
envDetails, err := impl.envRepository.FindById(cdPipeline.EnvironmentId)
if err != nil {
impl.logger.Errorw("error fetching cluster details by env, GetArtifactVulnerabilityStatus", "envId", cdPipeline.EnvironmentId, "err", err)
return false, err
}
cdPipeline.Environment = *envDetails
}
blockCveList, err := impl.cvePolicyRepository.GetBlockedCVEList(cveStores, cdPipeline.Environment.ClusterId, cdPipeline.EnvironmentId, cdPipeline.AppId, false)
span.End()
if err != nil {
impl.logger.Errorw("error while fetching env", "err", err)
return false, err
}
if len(blockCveList) > 0 {
isVulnerable = true
}
}
return isVulnerable, nil
}

func (impl *TriggerServiceImpl) ReserveImagesGeneratedAtPlugin(customTagId int, registryImageMap map[string][]string) ([]int, error) {
var imagePathReservationIds []int
for _, images := range registryImageMap {
Expand Down
50 changes: 14 additions & 36 deletions pkg/deployment/trigger/devtronApps/TriggerService.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import (
"github.com/devtron-labs/devtron/pkg/pipeline/repository"
"github.com/devtron-labs/devtron/pkg/pipeline/types"
"github.com/devtron-labs/devtron/pkg/plugin"
security2 "github.com/devtron-labs/devtron/pkg/security"
"github.com/devtron-labs/devtron/pkg/sql"
"github.com/devtron-labs/devtron/pkg/variables"
"github.com/devtron-labs/devtron/pkg/workflow/cd"
Expand Down Expand Up @@ -114,13 +115,11 @@ type TriggerServiceImpl struct {
gitSensorGrpcClient gitSensorClient.Client
config *types.CdConfig
helmAppService client2.HelmAppService

enforcerUtil rbac.EnforcerUtil
helmAppClient gRPC.HelmAppClient //TODO refactoring: use helm app service instead
imageScanService security2.ImageScanService
enforcerUtil rbac.EnforcerUtil
helmAppClient gRPC.HelmAppClient //TODO refactoring: use helm app service instead

appRepository appRepository.AppRepository
scanResultRepository security.ImageScanResultRepository
cvePolicyRepository security.CvePolicyRepository
ciPipelineMaterialRepository pipelineConfig.CiPipelineMaterialRepository
imageScanHistoryRepository security.ImageScanHistoryRepository
imageScanDeployInfoRepository security.ImageScanDeployInfoRepository
Expand Down Expand Up @@ -170,8 +169,6 @@ func NewTriggerServiceImpl(logger *zap.SugaredLogger, cdWorkflowCommonService cd
eventClient client.EventClient,
envVariables *util3.EnvironmentVariables,
appRepository appRepository.AppRepository,
scanResultRepository security.ImageScanResultRepository,
cvePolicyRepository security.CvePolicyRepository,
ciPipelineMaterialRepository pipelineConfig.CiPipelineMaterialRepository,
imageScanHistoryRepository security.ImageScanHistoryRepository,
imageScanDeployInfoRepository security.ImageScanDeployInfoRepository,
Expand All @@ -188,7 +185,8 @@ func NewTriggerServiceImpl(logger *zap.SugaredLogger, cdWorkflowCommonService cd
appLabelRepository pipelineConfig.AppLabelRepository,
ciPipelineRepository pipelineConfig.CiPipelineRepository,
appWorkflowRepository appWorkflow.AppWorkflowRepository,
dockerArtifactStoreRepository repository4.DockerArtifactStoreRepository) (*TriggerServiceImpl, error) {
dockerArtifactStoreRepository repository4.DockerArtifactStoreRepository,
imageScanService security2.ImageScanService) (*TriggerServiceImpl, error) {
impl := &TriggerServiceImpl{
logger: logger,
cdWorkflowCommonService: cdWorkflowCommonService,
Expand Down Expand Up @@ -221,8 +219,6 @@ func NewTriggerServiceImpl(logger *zap.SugaredLogger, cdWorkflowCommonService cd
globalEnvVariables: envVariables.GlobalEnvVariables,
helmAppClient: helmAppClient,
appRepository: appRepository,
scanResultRepository: scanResultRepository,
cvePolicyRepository: cvePolicyRepository,
ciPipelineMaterialRepository: ciPipelineMaterialRepository,
imageScanHistoryRepository: imageScanHistoryRepository,
imageScanDeployInfoRepository: imageScanDeployInfoRepository,
Expand All @@ -240,6 +236,7 @@ func NewTriggerServiceImpl(logger *zap.SugaredLogger, cdWorkflowCommonService cd
ciPipelineRepository: ciPipelineRepository,
appWorkflowRepository: appWorkflowRepository,
dockerArtifactStoreRepository: dockerArtifactStoreRepository,
imageScanService: imageScanService,
}
config, err := types.GetCdConfig()
if err != nil {
Expand Down Expand Up @@ -400,7 +397,8 @@ func (impl *TriggerServiceImpl) ManualCdTrigger(triggerContext bean.TriggerConte
impl.logger.Warnw("unable to migrate deprecated DataSource", "artifactId", artifact.Id)
}
}
isVulnerable, err := impl.GetArtifactVulnerabilityStatus(artifact, cdPipeline, ctx)
vulnerabilityCheckRequest := adapter.GetVulnerabilityCheckRequest(cdPipeline, artifact.ImageDigest)
isVulnerable, err := impl.imageScanService.GetArtifactVulnerabilityStatus(ctx, vulnerabilityCheckRequest)
if err != nil {
impl.logger.Errorw("error in getting Artifact vulnerability status, ManualCdTrigger", "err", err)
return 0, err
Expand Down Expand Up @@ -579,32 +577,12 @@ func (impl *TriggerServiceImpl) TriggerAutomaticDeployment(request bean.TriggerR
return err
}
// custom GitOps repo url validation --> Ends

vulnerabilityCheckRequest := adapter.GetVulnerabilityCheckRequest(pipeline, artifact.ImageDigest)
//checking vulnerability for deploying image
isVulnerable := false
if len(artifact.ImageDigest) > 0 {
var cveStores []*security.CveStore
imageScanResult, err := impl.scanResultRepository.FindByImageDigest(artifact.ImageDigest)
if err != nil && err != pg.ErrNoRows {
impl.logger.Errorw("error fetching image digest", "digest", artifact.ImageDigest, "err", err)
return err
}
for _, item := range imageScanResult {
cveStores = append(cveStores, &item.CveStore)
}
env, err := impl.envRepository.FindById(pipeline.EnvironmentId)
if err != nil {
impl.logger.Errorw("error while fetching env", "err", err)
return err
}
blockCveList, err := impl.cvePolicyRepository.GetBlockedCVEList(cveStores, env.ClusterId, pipeline.EnvironmentId, pipeline.AppId, false)
if err != nil {
impl.logger.Errorw("error while fetching blocked cve list", "err", err)
return err
}
if len(blockCveList) > 0 {
isVulnerable = true
}
isVulnerable, err := impl.imageScanService.GetArtifactVulnerabilityStatus(request.TriggerContext.Context, vulnerabilityCheckRequest)
if err != nil {
impl.logger.Errorw("error in getting Artifact vulnerability status, ManualCdTrigger", "err", err)
return err
}
if isVulnerable == true {
if err = impl.cdWorkflowCommonService.MarkCurrentDeploymentFailed(runner, errors.New(pipelineConfig.FOUND_VULNERABILITY), triggeredBy); err != nil {
Expand Down
8 changes: 8 additions & 0 deletions pkg/deployment/trigger/devtronApps/adapter/adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package adapter
import (
bean3 "github.com/devtron-labs/devtron/api/bean"
"github.com/devtron-labs/devtron/internal/sql/repository/pipelineConfig"
"github.com/devtron-labs/devtron/pkg/deployment/trigger/devtronApps/bean"
)

func SetPipelineFieldsInOverrideRequest(overrideRequest *bean3.ValuesOverrideRequest, pipeline *pipelineConfig.Pipeline) {
Expand All @@ -15,3 +16,10 @@ func SetPipelineFieldsInOverrideRequest(overrideRequest *bean3.ValuesOverrideReq
overrideRequest.AppName = pipeline.App.AppName
overrideRequest.DeploymentAppType = pipeline.DeploymentAppType
}

func GetVulnerabilityCheckRequest(cdPipeline *pipelineConfig.Pipeline, imageDigest string) *bean.VulnerabilityCheckRequest {
return &bean.VulnerabilityCheckRequest{
CdPipeline: cdPipeline,
ImageDigest: imageDigest,
}
}
9 changes: 9 additions & 0 deletions pkg/deployment/trigger/devtronApps/bean/bean.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,12 @@ const (
ManifestDownload DeploymentType = "manifest_download"
GitOpsWithoutDeployment DeploymentType = "git_ops_without_deployment"
)

type TriggerRequirementRequestDto struct {
TriggerRequest TriggerRequest
}

type VulnerabilityCheckRequest struct {
ImageDigest string
CdPipeline *pipelineConfig.Pipeline
}
14 changes: 14 additions & 0 deletions pkg/deployment/trigger/devtronApps/feasibilityChecker.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package devtronApps

import (
"github.com/devtron-labs/devtron/pkg/deployment/trigger/devtronApps/bean"
)

type FeasibilityManager interface {
CheckFeasibility(triggerRequirementRequest *bean.TriggerRequirementRequestDto) error
}

func (impl *TriggerServiceImpl) CheckFeasibility(triggerRequirementRequest *bean.TriggerRequirementRequestDto) error {
// have not implemented right now, will be implemented in future for security vulnerability
return nil
}
1 change: 1 addition & 0 deletions pkg/eventProcessor/in/WorkflowEventProcessorService.go
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,7 @@ func (impl *WorkflowEventProcessorImpl) SubscribeCICompleteEvent() error {
}

triggerContext := bean5.TriggerContext{
Context: context.Background(),
ReferenceId: pointer.String(msg.MsgId),
}

Expand Down
45 changes: 44 additions & 1 deletion pkg/security/ImageScanService.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@
package security

import (
"context"
"github.com/devtron-labs/devtron/pkg/cluster/repository/bean"
bean2 "github.com/devtron-labs/devtron/pkg/deployment/trigger/devtronApps/bean"
"go.opentelemetry.io/otel"
"time"

repository1 "github.com/devtron-labs/devtron/internal/sql/repository/app"
Expand All @@ -40,6 +43,7 @@ type ImageScanService interface {
FetchExecutionDetailResult(request *ImageScanRequest) (*ImageScanExecutionDetail, error)
FetchMinScanResultByAppIdAndEnvId(request *ImageScanRequest) (*ImageScanExecutionDetail, error)
VulnerabilityExposure(request *security.VulnerabilityRequest) (*security.VulnerabilityExposureListingResponse, error)
GetArtifactVulnerabilityStatus(ctx context.Context, request *bean2.VulnerabilityCheckRequest) (bool, error)
}

type ImageScanServiceImpl struct {
Expand All @@ -59,6 +63,7 @@ type ImageScanServiceImpl struct {
ciPipelineRepository pipelineConfig.CiPipelineRepository
scanToolMetaDataRepository security.ScanToolMetadataRepository
scanToolExecutionHistoryMappingRepository security.ScanToolExecutionHistoryMappingRepository
cvePolicyRepository security.CvePolicyRepository
}

type ImageScanRequest struct {
Expand Down Expand Up @@ -131,7 +136,8 @@ func NewImageScanServiceImpl(Logger *zap.SugaredLogger, scanHistoryRepository se
userService user.UserService, teamRepository repository2.TeamRepository,
appRepository repository1.AppRepository,
envService cluster.EnvironmentService, ciArtifactRepository repository.CiArtifactRepository, policyService PolicyService,
pipelineRepository pipelineConfig.PipelineRepository, ciPipelineRepository pipelineConfig.CiPipelineRepository, scanToolMetaDataRepository security.ScanToolMetadataRepository, scanToolExecutionHistoryMappingRepository security.ScanToolExecutionHistoryMappingRepository) *ImageScanServiceImpl {
pipelineRepository pipelineConfig.PipelineRepository, ciPipelineRepository pipelineConfig.CiPipelineRepository, scanToolMetaDataRepository security.ScanToolMetadataRepository, scanToolExecutionHistoryMappingRepository security.ScanToolExecutionHistoryMappingRepository,
cvePolicyRepository security.CvePolicyRepository) *ImageScanServiceImpl {
return &ImageScanServiceImpl{Logger: Logger, scanHistoryRepository: scanHistoryRepository, scanResultRepository: scanResultRepository,
scanObjectMetaRepository: scanObjectMetaRepository, cveStoreRepository: cveStoreRepository,
imageScanDeployInfoRepository: imageScanDeployInfoRepository,
Expand All @@ -145,6 +151,7 @@ func NewImageScanServiceImpl(Logger *zap.SugaredLogger, scanHistoryRepository se
ciPipelineRepository: ciPipelineRepository,
scanToolMetaDataRepository: scanToolMetaDataRepository,
scanToolExecutionHistoryMappingRepository: scanToolExecutionHistoryMappingRepository,
cvePolicyRepository: cvePolicyRepository,
}
}

Expand Down Expand Up @@ -605,3 +612,39 @@ func (impl ImageScanServiceImpl) VulnerabilityExposure(request *security.Vulnera
vulnerabilityExposureListingResponse.VulnerabilityExposure = vulnerabilityExposureList
return vulnerabilityExposureListingResponse, nil
}

func (impl ImageScanServiceImpl) GetArtifactVulnerabilityStatus(ctx context.Context, request *bean2.VulnerabilityCheckRequest) (bool, error) {
isVulnerable := false
if len(request.ImageDigest) > 0 {
var cveStores []*security.CveStore
_, span := otel.Tracer("orchestrator").Start(ctx, "scanResultRepository.FindByImageDigest")
imageScanResult, err := impl.scanResultRepository.FindByImageDigest(request.ImageDigest)
span.End()
if err != nil && err != pg.ErrNoRows {
impl.Logger.Errorw("error fetching image digest", "digest", request.ImageDigest, "err", err)
return false, err
}
for _, item := range imageScanResult {
cveStores = append(cveStores, &item.CveStore)
}
_, span = otel.Tracer("orchestrator").Start(ctx, "cvePolicyRepository.GetBlockedCVEList")
if request.CdPipeline.Environment.ClusterId == 0 {
envDetails, err := impl.envService.GetDetailsById(request.CdPipeline.EnvironmentId)
if err != nil {
impl.Logger.Errorw("error fetching cluster details by env, GetArtifactVulnerabilityStatus", "envId", request.CdPipeline.EnvironmentId, "err", err)
return false, err
}
request.CdPipeline.Environment = *envDetails
}
blockCveList, err := impl.cvePolicyRepository.GetBlockedCVEList(cveStores, request.CdPipeline.Environment.ClusterId, request.CdPipeline.EnvironmentId, request.CdPipeline.AppId, false)
span.End()
if err != nil {
impl.Logger.Errorw("error encountered in GetArtifactVulnerabilityStatus", "clusterId", request.CdPipeline.Environment.ClusterId, "envId", request.CdPipeline.EnvironmentId, "appId", request.CdPipeline.AppId, "err", err)
return false, err
}
if len(blockCveList) > 0 {
isVulnerable = true
}
}
return isVulnerable, nil
}
Loading