Skip to content

Commit

Permalink
enhanced scan update
Browse files Browse the repository at this point in the history
  • Loading branch information
sainathdev committed Jan 25, 2022
1 parent e4e07f3 commit 4d5b736
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 16 deletions.
20 changes: 20 additions & 0 deletions pkg/aws/ecr.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
// ECRSVC is a wrapper for ECR Image Scan API calls
type ECRSVC interface {
GetECRImagesWithTag(tag string) (map[string][]*ecr.ImageDetail, error)
GetECRImageScanFindings(*ecr.ImageDetail) map[string]int64
}

// GetECRImagesWithTag finds all ECR images with a given tag. If no tag specified, all tagged images are returned
Expand Down Expand Up @@ -66,3 +67,22 @@ func (client *Client) GetECRImagesWithTag(tag string) (map[string][]*ecr.ImageDe

return images, nil
}

func (client *Client) GetECRImageScanFindings(image *ecr.ImageDetail) map[string]int64 {
if image != nil {
scanFindings, err := client.ECR.DescribeImageScanFindings(&ecr.DescribeImageScanFindingsInput{
ImageId: &ecr.ImageIdentifier{
ImageDigest: image.ImageDigest,
},
RegistryId: image.RegistryId,
RepositoryName: image.RepositoryName,
})
if err != nil {
return nil
}
if scanFindings != nil && scanFindings.ImageScanStatus != nil {
return aws.Int64ValueMap(scanFindings.ImageScanFindings.FindingSeverityCounts)
}
}
return nil
}
56 changes: 56 additions & 0 deletions pkg/aws/ecr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,3 +223,59 @@ func TestClient_GetECRImagesWithTag(t *testing.T) {
})
}
}

func TestClient_GetECRImageScanFindings(t *testing.T) {
testCases := []struct {
name string
image *ecr.ImageDetail
describeImageScanFindingsOutput *ecr.DescribeImageScanFindingsOutput
scanFindingsMap map[string]int64
}{
{
name: "test case with empty image details",
image: nil,
scanFindingsMap: nil,
describeImageScanFindingsOutput: nil,
}, {
name: "test case with valid image details",
image: &ecr.ImageDetail{
ImageTags: aws.StringSlice([]string{"prod-canary"}),
RegistryId: aws.String("012345678910"),
RepositoryName: aws.String("app/web-server"),
ImageDigest: aws.String("prod-canary-image-digest"),
},
describeImageScanFindingsOutput: &ecr.DescribeImageScanFindingsOutput{
ImageScanStatus: &ecr.ImageScanStatus{
Status: aws.String("COMPLETE"),
},
ImageScanFindings: &ecr.ImageScanFindings{
FindingSeverityCounts: map[string]*int64{
"MEDIUM": aws.Int64(1),
"CRITICAL": aws.Int64(1),
},
},
},
scanFindingsMap: map[string]int64{
"MEDIUM": 1,
"CRITICAL": 1,
},
},
}
for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
mockECRAPI := mocks.NewMockECRAPI(mockCtrl)
if test.image != nil {
mockECRAPI.EXPECT().DescribeImageScanFindings(gomock.Any()).Return(test.describeImageScanFindingsOutput, nil).MaxTimes(1)
}
client := &Client{
ECR: mockECRAPI,
}
got := client.GetECRImageScanFindings(test.image)
if !reflect.DeepEqual(got, test.scanFindingsMap) {
t.Errorf("GetECRImageScanFindings() got = %v, want %v", got, test.scanFindingsMap)
}
})
}
}
46 changes: 30 additions & 16 deletions pkg/cloudig/ecrscan.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cloudig

import (
"strings"
"time"

awslocal "github.com/Optum/cloudig/pkg/aws"
Expand Down Expand Up @@ -60,33 +61,39 @@ func (report *ImageScanReports) GetReport(client awslocal.APIs, comments []Comme
for repo, imageList := range images {
// If a tag was specified there should only be one image returned per repo
if report.Flags.Tag != "" && len(imageList) == 1 {
imageURI := repo + ":" + report.Flags.Tag
scanReport := ImageScanFindings{
AccountID: accountID,
ImageDigest: aws.StringValue(imageList[0].ImageDigest),
ImageTag: report.Flags.Tag,
RepositoryName: aws.StringValue(imageList[0].RepositoryName),
ImageFindingsCount: convertScanFindings(imageList[0]),
Comments: getComments(comments, accountID, findingTypeECRScan, imageURI),
Region: report.Flags.Region,
scanFindingCountMap := convertScanFindings(imageList[0], client)
if len(scanFindingCountMap) > 0 {
imageURI := repo + ":" + report.Flags.Tag
scanReport := ImageScanFindings{
AccountID: accountID,
ImageDigest: aws.StringValue(imageList[0].ImageDigest),
ImageTag: report.Flags.Tag,
RepositoryName: aws.StringValue(imageList[0].RepositoryName),
ImageFindingsCount: scanFindingCountMap,
Comments: getComments(comments, accountID, findingTypeECRScan, imageURI),
Region: report.Flags.Region,
}
report.Findings = append(report.Findings, scanReport)
}
report.Findings = append(report.Findings, scanReport)

} else {
// Create finding for each tag
for _, image := range imageList {
for _, tag := range aws.StringValueSlice(image.ImageTags) {
imageURI := repo + ":" + tag
scanFindingCountMap := convertScanFindings(image, client)
if len(scanFindingCountMap) > 0 {
imageURI := repo + ":" + aws.StringValueSlice(image.ImageTags)[0]
scanReport := ImageScanFindings{
AccountID: accountID,
ImageDigest: aws.StringValue(image.ImageDigest),
ImageTag: tag,
ImageTag: strings.Join(aws.StringValueSlice(image.ImageTags), ","),
RepositoryName: aws.StringValue(image.RepositoryName),
ImageFindingsCount: convertScanFindings(image),
ImageFindingsCount: scanFindingCountMap,
Comments: getComments(comments, accountID, findingTypeECRScan, imageURI),
Region: report.Flags.Region,
}
report.Findings = append(report.Findings, scanReport)
}

}
}
}
Expand All @@ -95,9 +102,16 @@ func (report *ImageScanReports) GetReport(client awslocal.APIs, comments []Comme
return nil
}

func convertScanFindings(image *ecr.ImageDetail) map[string]int64 {
func convertScanFindings(image *ecr.ImageDetail, client awslocal.APIs) map[string]int64 {
if image != nil && image.ImageScanStatus != nil && aws.StringValue(image.ImageScanStatus.Status) == "COMPLETE" {
return aws.Int64ValueMap(image.ImageScanFindingsSummary.FindingSeverityCounts)
} else {
/**
* we are unable to get the FindingSeverityCounts, ImageScanStatus for enhanced scanning.
* it is known bug in aws side, so we are calling describe-images-scan-findings to get the details.
* we will reverse these , once aws fix issue in describe-image
**/
return client.GetECRImageScanFindings(image)

}
return nil
}
8 changes: 8 additions & 0 deletions pkg/mocks/mock_aws.go

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

0 comments on commit 4d5b736

Please sign in to comment.