From e57d65541c99dfa094117c95d27b98cbd96f4f9e Mon Sep 17 00:00:00 2001 From: Daniel Grunberger Date: Wed, 26 Jul 2023 08:55:31 +0300 Subject: [PATCH] integrate img scan --- cmd/scan/image.go | 22 ++++++++++--------- cmd/scan/scan.go | 3 +-- core/cautils/scaninfo.go | 6 +++++ core/core/scan.go | 11 +++++++--- .../resultshandling/printer/v2/jsonprinter.go | 13 +++-------- go.mod | 3 +++ go.sum | 4 ++++ 7 files changed, 37 insertions(+), 25 deletions(-) diff --git a/cmd/scan/image.go b/cmd/scan/image.go index bdf66b5c..c5d5ad2d 100644 --- a/cmd/scan/image.go +++ b/cmd/scan/image.go @@ -14,11 +14,6 @@ import ( "github.com/spf13/cobra" ) -type imageScanInfo struct { - Username string - Password string -} - // TODO(vladklokun): document image scanning on the Kubescape Docs Hub? var ( imageExample = fmt.Sprintf(` @@ -31,7 +26,7 @@ var ( ) // imageCmd represents the image command -func getImageCmd(ks meta.IKubescape, scanInfo *cautils.ScanInfo, imgScanInfo *imageScanInfo) *cobra.Command { +func getImageCmd(ks meta.IKubescape, scanInfo *cautils.ScanInfo) *cobra.Command { cmd := &cobra.Command{ Use: "image ", Short: "Scans an image for vulnerabilities", @@ -53,8 +48,8 @@ func getImageCmd(ks meta.IKubescape, scanInfo *cautils.ScanInfo, imgScanInfo *im svc := imagescan.NewScanService(dbCfg) creds := imagescan.RegistryCredentials{ - Username: imgScanInfo.Username, - Password: imgScanInfo.Password, + Username: scanInfo.ImageScanInfo.Username, + Password: scanInfo.ImageScanInfo.Password, } userInput := args[0] @@ -71,6 +66,13 @@ func getImageCmd(ks meta.IKubescape, scanInfo *cautils.ScanInfo, imgScanInfo *im resultsHandler := resultshandling.NewResultsHandler(nil, outputPrinters, uiPrinter, scanResults) + resultsHandler.ImageScanData = []cautils.ImageScanData{ + { + PresenterConfig: scanResults, + Image: userInput, + }, + } + resultsHandler.HandleResults(ctx) if !scanInfo.VerboseMode { @@ -85,8 +87,8 @@ func getImageCmd(ks meta.IKubescape, scanInfo *cautils.ScanInfo, imgScanInfo *im }, } - cmd.PersistentFlags().StringVarP(&imgScanInfo.Username, "username", "u", "", "Username for registry login") - cmd.PersistentFlags().StringVarP(&imgScanInfo.Password, "password", "p", "", "Password for registry login") + cmd.PersistentFlags().StringVarP(&scanInfo.ImageScanInfo.Username, "username", "u", "", "Username for registry login") + cmd.PersistentFlags().StringVarP(&scanInfo.ImageScanInfo.Password, "password", "p", "", "Password for registry login") return cmd } diff --git a/cmd/scan/scan.go b/cmd/scan/scan.go index c06e74bc..59c3f5e5 100644 --- a/cmd/scan/scan.go +++ b/cmd/scan/scan.go @@ -123,8 +123,7 @@ func GetScanCommand(ks meta.IKubescape) *cobra.Command { scanCmd.AddCommand(getFrameworkCmd(ks, &scanInfo)) scanCmd.AddCommand(getWorkloadCmd(ks, &scanInfo)) - isi := &imageScanInfo{} - scanCmd.AddCommand(getImageCmd(ks, &scanInfo, isi)) + scanCmd.AddCommand(getImageCmd(ks, &scanInfo)) return scanCmd } diff --git a/core/cautils/scaninfo.go b/core/cautils/scaninfo.go index 2ca94908..7e16fbbc 100644 --- a/core/cautils/scaninfo.go +++ b/core/cautils/scaninfo.go @@ -106,6 +106,11 @@ type WorkloadIdentifier struct { Name string } +type ImageScanInfo struct { + Username string + Password string +} + type ScanInfo struct { Getters // TODO - remove from object PolicyIdentifier []PolicyIdentifier // TODO - remove from object @@ -145,6 +150,7 @@ type ScanInfo struct { ScanImages bool ChartPath string FilePath string + ImageScanInfo ImageScanInfo } type Getters struct { diff --git a/core/core/scan.go b/core/core/scan.go index 0021a65d..43ed6ba3 100644 --- a/core/core/scan.go +++ b/core/core/scan.go @@ -228,16 +228,21 @@ func scanImages(scanInfo *cautils.ScanInfo, scanData *cautils.OPASessionObj, ctx for _, imgs := range scanData.ResourceIDToImageMap { for _, img := range imgs { - scanSingleImage(ctx, img, svc, resultsHandling) + scanSingleImage(ctx, img, svc, resultsHandling, *scanInfo) } } logger.L().Ctx(ctx).Success("Finished scanning images") } -func scanSingleImage(ctx context.Context, img string, svc imagescan.Service, resultsHandling *resultshandling.ResultsHandler) { +func scanSingleImage(ctx context.Context, img string, svc imagescan.Service, resultsHandling *resultshandling.ResultsHandler, scanInfo cautils.ScanInfo) { logger.L().Ctx(ctx).Debug(fmt.Sprintf("Scanning image: %s", img)) - scanResults, err := svc.Scan(ctx, img) + registryCredentials := imagescan.RegistryCredentials{ + Username: scanInfo.ImageScanInfo.Username, + Password: scanInfo.ImageScanInfo.Password, + } + + scanResults, err := svc.Scan(ctx, img, registryCredentials) if err != nil { logger.L().Ctx(ctx).Error(fmt.Sprintf("failed to scan image: %s", img), helpers.Error(err)) return diff --git a/core/pkg/resultshandling/printer/v2/jsonprinter.go b/core/pkg/resultshandling/printer/v2/jsonprinter.go index ca85de61..ea21cf9c 100644 --- a/core/pkg/resultshandling/printer/v2/jsonprinter.go +++ b/core/pkg/resultshandling/printer/v2/jsonprinter.go @@ -9,6 +9,7 @@ import ( "path/filepath" "strings" + "github.com/anchore/grype/grype/presenter" "github.com/anchore/grype/grype/presenter/models" logger "github.com/kubescape/go-logger" "github.com/kubescape/go-logger/helpers" @@ -102,17 +103,9 @@ func printConfigurationsScanning(opaSessionObj *cautils.OPASessionObj, ctx conte } func (jp *JsonPrinter) PrintImageScan(ctx context.Context, scanResults *models.PresenterConfig) error { - // presenterConfig, err := presenter.ValidatedConfig("json", "", false) - // if err != nil { - // return err - // } + pres := presenter.GetPresenter("json", jp.writer.Name(), false, *scanResults) - // pres := presenter.GetPresenter(presenterConfig, *scanResults) - - // if err = pres.Present(jp.writer); err != nil { - // return err - // } - return nil + return pres.Present(jp.writer) } func (jp *JsonPrinter) PrintNextSteps() { diff --git a/go.mod b/go.mod index 539aadb5..8a71186d 100644 --- a/go.mod +++ b/go.mod @@ -297,6 +297,7 @@ require ( github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.0-rc3 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect + github.com/owenrumney/go-sarif v1.1.1 // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.0.8 // indirect github.com/pierrec/lz4/v4 v4.1.15 // indirect @@ -358,6 +359,7 @@ require ( github.com/vbatts/tar-split v0.11.3 // indirect github.com/vifraa/gopom v0.2.1 // indirect github.com/wagoodman/go-partybus v0.0.0-20230516145632-8ccac152c651 // indirect + github.com/wagoodman/go-presenter v0.0.0-20211015174752-f9c01afc824b // indirect github.com/wagoodman/go-progress v0.0.0-20230301185719-21920a456ad5 // indirect github.com/xanzy/go-gitlab v0.73.1 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect @@ -368,6 +370,7 @@ require ( github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect github.com/xlab/treeprint v1.1.0 // indirect github.com/yashtewari/glob-intersection v0.1.0 // indirect + github.com/zclconf/go-cty v1.10.0 // indirect github.com/zeebo/errs v1.2.2 // indirect go.etcd.io/bbolt v1.3.7 // indirect go.etcd.io/etcd/api/v3 v3.6.0-alpha.0 // indirect diff --git a/go.sum b/go.sum index 7fc7900a..47da7d6e 100644 --- a/go.sum +++ b/go.sum @@ -1729,6 +1729,7 @@ github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJ github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= github.com/otiai10/mint v1.3.1/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= +github.com/owenrumney/go-sarif v1.1.1 h1:QNObu6YX1igyFKhdzd7vgzmw7XsWN3/6NMGuDzBgXmE= github.com/owenrumney/go-sarif v1.1.1/go.mod h1:dNDiPlF04ESR/6fHlPyq7gHKmrM0sHUvAGjsoh8ZH0U= github.com/owenrumney/go-sarif/v2 v2.1.2 h1:PMDK7tXShJ9zsB7bfvlpADH5NEw1dfA9xwU8Xtdj73U= github.com/owenrumney/go-sarif/v2 v2.1.2/go.mod h1:MSqMMx9WqlBSY7pXoOZWgEsVB4FDNfhcaXDA1j6Sr+w= @@ -2090,6 +2091,8 @@ github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgq github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/wagoodman/go-partybus v0.0.0-20230516145632-8ccac152c651 h1:jIVmlAFIqV3d+DOxazTR9v+zgj8+VYuQBzPgBZvWBHA= github.com/wagoodman/go-partybus v0.0.0-20230516145632-8ccac152c651/go.mod h1:b26F2tHLqaoRQf8DywqzVaV1MQ9yvjb0OMcNl7Nxu20= +github.com/wagoodman/go-presenter v0.0.0-20211015174752-f9c01afc824b h1:uWNQ0khA6RdFzODOMwKo9XXu7fuewnnkHykUtuKru8s= +github.com/wagoodman/go-presenter v0.0.0-20211015174752-f9c01afc824b/go.mod h1:ewlIKbKV8l+jCj8rkdXIs361ocR5x3qGyoCSca47Gx8= github.com/wagoodman/go-progress v0.0.0-20230301185719-21920a456ad5 h1:lwgTsTy18nYqASnH58qyfRW/ldj7Gt2zzBvgYPzdA4s= github.com/wagoodman/go-progress v0.0.0-20230301185719-21920a456ad5/go.mod h1:jLXFoL31zFaHKAAyZUh+sxiTDFe1L1ZHrcK2T1itVKA= github.com/whilp/git-urls v1.0.0 h1:95f6UMWN5FKW71ECsXRUd3FVYiXdrE7aX4NZKcPmIjU= @@ -2135,6 +2138,7 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1 github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zalando/go-keyring v0.1.0/go.mod h1:RaxNwUITJaHVdQ0VC7pELPZ3tOWn13nr0gZMZEhpVU0= +github.com/zclconf/go-cty v1.10.0 h1:mp9ZXQeIcN8kAwuqorjH+Q+njbJKjLrvB2yIh4q7U+0= github.com/zclconf/go-cty v1.10.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk= github.com/zeebo/errs v1.2.2 h1:5NFypMTuSdoySVTqlNs1dEoU21QVamMQJxW/Fii5O7g= github.com/zeebo/errs v1.2.2/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4=