diff --git a/README.md b/README.md index 2fae7f31..65a9b6b8 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ curl -s https://raw.githubusercontent.com/armosec/kubescape/master/install.sh | ## Run: ``` -kubescape scan --submit --enable-host-scan --format-version v2 --verbose +kubescape scan --submit --enable-host-scan --verbose ``` @@ -276,6 +276,9 @@ kubescape submit results path/to/results.json Scan the YAML files while writing them using the [vs code extension](https://github.com/armosec/vscode-kubescape/blob/master/README.md) +## Lens Extension + +View Kubescape scan results directly in [Lens IDE](https://k8slens.dev/) using kubescape [Lens extension](https://github.com/armosec/lens-kubescape/blob/master/README.md) # Under the hood diff --git a/cmd/scan/scan.go b/cmd/scan/scan.go index 8b4e0c83..f6f47ed6 100644 --- a/cmd/scan/scan.go +++ b/cmd/scan/scan.go @@ -1,6 +1,8 @@ package scan import ( + "fmt" + "github.com/armosec/k8s-interface/k8sinterface" "github.com/armosec/kubescape/v2/core/cautils" "github.com/armosec/kubescape/v2/core/meta" @@ -73,6 +75,7 @@ func GetScanCommand(ks meta.IKubescape) *cobra.Command { scanCmd.PersistentFlags().BoolVarP(&scanInfo.Local, "keep-local", "", false, "If you do not want your Kubescape results reported to ARMO backend. Use this flag if you ran with the '--submit' flag in the past and you do not want to submit your current scan results") scanCmd.PersistentFlags().StringVarP(&scanInfo.Output, "output", "o", "", "Output file. Print output to file and not stdout") scanCmd.PersistentFlags().BoolVarP(&scanInfo.VerboseMode, "verbose", "v", false, "Display all of the input resources and not only failed resources") + scanCmd.PersistentFlags().StringVar(&scanInfo.View, "view", string(cautils.ResourceViewType), fmt.Sprintf("View results based on the %s/%s. default is --view=%s", cautils.ResourceViewType, cautils.ControlViewType, cautils.ResourceViewType)) scanCmd.PersistentFlags().BoolVar(&scanInfo.UseDefault, "use-default", false, "Load local policy object from default path. If not used will download latest") scanCmd.PersistentFlags().StringSliceVar(&scanInfo.UseFrom, "use-from", nil, "Load local policy object from specified path. If not used will download latest") scanCmd.PersistentFlags().BoolVarP(&scanInfo.Submit, "submit", "", false, "Send the scan results to ARMO management portal where you can see the results in a user-friendly UI, choose your preferred compliance framework, check risk results history and trends, manage exceptions, get remediation recommendations and much more. By default the results are not submitted") diff --git a/core/cautils/scaninfo.go b/core/cautils/scaninfo.go index 893fa2ec..474e5627 100644 --- a/core/cautils/scaninfo.go +++ b/core/cautils/scaninfo.go @@ -70,6 +70,13 @@ func (bpf *BoolPtrFlag) Set(val string) error { } // TODO - UPDATE +type ViewTypes string + +const ( + ResourceViewType ViewTypes = "resource" + ControlViewType ViewTypes = "control" +) + type ScanInfo struct { Getters // TODO - remove from object PolicyIdentifier []reporthandling.PolicyIdentifier // TODO - remove from object @@ -79,6 +86,7 @@ type ScanInfo struct { UseDefault bool // Load framework from cached file (instead of download). Use when running offline UseArtifactsFrom string // Load artifacts from local path. Use when running offline VerboseMode bool // Display all of the input resources and not only failed resources + View string // Display all of the input resources and not only failed resources Format string // Format results (table, json, junit ...) Output string // Store results in an output file, Output file name FormatVersion string // Output object can be differnet between versions, this is for testing and backward compatibility diff --git a/core/core/scan.go b/core/core/scan.go index 68a90b5c..1f0208dc 100644 --- a/core/core/scan.go +++ b/core/core/scan.go @@ -96,7 +96,7 @@ func getInterfaces(scanInfo *cautils.ScanInfo) componentInterfaces { reportHandler := getReporter(tenantConfig, scanInfo.ScanID, scanInfo.Submit, scanInfo.FrameworkScan) // setup printer - printerHandler := resultshandling.NewPrinter(scanInfo.Format, scanInfo.FormatVersion, scanInfo.VerboseMode) + printerHandler := resultshandling.NewPrinter(scanInfo.Format, scanInfo.FormatVersion, scanInfo.VerboseMode, cautils.ViewTypes(scanInfo.View)) printerHandler.SetWriter(scanInfo.Output) // ================== return interface ====================================== diff --git a/core/pkg/resultshandling/printer/v2/prettyprinter.go b/core/pkg/resultshandling/printer/v2/prettyprinter.go index de2b6f17..ce3a7957 100644 --- a/core/pkg/resultshandling/printer/v2/prettyprinter.go +++ b/core/pkg/resultshandling/printer/v2/prettyprinter.go @@ -19,14 +19,16 @@ import ( type PrettyPrinter struct { formatVersion string + viewType cautils.ViewTypes writer *os.File verboseMode bool } -func NewPrettyPrinter(verboseMode bool, formatVersion string) *PrettyPrinter { +func NewPrettyPrinter(verboseMode bool, formatVersion string, viewType cautils.ViewTypes) *PrettyPrinter { return &PrettyPrinter{ verboseMode: verboseMode, formatVersion: formatVersion, + viewType: viewType, } } @@ -35,9 +37,15 @@ func (prettyPrinter *PrettyPrinter) ActionPrint(opaSessionObj *cautils.OPASessio sortedControlNames := getSortedControlsNames(opaSessionObj.Report.SummaryDetails.Controls) // ListControls().All()) - if prettyPrinter.verboseMode { - prettyPrinter.resourceTable(opaSessionObj) + switch prettyPrinter.viewType { + case cautils.ControlViewType: + prettyPrinter.printResults(&opaSessionObj.Report.SummaryDetails.Controls, opaSessionObj.AllResources, sortedControlNames) + case cautils.ResourceViewType: + if prettyPrinter.verboseMode { + prettyPrinter.resourceTable(opaSessionObj) + } } + prettyPrinter.printSummaryTable(&opaSessionObj.Report.SummaryDetails, sortedControlNames) } diff --git a/core/pkg/resultshandling/results.go b/core/pkg/resultshandling/results.go index 8ea331ec..8ea0fac0 100644 --- a/core/pkg/resultshandling/results.go +++ b/core/pkg/resultshandling/results.go @@ -72,7 +72,7 @@ func (resultsHandler *ResultsHandler) HandleResults() error { } // NewPrinter defind output format -func NewPrinter(printFormat, formatVersion string, verboseMode bool) printer.IPrinter { +func NewPrinter(printFormat, formatVersion string, verboseMode bool, viewType cautils.ViewTypes) printer.IPrinter { switch printFormat { case printer.JsonFormat: @@ -90,6 +90,6 @@ func NewPrinter(printFormat, formatVersion string, verboseMode bool) printer.IPr case printer.PdfFormat: return printerv2.NewPdfPrinter() default: - return printerv2.NewPrettyPrinter(verboseMode, formatVersion) + return printerv2.NewPrettyPrinter(verboseMode, formatVersion, viewType) } } diff --git a/install.sh b/install.sh index 533475f4..c1ba68f5 100755 --- a/install.sh +++ b/install.sh @@ -54,6 +54,6 @@ echo -e "\033[0m" $KUBESCAPE_EXEC version echo -echo -e "\033[35mUsage: $ $KUBESCAPE_EXEC scan --submit --enable-host-scan --format-version v2 --verbose" +echo -e "\033[35mUsage: $ $KUBESCAPE_EXEC scan --submit --enable-host-scan --verbose" echo -e "\033[0m"