From bd9e44382eaa8a0728a0356593d9f9dc0d0ee250 Mon Sep 17 00:00:00 2001 From: David Wertenteil Date: Thu, 7 Apr 2022 13:54:49 +0300 Subject: [PATCH] format v2 --- .../printer/v2/controltable.go | 22 ++--- .../printer/v2/prettyprinter.go | 11 ++- .../printer/v2/resourcetable.go | 89 ++++++++++++------- .../reporter/v2/reporteventreceiver.go | 11 ++- 4 files changed, 82 insertions(+), 51 deletions(-) diff --git a/core/pkg/resultshandling/printer/v2/controltable.go b/core/pkg/resultshandling/printer/v2/controltable.go index 3797c43c..e84d44b0 100644 --- a/core/pkg/resultshandling/printer/v2/controltable.go +++ b/core/pkg/resultshandling/printer/v2/controltable.go @@ -18,7 +18,6 @@ const ( columnCounterExclude = iota columnCounterAll = iota columnRiskScore = iota - columnInfo = iota _rowLen = iota ) @@ -40,30 +39,23 @@ func generateRow(controlSummary reportsummary.IControlSummary, infoToPrintInfo [ row[columnCounterFailed] = fmt.Sprintf("%d", controlSummary.NumberOfResources().Failed()) row[columnCounterExclude] = fmt.Sprintf("%d", controlSummary.NumberOfResources().Excluded()) row[columnCounterAll] = fmt.Sprintf("%d", controlSummary.NumberOfResources().All()) - row[columnRiskScore] = getRiskScoreColumn(controlSummary) - row[columnInfo] = getInfoColumn(controlSummary, infoToPrintInfo) + row[columnRiskScore] = getRiskScoreColumn(controlSummary, infoToPrintInfo) return row } func getInfoColumn(controlSummary reportsummary.IControlSummary, infoToPrintInfo []infoStars) string { - if !controlSummary.GetStatus().IsSkipped() { - return "" - } - - if controlSummary.GetStatus().IsSkipped() { - for i := range infoToPrintInfo { - if infoToPrintInfo[i].info == controlSummary.GetStatus().Info() { - return infoToPrintInfo[i].stars - } + for i := range infoToPrintInfo { + if infoToPrintInfo[i].info == controlSummary.GetStatus().Info() { + return infoToPrintInfo[i].stars } } return "" } -func getRiskScoreColumn(controlSummary reportsummary.IControlSummary) string { +func getRiskScoreColumn(controlSummary reportsummary.IControlSummary, infoToPrintInfo []infoStars) string { if controlSummary.GetStatus().IsSkipped() { - return string(controlSummary.GetStatus().Status()) + return fmt.Sprintf("%s%s", controlSummary.GetStatus().Status(), getInfoColumn(controlSummary, infoToPrintInfo)) } return fmt.Sprintf("%d", cautils.Float32ToInt(controlSummary.GetScore())) + "%" } @@ -111,7 +103,6 @@ func getControlTableHeaders() []string { headers[columnCounterAll] = "ALL RESOURCES" headers[columnSeverity] = "SEVERITY" headers[columnRiskScore] = "% RISK-SCORE" - headers[columnInfo] = "INFO" return headers } @@ -123,6 +114,5 @@ func getColumnsAlignments() []int { alignments[columnCounterAll] = tablewriter.ALIGN_CENTER alignments[columnSeverity] = tablewriter.ALIGN_LEFT alignments[columnRiskScore] = tablewriter.ALIGN_CENTER - alignments[columnRiskScore] = tablewriter.ALIGN_CENTER return alignments } diff --git a/core/pkg/resultshandling/printer/v2/prettyprinter.go b/core/pkg/resultshandling/printer/v2/prettyprinter.go index 8a2842b2..8935350c 100644 --- a/core/pkg/resultshandling/printer/v2/prettyprinter.go +++ b/core/pkg/resultshandling/printer/v2/prettyprinter.go @@ -30,13 +30,15 @@ func NewPrettyPrinter(verboseMode bool, formatVersion string) *PrettyPrinter { } func (prettyPrinter *PrettyPrinter) ActionPrint(opaSessionObj *cautils.OPASessionObj) { + fmt.Fprintf(prettyPrinter.writer, "\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n") + sortedControlNames := getSortedControlsNames(opaSessionObj.Report.SummaryDetails.Controls) // ListControls().All()) if prettyPrinter.verboseMode { if prettyPrinter.formatVersion == "v1" { prettyPrinter.printResults(&opaSessionObj.Report.SummaryDetails.Controls, opaSessionObj.AllResources, sortedControlNames) } else if prettyPrinter.formatVersion == "v2" { - prettyPrinter.resourceTable(opaSessionObj.ResourcesResult, opaSessionObj.AllResources) + prettyPrinter.resourceTable(opaSessionObj) } } prettyPrinter.printSummaryTable(&opaSessionObj.Report.SummaryDetails, sortedControlNames) @@ -176,12 +178,13 @@ func generateFooter(summaryDetails *reportsummary.SummaryDetails) []string { row[columnCounterAll] = fmt.Sprintf("%d", summaryDetails.NumberOfResources().All()) row[columnSeverity] = " " row[columnRiskScore] = fmt.Sprintf("%.2f%s", summaryDetails.Score, "%") - row[columnInfo] = " " return row } func (prettyPrinter *PrettyPrinter) printSummaryTable(summaryDetails *reportsummary.SummaryDetails, sortedControlNames [][]string) { + cautils.InfoTextDisplay(prettyPrinter.writer, "\n"+controlListSummary(summaryDetails)+"\n\n") + summaryTable := tablewriter.NewWriter(prettyPrinter.writer) summaryTable.SetAutoWrapText(false) summaryTable.SetHeader(getControlTableHeaders()) @@ -237,3 +240,7 @@ func frameworksScoresToString(frameworks []reportsummary.IFrameworkSummary) stri func getControlLink(controlID string) string { return fmt.Sprintf("https://hub.armo.cloud/docs/%s", strings.ToLower(controlID)) } + +func controlListSummary(summaryDetails *reportsummary.SummaryDetails) string { + return fmt.Sprintf("Controls: %d (Failed: %d, Excluded: %d, Skipped: %d)", summaryDetails.NumberOfControls().All(), summaryDetails.NumberOfControls().Failed(), summaryDetails.NumberOfControls().Excluded(), summaryDetails.NumberOfControls().Skipped()) +} diff --git a/core/pkg/resultshandling/printer/v2/resourcetable.go b/core/pkg/resultshandling/printer/v2/resourcetable.go index b1555fc1..e88f8a6f 100644 --- a/core/pkg/resultshandling/printer/v2/resourcetable.go +++ b/core/pkg/resultshandling/printer/v2/resourcetable.go @@ -5,58 +5,80 @@ import ( "sort" "strings" - "github.com/armosec/k8s-interface/workloadinterface" + "github.com/armosec/kubescape/core/cautils" + "github.com/armosec/opa-utils/reporthandling/results/v1/reportsummary" "github.com/armosec/opa-utils/reporthandling/results/v1/resourcesresults" "github.com/olekukonko/tablewriter" ) -func (prettyPrinter *PrettyPrinter) resourceTable(results map[string]resourcesresults.Result, allResources map[string]workloadinterface.IMetadata) { +const ( + resourceColumnSeverity = iota + resourceColumnName = iota + resourceColumnURL = iota + resourceColumnPath = iota + _resourceRowLen = iota +) - summaryTable := tablewriter.NewWriter(prettyPrinter.writer) - summaryTable.SetAutoWrapText(true) - summaryTable.SetAutoMergeCells(true) - summaryTable.SetHeader(generateResourceHeader()) - summaryTable.SetHeaderLine(true) - summaryTable.SetRowLine(true) - // summaryTable.SetFooter([]string{"", "", "Total", "", "$146.93"}) - // For control scan framework will be nil - data := Matrix{} - for i := range results { - resource, ok := allResources[i] +func (prettyPrinter *PrettyPrinter) resourceTable(opaSessionObj *cautils.OPASessionObj) { + + for resourceID, result := range opaSessionObj.ResourcesResult { + if !result.GetStatus(nil).IsFailed() { + continue + } + resource, ok := opaSessionObj.AllResources[resourceID] if !ok { continue } - s := results[i] - if raw := generateResourceRows(resource, s.ListControls(), prettyPrinter.verboseMode); len(raw) > 0 { + fmt.Fprintf(prettyPrinter.writer, "\n#######################################################################################################\n") + + if source, ok := opaSessionObj.ResourceSource[resourceID]; ok { + fmt.Fprintf(prettyPrinter.writer, "Source: %s\n", source) + } + fmt.Fprintf(prettyPrinter.writer, "%s/%s, Name: %s", resource.GetApiVersion(), resource.GetKind(), resource.GetName()) + if resource.GetNamespace() != "" { + fmt.Fprintf(prettyPrinter.writer, ", Namespace: %s", resource.GetNamespace()) + } + fmt.Fprintf(prettyPrinter.writer, "\n\n") + + summaryTable := tablewriter.NewWriter(prettyPrinter.writer) + summaryTable.SetAutoWrapText(true) + summaryTable.SetAutoMergeCells(true) + summaryTable.SetHeader(generateResourceHeader()) + summaryTable.SetHeaderLine(true) + summaryTable.SetRowLine(true) + data := Matrix{} + + if raw := generateResourceRows(result.ListControls(), &opaSessionObj.Report.SummaryDetails); len(raw) > 0 { data = append(data, raw...) } + // For control scan framework will be nil + + sort.Sort(data) + summaryTable.AppendBulk(data) + + summaryTable.Render() } - sort.Sort(data) - summaryTable.AppendBulk(data) - summaryTable.Render() } -func generateResourceRows(resource workloadinterface.IMetadata, controls []resourcesresults.ResourceAssociatedControl, verboseMode bool) [][]string { +func generateResourceRows(controls []resourcesresults.ResourceAssociatedControl, summaryDetails *reportsummary.SummaryDetails) [][]string { rows := [][]string{} for i := range controls { + row := make([]string, _resourceRowLen) - if controls[i].GetName() == "" { - continue - } - row := []string{} - - if !verboseMode && controls[i].GetStatus(nil).IsPassed() { + if !controls[i].GetStatus(nil).IsFailed() { continue } - row = append(row, fmt.Sprintf("%s\nhttps://hub.armo.cloud/docs/%s", controls[i].GetName(), strings.ToLower(controls[i].GetID()))) - row = append(row, resource.GetNamespace()) - paths := failedPathsToString(&controls[i]) + row[resourceColumnURL] = fmt.Sprintf("https://hub.armo.cloud/docs/%s", strings.ToLower(controls[i].GetID())) + row[resourceColumnPath] = strings.Join(failedPathsToString(&controls[i]), "\n") + row[resourceColumnName] = controls[i].GetName() + + if c := summaryDetails.Controls.GetControl(reportsummary.EControlCriteriaName, controls[i].GetName()); c != nil { + row[resourceColumnSeverity] = getSeverityColumn(c) + } - row = append(row, fmt.Sprintf("%s/%s\n%s", resource.GetKind(), resource.GetName(), strings.Join(paths, ";\n"))) - row = append(row, string(controls[i].GetStatus(nil).Status())) rows = append(rows, row) } @@ -64,7 +86,12 @@ func generateResourceRows(resource workloadinterface.IMetadata, controls []resou } func generateResourceHeader() []string { - return []string{"Control", "Namespace", "Kind/Name", "Statues"} + headers := make([]string, _resourceRowLen) + headers[resourceColumnSeverity] = "Severity" + headers[resourceColumnName] = "Control Name" + headers[resourceColumnURL] = "Docs" + headers[resourceColumnPath] = "Assistant Remediation" + return headers } type Matrix [][]string diff --git a/core/pkg/resultshandling/reporter/v2/reporteventreceiver.go b/core/pkg/resultshandling/reporter/v2/reporteventreceiver.go index 7bc8b7e6..3c1d2d4b 100644 --- a/core/pkg/resultshandling/reporter/v2/reporteventreceiver.go +++ b/core/pkg/resultshandling/reporter/v2/reporteventreceiver.go @@ -92,6 +92,8 @@ func (report *ReportEventReceiver) GetURL() string { u.Scheme = "https" u.Host = getter.GetArmoAPIConnector().GetFrontendURL() + q := u.Query() + if report.customerAdminEMail != "" || report.token == "" { // data has been submitted u.Path = fmt.Sprintf("configuration-scanning/%s", report.clusterName) } else { @@ -99,9 +101,14 @@ func (report *ReportEventReceiver) GetURL() string { q := u.Query() q.Add("invitationToken", report.token) q.Add("customerGUID", report.customerGUID) - - u.RawQuery = q.Encode() } + + q.Add("utm_source", "GitHub") + q.Add("utm_medium", "CLI") + q.Add("utm_campaign", "Submit") + + u.RawQuery = q.Encode() + return u.String() }