mirror of
https://github.com/aquasecurity/trivy.git
synced 2025-12-12 15:50:15 -08:00
refactor: move from urfave/cli to spf13/cobra (#2458)
Co-authored-by: afdesk <work@afdesk.com> Co-authored-by: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com>
This commit is contained in:
@@ -1,25 +1,26 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/aquasecurity/trivy-kubernetes/pkg/k8s"
|
||||
"github.com/aquasecurity/trivy-kubernetes/pkg/trivyk8s"
|
||||
cmd "github.com/aquasecurity/trivy/pkg/commands/artifact"
|
||||
"github.com/aquasecurity/trivy/pkg/flag"
|
||||
"github.com/aquasecurity/trivy/pkg/log"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
// clusterRun runs scan on kubernetes cluster
|
||||
func clusterRun(cliCtx *cli.Context, opt cmd.Option, cluster k8s.Cluster) error {
|
||||
if err := validateReportArguments(cliCtx); err != nil {
|
||||
func clusterRun(ctx context.Context, opts flag.Options, cluster k8s.Cluster) error {
|
||||
if err := validateReportArguments(opts); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
artifacts, err := trivyk8s.New(cluster, log.Logger).ListArtifacts(cliCtx.Context)
|
||||
artifacts, err := trivyk8s.New(cluster, log.Logger).ListArtifacts(ctx)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("get k8s artifacts error: %w", err)
|
||||
}
|
||||
|
||||
return run(cliCtx.Context, opt, cluster.GetCurrentContext(), artifacts)
|
||||
return run(ctx, opts, cluster.GetCurrentContext(), artifacts)
|
||||
}
|
||||
|
||||
@@ -1,35 +1,35 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"github.com/urfave/cli/v2"
|
||||
"golang.org/x/xerrors"
|
||||
"context"
|
||||
|
||||
cmd "github.com/aquasecurity/trivy/pkg/commands/artifact"
|
||||
"github.com/aquasecurity/trivy/pkg/log"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"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"
|
||||
)
|
||||
|
||||
// namespaceRun runs scan on kubernetes cluster
|
||||
func namespaceRun(cliCtx *cli.Context, opt cmd.Option, cluster k8s.Cluster) error {
|
||||
if err := validateReportArguments(cliCtx); err != nil {
|
||||
func namespaceRun(ctx context.Context, opts flag.Options, cluster k8s.Cluster) error {
|
||||
if err := validateReportArguments(opts); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
trivyk8s := trivyk8s.New(cluster, log.Logger).Namespace(getNamespace(opt, cluster.GetCurrentNamespace()))
|
||||
trivyk8s := trivyk8s.New(cluster, log.Logger).Namespace(getNamespace(opts, cluster.GetCurrentNamespace()))
|
||||
|
||||
artifacts, err := trivyk8s.ListArtifacts(cliCtx.Context)
|
||||
artifacts, err := trivyk8s.ListArtifacts(ctx)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("get k8s artifacts error: %w", err)
|
||||
}
|
||||
|
||||
return run(cliCtx.Context, opt, cluster.GetCurrentContext(), artifacts)
|
||||
return run(ctx, opts, cluster.GetCurrentContext(), artifacts)
|
||||
}
|
||||
|
||||
func getNamespace(opt cmd.Option, currentNamespace string) string {
|
||||
if len(opt.KubernetesOption.Namespace) > 0 {
|
||||
return opt.KubernetesOption.Namespace
|
||||
func getNamespace(opts flag.Options, currentNamespace string) string {
|
||||
if len(opts.K8sOptions.Namespace) > 0 {
|
||||
return opts.K8sOptions.Namespace
|
||||
}
|
||||
|
||||
return currentNamespace
|
||||
|
||||
@@ -3,9 +3,9 @@ package commands
|
||||
import (
|
||||
"testing"
|
||||
|
||||
cmd "github.com/aquasecurity/trivy/pkg/commands/artifact"
|
||||
"github.com/aquasecurity/trivy/pkg/commands/option"
|
||||
"gotest.tools/assert"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/aquasecurity/trivy/pkg/flag"
|
||||
)
|
||||
|
||||
func Test_getNamespace(t *testing.T) {
|
||||
@@ -13,27 +13,35 @@ func Test_getNamespace(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
currentNamespace string
|
||||
opt cmd.Option
|
||||
expected string
|
||||
opts flag.Options
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "--namespace=custom",
|
||||
currentNamespace: "default",
|
||||
opt: cmd.Option{KubernetesOption: option.KubernetesOption{Namespace: "custom"}},
|
||||
expected: "custom",
|
||||
opts: flag.Options{
|
||||
K8sOptions: flag.K8sOptions{
|
||||
Namespace: "custom",
|
||||
},
|
||||
},
|
||||
want: "custom",
|
||||
},
|
||||
{
|
||||
name: "no namespaces passed",
|
||||
currentNamespace: "default",
|
||||
opt: cmd.Option{KubernetesOption: option.KubernetesOption{Namespace: ""}},
|
||||
expected: "default",
|
||||
opts: flag.Options{
|
||||
K8sOptions: flag.K8sOptions{
|
||||
Namespace: "",
|
||||
},
|
||||
},
|
||||
want: "default",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
got := getNamespace(test.opt, test.currentNamespace)
|
||||
assert.Equal(t, test.expected, got)
|
||||
got := getNamespace(test.opts, test.currentNamespace)
|
||||
assert.Equal(t, test.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,47 +1,48 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/aquasecurity/trivy/pkg/flag"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/aquasecurity/trivy-kubernetes/pkg/artifacts"
|
||||
"github.com/aquasecurity/trivy-kubernetes/pkg/k8s"
|
||||
"github.com/aquasecurity/trivy-kubernetes/pkg/trivyk8s"
|
||||
cmd "github.com/aquasecurity/trivy/pkg/commands/artifact"
|
||||
"github.com/aquasecurity/trivy/pkg/log"
|
||||
)
|
||||
|
||||
// resourceRun runs scan on kubernetes cluster
|
||||
func resourceRun(cliCtx *cli.Context, opt cmd.Option, cluster k8s.Cluster) error {
|
||||
kind, name, err := extractKindAndName(cliCtx.Args().Slice())
|
||||
func resourceRun(ctx context.Context, args []string, opts flag.Options, cluster k8s.Cluster) error {
|
||||
kind, name, err := extractKindAndName(args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
trivyk8s := trivyk8s.New(cluster, log.Logger).Namespace(getNamespace(opt, cluster.GetCurrentNamespace()))
|
||||
trivyk8s := trivyk8s.New(cluster, log.Logger).Namespace(getNamespace(opts, cluster.GetCurrentNamespace()))
|
||||
|
||||
if len(name) == 0 { // pods or configmaps etc
|
||||
if err := validateReportArguments(cliCtx); err != nil {
|
||||
if err = validateReportArguments(opts); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
targets, err := trivyk8s.Resources(kind).ListArtifacts(cliCtx.Context)
|
||||
targets, err := trivyk8s.Resources(kind).ListArtifacts(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return run(cliCtx.Context, opt, cluster.GetCurrentContext(), targets)
|
||||
return run(ctx, opts, cluster.GetCurrentContext(), targets)
|
||||
}
|
||||
|
||||
// pod/NAME or pod NAME etc
|
||||
artifact, err := trivyk8s.GetArtifact(cliCtx.Context, kind, name)
|
||||
artifact, err := trivyk8s.GetArtifact(ctx, kind, name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return run(cliCtx.Context, opt, cluster.GetCurrentContext(), []*artifacts.Artifact{artifact})
|
||||
return run(ctx, opts, cluster.GetCurrentContext(), []*artifacts.Artifact{artifact})
|
||||
}
|
||||
|
||||
func extractKindAndName(args []string) (string, string, error) {
|
||||
|
||||
@@ -4,7 +4,10 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/aquasecurity/trivy/pkg/flag"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
cmd "github.com/aquasecurity/trivy/pkg/commands/artifact"
|
||||
@@ -22,29 +25,24 @@ const (
|
||||
)
|
||||
|
||||
// Run runs a k8s scan
|
||||
func Run(cliCtx *cli.Context) error {
|
||||
opt, err := cmd.InitOption(cliCtx)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("option error: %w", err)
|
||||
}
|
||||
|
||||
cluster, err := k8s.GetCluster(opt.KubernetesOption.ClusterContext)
|
||||
func Run(ctx context.Context, args []string, opts flag.Options) error {
|
||||
cluster, err := k8s.GetCluster(opts.K8sOptions.ClusterContext)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed getting k8s cluster: %w", err)
|
||||
}
|
||||
|
||||
switch cliCtx.Args().Get(0) {
|
||||
switch args[0] {
|
||||
case clusterArtifact:
|
||||
return clusterRun(cliCtx, opt, cluster)
|
||||
return clusterRun(ctx, opts, cluster)
|
||||
case allArtifact:
|
||||
return namespaceRun(cliCtx, opt, cluster)
|
||||
return namespaceRun(ctx, opts, cluster)
|
||||
default: // resourceArtifact
|
||||
return resourceRun(cliCtx, opt, cluster)
|
||||
return resourceRun(ctx, args, opts, cluster)
|
||||
}
|
||||
}
|
||||
|
||||
func run(ctx context.Context, opt cmd.Option, cluster string, artifacts []*artifacts.Artifact) error {
|
||||
ctx, cancel := context.WithTimeout(ctx, opt.Timeout)
|
||||
func run(ctx context.Context, opts flag.Options, cluster string, artifacts []*artifacts.Artifact) error {
|
||||
ctx, cancel := context.WithTimeout(ctx, opts.Timeout)
|
||||
defer cancel()
|
||||
|
||||
var err error
|
||||
@@ -54,7 +52,7 @@ func run(ctx context.Context, opt cmd.Option, cluster string, artifacts []*artif
|
||||
}
|
||||
}()
|
||||
|
||||
runner, err := cmd.NewRunner(opt)
|
||||
runner, err := cmd.NewRunner(ctx, opts)
|
||||
if err != nil {
|
||||
if errors.Is(err, cmd.SkipScan) {
|
||||
return nil
|
||||
@@ -67,22 +65,22 @@ func run(ctx context.Context, opt cmd.Option, cluster string, artifacts []*artif
|
||||
}
|
||||
}()
|
||||
|
||||
s := scanner.NewScanner(cluster, runner, opt)
|
||||
s := scanner.NewScanner(cluster, runner, opts)
|
||||
|
||||
r, err := s.Scan(ctx, artifacts)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("k8s scan error: %w", err)
|
||||
}
|
||||
if err := report.Write(r, report.Option{
|
||||
Format: opt.Format,
|
||||
Report: opt.KubernetesOption.ReportFormat,
|
||||
Output: opt.Output,
|
||||
Severities: opt.Severities,
|
||||
}, opt.ReportOption.SecurityChecks); err != nil {
|
||||
Format: opts.Format,
|
||||
Report: opts.ReportFormat,
|
||||
Output: opts.Output,
|
||||
Severities: opts.Severities,
|
||||
}, opts.ScanOptions.SecurityChecks); err != nil {
|
||||
return xerrors.Errorf("unable to write results: %w", err)
|
||||
}
|
||||
|
||||
cmd.Exit(opt, r.Failed())
|
||||
cmd.Exit(opts, r.Failed())
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -101,10 +99,10 @@ func run(ctx context.Context, opt cmd.Option, cluster string, artifacts []*artif
|
||||
// Single resource scanning is allowed with implicit "--report all".
|
||||
//
|
||||
// e.g. $ trivy k8s pod myapp
|
||||
func validateReportArguments(cliCtx *cli.Context) error {
|
||||
if cliCtx.String("report") == "all" &&
|
||||
!cliCtx.IsSet("report") &&
|
||||
cliCtx.String("format") == "table" {
|
||||
func validateReportArguments(opts flag.Options) error {
|
||||
if opts.ReportFormat == "all" &&
|
||||
!viper.IsSet("report") &&
|
||||
opts.Format == "table" {
|
||||
|
||||
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."
|
||||
|
||||
|
||||
Reference in New Issue
Block a user