From 6cefada215823859d29923f66ac740256318cacd Mon Sep 17 00:00:00 2001 From: Nitish Chauhan <72253189+nitishchauhan0022@users.noreply.github.com> Date: Sun, 4 Jun 2023 17:51:07 +0530 Subject: [PATCH] correcting the formating of the table in pdf output (#1244) * correcting the formatting of the table in pdf output Signed-off-by: ntishchauhan0022 * adding some starting unit tests Signed-off-by: ntishchauhan0022 * resolving the mod error Signed-off-by: ntishchauhan0022 --------- Signed-off-by: ntishchauhan0022 --- .../printer/v2/controltable.go | 21 + .../printer/v2/controltable_test.go | 78 ++ core/pkg/resultshandling/printer/v2/pdf.go | 78 +- .../v2/testdata/mock_summaryDetails.json | 1016 +++++++++++++++++ go.mod | 4 +- go.sum | 7 +- httphandler/go.mod | 4 +- httphandler/go.sum | 7 +- 8 files changed, 1179 insertions(+), 36 deletions(-) create mode 100644 core/pkg/resultshandling/printer/v2/controltable_test.go create mode 100644 core/pkg/resultshandling/printer/v2/testdata/mock_summaryDetails.json diff --git a/core/pkg/resultshandling/printer/v2/controltable.go b/core/pkg/resultshandling/printer/v2/controltable.go index 2c10c9a8..bbf8af81 100644 --- a/core/pkg/resultshandling/printer/v2/controltable.go +++ b/core/pkg/resultshandling/printer/v2/controltable.go @@ -41,6 +41,27 @@ func generateRow(controlSummary reportsummary.IControlSummary, infoToPrintInfo [ return row } +func generateRowPdf(controlSummary reportsummary.IControlSummary, infoToPrintInfo []infoStars, verbose bool) []string { + row := make([]string, _rowLen) + + // ignore passed results + if !verbose && (controlSummary.GetStatus().IsPassed()) { + return []string{} + } + + row[columnSeverity] = apis.ControlSeverityToString(controlSummary.GetScoreFactor()) + if len(controlSummary.GetName()) > 50 { + row[columnName] = controlSummary.GetName()[:50] + "..." + } else { + row[columnName] = controlSummary.GetName() + } + row[columnCounterFailed] = fmt.Sprintf("%d", controlSummary.NumberOfResources().Failed()) + row[columnCounterAll] = fmt.Sprintf("%d", controlSummary.NumberOfResources().All()) + row[columnComplianceScore] = getComplianceScoreColumn(controlSummary, infoToPrintInfo) + + return row +} + func getInfoColumn(controlSummary reportsummary.IControlSummary, infoToPrintInfo []infoStars) string { for i := range infoToPrintInfo { if infoToPrintInfo[i].info == controlSummary.GetStatus().Info() { diff --git a/core/pkg/resultshandling/printer/v2/controltable_test.go b/core/pkg/resultshandling/printer/v2/controltable_test.go new file mode 100644 index 00000000..b1932ba8 --- /dev/null +++ b/core/pkg/resultshandling/printer/v2/controltable_test.go @@ -0,0 +1,78 @@ +package printer + +import ( + "encoding/json" + "os" + "path/filepath" + "strconv" + "testing" + + "github.com/kubescape/kubescape/v2/internal/testutils" + "github.com/kubescape/opa-utils/reporthandling/results/v1/reportsummary" + + "github.com/stretchr/testify/assert" +) + +func Test_generateRowPdf(t *testing.T) { + + mockSummary, err := mockSummaryDetails() + if err != nil { + t.Errorf("Error in creating mock summary %s", err) + } + + infoToPrintInfoMap := mapInfoToPrintInfo(mockSummary.Controls) + sortedControlIDs := getSortedControlsIDs(mockSummary.Controls) + + var results [][]string + + for i := len(sortedControlIDs) - 1; i >= 0; i-- { + for _, c := range sortedControlIDs[i] { + result := generateRowPdf(mockSummary.Controls.GetControl(reportsummary.EControlCriteriaID, c), infoToPrintInfoMap, true) + if len(result) > 0 { + results = append(results, result) + } + } + } + + for _, c := range results { + //validating severity column + if c[0] != "Low" && c[0] != "Medium" && c[0] != "High" && c[0] != "Critical" { + t.Errorf("got %s, want either of these: %s", c[0], "Low, Medium, High, Critical") + } + + // Validating length of control name + if len(c[1]) > 53 { + t.Errorf("got %s, want %s", c[1], "less than 54 characters") + } + + // Validating numeric fields + _, err := strconv.Atoi(c[2]) + if err != nil { + t.Errorf("got %s, want an integer %s", c[2], err) + } + + _, err = strconv.Atoi(c[3]) + if err != nil { + t.Errorf("got %s, want an integer %s", c[3], err) + } + + assert.NotEmpty(t, c[4], "expected a non-empty string") + + } + +} + +func mockSummaryDetails() (*reportsummary.SummaryDetails, error) { + data, err := os.ReadFile(filepath.Join(testutils.CurrentDir(), "testdata", "mock_summaryDetails.json")) + if err != nil { + return nil, err + } + + var v *reportsummary.SummaryDetails + + if err := json.Unmarshal(data, &v); err != nil { + return nil, err + } + + return v, nil +} \ No newline at end of file diff --git a/core/pkg/resultshandling/printer/v2/pdf.go b/core/pkg/resultshandling/printer/v2/pdf.go index 904ac57f..f8093783 100644 --- a/core/pkg/resultshandling/printer/v2/pdf.go +++ b/core/pkg/resultshandling/printer/v2/pdf.go @@ -62,11 +62,18 @@ func (pp *PdfPrinter) printInfo(m pdf.Maroto, summaryDetails *reportsummary.Summ for i := range infoMap { if infoMap[i].info != "" { m.Row(5, func() { - m.Col(1, func() { - m.Text(fmt.Sprintf("%v", infoMap[i].info)) - }) m.Col(12, func() { - m.Text(fmt.Sprintf("%v", infoMap[i].stars)) + m.Text(fmt.Sprintf("%v %v", infoMap[i].stars, infoMap[i].info),props.Text{ + Style: consts.Bold, + Align: consts.Left, + Size: 8, + Extrapolate: false, + Color: color.Color{ + Red: 0, + Green: 0, + Blue: 255, + }, + }) }) }) if emptyRowCounter < len(infoMap) { @@ -156,28 +163,53 @@ func (pp *PdfPrinter) printFramework(m pdf.Maroto, frameworks []reportsummary.IF func (pp *PdfPrinter) printTable(m pdf.Maroto, summaryDetails *reportsummary.SummaryDetails, sortedControlIDs [][]string) { headers := getControlTableHeaders() infoToPrintInfoMap := mapInfoToPrintInfo(summaryDetails.Controls) - controls := make([][]string, len(sortedControlIDs)) - for i := range controls { - controls[i] = make([]string, len(headers)) - } + var controls [][]string for i := len(sortedControlIDs) - 1; i >= 0; i-- { for _, c := range sortedControlIDs[i] { - controls[i] = generateRow(summaryDetails.Controls.GetControl(reportsummary.EControlCriteriaID, c), infoToPrintInfoMap, true) + row := generateRowPdf(summaryDetails.Controls.GetControl(reportsummary.EControlCriteriaID, c), infoToPrintInfoMap, true) + if len(row) > 0 { + controls = append(controls, row) + } } } m.TableList(headers, controls, props.TableList{ HeaderProp: props.TableListContent{ - Family: consts.Arial, - Style: consts.Bold, - Size: 8.0, + Family: consts.Arial, + Style: consts.Bold, + Size: 6.0, + GridSizes: []uint{1, 5, 2, 2, 2}, }, ContentProp: props.TableListContent{ - Family: consts.Courier, - Style: consts.Normal, - Size: 8.0, + Family: consts.Courier, + Style: consts.Normal, + Size: 6.0, + GridSizes: []uint{1, 5, 2, 2, 2}, + CellTextColorChangerColumnIndex: 0, + CellTextColorChangerFunc: func(cellValue string) color.Color { + if cellValue == "Critical" { + return color.Color{ + Red: 255, + Green: 0, + Blue: 0, + } + } else if cellValue == "High" { + return color.Color{ + Red: 0, + Green: 0, + Blue: 255, + } + } else if cellValue == "Medium" { + return color.Color{ + Red: 252, + Green: 186, + Blue: 3, + } + } + return color.NewBlack() + }, }, - Align: consts.Center, + Align: consts.Left, AlternatedBackground: &color.Color{ Red: 224, Green: 224, @@ -193,7 +225,9 @@ func (pp *PdfPrinter) printTable(m pdf.Maroto, summaryDetails *reportsummary.Sum // printFinalResult adds the final results func (pp *PdfPrinter) printFinalResult(m pdf.Maroto, summaryDetails *reportsummary.SummaryDetails) { m.Row(_rowLen, func() { - m.Col(3, func() { + m.Col(1, func() { + }) + m.Col(5, func() { m.Text("Resource summary", props.Text{ Align: consts.Left, Size: 8.0, @@ -209,14 +243,6 @@ func (pp *PdfPrinter) printFinalResult(m pdf.Maroto, summaryDetails *reportsumma Family: consts.Arial, }) }) - m.Col(2, func() { - m.Text(fmt.Sprintf("%d", summaryDetails.NumberOfResources().Skipped()), props.Text{ - Align: consts.Left, - Size: 8.0, - Style: consts.Bold, - Family: consts.Arial, - }) - }) m.Col(2, func() { m.Text(fmt.Sprintf("%d", summaryDetails.NumberOfResources().All()), props.Text{ Align: consts.Left, @@ -226,7 +252,7 @@ func (pp *PdfPrinter) printFinalResult(m pdf.Maroto, summaryDetails *reportsumma }) }) m.Col(2, func() { - m.Text(fmt.Sprintf("%.2f%s", summaryDetails.Score, "%"), props.Text{ + m.Text(fmt.Sprintf("%.2f%s", summaryDetails.ComplianceScore, "%"), props.Text{ Align: consts.Left, Size: 8.0, Style: consts.Bold, diff --git a/core/pkg/resultshandling/printer/v2/testdata/mock_summaryDetails.json b/core/pkg/resultshandling/printer/v2/testdata/mock_summaryDetails.json new file mode 100644 index 00000000..1bc65aed --- /dev/null +++ b/core/pkg/resultshandling/printer/v2/testdata/mock_summaryDetails.json @@ -0,0 +1,1016 @@ +{ + "controls": { + "C-0002": { + "statusInfo": { + "status": "failed" + }, + "controlID": "C-0002", + "name": "Exec into container", + "status": "failed", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 151, + "failedResources": 2, + "skippedResources": 0, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 2 + }, + "score": 1.3071896, + "scoreFactor": 5 + }, + "C-0005": { + "statusInfo": { + "status": "passed", + "subStatus": "irrelevant" + }, + "controlID": "C-0005", + "name": "API server insecure port is enabled", + "status": "passed", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 0, + "failedResources": 0, + "skippedResources": 0, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 0 + }, + "score": 0, + "scoreFactor": 9 + }, + "C-0009": { + "statusInfo": { + "status": "failed" + }, + "controlID": "C-0009", + "name": "Resource limits", + "status": "failed", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 33, + "failedResources": 36, + "skippedResources": 0, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 18 + }, + "score": 50.559006, + "scoreFactor": 7 + }, + "C-0012": { + "statusInfo": { + "status": "skipped", + "subStatus": "configuration", + "info": "Control configurations are empty" + }, + "controlID": "C-0012", + "name": "Applications credentials in configuration files", + "status": "skipped", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 0, + "failedResources": 0, + "skippedResources": 134, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 0 + }, + "score": 0, + "scoreFactor": 8 + }, + "C-0013": { + "statusInfo": { + "status": "failed" + }, + "controlID": "C-0013", + "name": "Non-root containers", + "status": "failed", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 32, + "failedResources": 37, + "skippedResources": 0, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 14 + }, + "score": 48.81987, + "scoreFactor": 6 + }, + "C-0016": { + "statusInfo": { + "status": "failed" + }, + "controlID": "C-0016", + "name": "Allow privilege escalation", + "status": "failed", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 39, + "failedResources": 37, + "skippedResources": 0, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 14 + }, + "score": 44.914284, + "scoreFactor": 6 + }, + "C-0017": { + "statusInfo": { + "status": "failed" + }, + "controlID": "C-0017", + "name": "Immutable container filesystem", + "status": "failed", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 27, + "failedResources": 42, + "skippedResources": 0, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 23 + }, + "score": 55.03105, + "scoreFactor": 3 + }, + "C-0030": { + "statusInfo": { + "status": "failed" + }, + "controlID": "C-0030", + "name": "Ingress and Egress blocked", + "status": "failed", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 24, + "failedResources": 45, + "skippedResources": 0, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 24 + }, + "score": 61.739136, + "scoreFactor": 6 + }, + "C-0034": { + "statusInfo": { + "status": "failed" + }, + "controlID": "C-0034", + "name": "Automatic mapping of service account", + "status": "failed", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 84, + "failedResources": 59, + "skippedResources": 0, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 64 + }, + "score": 41.229774, + "scoreFactor": 6 + }, + "C-0035": { + "statusInfo": { + "status": "failed" + }, + "controlID": "C-0035", + "name": "Cluster-admin binding", + "status": "failed", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 151, + "failedResources": 2, + "skippedResources": 0, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 2 + }, + "score": 1.3071896, + "scoreFactor": 6 + }, + "C-0038": { + "statusInfo": { + "status": "failed" + }, + "controlID": "C-0038", + "name": "Host PID/IPC privileges", + "status": "failed", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 68, + "failedResources": 1, + "skippedResources": 0, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 1 + }, + "score": 1.242236, + "scoreFactor": 7 + }, + "C-0041": { + "statusInfo": { + "status": "passed", + "subStatus": "w/exceptions" + }, + "controlID": "C-0041", + "name": "HostNetwork access", + "status": "passed", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 69, + "failedResources": 0, + "skippedResources": 0, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 11 + }, + "score": 0, + "scoreFactor": 7 + }, + "C-0044": { + "statusInfo": { + "status": "passed" + }, + "controlID": "C-0044", + "name": "Container hostPort", + "status": "passed", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 69, + "failedResources": 0, + "skippedResources": 0, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 0 + }, + "score": 0, + "scoreFactor": 4 + }, + "C-0046": { + "statusInfo": { + "status": "failed" + }, + "controlID": "C-0046", + "name": "Insecure capabilities", + "status": "failed", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 68, + "failedResources": 1, + "skippedResources": 0, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 0 + }, + "score": 1.242236, + "scoreFactor": 7 + }, + "C-0054": { + "statusInfo": { + "status": "failed" + }, + "controlID": "C-0054", + "name": "Cluster internal networking", + "status": "failed", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 4, + "failedResources": 9, + "skippedResources": 0, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 4 + }, + "score": 69.23077, + "scoreFactor": 4 + }, + "C-0055": { + "statusInfo": { + "status": "failed" + }, + "controlID": "C-0055", + "name": "Linux hardening", + "status": "failed", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 39, + "failedResources": 30, + "skippedResources": 0, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 16 + }, + "score": 40.12422, + "scoreFactor": 4 + }, + "C-0057": { + "statusInfo": { + "status": "failed" + }, + "controlID": "C-0057", + "name": "Privileged container", + "status": "failed", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 68, + "failedResources": 1, + "skippedResources": 0, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 11 + }, + "score": 1.242236, + "scoreFactor": 8 + }, + "C-0058": { + "statusInfo": { + "status": "passed", + "subStatus": "irrelevant" + }, + "controlID": "C-0058", + "name": "CVE-2021-25741 - Using symlink for arbitrary host file system access.", + "status": "passed", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 0, + "failedResources": 0, + "skippedResources": 0, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 0 + }, + "score": 0, + "scoreFactor": 6 + }, + "C-0059": { + "statusInfo": { + "status": "passed", + "subStatus": "irrelevant" + }, + "controlID": "C-0059", + "name": "CVE-2021-25742-nginx-ingress-snippet-annotation-vulnerability", + "status": "passed", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 0, + "failedResources": 0, + "skippedResources": 0, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 0 + }, + "score": 0, + "scoreFactor": 8 + }, + "C-0066": { + "statusInfo": { + "status": "failed" + }, + "controlID": "C-0066", + "name": "Secret/ETCD encryption enabled", + "status": "failed", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 0, + "failedResources": 1, + "skippedResources": 0, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 0 + }, + "score": 100, + "scoreFactor": 6 + }, + "C-0067": { + "statusInfo": { + "status": "failed" + }, + "controlID": "C-0067", + "name": "Audit logs enabled", + "status": "failed", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 0, + "failedResources": 1, + "skippedResources": 0, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 0 + }, + "score": 100, + "scoreFactor": 5 + }, + "C-0068": { + "statusInfo": { + "status": "failed" + }, + "controlID": "C-0068", + "name": "PSP enabled", + "status": "failed", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 0, + "failedResources": 1, + "skippedResources": 0, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 0 + }, + "score": 100, + "scoreFactor": 1 + }, + "C-0069": { + "statusInfo": { + "status": "skipped", + "info": "enable-host-scan flag not used. For more information: https://hub.armosec.io/docs/host-sensor" + }, + "controlID": "C-0069", + "name": "Disable anonymous access to Kubelet service", + "status": "skipped", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 0, + "failedResources": 0, + "skippedResources": 0, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 0 + }, + "score": 0, + "scoreFactor": 10 + }, + "C-0070": { + "statusInfo": { + "status": "skipped", + "info": "enable-host-scan flag not used. For more information: https://hub.armosec.io/docs/host-sensor" + }, + "controlID": "C-0070", + "name": "Enforce Kubelet client TLS authentication", + "status": "skipped", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 0, + "failedResources": 0, + "skippedResources": 0, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 0 + }, + "score": 0, + "scoreFactor": 9 + } + }, + "status": "failed", + "frameworks": [ + { + "controls": { + "C-0002": { + "statusInfo": { + "status": "failed" + }, + "controlID": "C-0002", + "name": "Exec into container", + "status": "failed", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 151, + "failedResources": 2, + "skippedResources": 0, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 2 + }, + "score": 1.3071896, + "scoreFactor": 5 + }, + "C-0005": { + "statusInfo": { + "status": "passed", + "subStatus": "irrelevant" + }, + "controlID": "C-0005", + "name": "API server insecure port is enabled", + "status": "passed", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 0, + "failedResources": 0, + "skippedResources": 0, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 0 + }, + "score": 0, + "scoreFactor": 9 + }, + "C-0009": { + "statusInfo": { + "status": "failed" + }, + "controlID": "C-0009", + "name": "Resource limits", + "status": "failed", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 33, + "failedResources": 36, + "skippedResources": 0, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 18 + }, + "score": 50.559006, + "scoreFactor": 7 + }, + "C-0012": { + "statusInfo": { + "status": "skipped", + "subStatus": "configuration", + "info": "Control configurations are empty" + }, + "controlID": "C-0012", + "name": "Applications credentials in configuration files", + "status": "skipped", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 0, + "failedResources": 0, + "skippedResources": 134, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 0 + }, + "score": 0, + "scoreFactor": 8 + }, + "C-0013": { + "statusInfo": { + "status": "failed" + }, + "controlID": "C-0013", + "name": "Non-root containers", + "status": "failed", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 32, + "failedResources": 37, + "skippedResources": 0, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 14 + }, + "score": 48.81987, + "scoreFactor": 6 + }, + "C-0016": { + "statusInfo": { + "status": "failed" + }, + "controlID": "C-0016", + "name": "Allow privilege escalation", + "status": "failed", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 39, + "failedResources": 37, + "skippedResources": 0, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 14 + }, + "score": 44.914284, + "scoreFactor": 6 + }, + "C-0017": { + "statusInfo": { + "status": "failed" + }, + "controlID": "C-0017", + "name": "Immutable container filesystem", + "status": "failed", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 27, + "failedResources": 42, + "skippedResources": 0, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 23 + }, + "score": 55.03105, + "scoreFactor": 3 + }, + "C-0030": { + "statusInfo": { + "status": "failed" + }, + "controlID": "C-0030", + "name": "Ingress and Egress blocked", + "status": "failed", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 24, + "failedResources": 45, + "skippedResources": 0, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 24 + }, + "score": 61.739136, + "scoreFactor": 6 + }, + "C-0034": { + "statusInfo": { + "status": "failed" + }, + "controlID": "C-0034", + "name": "Automatic mapping of service account", + "status": "failed", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 84, + "failedResources": 59, + "skippedResources": 0, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 64 + }, + "score": 41.229774, + "scoreFactor": 6 + }, + "C-0035": { + "statusInfo": { + "status": "failed" + }, + "controlID": "C-0035", + "name": "Cluster-admin binding", + "status": "failed", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 151, + "failedResources": 2, + "skippedResources": 0, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 2 + }, + "score": 1.3071896, + "scoreFactor": 6 + }, + "C-0038": { + "statusInfo": { + "status": "failed" + }, + "controlID": "C-0038", + "name": "Host PID/IPC privileges", + "status": "failed", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 68, + "failedResources": 1, + "skippedResources": 0, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 1 + }, + "score": 1.242236, + "scoreFactor": 7 + }, + "C-0041": { + "statusInfo": { + "status": "passed", + "subStatus": "w/exceptions" + }, + "controlID": "C-0041", + "name": "HostNetwork access", + "status": "passed", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 69, + "failedResources": 0, + "skippedResources": 0, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 11 + }, + "score": 0, + "scoreFactor": 7 + }, + "C-0044": { + "statusInfo": { + "status": "passed" + }, + "controlID": "C-0044", + "name": "Container hostPort", + "status": "passed", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 69, + "failedResources": 0, + "skippedResources": 0, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 0 + }, + "score": 0, + "scoreFactor": 4 + }, + "C-0046": { + "statusInfo": { + "status": "failed" + }, + "controlID": "C-0046", + "name": "Insecure capabilities", + "status": "failed", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 68, + "failedResources": 1, + "skippedResources": 0, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 0 + }, + "score": 1.242236, + "scoreFactor": 7 + }, + "C-0054": { + "statusInfo": { + "status": "failed" + }, + "controlID": "C-0054", + "name": "Cluster internal networking", + "status": "failed", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 4, + "failedResources": 9, + "skippedResources": 0, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 4 + }, + "score": 69.23077, + "scoreFactor": 4 + }, + "C-0055": { + "statusInfo": { + "status": "failed" + }, + "controlID": "C-0055", + "name": "Linux hardening", + "status": "failed", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 39, + "failedResources": 30, + "skippedResources": 0, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 16 + }, + "score": 40.12422, + "scoreFactor": 4 + }, + "C-0057": { + "statusInfo": { + "status": "failed" + }, + "controlID": "C-0057", + "name": "Privileged container", + "status": "failed", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 68, + "failedResources": 1, + "skippedResources": 0, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 11 + }, + "score": 1.242236, + "scoreFactor": 8 + }, + "C-0058": { + "statusInfo": { + "status": "passed", + "subStatus": "irrelevant" + }, + "controlID": "C-0058", + "name": "CVE-2021-25741 - Using symlink for arbitrary host file system access.", + "status": "passed", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 0, + "failedResources": 0, + "skippedResources": 0, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 0 + }, + "score": 0, + "scoreFactor": 6 + }, + "C-0059": { + "statusInfo": { + "status": "passed", + "subStatus": "irrelevant" + }, + "controlID": "C-0059", + "name": "CVE-2021-25742-nginx-ingress-snippet-annotation-vulnerability", + "status": "passed", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 0, + "failedResources": 0, + "skippedResources": 0, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 0 + }, + "score": 0, + "scoreFactor": 8 + }, + "C-0066": { + "statusInfo": { + "status": "failed" + }, + "controlID": "C-0066", + "name": "Secret/ETCD encryption enabled", + "status": "failed", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 0, + "failedResources": 1, + "skippedResources": 0, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 0 + }, + "score": 100, + "scoreFactor": 6 + }, + "C-0067": { + "statusInfo": { + "status": "failed" + }, + "controlID": "C-0067", + "name": "Audit logs enabled", + "status": "failed", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 0, + "failedResources": 1, + "skippedResources": 0, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 0 + }, + "score": 100, + "scoreFactor": 5 + }, + "C-0068": { + "statusInfo": { + "status": "failed" + }, + "controlID": "C-0068", + "name": "PSP enabled", + "status": "failed", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 0, + "failedResources": 1, + "skippedResources": 0, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 0 + }, + "score": 100, + "scoreFactor": 1 + }, + "C-0069": { + "statusInfo": { + "status": "skipped", + "info": "enable-host-scan flag not used. For more information: https://hub.armosec.io/docs/host-sensor" + }, + "controlID": "C-0069", + "name": "Disable anonymous access to Kubelet service", + "status": "skipped", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 0, + "failedResources": 0, + "skippedResources": 0, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 0 + }, + "score": 0, + "scoreFactor": 10 + }, + "C-0070": { + "statusInfo": { + "status": "skipped", + "info": "enable-host-scan flag not used. For more information: https://hub.armosec.io/docs/host-sensor" + }, + "controlID": "C-0070", + "name": "Enforce Kubelet client TLS authentication", + "status": "skipped", + "resourceIDs": {}, + "ResourceCounters": { + "passedResources": 0, + "failedResources": 0, + "skippedResources": 0, + "excludedResources": 0 + }, + "subStatusCounters": { + "ignoredResources": 0 + }, + "score": 0, + "scoreFactor": 9 + } + }, + "name": "NSA", + "status": "failed", + "version": "", + "ResourceCounters": { + "passedResources": 210, + "failedResources": 83, + "skippedResources": 89, + "excludedResources": 0 + }, + "score": 19.654322 + } + ], + "resourcesSeverityCounters": { + "criticalSeverity": 0, + "highSeverity": 39, + "mediumSeverity": 223, + "lowSeverity": 43 + }, + "controlsSeverityCounters": { + "criticalSeverity": 0, + "highSeverity": 4, + "mediumSeverity": 10, + "lowSeverity": 2 + }, + "ResourceCounters": { + "passedResources": 210, + "failedResources": 83, + "skippedResources": 89, + "excludedResources": 0 + }, + "score": 19.654322 +} diff --git a/go.mod b/go.mod index d54deb46..eab4e90f 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/go-git/go-git/v5 v5.5.2 github.com/google/go-containerregistry v0.13.0 github.com/google/uuid v1.3.0 - github.com/johnfercher/maroto v0.37.0 + github.com/johnfercher/maroto v0.42.0 github.com/json-iterator/go v1.1.12 github.com/kubescape/go-git-url v0.0.25 github.com/kubescape/go-logger v0.0.11 @@ -260,7 +260,7 @@ require ( github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rivo/uniseg v0.4.3 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58 // indirect + github.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245 // indirect github.com/sassoftware/relic v0.0.0-20210427151427-dfb082b79b74 // indirect github.com/secure-systems-lab/go-securesystemslib v0.4.0 // indirect github.com/segmentio/ksuid v1.0.4 // indirect diff --git a/go.sum b/go.sum index 3262f2df..a85288ac 100644 --- a/go.sum +++ b/go.sum @@ -1036,8 +1036,8 @@ github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHW github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jmhodges/clock v0.0.0-20160418191101-880ee4c33548 h1:dYTbLf4m0a5u0KLmPfB6mgxbcV7588bOCx79hxa5Sr4= -github.com/johnfercher/maroto v0.37.0 h1:W5xA6dixF7PwxT0N6mfbRg0zjQSMXeSIzplUucAuZTE= -github.com/johnfercher/maroto v0.37.0/go.mod h1:f9vLjznW+aVsf5R0F90P+PYi2maaYOHq8l07mvOP+ew= +github.com/johnfercher/maroto v0.42.0 h1:NlZQsSyfDnBcGBZ6M6ZV+PDrdwzoiClzbWp872viP+g= +github.com/johnfercher/maroto v0.42.0/go.mod h1:qeujdhKT+677jMjGWlIa5OCgR04GgIHvByJ6pSC+hOw= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= @@ -1413,8 +1413,9 @@ github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58 h1:nlG4Wa5+minh3S9LVFtNoY+GVRiudA2e3EVfcCi3RCA= github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w= +github.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245 h1:K1Xf3bKttbF+koVGaX5xngRIZ5bVjbmPnaxE/dR08uY= +github.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245/go.mod h1:pQAZKsJ8yyVxGRWYNEm9oFB8ieLgKFnamEyDmSA0BRk= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= diff --git a/httphandler/go.mod b/httphandler/go.mod index 6d4b95a2..b28cfdba 100644 --- a/httphandler/go.mod +++ b/httphandler/go.mod @@ -210,7 +210,7 @@ require ( github.com/jhump/protoreflect v1.13.0 // indirect github.com/jinzhu/copier v0.3.5 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect - github.com/johnfercher/maroto v0.37.0 // indirect + github.com/johnfercher/maroto v0.42.0 // indirect github.com/jonboulle/clockwork v0.3.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect @@ -263,7 +263,7 @@ require ( github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rivo/uniseg v0.4.3 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58 // indirect + github.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245 // indirect github.com/sassoftware/relic v0.0.0-20210427151427-dfb082b79b74 // indirect github.com/schollz/progressbar/v3 v3.13.0 // indirect github.com/secure-systems-lab/go-securesystemslib v0.4.0 // indirect diff --git a/httphandler/go.sum b/httphandler/go.sum index 91aae17f..b50ab833 100644 --- a/httphandler/go.sum +++ b/httphandler/go.sum @@ -1041,8 +1041,8 @@ github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHW github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jmhodges/clock v0.0.0-20160418191101-880ee4c33548 h1:dYTbLf4m0a5u0KLmPfB6mgxbcV7588bOCx79hxa5Sr4= -github.com/johnfercher/maroto v0.37.0 h1:W5xA6dixF7PwxT0N6mfbRg0zjQSMXeSIzplUucAuZTE= -github.com/johnfercher/maroto v0.37.0/go.mod h1:f9vLjznW+aVsf5R0F90P+PYi2maaYOHq8l07mvOP+ew= +github.com/johnfercher/maroto v0.42.0 h1:NlZQsSyfDnBcGBZ6M6ZV+PDrdwzoiClzbWp872viP+g= +github.com/johnfercher/maroto v0.42.0/go.mod h1:qeujdhKT+677jMjGWlIa5OCgR04GgIHvByJ6pSC+hOw= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= @@ -1418,8 +1418,9 @@ github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58 h1:nlG4Wa5+minh3S9LVFtNoY+GVRiudA2e3EVfcCi3RCA= github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w= +github.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245 h1:K1Xf3bKttbF+koVGaX5xngRIZ5bVjbmPnaxE/dR08uY= +github.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245/go.mod h1:pQAZKsJ8yyVxGRWYNEm9oFB8ieLgKFnamEyDmSA0BRk= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=