mirror of
https://github.com/aquasecurity/trivy.git
synced 2025-12-22 23:26:39 -08:00
* refactor: add pkg/k8s Signed-off-by: Jose Donizetti <jdbjunior@gmail.com> * refactor: extract scanner Signed-off-by: Jose Donizetti <jdbjunior@gmail.com> * refactor: extract scanVulns Signed-off-by: Jose Donizetti <jdbjunior@gmail.com> * refactor: extract scanMisconfigs Signed-off-by: Jose Donizetti <jdbjunior@gmail.com> * refactor: extract filter Signed-off-by: Jose Donizetti <jdbjunior@gmail.com> * refactor: improve k8s/run.go Signed-off-by: Jose Donizetti <jdbjunior@gmail.com> * fix(k8s): code improvements Signed-off-by: Jose Donizetti <jdbjunior@gmail.com> * chore: go mod tidy Signed-off-by: Jose Donizetti <jdbjunior@gmail.com>
128 lines
3.3 KiB
Go
128 lines
3.3 KiB
Go
package k8s
|
|
|
|
import (
|
|
"context"
|
|
"io"
|
|
|
|
"github.com/cheggaaa/pb/v3"
|
|
"golang.org/x/xerrors"
|
|
|
|
cmd "github.com/aquasecurity/trivy/pkg/commands/artifact"
|
|
"github.com/aquasecurity/trivy/pkg/log"
|
|
"github.com/aquasecurity/trivy/pkg/types"
|
|
|
|
"github.com/aquasecurity/trivy-kubernetes/pkg/artifacts"
|
|
)
|
|
|
|
type scanner struct {
|
|
cluster string
|
|
runner *cmd.Runner
|
|
opt cmd.Option
|
|
}
|
|
|
|
func (s *scanner) run(ctx context.Context, artifacts []*artifacts.Artifact) (Report, error) {
|
|
// Todo move to run.go
|
|
s.opt.SecurityChecks = []string{types.SecurityCheckVulnerability, types.SecurityCheckConfig}
|
|
|
|
// progress bar
|
|
bar := pb.StartNew(len(artifacts))
|
|
if s.opt.NoProgress {
|
|
bar.SetWriter(io.Discard)
|
|
}
|
|
defer bar.Finish()
|
|
|
|
var vulns, misconfigs []Resource
|
|
|
|
// disable logs before scanning
|
|
err := log.InitLogger(s.opt.Debug, true)
|
|
if err != nil {
|
|
return Report{}, xerrors.Errorf("logger error: %w", err)
|
|
}
|
|
|
|
// Loops once over all artifacts, and execute scanners as necessary. Not every artifacts has an image,
|
|
// so image scanner is not always executed.
|
|
for _, artifact := range artifacts {
|
|
bar.Increment()
|
|
|
|
resources, err := s.scanVulns(ctx, artifact)
|
|
if err != nil {
|
|
return Report{}, xerrors.Errorf("scanning vulnerabilities error: %w", err)
|
|
}
|
|
vulns = append(vulns, resources...)
|
|
|
|
resource, err := s.scanMisconfigs(ctx, artifact)
|
|
if err != nil {
|
|
return Report{}, xerrors.Errorf("scanning misconfigurations error: %w", err)
|
|
}
|
|
misconfigs = append(misconfigs, resource)
|
|
}
|
|
|
|
// enable logs after scanning
|
|
err = log.InitLogger(s.opt.Debug, s.opt.Quiet)
|
|
if err != nil {
|
|
return Report{}, xerrors.Errorf("logger error: %w", err)
|
|
}
|
|
|
|
return Report{
|
|
SchemaVersion: 0,
|
|
ClusterName: s.cluster,
|
|
Vulnerabilities: vulns,
|
|
Misconfigurations: misconfigs,
|
|
}, nil
|
|
}
|
|
|
|
func (s *scanner) scanVulns(ctx context.Context, artifact *artifacts.Artifact) ([]Resource, error) {
|
|
resources := make([]Resource, 0, len(artifact.Images))
|
|
|
|
for _, image := range artifact.Images {
|
|
|
|
s.opt.Target = image
|
|
|
|
imageReport, err := s.runner.ScanImage(ctx, s.opt)
|
|
|
|
if err != nil {
|
|
log.Logger.Debugf("failed to scan image %s: %s", image, err)
|
|
resources = append(resources, createResource(artifact, imageReport, err))
|
|
continue
|
|
}
|
|
|
|
resource, err := s.filter(ctx, imageReport, artifact)
|
|
if err != nil {
|
|
return nil, xerrors.Errorf("filter error: %w", err)
|
|
}
|
|
|
|
resources = append(resources, resource)
|
|
}
|
|
|
|
return resources, nil
|
|
}
|
|
|
|
func (s *scanner) scanMisconfigs(ctx context.Context, artifact *artifacts.Artifact) (Resource, error) {
|
|
configFile, err := createTempFile(artifact)
|
|
if err != nil {
|
|
return Resource{}, xerrors.Errorf("scan error: %w", err)
|
|
}
|
|
|
|
s.opt.Target = configFile
|
|
|
|
configReport, err := s.runner.ScanFilesystem(ctx, s.opt)
|
|
//remove config file after scanning
|
|
removeFile(configFile)
|
|
if err != nil {
|
|
log.Logger.Debugf("failed to scan config %s/%s: %s", artifact.Kind, artifact.Name, err)
|
|
return createResource(artifact, configReport, err), err
|
|
}
|
|
|
|
return s.filter(ctx, configReport, artifact)
|
|
}
|
|
|
|
func (s *scanner) filter(ctx context.Context, report types.Report, artifact *artifacts.Artifact) (Resource, error) {
|
|
report, err := s.runner.Filter(ctx, s.opt, report)
|
|
if err != nil {
|
|
return Resource{}, xerrors.Errorf("filter error: %w", err)
|
|
}
|
|
|
|
return createResource(artifact, report, nil), nil
|
|
|
|
}
|