From c6d5d856ce0d87d8eda2e27a432277aee5319a35 Mon Sep 17 00:00:00 2001 From: chenk Date: Thu, 2 May 2024 14:08:59 +0300 Subject: [PATCH] BREAKING: add support for k8s `disable-node-collector` flag (#6311) Signed-off-by: chenk --- .../configuration/cli/trivy_kubernetes.md | 2 +- pkg/flag/kubernetes_flags.go | 28 +++---- pkg/flag/options.go | 7 +- pkg/k8s/commands/cluster.go | 8 +- pkg/k8s/commands/run.go | 1 - pkg/k8s/report/report.go | 28 +++---- pkg/k8s/report/report_test.go | 42 ++++++----- pkg/k8s/report/summary.go | 9 +-- pkg/k8s/report/summary_test.go | 26 ++----- pkg/k8s/writer.go | 4 +- pkg/k8s/writer_test.go | 73 +++++++++++++------ 11 files changed, 114 insertions(+), 114 deletions(-) diff --git a/docs/docs/references/configuration/cli/trivy_kubernetes.md b/docs/docs/references/configuration/cli/trivy_kubernetes.md index 7b7c91f3d88e..4c3aaf5bb144 100644 --- a/docs/docs/references/configuration/cli/trivy_kubernetes.md +++ b/docs/docs/references/configuration/cli/trivy_kubernetes.md @@ -34,11 +34,11 @@ trivy kubernetes [flags] [CONTEXT] --cache-ttl duration cache TTL when using redis as cache backend --clear-cache clear image caches without scanning --compliance string compliance report to generate (k8s-nsa,k8s-cis,k8s-pss-baseline,k8s-pss-restricted) - --components strings specify which components to scan (workload,infra) (default [workload,infra]) --config-data strings specify paths from which data for the Rego policies will be recursively loaded --config-policy strings specify the paths to the Rego policy files or to the directories containing them, applying config files --db-repository string OCI repository to retrieve trivy-db from (default "ghcr.io/aquasecurity/trivy-db:2") --dependency-tree [EXPERIMENTAL] show dependency origin tree of vulnerable packages + --disable-node-collector When the flag is activated, the node-collector job will not be executed, thus skipping misconfiguration findings on the node. --download-db-only download/update vulnerability database but don't run a scan --download-java-db-only download/update Java index database but don't run a scan --exclude-kinds strings indicate the kinds exclude from scanning (example: node) diff --git a/pkg/flag/kubernetes_flags.go b/pkg/flag/kubernetes_flags.go index e325eb861045..996317e0be4f 100644 --- a/pkg/flag/kubernetes_flags.go +++ b/pkg/flag/kubernetes_flags.go @@ -15,19 +15,6 @@ var ( ConfigName: "kubernetes.kubeconfig", Usage: "specify the kubeconfig file path to use", } - ComponentsFlag = Flag[[]string]{ - Name: "components", - ConfigName: "kubernetes.components", - Default: []string{ - "workload", - "infra", - }, - Values: []string{ - "workload", - "infra", - }, - Usage: "specify which components to scan", - } K8sVersionFlag = Flag[string]{ Name: "k8s-version", ConfigName: "kubernetes.k8s-version", @@ -38,6 +25,11 @@ var ( ConfigName: "kubernetes.tolerations", Usage: "specify node-collector job tolerations (example: key1=value1:NoExecute,key2=value2:NoSchedule)", } + DisableNodeCollector = Flag[bool]{ + Name: "disable-node-collector", + ConfigName: "kubernetes.disableNodeCollector", + Usage: "When the flag is activated, the node-collector job will not be executed, thus skipping misconfiguration findings on the node.", + } NodeCollectorNamespace = Flag[string]{ Name: "node-collector-namespace", ConfigName: "kubernetes.node-collector.namespace", @@ -97,9 +89,9 @@ var ( type K8sFlagGroup struct { KubeConfig *Flag[string] - Components *Flag[[]string] K8sVersion *Flag[string] Tolerations *Flag[[]string] + DisableNodeCollector *Flag[bool] NodeCollectorImageRef *Flag[string] NodeCollectorNamespace *Flag[string] ExcludeOwned *Flag[bool] @@ -114,12 +106,12 @@ type K8sFlagGroup struct { type K8sOptions struct { KubeConfig string - Components []string K8sVersion string Tolerations []corev1.Toleration NodeCollectorImageRef string NodeCollectorNamespace string ExcludeOwned bool + DisableNodeCollector bool ExcludeNodes map[string]string ExcludeKinds []string IncludeKinds []string @@ -132,9 +124,9 @@ type K8sOptions struct { func NewK8sFlagGroup() *K8sFlagGroup { return &K8sFlagGroup{ KubeConfig: KubeConfigFlag.Clone(), - Components: ComponentsFlag.Clone(), K8sVersion: K8sVersionFlag.Clone(), Tolerations: TolerationsFlag.Clone(), + DisableNodeCollector: DisableNodeCollector.Clone(), NodeCollectorNamespace: NodeCollectorNamespace.Clone(), ExcludeOwned: ExcludeOwned.Clone(), ExcludeNodes: ExcludeNodes.Clone(), @@ -155,8 +147,8 @@ func (f *K8sFlagGroup) Name() string { func (f *K8sFlagGroup) Flags() []Flagger { return []Flagger{ f.KubeConfig, - f.Components, f.K8sVersion, + f.DisableNodeCollector, f.Tolerations, f.NodeCollectorNamespace, f.ExcludeOwned, @@ -199,9 +191,9 @@ func (f *K8sFlagGroup) ToOptions() (K8sOptions, error) { return K8sOptions{ KubeConfig: f.KubeConfig.Value(), - Components: f.Components.Value(), K8sVersion: f.K8sVersion.Value(), Tolerations: tolerations, + DisableNodeCollector: f.DisableNodeCollector.Value(), NodeCollectorNamespace: f.NodeCollectorNamespace.Value(), ExcludeOwned: f.ExcludeOwned.Value(), ExcludeNodes: exludeNodeLabels, diff --git a/pkg/flag/options.go b/pkg/flag/options.go index 9448f7c0f2fa..9d49f5dfe807 100644 --- a/pkg/flag/options.go +++ b/pkg/flag/options.go @@ -360,15 +360,10 @@ func (o *Options) Align() { } // Vulnerability scanning is disabled by default for CycloneDX. - if o.Format == types.FormatCycloneDX && !viper.IsSet(ScannersFlag.ConfigName) && len(o.K8sOptions.Components) == 0 { // remove K8sOptions.Components validation check when vuln scan is supported for k8s report with cycloneDX + if o.Format == types.FormatCycloneDX && !viper.IsSet(ScannersFlag.ConfigName) { log.Info(`"--format cyclonedx" disables security scanning. Specify "--scanners vuln" explicitly if you want to include vulnerabilities in the CycloneDX report.`) o.Scanners = nil } - - if o.Format == types.FormatCycloneDX && len(o.K8sOptions.Components) > 0 { - log.Info(`"k8s with --format cyclonedx" disable security scanning`) - o.Scanners = nil - } } // RegistryOpts returns options for OCI registries diff --git a/pkg/k8s/commands/cluster.go b/pkg/k8s/commands/cluster.go index bc985bff7393..6b169771f1ca 100644 --- a/pkg/k8s/commands/cluster.go +++ b/pkg/k8s/commands/cluster.go @@ -3,13 +3,13 @@ package commands import ( "context" - "golang.org/x/exp/slices" "golang.org/x/xerrors" k8sArtifacts "github.com/aquasecurity/trivy-kubernetes/pkg/artifacts" "github.com/aquasecurity/trivy-kubernetes/pkg/k8s" "github.com/aquasecurity/trivy-kubernetes/pkg/trivyk8s" "github.com/aquasecurity/trivy/pkg/flag" + "github.com/aquasecurity/trivy/pkg/log" "github.com/aquasecurity/trivy/pkg/types" ) @@ -34,7 +34,7 @@ func clusterRun(ctx context.Context, opts flag.Options, cluster k8s.Cluster) err trivyk8s.WithIncludeKinds(opts.IncludeKinds), trivyk8s.WithExcludeOwned(opts.ExcludeOwned), } - if opts.Scanners.AnyEnabled(types.MisconfigScanner) && slices.Contains(opts.Components, "infra") { + if opts.Scanners.AnyEnabled(types.MisconfigScanner) && !opts.DisableNodeCollector { artifacts, err = trivyk8s.New(cluster, k8sOpts...).ListArtifactAndNodeInfo(ctx, trivyk8s.WithScanJobNamespace(opts.NodeCollectorNamespace), trivyk8s.WithIgnoreLabels(opts.ExcludeNodes), @@ -53,6 +53,10 @@ func clusterRun(ctx context.Context, opts flag.Options, cluster k8s.Cluster) err return xerrors.Errorf(`unknown format %q. Use "json" or "table" or "cyclonedx"`, opts.Format) } + if !opts.DisableNodeCollector && !opts.Quiet { + log.InfoContext(ctx, "Node scanning is enabled") + log.InfoContext(ctx, "If you want to disable Node scanning via an in-cluster Job, please try '--disable-node-collector' to disable the Node-Collector job.") + } runner := newRunner(opts, cluster.GetCurrentContext()) return runner.run(ctx, artifacts) } diff --git a/pkg/k8s/commands/run.go b/pkg/k8s/commands/run.go index 01ebf1db645f..3516f1afc8e9 100644 --- a/pkg/k8s/commands/run.go +++ b/pkg/k8s/commands/run.go @@ -115,7 +115,6 @@ func (r *runner) run(ctx context.Context, artifacts []*k8sArtifacts.Artifact) er Report: r.flagOpts.ReportFormat, Output: output, Severities: r.flagOpts.Severities, - Components: r.flagOpts.Components, Scanners: r.flagOpts.ScanOptions.Scanners, APIVersion: r.flagOpts.AppVersion, }); err != nil { diff --git a/pkg/k8s/report/report.go b/pkg/k8s/report/report.go index 0861a8669143..1db95394514e 100644 --- a/pkg/k8s/report/report.go +++ b/pkg/k8s/report/report.go @@ -33,7 +33,6 @@ type Option struct { Severities []dbTypes.Severity ColumnHeading []string Scanners types.Scanners - Components []string APIVersion string } @@ -134,12 +133,12 @@ type reports struct { // - misconfiguration report // - rbac report // - infra checks report -func SeparateMisconfigReports(k8sReport Report, scanners types.Scanners, components []string) []reports { +func SeparateMisconfigReports(k8sReport Report, scanners types.Scanners) []reports { var workloadMisconfig, infraMisconfig, rbacAssessment, workloadVulnerabilities, infraVulnerabilities, workloadResource []Resource for _, resource := range k8sReport.Resources { switch { - case vulnerabilitiesOrSecretResource(resource): + case vulnerabilitiesOrSecretResource(resource) && !infraResource(resource): if resource.Namespace == infraNamespace || nodeInfoResource(resource) { infraVulnerabilities = append(infraVulnerabilities, nodeKind(resource)) } else { @@ -150,8 +149,7 @@ func SeparateMisconfigReports(k8sReport Report, scanners types.Scanners, compone case infraResource(resource): infraMisconfig = append(infraMisconfig, nodeKind(resource)) case scanners.Enabled(types.MisconfigScanner) && - !rbacResource(resource) && - slices.Contains(components, workloadComponent): + !rbacResource(resource): workloadMisconfig = append(workloadMisconfig, resource) } } @@ -159,22 +157,21 @@ func SeparateMisconfigReports(k8sReport Report, scanners types.Scanners, compone var r []reports workloadResource = append(workloadResource, workloadVulnerabilities...) workloadResource = append(workloadResource, workloadMisconfig...) - if shouldAddToReport(scanners, components, workloadComponent) { + if shouldAddToReport(scanners) { workloadReport := Report{ SchemaVersion: 0, ClusterName: k8sReport.ClusterName, Resources: workloadResource, name: "Workload Assessment", } - if slices.Contains(components, workloadComponent) { - r = append(r, reports{ - Report: workloadReport, - Columns: WorkloadColumns(), - }) - } + r = append(r, reports{ + Report: workloadReport, + Columns: WorkloadColumns(), + }) + } infraMisconfig = append(infraMisconfig, infraVulnerabilities...) - if shouldAddToReport(scanners, components, infraComponent) { + if shouldAddToReport(scanners) { r = append(r, reports{ Report: Report{ SchemaVersion: 0, @@ -266,12 +263,11 @@ func (r Report) PrintErrors() { } } -func shouldAddToReport(scanners types.Scanners, components []string, componentType string) bool { +func shouldAddToReport(scanners types.Scanners) bool { return scanners.AnyEnabled( types.MisconfigScanner, types.VulnerabilityScanner, - types.SecretScanner) && - slices.Contains(components, componentType) + types.SecretScanner) } func vulnerabilitiesOrSecretResource(resource Resource) bool { diff --git a/pkg/k8s/report/report_test.go b/pkg/k8s/report/report_test.go index 6d14b52e12a9..e9e9ae5e3a91 100644 --- a/pkg/k8s/report/report_test.go +++ b/pkg/k8s/report/report_test.go @@ -515,7 +515,6 @@ func Test_separateMisconfigReports(t *testing.T) { name string k8sReport Report scanners types.Scanners - components []string expectedReports []Report }{ { @@ -525,10 +524,6 @@ func Test_separateMisconfigReports(t *testing.T) { types.MisconfigScanner, types.RBACScanner, }, - components: []string{ - workloadComponent, - infraComponent, - }, expectedReports: []Report{ // the order matter for the test { @@ -545,10 +540,6 @@ func Test_separateMisconfigReports(t *testing.T) { name: "Config and Infra for the same resource", k8sReport: k8sReport, scanners: types.Scanners{types.MisconfigScanner}, - components: []string{ - workloadComponent, - infraComponent, - }, expectedReports: []Report{ // the order matter for the test { @@ -569,10 +560,9 @@ func Test_separateMisconfigReports(t *testing.T) { }, }, { - name: "Config Report Only", - k8sReport: k8sReport, - scanners: types.Scanners{types.MisconfigScanner}, - components: []string{workloadComponent}, + name: "Config Report Only", + k8sReport: k8sReport, + scanners: types.Scanners{types.MisconfigScanner}, expectedReports: []Report{ { Resources: []Resource{ @@ -580,15 +570,29 @@ func Test_separateMisconfigReports(t *testing.T) { {Kind: "StatefulSet"}, }, }, + { + Resources: []Resource{ + {Kind: "Pod"}, + }, + }, }, }, { - name: "Infra Report Only", - k8sReport: k8sReport, - scanners: types.Scanners{types.MisconfigScanner}, - components: []string{infraComponent}, + name: "Infra Report Only", + k8sReport: k8sReport, + scanners: types.Scanners{types.MisconfigScanner}, expectedReports: []Report{ - {Resources: []Resource{{Kind: "Pod"}}}, + { + Resources: []Resource{ + {Kind: "Deployment"}, + {Kind: "StatefulSet"}, + }, + }, + { + Resources: []Resource{ + {Kind: "Pod"}, + }, + }, }, }, @@ -597,7 +601,7 @@ func Test_separateMisconfigReports(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - reports := SeparateMisconfigReports(tt.k8sReport, tt.scanners, tt.components) + reports := SeparateMisconfigReports(tt.k8sReport, tt.scanners) assert.Equal(t, len(tt.expectedReports), len(reports)) for i := range reports { diff --git a/pkg/k8s/report/summary.go b/pkg/k8s/report/summary.go index f35a1b3f6624..de81e1a7b532 100644 --- a/pkg/k8s/report/summary.go +++ b/pkg/k8s/report/summary.go @@ -35,7 +35,7 @@ func NewSummaryWriter(output io.Writer, requiredSevs []dbTypes.Severity, columnH } } -func ColumnHeading(scanners types.Scanners, components, availableColumns []string) []string { +func ColumnHeading(scanners types.Scanners, availableColumns []string) []string { columns := []string{ NamespaceColumn, ResourceColumn, @@ -47,12 +47,7 @@ func ColumnHeading(scanners types.Scanners, components, availableColumns []strin case types.VulnerabilityScanner: securityOptions[VulnerabilitiesColumn] = nil case types.MisconfigScanner: - if slices.Contains(components, workloadComponent) { - securityOptions[MisconfigurationsColumn] = nil - } - if slices.Contains(components, infraComponent) { - securityOptions[MisconfigurationsColumn] = nil - } + securityOptions[MisconfigurationsColumn] = nil case types.SecretScanner: securityOptions[SecretsColumn] = nil case types.RBACScanner: diff --git a/pkg/k8s/report/summary_test.go b/pkg/k8s/report/summary_test.go index 8744db1c6233..7a38f3b01993 100644 --- a/pkg/k8s/report/summary_test.go +++ b/pkg/k8s/report/summary_test.go @@ -20,7 +20,6 @@ func TestReport_ColumnHeading(t *testing.T) { tests := []struct { name string scanners types.Scanners - components []string availableColumns []string want []string }{ @@ -28,10 +27,6 @@ func TestReport_ColumnHeading(t *testing.T) { name: "filter workload columns", scanners: allScanners, availableColumns: WorkloadColumns(), - components: []string{ - workloadComponent, - infraComponent, - }, want: []string{ NamespaceColumn, ResourceColumn, @@ -43,7 +38,6 @@ func TestReport_ColumnHeading(t *testing.T) { { name: "filter rbac columns", scanners: allScanners, - components: []string{}, availableColumns: RoleColumns(), want: []string{ NamespaceColumn, @@ -52,12 +46,8 @@ func TestReport_ColumnHeading(t *testing.T) { }, }, { - name: "filter infra columns", - scanners: allScanners, - components: []string{ - workloadComponent, - infraComponent, - }, + name: "filter infra columns", + scanners: allScanners, availableColumns: InfraColumns(), want: []string{ NamespaceColumn, @@ -68,12 +58,8 @@ func TestReport_ColumnHeading(t *testing.T) { }, }, { - name: "config column only", - scanners: types.Scanners{types.MisconfigScanner}, - components: []string{ - workloadComponent, - infraComponent, - }, + name: "config column only", + scanners: types.Scanners{types.MisconfigScanner}, availableColumns: WorkloadColumns(), want: []string{ NamespaceColumn, @@ -84,7 +70,6 @@ func TestReport_ColumnHeading(t *testing.T) { { name: "secret column only", scanners: types.Scanners{types.SecretScanner}, - components: []string{}, availableColumns: WorkloadColumns(), want: []string{ NamespaceColumn, @@ -95,7 +80,6 @@ func TestReport_ColumnHeading(t *testing.T) { { name: "vuln column only", scanners: types.Scanners{types.VulnerabilityScanner}, - components: []string{}, availableColumns: WorkloadColumns(), want: []string{ NamespaceColumn, @@ -107,7 +91,7 @@ func TestReport_ColumnHeading(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - column := ColumnHeading(tt.scanners, tt.components, tt.availableColumns) + column := ColumnHeading(tt.scanners, tt.availableColumns) if !assert.Equal(t, column, tt.want) { t.Error(fmt.Errorf("TestReport_ColumnHeading want %v got %v", tt.want, column)) } diff --git a/pkg/k8s/writer.go b/pkg/k8s/writer.go index 13204501fb59..abc5bb381b64 100644 --- a/pkg/k8s/writer.go +++ b/pkg/k8s/writer.go @@ -23,7 +23,7 @@ func Write(ctx context.Context, k8sreport report.Report, option report.Option) e } return jwriter.Write(k8sreport) case types.FormatTable: - separatedReports := report.SeparateMisconfigReports(k8sreport, option.Scanners, option.Components) + separatedReports := report.SeparateMisconfigReports(k8sreport, option.Scanners) if option.Report == report.SummaryReport { target := fmt.Sprintf("Summary Report for %s", k8sreport.ClusterName) @@ -35,7 +35,7 @@ func Write(ctx context.Context, k8sreport report.Report, option report.Option) e Output: option.Output, Report: option.Report, Severities: option.Severities, - ColumnHeading: report.ColumnHeading(option.Scanners, option.Components, r.Columns), + ColumnHeading: report.ColumnHeading(option.Scanners, r.Columns), } if err := writer.Write(ctx, r.Report); err != nil { diff --git a/pkg/k8s/writer_test.go b/pkg/k8s/writer_test.go index 23342a044916..1b5b6af93c9c 100644 --- a/pkg/k8s/writer_test.go +++ b/pkg/k8s/writer_test.go @@ -23,9 +23,6 @@ const ( tableFormat = "table" jsonFormat = "json" cycloneDXFormat = "cyclonedx" - - workloadComponent = "workload" - infraComponent = "infra" ) var ( @@ -202,18 +199,16 @@ func TestReportWrite_Summary(t *testing.T) { report report.Report opt report.Option scanners types.Scanners - components []string severities []dbTypes.Severity expectedOutput string }{ { - name: "Only config, all severities", + name: "Only config, all serverities", report: report.Report{ ClusterName: "test", Resources: []report.Resource{deployOrionWithMisconfigs}, }, scanners: types.Scanners{types.MisconfigScanner}, - components: []string{workloadComponent}, severities: allSeverities, expectedOutput: `Summary Report for test ======================= @@ -226,16 +221,24 @@ Workload Assessment ├───────────┼──────────────┼───┼───┼───┼───┼───┤ │ default │ Deploy/orion │ 1 │ 2 │ 1 │ 2 │ 1 │ └───────────┴──────────────┴───┴───┴───┴───┴───┘ +Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN + + +Infra Assessment +┌───────────┬──────────┬───────────────────┐ +│ Namespace │ Resource │ Misconfigurations │ +│ │ ├───┬───┬───┬───┬───┤ +│ │ │ C │ H │ M │ L │ U │ +└───────────┴──────────┴───┴───┴───┴───┴───┘ Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN`, }, { - name: "Only vuln, all severities", + name: "Only vuln, all serverities", report: report.Report{ ClusterName: "test", Resources: []report.Resource{deployOrionWithVulns}, }, scanners: types.Scanners{types.VulnerabilityScanner}, - components: []string{workloadComponent}, severities: allSeverities, expectedOutput: `Summary Report for test ======================= @@ -248,10 +251,19 @@ Workload Assessment ├───────────┼──────────────┼───┼───┼───┼───┼───┤ │ default │ Deploy/orion │ 2 │ 1 │ 2 │ 1 │ 1 │ └───────────┴──────────────┴───┴───┴───┴───┴───┘ +Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN + + +Infra Assessment +┌───────────┬──────────┬───────────────────┐ +│ Namespace │ Resource │ Vulnerabilities │ +│ │ ├───┬───┬───┬───┬───┤ +│ │ │ C │ H │ M │ L │ U │ +└───────────┴──────────┴───┴───┴───┴───┴───┘ Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN`, }, { - name: "Only rbac, all severities", + name: "Only rbac, all serverities", report: report.Report{ ClusterName: "test", Resources: []report.Resource{roleWithMisconfig}, @@ -272,13 +284,12 @@ RBAC Assessment Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN`, }, { - name: "Only secret, all severities", + name: "Only secret, all serverities", report: report.Report{ ClusterName: "test", Resources: []report.Resource{deployLuaWithSecrets}, }, scanners: types.Scanners{types.SecretScanner}, - components: []string{workloadComponent}, severities: allSeverities, expectedOutput: `Summary Report for test ======================= @@ -291,20 +302,37 @@ Workload Assessment ├───────────┼────────────┼───┼───┼───┼───┼───┤ │ default │ Deploy/lua │ 1 │ │ 1 │ │ │ └───────────┴────────────┴───┴───┴───┴───┴───┘ +Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN + + +Infra Assessment +┌───────────┬──────────┬───────────────────┐ +│ Namespace │ Resource │ Secrets │ +│ │ ├───┬───┬───┬───┬───┤ +│ │ │ C │ H │ M │ L │ U │ +└───────────┴──────────┴───┴───┴───┴───┴───┘ Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN`, }, { - name: "apiserver, only infra and severities", + name: "apiserver, only infra and serverities", report: report.Report{ ClusterName: "test", Resources: []report.Resource{apiseverPodWithMisconfigAndInfra}, }, scanners: types.Scanners{types.MisconfigScanner}, - components: []string{infraComponent}, severities: allSeverities, expectedOutput: `Summary Report for test ======================= +Workload Assessment +┌───────────┬──────────┬───────────────────┐ +│ Namespace │ Resource │ Misconfigurations │ +│ │ ├───┬───┬───┬───┬───┤ +│ │ │ C │ H │ M │ L │ U │ +└───────────┴──────────┴───┴───┴───┴───┴───┘ +Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN + + Infra Assessment ┌─────────────┬────────────────────┬───────────────────┐ │ Namespace │ Resource │ Misconfigurations │ @@ -316,7 +344,7 @@ Infra Assessment Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN`, }, { - name: "apiserver, vuln,config,secret and severities", + name: "apiserver, vuln,config,secret and serverities", report: report.Report{ ClusterName: "test", Resources: []report.Resource{apiseverPodWithMisconfigAndInfra}, @@ -326,11 +354,19 @@ Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN`, types.MisconfigScanner, types.SecretScanner, }, - components: []string{infraComponent}, severities: allSeverities, expectedOutput: `Summary Report for test ======================= +Workload Assessment +┌───────────┬──────────┬───────────────────┬───────────────────┬───────────────────┐ +│ Namespace │ Resource │ Vulnerabilities │ Misconfigurations │ Secrets │ +│ │ ├───┬───┬───┬───┬───┼───┬───┬───┬───┬───┼───┬───┬───┬───┬───┤ +│ │ │ C │ H │ M │ L │ U │ C │ H │ M │ L │ U │ C │ H │ M │ L │ U │ +└───────────┴──────────┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘ +Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN + + Infra Assessment ┌─────────────┬────────────────────┬───────────────────┬───────────────────┬───────────────────┐ │ Namespace │ Resource │ Vulnerabilities │ Misconfigurations │ Secrets │ @@ -342,7 +378,7 @@ Infra Assessment Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN`, }, { - name: "apiserver, all misconfig and vuln scanners and severities", + name: "apiserver, all misconfig and vuln scanners and serverities", report: report.Report{ ClusterName: "test", Resources: []report.Resource{apiseverPodWithMisconfigAndInfra}, @@ -351,10 +387,6 @@ Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN`, types.MisconfigScanner, types.VulnerabilityScanner, }, - components: []string{ - workloadComponent, - infraComponent, - }, severities: allSeverities, expectedOutput: `Summary Report for test ======================= @@ -390,7 +422,6 @@ Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN`, Output: &output, Scanners: tc.scanners, Severities: tc.severities, - Components: tc.components, } err := Write(context.Background(), tc.report, opt)