mirror of
https://github.com/kubescape/kubescape.git
synced 2026-02-14 18:09:55 +00:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8b32de42a2 | ||
|
|
b7a9a1f3d7 | ||
|
|
a0b6f5ffac |
11
cmd/root.go
11
cmd/root.go
@@ -6,6 +6,7 @@ import (
|
||||
|
||||
logger "github.com/kubescape/go-logger"
|
||||
"github.com/kubescape/go-logger/helpers"
|
||||
"github.com/kubescape/k8s-interface/k8sinterface"
|
||||
"github.com/kubescape/kubescape/v2/cmd/completion"
|
||||
"github.com/kubescape/kubescape/v2/cmd/config"
|
||||
"github.com/kubescape/kubescape/v2/cmd/download"
|
||||
@@ -49,6 +50,13 @@ func getRootCmd(ks meta.IKubescape) *cobra.Command {
|
||||
Use: "kubescape",
|
||||
Short: "Kubescape is a tool for testing Kubernetes security posture. Docs: https://hub.armosec.io/docs",
|
||||
Example: ksExamples,
|
||||
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
||||
k8sinterface.SetClusterContextName(rootInfo.KubeContext)
|
||||
initLogger()
|
||||
initLoggerLevel()
|
||||
initEnvironment()
|
||||
initCacheDir()
|
||||
},
|
||||
}
|
||||
|
||||
if cautils.IsKrewPlugin() {
|
||||
@@ -76,8 +84,7 @@ func getRootCmd(ks meta.IKubescape) *cobra.Command {
|
||||
rootCmd.PersistentFlags().BoolVarP(&rootInfo.DisableColor, "disable-color", "", false, "Disable color output for logging")
|
||||
rootCmd.PersistentFlags().BoolVarP(&rootInfo.EnableColor, "enable-color", "", false, "Force enable color output for logging")
|
||||
|
||||
cobra.OnInitialize(initLogger, initLoggerLevel, initEnvironment, initCacheDir)
|
||||
|
||||
rootCmd.PersistentFlags().StringVarP(&rootInfo.KubeContext, "kube-context", "", "", "Kube context. Default will use the current-context")
|
||||
// Supported commands
|
||||
rootCmd.AddCommand(scan.GetScanCommand(ks))
|
||||
rootCmd.AddCommand(download.GetDownloadCmd(ks))
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/kubescape/k8s-interface/k8sinterface"
|
||||
"github.com/kubescape/kubescape/v2/core/cautils"
|
||||
"github.com/kubescape/kubescape/v2/core/cautils/getter"
|
||||
"github.com/kubescape/kubescape/v2/core/meta"
|
||||
@@ -63,17 +62,12 @@ func GetScanCommand(ks meta.IKubescape) *cobra.Command {
|
||||
}
|
||||
return nil
|
||||
},
|
||||
PreRun: func(cmd *cobra.Command, args []string) {
|
||||
k8sinterface.SetClusterContextName(scanInfo.KubeContext)
|
||||
|
||||
},
|
||||
PostRun: func(cmd *cobra.Command, args []string) {
|
||||
// TODO - revert context
|
||||
},
|
||||
}
|
||||
|
||||
scanCmd.PersistentFlags().StringVarP(&scanInfo.AccountID, "account", "", "", "Kubescape SaaS account ID. Default will load account ID from cache")
|
||||
scanCmd.PersistentFlags().StringVarP(&scanInfo.KubeContext, "kube-context", "", "", "Kube context. Default will use the current-context")
|
||||
scanCmd.PersistentFlags().StringVar(&scanInfo.ControlsInputs, "controls-config", "", "Path to an controls-config obj. If not set will download controls-config from ARMO management portal")
|
||||
scanCmd.PersistentFlags().StringVar(&scanInfo.UseExceptions, "exceptions", "", "Path to an exceptions obj. If not set will download exceptions from ARMO management portal")
|
||||
scanCmd.PersistentFlags().StringVar(&scanInfo.UseArtifactsFrom, "use-artifacts-from", "", "Load artifacts from local directory. If not used will download them")
|
||||
|
||||
@@ -13,6 +13,7 @@ type RootInfo struct {
|
||||
DisableColor bool // Disable Color
|
||||
EnableColor bool // Force enable Color
|
||||
DiscoveryServerURL string // Discovery Server URL (See https://github.com/kubescape/backend/tree/main/pkg/servicediscovery)
|
||||
KubeContext string // context name
|
||||
}
|
||||
type CloudURLs struct {
|
||||
CloudReportURL string
|
||||
|
||||
@@ -129,7 +129,6 @@ type ScanInfo struct {
|
||||
HostSensorYamlPath string // Path to hostsensor file
|
||||
Local bool // Do not submit results
|
||||
AccountID string // account ID
|
||||
KubeContext string // context name
|
||||
FrameworkScan bool // false if scanning control
|
||||
ScanAll bool // true if scan all frameworks
|
||||
OmitRawResources bool // true if omit raw resources from the output
|
||||
|
||||
@@ -106,9 +106,8 @@ func GetOutputPrinters(scanInfo *cautils.ScanInfo, ctx context.Context, clusterN
|
||||
|
||||
outputPrinters := make([]printer.IPrinter, 0)
|
||||
for _, format := range formats {
|
||||
if !resultshandling.ValidatePrinter(scanInfo.ScanType, format) {
|
||||
logger.L().Ctx(ctx).Fatal(fmt.Sprintf("Unsupported output format: %s", format))
|
||||
continue
|
||||
if err := resultshandling.ValidatePrinter(scanInfo.ScanType, scanInfo.GetScanningContext(), format); err != nil {
|
||||
logger.L().Ctx(ctx).Fatal(err.Error())
|
||||
}
|
||||
|
||||
printerHandler := resultshandling.NewPrinter(ctx, format, scanInfo.FormatVersion, scanInfo.PrintAttackTree, scanInfo.VerboseMode, cautils.ViewTypes(scanInfo.View), clusterName)
|
||||
|
||||
@@ -176,6 +176,7 @@ func (sp *SARIFPrinter) printConfigurationScan(ctx context.Context, opaSessionOb
|
||||
locationResolver, err := locationresolver.NewFixPathLocationResolver(rsrcAbsPath)
|
||||
if err != nil {
|
||||
logger.L().Debug("failed to create location resolver", helpers.Error(err))
|
||||
continue
|
||||
}
|
||||
|
||||
for _, toPin := range result.AssociatedControls {
|
||||
|
||||
@@ -132,16 +132,26 @@ func NewPrinter(ctx context.Context, printFormat, formatVersion string, verboseM
|
||||
}
|
||||
}
|
||||
|
||||
func ValidatePrinter(scanType cautils.ScanTypes, printFormat string) bool {
|
||||
if scanType != cautils.ScanTypeImage {
|
||||
return true
|
||||
func ValidatePrinter(scanType cautils.ScanTypes, scanContext cautils.ScanningContext, printFormat string) error {
|
||||
if scanType == cautils.ScanTypeImage {
|
||||
// supported types for image scanning
|
||||
switch printFormat {
|
||||
case printer.JsonFormat, printer.PrettyFormat, printer.SARIFFormat:
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("format \"%s\"is not supported for image scanning", printFormat)
|
||||
}
|
||||
}
|
||||
|
||||
// supported types for image scanning
|
||||
switch printFormat {
|
||||
case printer.JsonFormat, printer.PrettyFormat, printer.SARIFFormat:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
if printFormat == printer.SARIFFormat {
|
||||
// supported types for SARIF
|
||||
switch scanContext {
|
||||
case cautils.ContextDir, cautils.ContextFile, cautils.ContextGitLocal:
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("format \"%s\" is only supported when scanning local files", printFormat)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -2,12 +2,14 @@ package resultshandling
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/kubescape/kubescape/v2/core/cautils"
|
||||
"github.com/kubescape/kubescape/v2/core/pkg/resultshandling/printer"
|
||||
"github.com/kubescape/opa-utils/reporthandling/results/v1/reportsummary"
|
||||
reporthandlingv2 "github.com/kubescape/opa-utils/reporthandling/v2"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type DummyReporter struct{}
|
||||
@@ -59,92 +61,123 @@ func TestResultsHandlerHandleResultsPrintsResultsToUI(t *testing.T) {
|
||||
|
||||
func TestValidatePrinter(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
scanType cautils.ScanTypes
|
||||
format string
|
||||
expected bool
|
||||
name string
|
||||
scanType cautils.ScanTypes
|
||||
scanContext cautils.ScanningContext
|
||||
format string
|
||||
expectErr error
|
||||
}{
|
||||
{
|
||||
name: "json format for cluster scan",
|
||||
scanType: cautils.ScanTypeCluster,
|
||||
format: printer.JsonFormat,
|
||||
expected: true,
|
||||
name: "json format for cluster scan should not return error",
|
||||
scanType: cautils.ScanTypeCluster,
|
||||
format: printer.JsonFormat,
|
||||
expectErr: nil,
|
||||
},
|
||||
{
|
||||
name: "junit format for cluster scan",
|
||||
scanType: cautils.ScanTypeCluster,
|
||||
format: printer.JunitResultFormat,
|
||||
expected: true,
|
||||
name: "junit format for cluster scan should return error",
|
||||
scanType: cautils.ScanTypeCluster,
|
||||
format: printer.JunitResultFormat,
|
||||
expectErr: nil,
|
||||
},
|
||||
{
|
||||
name: "sarif format for cluster scan",
|
||||
scanType: cautils.ScanTypeCluster,
|
||||
format: printer.SARIFFormat,
|
||||
expected: true,
|
||||
name: "sarif format for cluster scan and git url context should not return error",
|
||||
scanType: cautils.ScanTypeCluster,
|
||||
scanContext: cautils.ContextGitLocal,
|
||||
format: printer.SARIFFormat,
|
||||
expectErr: nil,
|
||||
},
|
||||
{
|
||||
name: "pretty format for cluster scan",
|
||||
scanType: cautils.ScanTypeCluster,
|
||||
format: printer.PrettyFormat,
|
||||
expected: true,
|
||||
name: "pretty format for cluster scan should not return error",
|
||||
scanType: cautils.ScanTypeCluster,
|
||||
format: printer.PrettyFormat,
|
||||
expectErr: nil,
|
||||
},
|
||||
{
|
||||
name: "html format for cluster scan",
|
||||
scanType: cautils.ScanTypeCluster,
|
||||
format: printer.HtmlFormat,
|
||||
expected: true,
|
||||
name: "html format for cluster scan should not return error",
|
||||
scanType: cautils.ScanTypeCluster,
|
||||
format: printer.HtmlFormat,
|
||||
expectErr: nil,
|
||||
},
|
||||
{
|
||||
name: "prometheus format for cluster scan",
|
||||
scanType: cautils.ScanTypeCluster,
|
||||
format: printer.PrometheusFormat,
|
||||
expected: true,
|
||||
name: "prometheus format for cluster scan should not return error",
|
||||
scanType: cautils.ScanTypeCluster,
|
||||
format: printer.PrometheusFormat,
|
||||
expectErr: nil,
|
||||
},
|
||||
|
||||
{
|
||||
name: "json format for image scan",
|
||||
scanType: cautils.ScanTypeImage,
|
||||
format: printer.JsonFormat,
|
||||
expected: true,
|
||||
name: "json format for image scan should not return error",
|
||||
scanType: cautils.ScanTypeImage,
|
||||
format: printer.JsonFormat,
|
||||
expectErr: nil,
|
||||
},
|
||||
{
|
||||
name: "junit format for image scan",
|
||||
scanType: cautils.ScanTypeImage,
|
||||
format: printer.JunitResultFormat,
|
||||
expected: false,
|
||||
name: "junit format for image scan should return error",
|
||||
scanType: cautils.ScanTypeImage,
|
||||
format: printer.JunitResultFormat,
|
||||
expectErr: errors.New("format \"junit\"is not supported for image scanning"),
|
||||
},
|
||||
{
|
||||
name: "sarif format for image scan",
|
||||
scanType: cautils.ScanTypeImage,
|
||||
format: printer.SARIFFormat,
|
||||
expected: true,
|
||||
name: "sarif format for image scan should not return error",
|
||||
scanType: cautils.ScanTypeImage,
|
||||
format: printer.SARIFFormat,
|
||||
expectErr: nil,
|
||||
},
|
||||
{
|
||||
name: "pretty format for image scan",
|
||||
scanType: cautils.ScanTypeImage,
|
||||
format: printer.PrettyFormat,
|
||||
expected: true,
|
||||
name: "pretty format for image scan should not return error",
|
||||
scanType: cautils.ScanTypeImage,
|
||||
format: printer.PrettyFormat,
|
||||
expectErr: nil,
|
||||
},
|
||||
{
|
||||
name: "html format for image scan",
|
||||
scanType: cautils.ScanTypeImage,
|
||||
format: printer.HtmlFormat,
|
||||
expected: false,
|
||||
name: "html format for image scan should return error",
|
||||
scanType: cautils.ScanTypeImage,
|
||||
format: printer.HtmlFormat,
|
||||
expectErr: errors.New("format \"html\"is not supported for image scanning"),
|
||||
},
|
||||
{
|
||||
name: "prometheus format for image scan",
|
||||
scanType: cautils.ScanTypeImage,
|
||||
format: printer.PrometheusFormat,
|
||||
expected: false,
|
||||
name: "prometheus format for image scan should return error",
|
||||
scanType: cautils.ScanTypeImage,
|
||||
format: printer.PrometheusFormat,
|
||||
expectErr: errors.New("format \"prometheus\"is not supported for image scanning"),
|
||||
},
|
||||
{
|
||||
name: "sarif format for cluster context should return error",
|
||||
scanContext: cautils.ContextCluster,
|
||||
format: printer.SARIFFormat,
|
||||
expectErr: errors.New("format \"sarif\" is only supported when scanning local files"),
|
||||
},
|
||||
{
|
||||
name: "sarif format for remote url context should return error",
|
||||
scanContext: cautils.ContextGitURL,
|
||||
format: printer.SARIFFormat,
|
||||
expectErr: errors.New("format \"sarif\" is only supported when scanning local files"),
|
||||
},
|
||||
{
|
||||
name: "sarif format for local dir context should not return error",
|
||||
scanContext: cautils.ContextDir,
|
||||
format: printer.SARIFFormat,
|
||||
expectErr: nil,
|
||||
},
|
||||
{
|
||||
name: "sarif format for local file context should not return error",
|
||||
scanContext: cautils.ContextFile,
|
||||
format: printer.SARIFFormat,
|
||||
expectErr: nil,
|
||||
},
|
||||
{
|
||||
name: "sarif format for local git context should not return error",
|
||||
scanContext: cautils.ContextGitLocal,
|
||||
format: printer.SARIFFormat,
|
||||
expectErr: nil,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := ValidatePrinter(tt.scanType, tt.format)
|
||||
if got != tt.expected {
|
||||
t.Errorf("%s failed - got = %v, want %v", tt.name, got, tt.expected)
|
||||
}
|
||||
got := ValidatePrinter(tt.scanType, tt.scanContext, tt.format)
|
||||
|
||||
assert.Equal(t, tt.expectErr, got)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -70,7 +70,6 @@ func scan(ctx context.Context, scanInfo *cautils.ScanInfo, scanID string) (*repo
|
||||
trace.WithAttributes(attribute.String("excludedNamespaces", scanInfo.ExcludedNamespaces)),
|
||||
trace.WithAttributes(attribute.String("includeNamespaces", scanInfo.IncludeNamespaces)),
|
||||
trace.WithAttributes(attribute.String("hostSensorYamlPath", scanInfo.HostSensorYamlPath)),
|
||||
trace.WithAttributes(attribute.String("kubeContext", scanInfo.KubeContext)),
|
||||
)
|
||||
|
||||
result, err := ks.Scan(ctx, scanInfo)
|
||||
@@ -151,8 +150,8 @@ func getScanCommand(scanRequest *utilsmetav1.PostScanRequest, scanID string) *ca
|
||||
scanInfo.Output = filepath.Join(OutputDir, scanID)
|
||||
// *** end ***
|
||||
|
||||
// Set default KubeContext from scanInfo input
|
||||
k8sinterface.SetClusterContextName(scanInfo.KubeContext)
|
||||
// Set default KubeContext from current context
|
||||
k8sinterface.SetClusterContextName(k8sinterface.GetContextName())
|
||||
|
||||
return scanInfo
|
||||
}
|
||||
@@ -173,7 +172,6 @@ func defaultScanInfo() *cautils.ScanInfo {
|
||||
if !envToBool("KS_DOWNLOAD_ARTIFACTS", false) {
|
||||
scanInfo.UseArtifactsFrom = getter.DefaultLocalStore // Load files from cache (this will prevent kubescape fom downloading the artifacts every time)
|
||||
}
|
||||
scanInfo.KubeContext = envToString("KS_CONTEXT", "") // publish results to Kubescape SaaS
|
||||
|
||||
return scanInfo
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user