refactor: extract commands Runner interface (#2147)

This commit is contained in:
Jose Donizetti
2022-06-06 05:04:24 -03:00
committed by GitHub
parent 60a81fcb95
commit d8b59efea9
2 changed files with 37 additions and 20 deletions

View File

@@ -63,24 +63,41 @@ type ScannerConfig struct {
ArtifactOption artifact.Option ArtifactOption artifact.Option
} }
type Runner struct { type Runner interface {
// ScanImage scans an image
ScanImage(ctx context.Context, opt Option) (types.Report, error)
// ScanFilesystem scans a filesystem
ScanFilesystem(ctx context.Context, opt Option) (types.Report, error)
// ScanRootfs scans rootfs
ScanRootfs(ctx context.Context, opt Option) (types.Report, error)
// ScanRepositroy scans repository
ScanRepository(ctx context.Context, opt Option) (types.Report, error)
// Filter filter a report
Filter(ctx context.Context, opt Option, report types.Report) (types.Report, error)
// Report a writes a report
Report(opt Option, report types.Report) error
// Close closes runner
Close() error
}
type runner struct {
cache cache.Cache cache cache.Cache
dbOpen bool dbOpen bool
} }
type runnerOption func(*Runner) type runnerOption func(*runner)
// WithCacheClient takes a custom cache implementation // WithCacheClient takes a custom cache implementation
func WithCacheClient(c cache.Cache) runnerOption { func WithCacheClient(c cache.Cache) runnerOption {
return func(r *Runner) { return func(r *runner) {
r.cache = c r.cache = c
} }
} }
// NewRunner initializes Runner that provides scanning functionalities. // NewRunner initializes Runner that provides scanning functionalities.
// It is possible to return SkipScan and it must be handled by caller. // It is possible to return SkipScan and it must be handled by caller.
func NewRunner(cliOption Option, opts ...runnerOption) (*Runner, error) { func NewRunner(cliOption Option, opts ...runnerOption) (Runner, error) {
r := &Runner{} r := &runner{}
for _, opt := range opts { for _, opt := range opts {
opt(r) opt(r)
} }
@@ -102,7 +119,7 @@ func NewRunner(cliOption Option, opts ...runnerOption) (*Runner, error) {
} }
// Close closes everything // Close closes everything
func (r *Runner) Close() error { func (r *runner) Close() error {
var errs error var errs error
if err := r.cache.Close(); err != nil { if err := r.cache.Close(); err != nil {
errs = multierror.Append(errs, err) errs = multierror.Append(errs, err)
@@ -116,7 +133,7 @@ func (r *Runner) Close() error {
return errs return errs
} }
func (r *Runner) ScanImage(ctx context.Context, opt Option) (types.Report, error) { func (r *runner) ScanImage(ctx context.Context, opt Option) (types.Report, error) {
// Disable the lock file scanning // Disable the lock file scanning
opt.DisabledAnalyzers = analyzer.TypeLockfiles opt.DisabledAnalyzers = analyzer.TypeLockfiles
@@ -136,24 +153,24 @@ func (r *Runner) ScanImage(ctx context.Context, opt Option) (types.Report, error
s = imageRemoteScanner s = imageRemoteScanner
} }
return r.Scan(ctx, opt, s) return r.scan(ctx, opt, s)
} }
func (r *Runner) ScanFilesystem(ctx context.Context, opt Option) (types.Report, error) { func (r *runner) ScanFilesystem(ctx context.Context, opt Option) (types.Report, error) {
// Disable the individual package scanning // Disable the individual package scanning
opt.DisabledAnalyzers = append(opt.DisabledAnalyzers, analyzer.TypeIndividualPkgs...) opt.DisabledAnalyzers = append(opt.DisabledAnalyzers, analyzer.TypeIndividualPkgs...)
return r.scanFS(ctx, opt) return r.scanFS(ctx, opt)
} }
func (r *Runner) ScanRootfs(ctx context.Context, opt Option) (types.Report, error) { func (r *runner) ScanRootfs(ctx context.Context, opt Option) (types.Report, error) {
// Disable the lock file scanning // Disable the lock file scanning
opt.DisabledAnalyzers = append(opt.DisabledAnalyzers, analyzer.TypeLockfiles...) opt.DisabledAnalyzers = append(opt.DisabledAnalyzers, analyzer.TypeLockfiles...)
return r.scanFS(ctx, opt) return r.scanFS(ctx, opt)
} }
func (r *Runner) scanFS(ctx context.Context, opt Option) (types.Report, error) { func (r *runner) scanFS(ctx context.Context, opt Option) (types.Report, error) {
var s InitializeScanner var s InitializeScanner
if opt.RemoteAddr == "" { if opt.RemoteAddr == "" {
// Scan filesystem in standalone mode // Scan filesystem in standalone mode
@@ -163,20 +180,20 @@ func (r *Runner) scanFS(ctx context.Context, opt Option) (types.Report, error) {
s = filesystemRemoteScanner s = filesystemRemoteScanner
} }
return r.Scan(ctx, opt, s) return r.scan(ctx, opt, s)
} }
func (r *Runner) ScanRepository(ctx context.Context, opt Option) (types.Report, error) { func (r *runner) ScanRepository(ctx context.Context, opt Option) (types.Report, error) {
// Do not scan OS packages // Do not scan OS packages
opt.VulnType = []string{types.VulnTypeLibrary} opt.VulnType = []string{types.VulnTypeLibrary}
// Disable the OS analyzers and individual package analyzers // Disable the OS analyzers and individual package analyzers
opt.DisabledAnalyzers = append(analyzer.TypeIndividualPkgs, analyzer.TypeOSes...) opt.DisabledAnalyzers = append(analyzer.TypeIndividualPkgs, analyzer.TypeOSes...)
return r.Scan(ctx, opt, repositoryStandaloneScanner) return r.scan(ctx, opt, repositoryStandaloneScanner)
} }
func (r *Runner) Scan(ctx context.Context, opt Option, initializeScanner InitializeScanner) (types.Report, error) { func (r *runner) scan(ctx context.Context, opt Option, initializeScanner InitializeScanner) (types.Report, error) {
report, err := scan(ctx, opt, initializeScanner, r.cache) report, err := scan(ctx, opt, initializeScanner, r.cache)
if err != nil { if err != nil {
return types.Report{}, xerrors.Errorf("scan error: %w", err) return types.Report{}, xerrors.Errorf("scan error: %w", err)
@@ -185,7 +202,7 @@ func (r *Runner) Scan(ctx context.Context, opt Option, initializeScanner Initial
return report, nil return report, nil
} }
func (r *Runner) Filter(ctx context.Context, opt Option, report types.Report) (types.Report, error) { func (r *runner) Filter(ctx context.Context, opt Option, report types.Report) (types.Report, error) {
resultClient := initializeResultClient() resultClient := initializeResultClient()
results := report.Results results := report.Results
for i := range results { for i := range results {
@@ -206,7 +223,7 @@ func (r *Runner) Filter(ctx context.Context, opt Option, report types.Report) (t
return report, nil return report, nil
} }
func (r *Runner) Report(opt Option, report types.Report) error { func (r *runner) Report(opt Option, report types.Report) error {
if err := pkgReport.Write(report, pkgReport.Option{ if err := pkgReport.Write(report, pkgReport.Option{
AppVersion: opt.GlobalOption.AppVersion, AppVersion: opt.GlobalOption.AppVersion,
Format: opt.Format, Format: opt.Format,
@@ -222,7 +239,7 @@ func (r *Runner) Report(opt Option, report types.Report) error {
return nil return nil
} }
func (r *Runner) initDB(c Option) error { func (r *runner) initDB(c Option) error {
// When scanning config files or running as client mode, it doesn't need to download the vulnerability database. // When scanning config files or running as client mode, it doesn't need to download the vulnerability database.
if c.RemoteAddr != "" || !slices.Contains(c.SecurityChecks, types.SecurityCheckVulnerability) { if c.RemoteAddr != "" || !slices.Contains(c.SecurityChecks, types.SecurityCheckVulnerability) {
return nil return nil
@@ -246,7 +263,7 @@ func (r *Runner) initDB(c Option) error {
return nil return nil
} }
func (r *Runner) initCache(c Option) error { func (r *runner) initCache(c Option) error {
// Skip initializing cache when custom cache is passed // Skip initializing cache when custom cache is passed
if r.cache != nil { if r.cache != nil {
return nil return nil

View File

@@ -17,7 +17,7 @@ import (
type scanner struct { type scanner struct {
cluster string cluster string
runner *cmd.Runner runner cmd.Runner
opt cmd.Option opt cmd.Option
} }