diff --git a/api/handlers_repositories.go b/api/handlers_repositories.go index c1de9f6..d48099c 100644 --- a/api/handlers_repositories.go +++ b/api/handlers_repositories.go @@ -5,6 +5,7 @@ import ( "fmt" "net/http" "strings" + "time" "github.com/YaleSpinup/apierror" "github.com/YaleSpinup/ecr-api/ecr" @@ -351,12 +352,20 @@ func (s *server) ScanRepositoriesHandler(w http.ResponseWriter, r *http.Request) handleError(w, err) return } + for _, image := range images { - err = service.ScanImage(r.Context(), image, repository) + imageScanFindings, err := service.GetImageScanFindingsByImageDigest(r.Context(), repository, *image.ImageDigest) if err != nil { handleError(w, err) return } + if imageScanFindings != nil && time.Now().UTC().Sub(*imageScanFindings.ImageScanCompletedAt) > 24*time.Hour { + err = service.ScanImage(r.Context(), image, repository) + if err != nil { + handleError(w, err) + return + } + } } } diff --git a/ecr/images.go b/ecr/images.go index df0af80..72889a1 100644 --- a/ecr/images.go +++ b/ecr/images.go @@ -52,6 +52,31 @@ func (e *ECR) GetImages(ctx context.Context, repoName string, imageIds ...*ecr.I return out.ImageDetails, nil } +// GetImageScanFindingsByImageDigest gets the scan findings for an image digest +func (e *ECR) GetImageScanFindingsByImageDigest(ctx context.Context, repoName, digest string) (*ecr.ImageScanFindings, error) { + if repoName == "" || digest == "" { + return nil, apierror.New(apierror.ErrBadRequest, "invalid input", nil) + } + + log.Infof("getting image scan findings for %s:%s", repoName, digest) + + out, err := e.Service.DescribeImageScanFindingsWithContext(ctx, &ecr.DescribeImageScanFindingsInput{ + ImageId: &ecr.ImageIdentifier{ + ImageDigest: aws.String(digest), + }, + MaxResults: aws.Int64(1000), + RepositoryName: aws.String(repoName), + }) + + if err != nil { + return nil, ErrCode("failed to get image scan findings", err) + } + + log.Debugf("got output from image scan findings %+v", out) + + return out.ImageScanFindings, nil +} + // GetImageScanFindings gets the scan findings for an image tag func (e *ECR) GetImageScanFindings(ctx context.Context, repoName, tag string) (*ecr.ImageScanFindings, error) { if repoName == "" || tag == "" {