mirror of
https://github.com/kubescape/kubescape.git
synced 2026-04-15 06:58:11 +00:00
Merge branch 'feat-image-scan-svc' of github.com:kubescape/kubescape into feat-image-scan-svc
This commit is contained in:
+39
-28
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user