Merge branch 'feat-image-scan-svc' of github.com:kubescape/kubescape into feat-image-scan-svc

This commit is contained in:
Daniel Grunberger
2023-07-25 17:00:12 +03:00
38 changed files with 42084 additions and 875 deletions
+39 -28
View File
@@ -1,80 +1,91 @@
package scan
import (
"fmt"
"strings"
"context"
"fmt"
"os"
logger "github.com/kubescape/go-logger"
"github.com/kubescape/kubescape/v2/core/cautils"
"github.com/kubescape/kubescape/v2/core/meta"
"github.com/kubescape/kubescape/v2/pkg/imagescan"
"github.com/spf13/cobra"
"github.com/anchore/grype/grype/presenter"
"github.com/spf13/cobra"
)
// TODO(vladklokun): image scan documentation
type imageScanInfo struct {
Username string
Password string
}
// TODO(vladklokun): document image scanning on the Kubescape Docs Hub?
var (
imageExample = fmt.Sprintf(`
# Scan the 'nginx' image
%[1]s scan image "nginx"
# Scan list of images separated with a comma
%[1]s scan image nginx,redis
# Image scan documentation:
# https://hub.armosec.io/docs/images
`, cautils.ExecName())
)
// imageCmd represents the image command
func getImageCmd(ks meta.IKubescape, scanInfo *cautils.ScanInfo) *cobra.Command {
return &cobra.Command{
Use: "image <image name>[,<image name>]",
Short: "Scans images for vulnerabilities",
func getImageCmd(ks meta.IKubescape, scanInfo *cautils.ScanInfo, imgScanInfo *imageScanInfo) *cobra.Command {
cmd := &cobra.Command{
Use: "image <IMAGE_NAME>",
Short: "Scans an image for vulnerabilities",
Example: imageExample,
Args: func(cmd *cobra.Command, args []string) error {
if len(args) > 0 {
images := strings.Split(args[0], ",")
if len(images) > 1 {
for _, image := range images {
if image == "" {
return fmt.Errorf("usage: <image-0>,<image-1>")
}
}
}
} else {
return fmt.Errorf("requires at least one image name")
if len(args) != 1 {
return fmt.Errorf("The command takes exactly one image.")
}
return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
if err := validateImageScanInfo(scanInfo); err != nil {
return err
}
failOnSeverity := imagescan.ParseSeverity(scanInfo.FailThresholdSeverity)
ctx := context.Background()
userInput := args[0]
dbCfg, _ := imagescan.NewDefaultDBConfig()
svc := imagescan.NewScanService(dbCfg)
scanResults, err := svc.Scan(ctx, userInput)
creds := imagescan.RegistryCredentials{
Username: imgScanInfo.Username,
Password: imgScanInfo.Password,
}
userInput := args[0]
scanResults, err := svc.Scan(ctx, userInput, creds)
if err != nil {
return err
}
presenterConfig, _ := presenter.ValidatedConfig("table", "", false)
pres := presenter.GetPresenter(presenterConfig, *scanResults)
pres.Present(os.Stdout)
if imagescan.ExceedsSeverityThreshold(scanResults, failOnSeverity) {
terminateOnExceedingSeverity(scanInfo, logger.L())
}
return err
},
}
cmd.PersistentFlags().StringVarP(&imgScanInfo.Username, "username", "u", "", "Username for registry login")
cmd.PersistentFlags().StringVarP(&imgScanInfo.Password, "password", "p", "", "Password for registry login")
return cmd
}
// validateImageScanInfo validates the ScanInfo struct for the `image` command
func validateImageScanInfo(scanInfo *cautils.ScanInfo) error {
severity := scanInfo.FailThresholdSeverity
if scanInfo.Submit && scanInfo.OmitRawResources {
return fmt.Errorf("you can use `omit-raw-resources` or `submit`, but not both")
}
if err := validateSeverity(severity); severity != "" && err != nil {
return err
}
+3
View File
@@ -119,5 +119,8 @@ func GetScanCommand(ks meta.IKubescape) *cobra.Command {
scanCmd.AddCommand(getFrameworkCmd(ks, &scanInfo))
scanCmd.AddCommand(getImageCmd(ks, &scanInfo))
isi := &imageScanInfo{}
scanCmd.AddCommand(getImageCmd(ks, &scanInfo, isi))
return scanCmd
}