Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(misconf): use slog #7295

Merged
merged 12 commits into from
Aug 23, 2024
1 change: 0 additions & 1 deletion pkg/commands/artifact/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -644,7 +644,6 @@ func initMisconfScannerOption(opts flag.Options) (misconf.ScannerOption, error)
}

return misconf.ScannerOption{
Debug: opts.Debug,
Trace: opts.Trace,
Namespaces: append(opts.CheckNamespaces, rego.BuiltinNamespaces()...),
PolicyPaths: append(opts.CheckPaths, downloadedPolicyPaths...),
Expand Down
38 changes: 0 additions & 38 deletions pkg/iac/debug/debug.go

This file was deleted.

39 changes: 26 additions & 13 deletions pkg/iac/rego/load.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (
"github.com/open-policy-agent/opa/ast"
"github.com/open-policy-agent/opa/bundle"
"github.com/samber/lo"

"github.com/aquasecurity/trivy/pkg/log"
)

var builtinNamespaces = map[string]struct{}{
Expand Down Expand Up @@ -61,14 +63,14 @@ func (s *Scanner) loadEmbedded() error {
return fmt.Errorf("failed to load embedded rego libraries: %w", err)
}
s.embeddedLibs = loaded
s.debug.Log("Loaded %d embedded libraries.", len(loaded))
s.logger.Debug("Embedded libraries are loaded", log.Int("count", len(loaded)))

loaded, err = LoadEmbeddedPolicies()
if err != nil {
return fmt.Errorf("failed to load embedded rego policies: %w", err)
return fmt.Errorf("failed to load embedded rego checks: %w", err)
}
s.embeddedChecks = loaded
s.debug.Log("Loaded %d embedded policies.", len(loaded))
s.logger.Debug("Embedded checks are loaded", log.Int("count", len(loaded)))

return nil
}
Expand All @@ -80,7 +82,7 @@ func (s *Scanner) LoadPolicies(enableEmbeddedLibraries, enableEmbeddedPolicies b
}

if s.policyFS != nil {
s.debug.Log("Overriding filesystem for checks!")
s.logger.Debug("Overriding filesystem for checks")
srcFS = s.policyFS
}

Expand All @@ -105,7 +107,7 @@ func (s *Scanner) LoadPolicies(enableEmbeddedLibraries, enableEmbeddedPolicies b
for name, policy := range loaded {
s.policies[name] = policy
}
s.debug.Log("Loaded %d checks from disk.", len(loaded))
s.logger.Debug("Checks from disk are loaded", log.Int("count", len(loaded)))
}

if len(readers) > 0 {
Expand All @@ -116,7 +118,7 @@ func (s *Scanner) LoadPolicies(enableEmbeddedLibraries, enableEmbeddedPolicies b
for name, policy := range loaded {
s.policies[name] = policy
}
s.debug.Log("Loaded %d checks from reader(s).", len(loaded))
s.logger.Debug("Checks from readers are loaded", log.Int("count", len(loaded)))
}

// gather namespaces
Expand All @@ -132,7 +134,7 @@ func (s *Scanner) LoadPolicies(enableEmbeddedLibraries, enableEmbeddedPolicies b

dataFS := srcFS
if s.dataFS != nil {
s.debug.Log("Overriding filesystem for data!")
s.logger.Debug("Overriding filesystem for data")
dataFS = s.dataFS
}
store, err := initStore(dataFS, s.dataDirs, namespaces)
Expand Down Expand Up @@ -168,15 +170,19 @@ func (s *Scanner) fallbackChecks(compiler *ast.Compiler) {
continue
}

s.debug.Log("Error occurred while parsing: %s, %s. Trying to fallback to embedded check.", loc, e.Error())
s.logger.Error(
"Error occurred while parsing. Trying to fallback to embedded check",
log.FilePath(loc),
log.Err(e),
)

embedded := s.findMatchedEmbeddedCheck(badPolicy)
if embedded == nil {
s.debug.Log("Failed to find embedded check: %s", loc)
s.logger.Error("Failed to find embedded check, skipping", log.FilePath(loc))
continue
}

s.debug.Log("Found embedded check: %s", embedded.Package.Location.File)
s.logger.Debug("Found embedded check", log.FilePath(embedded.Package.Location.File))
delete(s.policies, loc) // remove bad check
s.policies[embedded.Package.Location.File] = embedded
delete(s.embeddedChecks, embedded.Package.Location.File) // avoid infinite loop if embedded check contains ref error
Expand Down Expand Up @@ -214,15 +220,18 @@ func (s *Scanner) findMatchedEmbeddedCheck(badPolicy *ast.Module) *ast.Module {

func (s *Scanner) prunePoliciesWithError(compiler *ast.Compiler) error {
if len(compiler.Errors) > s.regoErrorLimit {
s.debug.Log("Error(s) occurred while loading checks")
s.logger.Error("Error(s) occurred while loading checks")
return compiler.Errors
}

for _, e := range compiler.Errors {
if e.Location == nil {
continue
}
s.debug.Log("Error occurred while parsing: %s, %s", e.Location.File, e.Error())
s.logger.Error(
"Error occurred while parsing",
log.FilePath(e.Location.File), log.Err(e),
)
delete(s.policies, e.Location.File)
}
return nil
Expand Down Expand Up @@ -282,7 +291,11 @@ func (s *Scanner) filterModules(retriever *MetadataRetriever) error {
return err
}
if len(meta.InputOptions.Selectors) == 0 {
s.debug.Log("WARNING: Module %s has no input selectors - it will be loaded for all inputs!", name)
s.logger.Warn(
"Module has no input selectors - it will be loaded for all inputs!",
log.FilePath(module.Package.Location.File),
log.String("module", name),
)
filtered[name] = module
continue
}
Expand Down
8 changes: 5 additions & 3 deletions pkg/iac/rego/load_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"embed"
"fmt"
"io"
"log/slog"
"strings"
"testing"
"testing/fstest"
Expand All @@ -17,6 +18,7 @@ import (
"github.com/aquasecurity/trivy/pkg/iac/rego"
"github.com/aquasecurity/trivy/pkg/iac/scanners/options"
"github.com/aquasecurity/trivy/pkg/iac/types"
"github.com/aquasecurity/trivy/pkg/log"
)

//go:embed all:testdata/policies
Expand All @@ -28,10 +30,10 @@ var embeddedChecksFS embed.FS
func Test_RegoScanning_WithSomeInvalidPolicies(t *testing.T) {
t.Run("allow no errors", func(t *testing.T) {
var debugBuf bytes.Buffer
slog.SetDefault(log.New(log.NewHandler(&debugBuf, nil)))
scanner := rego.NewScanner(
types.SourceDockerfile,
options.ScannerWithRegoErrorLimits(0),
options.ScannerWithDebug(&debugBuf),
)

err := scanner.LoadPolicies(false, false, testEmbedFS, []string{"."}, nil)
Expand All @@ -41,16 +43,16 @@ func Test_RegoScanning_WithSomeInvalidPolicies(t *testing.T) {

t.Run("allow up to max 1 error", func(t *testing.T) {
var debugBuf bytes.Buffer
slog.SetDefault(log.New(log.NewHandler(&debugBuf, nil)))
scanner := rego.NewScanner(
types.SourceDockerfile,
options.ScannerWithRegoErrorLimits(1),
options.ScannerWithDebug(&debugBuf),
)

err := scanner.LoadPolicies(false, false, testEmbedFS, []string{"."}, nil)
require.NoError(t, err)

assert.Contains(t, debugBuf.String(), "Error occurred while parsing: testdata/policies/invalid.rego, testdata/policies/invalid.rego:7")
assert.Contains(t, debugBuf.String(), "Error occurred while parsing\tfile_path=\"testdata/policies/invalid.rego\" err=\"testdata/policies/invalid.rego:7")
})

t.Run("schema does not exist", func(t *testing.T) {
Expand Down
34 changes: 16 additions & 18 deletions pkg/iac/rego/scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ import (
"github.com/open-policy-agent/opa/storage"
"github.com/open-policy-agent/opa/util"

"github.com/aquasecurity/trivy/pkg/iac/debug"
"github.com/aquasecurity/trivy/pkg/iac/framework"
"github.com/aquasecurity/trivy/pkg/iac/providers"
"github.com/aquasecurity/trivy/pkg/iac/rego/schemas"
"github.com/aquasecurity/trivy/pkg/iac/scan"
"github.com/aquasecurity/trivy/pkg/iac/scanners/options"
"github.com/aquasecurity/trivy/pkg/iac/types"
"github.com/aquasecurity/trivy/pkg/log"
)

var checkTypesWithSubtype = map[types.Source]struct{}{
Expand Down Expand Up @@ -51,7 +51,7 @@ type Scanner struct {
runtimeValues *ast.Term
compiler *ast.Compiler
regoErrorLimit int
debug debug.Logger
logger *log.Logger
traceWriter io.Writer
tracePerResult bool
retriever *MetadataRetriever
Expand Down Expand Up @@ -113,10 +113,6 @@ func (s *Scanner) SetPolicyReaders(_ []io.Reader) {
// NOTE: Policy readers option not applicable for rego, policies are loaded on-demand by other scanners.
}

func (s *Scanner) SetDebugWriter(writer io.Writer) {
s.debug = debug.New(writer, "rego", "scanner")
}

func (s *Scanner) SetTraceWriter(writer io.Writer) {
s.traceWriter = writer
}
Expand Down Expand Up @@ -166,6 +162,7 @@ func NewScanner(source types.Source, opts ...options.ScannerOption) *Scanner {
sourceType: source,
ruleNamespaces: make(map[string]struct{}),
runtimeValues: addRuntimeValues(),
logger: log.WithPrefix("rego"),
customSchemas: make(map[string][]byte),
}

Expand All @@ -183,10 +180,6 @@ func NewScanner(source types.Source, opts ...options.ScannerOption) *Scanner {
return s
}

func (s *Scanner) SetParentDebugLogger(l debug.Logger) {
s.debug = l.Extend("rego")
}

func (s *Scanner) runQuery(ctx context.Context, query string, input ast.Value, disableTracing bool) (rego.ResultSet, []string, error) {

trace := (s.traceWriter != nil || s.tracePerResult) && !disableTracing
Expand Down Expand Up @@ -247,7 +240,7 @@ func GetInputsContents(inputs []Input) []any {

func (s *Scanner) ScanInput(ctx context.Context, inputs ...Input) (scan.Results, error) {

s.debug.Log("Scanning %d inputs...", len(inputs))
s.logger.Debug("Scannning inputs", "count", len(inputs))

var results scan.Results

Expand All @@ -267,9 +260,11 @@ func (s *Scanner) ScanInput(ctx context.Context, inputs ...Input) (scan.Results,

staticMeta, err := s.retriever.RetrieveMetadata(ctx, module, GetInputsContents(inputs)...)
if err != nil {
s.debug.Log(
"Error occurred while retrieving metadata from check %q: %s",
module.Package.Location.File, err)
s.logger.Error(
"Error occurred while retrieving metadata from check",
log.FilePath(module.Package.Location.File),
log.Err(err),
)
continue
}

Expand Down Expand Up @@ -300,9 +295,12 @@ func (s *Scanner) ScanInput(ctx context.Context, inputs ...Input) (scan.Results,
if isEnforcedRule(ruleName) {
ruleResults, err := s.applyRule(ctx, namespace, ruleName, inputs, staticMeta.InputOptions.Combined)
if err != nil {
s.debug.Log(
"Error occurred while applying rule %q from check %q: %s",
ruleName, module.Package.Location.File, err)
s.logger.Error(
"Error occurred while applying rule from check",
log.String("rule", ruleName),
log.FilePath(module.Package.Location.File),
log.Err(err),
)
continue
}
results = append(results, s.embellishResultsWithRuleMetadata(ruleResults, *staticMeta)...)
Expand Down Expand Up @@ -390,7 +388,7 @@ func (s *Scanner) applyRule(ctx context.Context, namespace, rule string, inputs
s.trace("INPUT", input)
parsedInput, err := parseRawInput(input.Contents)
if err != nil {
s.debug.Log("Error occurred while parsing input: %s", err)
s.logger.Error("Error occurred while parsing input", log.Err(err))
continue
}
if ignored, err := s.isIgnored(ctx, namespace, rule, parsedInput); err != nil {
Expand Down
4 changes: 0 additions & 4 deletions pkg/iac/rego/scanner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -998,19 +998,15 @@ deny {
},
}

var buf bytes.Buffer
scanner := NewScanner(
types.SourceYAML,
options.ScannerWithDebug(&buf),
)
require.NoError(
t,
scanner.LoadPolicies(false, false, fsys, []string{"checks"}, nil),
)
_, err := scanner.ScanInput(context.TODO(), Input{})
require.NoError(t, err)
assert.Contains(t, buf.String(),
`Error occurred while applying rule "deny" from check "checks/bad.rego"`)
}

func Test_RegoScanning_WithDeprecatedCheck(t *testing.T) {
Expand Down
Loading