Skip to content

Commit

Permalink
refactor(terraform): remove unused options (aquasecurity#6446)
Browse files Browse the repository at this point in the history
  • Loading branch information
nikpivkin authored Apr 4, 2024
1 parent 8e4279b commit 6bca7c3
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 447 deletions.
111 changes: 23 additions & 88 deletions pkg/iac/scanners/terraform/executor/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,52 +14,31 @@ import (
"github.com/aquasecurity/trivy/pkg/iac/rego"
"github.com/aquasecurity/trivy/pkg/iac/rules"
"github.com/aquasecurity/trivy/pkg/iac/scan"
"github.com/aquasecurity/trivy/pkg/iac/severity"
"github.com/aquasecurity/trivy/pkg/iac/state"
"github.com/aquasecurity/trivy/pkg/iac/terraform"
"github.com/aquasecurity/trivy/pkg/iac/types"
)

// Executor scans HCL blocks by running all registered rules against them
type Executor struct {
enableIgnores bool
excludedRuleIDs []string
includedRuleIDs []string
ignoreCheckErrors bool
workspaceName string
useSingleThread bool
debug debug.Logger
resultsFilters []func(scan.Results) scan.Results
severityOverrides map[string]string
regoScanner *rego.Scanner
regoOnly bool
stateFuncs []func(*state.State)
frameworks []framework.Framework
workspaceName string
debug debug.Logger
resultsFilters []func(scan.Results) scan.Results
regoScanner *rego.Scanner
regoOnly bool
frameworks []framework.Framework
}

// New creates a new Executor
func New(options ...Option) *Executor {
s := &Executor{
ignoreCheckErrors: true,
enableIgnores: true,
regoOnly: false,
regoOnly: false,
}
for _, option := range options {
option(s)
}
return s
}

// Find element in list
func checkInList(id string, list []string) bool {
for _, codeIgnored := range list {
if codeIgnored == id {
return true
}
}
return false
}

func (e *Executor) Execute(modules terraform.Modules) (scan.Results, error) {

e.debug.Log("Adapting modules...")
Expand All @@ -70,90 +49,46 @@ func (e *Executor) Execute(modules terraform.Modules) (scan.Results, error) {
if threads > 1 {
threads--
}
if e.useSingleThread {
threads = 1
}
e.debug.Log("Using max routines of %d", threads)

e.debug.Log("Applying state modifier functions...")
for _, f := range e.stateFuncs {
f(infra)
}
e.debug.Log("Using max routines of %d", threads)

registeredRules := rules.GetRegistered(e.frameworks...)
e.debug.Log("Initialized %d rule(s).", len(registeredRules))

pool := NewPool(threads, registeredRules, modules, infra, e.ignoreCheckErrors, e.regoScanner, e.regoOnly)
pool := NewPool(threads, registeredRules, modules, infra, e.regoScanner, e.regoOnly)
e.debug.Log("Created pool with %d worker(s) to apply rules.", threads)

results, err := pool.Run()
if err != nil {
return nil, err
}
e.debug.Log("Finished applying rules.")

if e.enableIgnores {
e.debug.Log("Applying ignores...")
var ignores ignore.Rules
for _, module := range modules {
ignores = append(ignores, module.Ignores()...)
}
e.debug.Log("Finished applying rules.")

ignorers := map[string]ignore.Ignorer{
"ws": workspaceIgnorer(e.workspaceName),
"ignore": attributeIgnorer(modules),
}
e.debug.Log("Applying ignores...")
var ignores ignore.Rules
for _, module := range modules {
ignores = append(ignores, module.Ignores()...)
}

results.Ignore(ignores, ignorers)
ignorers := map[string]ignore.Ignorer{
"ws": workspaceIgnorer(e.workspaceName),
"ignore": attributeIgnorer(modules),
}

for _, ignored := range results.GetIgnored() {
e.debug.Log("Ignored '%s' at '%s'.", ignored.Rule().LongID(), ignored.Range())
}
results.Ignore(ignores, ignorers)

} else {
e.debug.Log("Ignores are disabled.")
for _, ignored := range results.GetIgnored() {
e.debug.Log("Ignored '%s' at '%s'.", ignored.Rule().LongID(), ignored.Range())
}

results = e.updateSeverity(results)
results = e.filterResults(results)

e.sortResults(results)
return results, nil
}

func (e *Executor) updateSeverity(results []scan.Result) scan.Results {
if len(e.severityOverrides) == 0 {
return results
}

var overriddenResults scan.Results
for _, res := range results {
for code, sev := range e.severityOverrides {
if res.Rule().LongID() != code {
continue
}

overrides := scan.Results([]scan.Result{res})
override := res.Rule()
override.Severity = severity.Severity(sev)
overrides.SetRule(override)
res = overrides[0]
}
overriddenResults = append(overriddenResults, res)
}

return overriddenResults
}

func (e *Executor) filterResults(results scan.Results) scan.Results {
includedOnly := len(e.includedRuleIDs) > 0
for i, result := range results {
id := result.Rule().LongID()
if (includedOnly && !checkInList(id, e.includedRuleIDs)) || checkInList(id, e.excludedRuleIDs) {
e.debug.Log("Excluding '%s' at '%s'.", result.Rule().LongID(), result.Range())
results[i].OverrideStatus(scan.StatusIgnored)
}
}

if len(e.resultsFilters) > 0 && len(results) > 0 {
before := len(results.GetIgnored())
e.debug.Log("Applying %d results filters to %d results...", len(results), before)
Expand Down
5 changes: 2 additions & 3 deletions pkg/iac/scanners/terraform/executor/executor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,7 @@ resource "problem" "this" {

modules, _, err := p.EvaluateAll(context.TODO())
require.NoError(t, err)

_, err = New(OptionStopOnErrors(false)).Execute(modules)
_, err = New().Execute(modules)
assert.Error(t, err)
}

Expand Down Expand Up @@ -127,6 +126,6 @@ resource "problem" "this" {
modules, _, err := p.EvaluateAll(context.TODO())
require.NoError(t, err)

_, err = New(OptionStopOnErrors(false)).Execute(modules)
_, err = New().Execute(modules)
assert.Error(t, err)
}
43 changes: 0 additions & 43 deletions pkg/iac/scanners/terraform/executor/option.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"github.com/aquasecurity/trivy/pkg/iac/framework"
"github.com/aquasecurity/trivy/pkg/iac/rego"
"github.com/aquasecurity/trivy/pkg/iac/scan"
"github.com/aquasecurity/trivy/pkg/iac/state"
)

type Option func(s *Executor)
Expand All @@ -24,66 +23,24 @@ func OptionWithResultsFilter(f func(scan.Results) scan.Results) Option {
}
}

func OptionWithSeverityOverrides(overrides map[string]string) Option {
return func(s *Executor) {
s.severityOverrides = overrides
}
}

func OptionWithDebugWriter(w io.Writer) Option {
return func(s *Executor) {
s.debug = debug.New(w, "terraform", "executor")
}
}

func OptionNoIgnores() Option {
return func(s *Executor) {
s.enableIgnores = false
}
}

func OptionExcludeRules(ruleIDs []string) Option {
return func(s *Executor) {
s.excludedRuleIDs = ruleIDs
}
}

func OptionIncludeRules(ruleIDs []string) Option {
return func(s *Executor) {
s.includedRuleIDs = ruleIDs
}
}

func OptionStopOnErrors(stop bool) Option {
return func(s *Executor) {
s.ignoreCheckErrors = !stop
}
}

func OptionWithWorkspaceName(workspaceName string) Option {
return func(s *Executor) {
s.workspaceName = workspaceName
}
}

func OptionWithSingleThread(single bool) Option {
return func(s *Executor) {
s.useSingleThread = single
}
}

func OptionWithRegoScanner(s *rego.Scanner) Option {
return func(e *Executor) {
e.regoScanner = s
}
}

func OptionWithStateFunc(f ...func(*state.State)) Option {
return func(e *Executor) {
e.stateFuncs = f
}
}

func OptionWithRegoOnly(regoOnly bool) Option {
return func(e *Executor) {
e.regoOnly = regoOnly
Expand Down
70 changes: 30 additions & 40 deletions pkg/iac/scanners/terraform/executor/pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,22 @@ import (
)

type Pool struct {
size int
modules terraform.Modules
state *state.State
rules []types.RegisteredRule
ignoreErrors bool
rs *rego.Scanner
regoOnly bool
size int
modules terraform.Modules
state *state.State
rules []types.RegisteredRule
rs *rego.Scanner
regoOnly bool
}

func NewPool(size int, rules []types.RegisteredRule, modules terraform.Modules, st *state.State, ignoreErrors bool, regoScanner *rego.Scanner, regoOnly bool) *Pool {
func NewPool(size int, rules []types.RegisteredRule, modules terraform.Modules, st *state.State, regoScanner *rego.Scanner, regoOnly bool) *Pool {
return &Pool{
size: size,
rules: rules,
state: st,
modules: modules,
ignoreErrors: ignoreErrors,
rs: regoScanner,
regoOnly: regoOnly,
size: size,
rules: rules,
state: st,
modules: modules,
rs: regoScanner,
regoOnly: regoOnly,
}
}

Expand Down Expand Up @@ -69,17 +67,15 @@ func (p *Pool) Run() (scan.Results, error) {
for _, module := range p.modules {
mod := *module
outgoing <- &hclModuleRuleJob{
module: &mod,
rule: r,
ignoreErrors: p.ignoreErrors,
module: &mod,
rule: r,
}
}
} else {
// run defsec rule
outgoing <- &infraRuleJob{
state: p.state,
rule: r,
ignoreErrors: p.ignoreErrors,
state: p.state,
rule: r,
}
}
}
Expand All @@ -105,14 +101,11 @@ type Job interface {
type infraRuleJob struct {
state *state.State
rule types.RegisteredRule

ignoreErrors bool
}

type hclModuleRuleJob struct {
module *terraform.Module
rule types.RegisteredRule
ignoreErrors bool
module *terraform.Module
rule types.RegisteredRule
}

type regoJob struct {
Expand All @@ -122,24 +115,21 @@ type regoJob struct {
}

func (h *infraRuleJob) Run() (_ scan.Results, err error) {
if h.ignoreErrors {
defer func() {
if panicErr := recover(); panicErr != nil {
err = fmt.Errorf("%s\n%s", panicErr, string(runtimeDebug.Stack()))
}
}()
}
defer func() {
if panicErr := recover(); panicErr != nil {
err = fmt.Errorf("%s\n%s", panicErr, string(runtimeDebug.Stack()))
}
}()

return h.rule.Evaluate(h.state), err
}

func (h *hclModuleRuleJob) Run() (results scan.Results, err error) {
if h.ignoreErrors {
defer func() {
if panicErr := recover(); panicErr != nil {
err = fmt.Errorf("%s\n%s", panicErr, string(runtimeDebug.Stack()))
}
}()
}
defer func() {
if panicErr := recover(); panicErr != nil {
err = fmt.Errorf("%s\n%s", panicErr, string(runtimeDebug.Stack()))
}
}()
customCheck := h.rule.GetRule().CustomChecks.Terraform
for _, block := range h.module.GetBlocks() {
if !isCustomCheckRequiredForBlock(customCheck, block) {
Expand Down
Loading

0 comments on commit 6bca7c3

Please sign in to comment.