mirror of
https://github.com/aquasecurity/trivy.git
synced 2025-12-22 23:26:39 -08:00
feat: k8s resource scanning (#2118)
This commit is contained in:
@@ -8,39 +8,41 @@ Scan your Kubernetes cluster for both Vulnerabilities and Misconfigurations.
|
||||
|
||||
Trivy uses your local kubectl configuration to access the API server to list artifacts.
|
||||
|
||||
Scan a full cluster:
|
||||
Scan a full cluster and generate a simple summary report:
|
||||
|
||||
```
|
||||
$ trivy k8s
|
||||
$ trivy k8s --report=summary
|
||||
```
|
||||
|
||||

|
||||
|
||||
The summary report is the default. To get all of the detail the output contains, use `--report all`.
|
||||
|
||||
Filter by severity:
|
||||
|
||||
```
|
||||
$ trivy k8s --severity=CRITICAL --report=all
|
||||
```
|
||||
|
||||
Scan a specific namespace:
|
||||
|
||||
```
|
||||
$ trivy k8s -n default
|
||||
$ trivy k8s -n kube-system --report=summary
|
||||
```
|
||||
|
||||
Scan a namespace for only `CRITICAL` Vulnerabilities and Misconfigurations:
|
||||
Scan a specific resource and get all the output:
|
||||
|
||||
```
|
||||
$ trivy k8s -n default --severity CRITICAL
|
||||
$ trivy k8s deployment/appname
|
||||
```
|
||||
|
||||
Scan a cluster and generate a simple summary report. The only outputs currently supported are `all` and `summary`. The default report format is `summary`
|
||||
The supported formats are `table`, which is the default, and `json`.
|
||||
To get a JSON output on a full cluster scan:
|
||||
|
||||
```
|
||||
$ trivy k8s
|
||||
$ trivy k8s --format json -o results.json
|
||||
```
|
||||
|
||||

|
||||
|
||||
To get all of the detail the output contains, use `--report all`, to get JSON output:
|
||||
|
||||
```
|
||||
$ trivy k8s --report all
|
||||
```
|
||||
|
||||
|
||||
<details>
|
||||
<summary>Result</summary>
|
||||
|
||||
|
||||
11
go.mod
11
go.mod
@@ -7,7 +7,7 @@ require (
|
||||
github.com/Masterminds/sprig/v3 v3.2.2
|
||||
github.com/NYTimes/gziphandler v1.1.1
|
||||
github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986
|
||||
github.com/aquasecurity/fanal v0.0.0-20220511115204-32614d79a234
|
||||
github.com/aquasecurity/fanal v0.0.0-20220513163515-33f2cd8392ee
|
||||
github.com/aquasecurity/go-dep-parser v0.0.0-20220503151658-d316f5cc2cff
|
||||
github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce
|
||||
github.com/aquasecurity/go-npm-version v0.0.0-20201110091526-0b796d180798
|
||||
@@ -54,7 +54,7 @@ require (
|
||||
require (
|
||||
cloud.google.com/go v0.99.0 // indirect
|
||||
cloud.google.com/go/storage v1.14.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go v63.0.0+incompatible // indirect
|
||||
github.com/Azure/azure-sdk-for-go v64.0.0+incompatible // indirect
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
|
||||
github.com/Azure/go-autorest/autorest v0.11.27 // indirect
|
||||
@@ -77,7 +77,7 @@ require (
|
||||
github.com/agext/levenshtein v1.2.3 // indirect
|
||||
github.com/apparentlymart/go-cidr v1.1.0 // indirect
|
||||
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
|
||||
github.com/aquasecurity/defsec v0.57.3
|
||||
github.com/aquasecurity/defsec v0.57.5
|
||||
github.com/aws/aws-sdk-go v1.44.5 // indirect
|
||||
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect
|
||||
github.com/bmatcuk/doublestar v1.3.4 // indirect
|
||||
@@ -198,7 +198,7 @@ require (
|
||||
|
||||
require (
|
||||
github.com/aquasecurity/table v1.5.1
|
||||
github.com/aquasecurity/trivy-kubernetes v0.1.0
|
||||
github.com/aquasecurity/trivy-kubernetes v0.2.1
|
||||
)
|
||||
|
||||
require (
|
||||
@@ -251,3 +251,6 @@ replace github.com/containerd/containerd v1.5.9 => github.com/containerd/contain
|
||||
|
||||
// See https://github.com/moby/moby/issues/42939#issuecomment-1114255529
|
||||
replace github.com/docker/docker => github.com/docker/docker v20.10.3-0.20220224222438-c78f6963a1c0+incompatible
|
||||
|
||||
// TODO: remove once the feature is merged upstream
|
||||
replace github.com/aquasecurity/trivy-kubernetes v0.1.0 => github.com/josedonizetti/trivy-kubernetes v0.0.0-20220515001536-b6e8afada9c5
|
||||
|
||||
16
go.sum
16
go.sum
@@ -56,8 +56,8 @@ dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20210715213245-6c3934b029d8/go.mod h1:CzsSbkDixRphAF5hS6wbMKq0eI6ccJRb7/A0M6JBnwg=
|
||||
github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/azure-sdk-for-go v56.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/azure-sdk-for-go v63.0.0+incompatible h1:whPsa+jCHQSo5wGMPNLw4bz8q9Co2+vnXHzXGctoTaQ=
|
||||
github.com/Azure/azure-sdk-for-go v63.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/azure-sdk-for-go v64.0.0+incompatible h1:WAA77WBDWYtNfCC95V70VvkdzHe+wM/r2MQ9mG7fnQs=
|
||||
github.com/Azure/azure-sdk-for-go v64.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210608223527-2377c96fe795/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
|
||||
@@ -180,10 +180,10 @@ github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6
|
||||
github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo=
|
||||
github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986 h1:2a30xLN2sUZcMXl50hg+PJCIDdJgIvIbVcKqLJ/ZrtM=
|
||||
github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986/go.mod h1:NT+jyeCzXk6vXR5MTkdn4z64TgGfE5HMLC8qfj5unl8=
|
||||
github.com/aquasecurity/defsec v0.57.3 h1:oiATfUTxOAcxAuXSH31RdgjtXJdQznlVzMJWdVYGmXY=
|
||||
github.com/aquasecurity/defsec v0.57.3/go.mod h1:42FxKif2itz+MHFlJ3TJjdroL9Jzj3THoexlueBTU5w=
|
||||
github.com/aquasecurity/fanal v0.0.0-20220511115204-32614d79a234 h1:NG9Qs4hocUWcGytaA0yhArPRoPmo12EPAUERwYCgvLA=
|
||||
github.com/aquasecurity/fanal v0.0.0-20220511115204-32614d79a234/go.mod h1:bqz0H4eqstkngJB0TJCk39GLXZcUtobMpuNr4ScC1vk=
|
||||
github.com/aquasecurity/defsec v0.57.5 h1:kOsRgMlQMxdOHYNEF0SCblZevrsdoz7c4fz5qYTTUFY=
|
||||
github.com/aquasecurity/defsec v0.57.5/go.mod h1:42FxKif2itz+MHFlJ3TJjdroL9Jzj3THoexlueBTU5w=
|
||||
github.com/aquasecurity/fanal v0.0.0-20220513163515-33f2cd8392ee h1:O7cN19V4W7u7s7M3kME21/IDUA4iQULDeo9g3DS4gdU=
|
||||
github.com/aquasecurity/fanal v0.0.0-20220513163515-33f2cd8392ee/go.mod h1:1FqeeQo0AKRIgYgv60r0SOBNMBenxBQF3jAnnICEFIE=
|
||||
github.com/aquasecurity/go-dep-parser v0.0.0-20220503151658-d316f5cc2cff h1:YNlzRYB0n4mZtfuWx6AWaGEjnLVNekchyoFDlYFZegs=
|
||||
github.com/aquasecurity/go-dep-parser v0.0.0-20220503151658-d316f5cc2cff/go.mod h1:7EOQWQmyavVPY3fScbbPdd3dB/b0Q4ZbJ/NZCvNKrLs=
|
||||
github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce h1:QgBRgJvtEOBtUXilDb1MLi1p1MWoyFDXAu5DEUl5nwM=
|
||||
@@ -200,8 +200,8 @@ github.com/aquasecurity/table v1.5.1/go.mod h1:1MFKrEPJ8NchM917BrVGvsqoXJo1OL1Ja
|
||||
github.com/aquasecurity/testdocker v0.0.0-20210911155206-e1e85f5a1516 h1:moQmzbpLo5dxHQCyEhqzizsDSNrNhn/7uRTCZzo4A1o=
|
||||
github.com/aquasecurity/trivy-db v0.0.0-20220510190819-8ca06716f46e h1:NLm5KWGcnkwaUR1GODPePyhNsbuFiT6lgKYcCcW9c10=
|
||||
github.com/aquasecurity/trivy-db v0.0.0-20220510190819-8ca06716f46e/go.mod h1:/nULgnDeq/JMPMVwE1dmf4kWlYn++7VrM3O2naj4BHA=
|
||||
github.com/aquasecurity/trivy-kubernetes v0.1.0 h1:eE7JSdqo83Kn87c86DcUIsPAtW0K9UnkkHEQ4sGI030=
|
||||
github.com/aquasecurity/trivy-kubernetes v0.1.0/go.mod h1:9fU3sHz/wXN5ruZ5snUEJpzm2X6pUndKucv1mz9Walc=
|
||||
github.com/aquasecurity/trivy-kubernetes v0.2.1 h1:h7MeJpwZXd4+9f6mWRslrYQWSY/NXede50zUDx4kwLk=
|
||||
github.com/aquasecurity/trivy-kubernetes v0.2.1/go.mod h1:9fU3sHz/wXN5ruZ5snUEJpzm2X6pUndKucv1mz9Walc=
|
||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||
|
||||
@@ -219,7 +219,7 @@ var (
|
||||
|
||||
reportFlag = cli.StringFlag{
|
||||
Name: "report",
|
||||
Value: "summary",
|
||||
Value: "all",
|
||||
Usage: "specify a report format for the output. (all,summary default: all)",
|
||||
}
|
||||
|
||||
@@ -804,10 +804,21 @@ func NewK8sCommand() *cli.Command {
|
||||
Name: "kubernetes",
|
||||
Aliases: []string{"k8s"},
|
||||
Usage: "scan kubernetes vulnerabilities and misconfigurations",
|
||||
Action: k8s.Run,
|
||||
CustomHelpTemplate: cli.CommandHelpTemplate + `EXAMPLES:
|
||||
- cluster scanning:
|
||||
$ trivy k8s --report summary
|
||||
|
||||
- namespace scanning:
|
||||
$ trivy k8s -n kube-system --report summary
|
||||
|
||||
- resource scanning:
|
||||
$ trivy k8s deployment/orion
|
||||
`,
|
||||
Action: k8s.Run,
|
||||
Flags: []cli.Flag{
|
||||
&namespaceFlag,
|
||||
&reportFlag,
|
||||
&formatFlag,
|
||||
&outputFlag,
|
||||
&severityFlag,
|
||||
&exitCodeFlag,
|
||||
|
||||
@@ -10,11 +10,23 @@ import (
|
||||
|
||||
type JSONWriter struct {
|
||||
Output io.Writer
|
||||
Report string
|
||||
}
|
||||
|
||||
// Write writes the results in JSON format
|
||||
func (jw JSONWriter) Write(report Report) error {
|
||||
output, err := json.MarshalIndent(report, "", " ")
|
||||
var output []byte
|
||||
var err error
|
||||
|
||||
switch jw.Report {
|
||||
case allReport:
|
||||
output, err = json.MarshalIndent(report, "", " ")
|
||||
case summaryReport:
|
||||
output, err = json.MarshalIndent(report.consolidate(), "", " ")
|
||||
default:
|
||||
err = fmt.Errorf("report %s not supported", jw.Report)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to marshal json: %w", err)
|
||||
}
|
||||
@@ -22,5 +34,6 @@ func (jw JSONWriter) Write(report Report) error {
|
||||
if _, err = fmt.Fprintln(jw.Output, string(output)); err != nil {
|
||||
return xerrors.Errorf("failed to write json: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package k8s
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
@@ -9,10 +10,24 @@ import (
|
||||
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
|
||||
"github.com/aquasecurity/trivy-kubernetes/pkg/artifacts"
|
||||
|
||||
"github.com/aquasecurity/trivy/pkg/report"
|
||||
"github.com/aquasecurity/trivy/pkg/types"
|
||||
)
|
||||
|
||||
const (
|
||||
allReport = "all"
|
||||
summaryReport = "summary"
|
||||
|
||||
tableFormat = "table"
|
||||
jsonFormat = "json"
|
||||
)
|
||||
|
||||
type Option struct {
|
||||
Format string
|
||||
Report string
|
||||
Output io.Writer
|
||||
Severities []dbTypes.Severity
|
||||
}
|
||||
|
||||
// Report represents a kubernetes scan report
|
||||
type Report struct {
|
||||
SchemaVersion int `json:",omitempty"`
|
||||
@@ -37,6 +52,9 @@ type Resource struct {
|
||||
// Metadata Metadata `json:",omitempty"`
|
||||
Results types.Results `json:",omitempty"`
|
||||
Error string `json:",omitempty"`
|
||||
|
||||
// original report
|
||||
Report types.Report `json:"-"`
|
||||
}
|
||||
|
||||
// Failed returns whether the k8s report includes any vulnerabilities or misconfigurations
|
||||
@@ -90,13 +108,17 @@ type Writer interface {
|
||||
}
|
||||
|
||||
// write writes the results in the give format
|
||||
func write(report Report, option report.Option, severities []dbTypes.Severity) error {
|
||||
func write(report Report, option Option) error {
|
||||
var writer Writer
|
||||
switch option.Format {
|
||||
case "all":
|
||||
writer = &JSONWriter{Output: option.Output}
|
||||
case "summary":
|
||||
writer = NewSummaryWriter(option.Output, severities)
|
||||
case jsonFormat:
|
||||
writer = &JSONWriter{Output: option.Output, Report: option.Report}
|
||||
case tableFormat:
|
||||
writer = &TableWriter{
|
||||
Output: option.Output,
|
||||
Report: option.Report,
|
||||
Severities: option.Severities,
|
||||
}
|
||||
default:
|
||||
return xerrors.Errorf("unknown format: %v", option.Format)
|
||||
}
|
||||
@@ -121,6 +143,7 @@ func createResource(artifact *artifacts.Artifact, report types.Report, err error
|
||||
Kind: artifact.Kind,
|
||||
Name: artifact.Name,
|
||||
Results: results,
|
||||
Report: report,
|
||||
}
|
||||
|
||||
// if there was any error during the scan
|
||||
|
||||
@@ -3,13 +3,13 @@ package k8s
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
cmd "github.com/aquasecurity/trivy/pkg/commands/artifact"
|
||||
"github.com/aquasecurity/trivy/pkg/log"
|
||||
pkgReport "github.com/aquasecurity/trivy/pkg/report"
|
||||
|
||||
"github.com/aquasecurity/trivy-kubernetes/pkg/artifacts"
|
||||
"github.com/aquasecurity/trivy-kubernetes/pkg/k8s"
|
||||
@@ -17,12 +17,36 @@ import (
|
||||
)
|
||||
|
||||
// Run runs scan on kubernetes cluster
|
||||
|
||||
func Run(cliCtx *cli.Context) error {
|
||||
opt, err := cmd.InitOption(cliCtx)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("option error: %w", err)
|
||||
}
|
||||
|
||||
// Full-cluster scanning with '--format table' without explicit '--report all' is not allowed so that it won't mess up user's terminal.
|
||||
// To show all the results, user needs to specify "--report all" explicitly
|
||||
// even though the default value of "--report" is "all".
|
||||
//
|
||||
// e.g. $ trivy k8s --report all
|
||||
//
|
||||
// Or they can use "--format json" with implicit "--report all".
|
||||
//
|
||||
// e.g. $ trivy k8s --format json // All the results are shown in JSON
|
||||
//
|
||||
// Single resource scanning is allowed with implicit "--report all".
|
||||
//
|
||||
// e.g. $ trivy k8s pod myapp
|
||||
if cliCtx.String("report") == allReport &&
|
||||
!cliCtx.IsSet("report") &&
|
||||
cliCtx.String("format") == tableFormat &&
|
||||
!cliCtx.Args().Present() {
|
||||
|
||||
m := "All the results in the table format can mess up your terminal. Use \"--report all\" to tell Trivy to output it to your terminal anyway, or consider \"--report summary\" to show the summary output."
|
||||
|
||||
return xerrors.New(m)
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(cliCtx.Context, opt.Timeout)
|
||||
defer cancel()
|
||||
|
||||
@@ -39,7 +63,11 @@ func Run(cliCtx *cli.Context) error {
|
||||
}
|
||||
return xerrors.Errorf("init error: %w", err)
|
||||
}
|
||||
defer runner.Close()
|
||||
defer func() {
|
||||
if err := runner.Close(); err != nil {
|
||||
log.Logger.Errorf("failed to close runner: %s", err)
|
||||
}
|
||||
}()
|
||||
|
||||
cluster, err := k8s.GetCluster()
|
||||
if err != nil {
|
||||
@@ -47,7 +75,7 @@ func Run(cliCtx *cli.Context) error {
|
||||
}
|
||||
|
||||
// get kubernetes scannable artifacts
|
||||
artifacts, err := getArtifacts(ctx, cluster, opt.KubernetesOption.Namespace)
|
||||
artifacts, err := getArtifacts(ctx, cliCtx.Args(), cluster, opt.KubernetesOption.Namespace)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("get k8s artifacts error: %w", err)
|
||||
}
|
||||
@@ -67,10 +95,12 @@ func run(ctx context.Context, s *scanner, opt cmd.Option, artifacts []*artifacts
|
||||
return xerrors.Errorf("k8s scan error: %w", err)
|
||||
}
|
||||
|
||||
if err = write(report, pkgReport.Option{
|
||||
Format: opt.KubernetesOption.ReportFormat,
|
||||
Output: opt.Output,
|
||||
}, opt.Severities); err != nil {
|
||||
if err = write(report, Option{
|
||||
Format: opt.Format,
|
||||
Report: opt.KubernetesOption.ReportFormat,
|
||||
Output: opt.Output,
|
||||
Severities: opt.Severities,
|
||||
}); err != nil {
|
||||
return xerrors.Errorf("unable to write results: %w", err)
|
||||
}
|
||||
|
||||
@@ -79,6 +109,44 @@ func run(ctx context.Context, s *scanner, opt cmd.Option, artifacts []*artifacts
|
||||
return nil
|
||||
}
|
||||
|
||||
func getArtifacts(ctx context.Context, cluster k8s.Cluster, namespace string) ([]*artifacts.Artifact, error) {
|
||||
return trivyk8s.New(cluster).Namespace(namespace).ListArtifacts(ctx)
|
||||
func getArtifacts(ctx context.Context, args cli.Args, cluster k8s.Cluster, namespace string) ([]*artifacts.Artifact, error) {
|
||||
trivyk8s := trivyk8s.New(cluster)
|
||||
|
||||
if !args.Present() {
|
||||
return trivyk8s.Namespace(namespace).ListArtifacts(ctx)
|
||||
}
|
||||
|
||||
// if scanning single resource, and namespace is empty
|
||||
// uses default namespace
|
||||
if len(namespace) == 0 {
|
||||
namespace = cluster.GetCurrentNamespace()
|
||||
}
|
||||
|
||||
kind, name, err := extractKindAndName(args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
artifact, err := trivyk8s.Namespace(namespace).GetArtifact(ctx, kind, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return []*artifacts.Artifact{artifact}, nil
|
||||
}
|
||||
|
||||
func extractKindAndName(args cli.Args) (string, string, error) {
|
||||
switch args.Len() {
|
||||
case 1:
|
||||
s := strings.Split(args.Get(0), "/")
|
||||
if len(s) != 2 {
|
||||
return "", "", xerrors.Errorf("can't parse arguments: %v", args.Slice())
|
||||
}
|
||||
|
||||
return s[0], s[1], nil
|
||||
case 2:
|
||||
return args.Get(0), args.Get(1), nil
|
||||
}
|
||||
|
||||
return "", "", xerrors.Errorf("can't parse arguments: %v", args.Slice())
|
||||
}
|
||||
|
||||
@@ -123,5 +123,4 @@ func (s *scanner) filter(ctx context.Context, report types.Report, artifact *art
|
||||
}
|
||||
|
||||
return createResource(artifact, report, nil), nil
|
||||
|
||||
}
|
||||
|
||||
41
pkg/k8s/table.go
Normal file
41
pkg/k8s/table.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package k8s
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
|
||||
pkgReport "github.com/aquasecurity/trivy/pkg/report"
|
||||
)
|
||||
|
||||
type TableWriter struct {
|
||||
Report string
|
||||
Output io.Writer
|
||||
Severities []dbTypes.Severity
|
||||
}
|
||||
|
||||
func (tw TableWriter) Write(report Report) error {
|
||||
switch tw.Report {
|
||||
case allReport:
|
||||
t := pkgReport.TableWriter{Output: tw.Output, Severities: tw.Severities}
|
||||
for _, r := range report.Vulnerabilities {
|
||||
if r.Report.Results.Failed() {
|
||||
err := t.Write(r.Report)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, r := range report.Misconfigurations {
|
||||
if r.Report.Results.Failed() {
|
||||
err := t.Write(r.Report)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
case summaryReport:
|
||||
writer := NewSummaryWriter(tw.Output, tw.Severities)
|
||||
return writer.Write(report)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user