Skip to content

Commit

Permalink
Add -p flag to allow panics in checks (#864)
Browse files Browse the repository at this point in the history
  • Loading branch information
liamg committed Jul 13, 2021
1 parent 44fe4bc commit 490358b
Show file tree
Hide file tree
Showing 7 changed files with 31 additions and 16 deletions.
4 changes: 4 additions & 0 deletions cmd/tfsec/main.go
Expand Up @@ -52,6 +52,7 @@ var ignoreInfo = false
var allDirs = false
var runStatistics bool
var ignoreHCLErrors bool
var stopOnCheckError bool

func init() {
rootCmd.Flags().BoolVar(&ignoreHCLErrors, "ignore-hcl-errors", ignoreHCLErrors, "Stop and report an error if an HCL parse error is encountered")
Expand All @@ -77,6 +78,7 @@ func init() {
rootCmd.Flags().BoolVar(&runStatistics, "run-statistics", runStatistics, "View statistics table of current findings.")
rootCmd.Flags().BoolVar(&ignoreWarnings, "ignore-warnings", ignoreWarnings, "Don't show warnings in the output.")
rootCmd.Flags().BoolVar(&ignoreInfo, "ignore-info", ignoreWarnings, "Don't show info results in the output.")
rootCmd.Flags().BoolVarP(&stopOnCheckError, "allow-checks-to-panic", "p", stopOnCheckError, "Allow panics to propagate up from rule checking")
}

func main() {
Expand Down Expand Up @@ -341,6 +343,8 @@ func getScannerOptions() []scanner.Option {
options = append(options, scanner.OptionIncludeIgnored())
}

options = append(options, scanner.OptionIgnoreCheckErrors(!stopOnCheckError))

var allExcludedRuleIDs []string
for _, exclude := range strings.Split(excludedRuleIDs, ",") {
allExcludedRuleIDs = append(allExcludedRuleIDs, strings.TrimSpace(exclude))
Expand Down
2 changes: 1 addition & 1 deletion internal/app/tfsec/custom/processing_test.go
Expand Up @@ -328,7 +328,7 @@ func scanTerraform(t *testing.T, mainTf string) []result.Result {
blocks, err := parser.New(dirName, parser.OptionStopOnHCLError()).ParseDirectory()
assert.NoError(t, err)

return scanner.New().Scan(blocks)
return scanner.New(scanner.OptionIgnoreCheckErrors(false)).Scan(blocks)
}

// This function is copied from setup_test.go as it is not possible to import function from test files.
Expand Down
6 changes: 6 additions & 0 deletions internal/app/tfsec/scanner/option.go
Expand Up @@ -19,3 +19,9 @@ func OptionExcludeRules(ruleIDs []string) func(s *Scanner) {
s.excludedRuleIDs = ruleIDs
}
}

func OptionIgnoreCheckErrors(ignore bool) func(s *Scanner) {
return func(s *Scanner) {
s.ignoreCheckErrors = ignore
}
}
13 changes: 8 additions & 5 deletions internal/app/tfsec/scanner/scanner.go
Expand Up @@ -21,14 +21,17 @@ import (

// Scanner scans HCL blocks by running all registered rules against them
type Scanner struct {
includePassed bool
includeIgnored bool
excludedRuleIDs []string
includePassed bool
includeIgnored bool
excludedRuleIDs []string
ignoreCheckErrors bool
}

// New creates a new Scanner
func New(options ...Option) *Scanner {
s := &Scanner{}
s := &Scanner{
ignoreCheckErrors: true,
}
for _, option := range options {
option(s)
}
Expand Down Expand Up @@ -62,7 +65,7 @@ func (scanner *Scanner) Scan(blocks []block.Block) []result.Result {
func(r *rule.Rule) {
if rule.IsRuleRequiredForBlock(r, checkBlock) {
debug.Log("Running rule for %s on %s.%s (%s)...", r.ID, checkBlock.Type(), checkBlock.FullName(), checkBlock.Range().Filename)
ruleResults := rule.CheckRule(r, checkBlock, context)
ruleResults := rule.CheckRule(r, checkBlock, context, scanner.ignoreCheckErrors)
if scanner.includePassed && ruleResults.All() == nil {
res := result.New(checkBlock).
WithRuleID(r.ID).
Expand Down
2 changes: 1 addition & 1 deletion internal/app/tfsec/test/module_scan_test.go
Expand Up @@ -39,7 +39,7 @@ resource "problem" "uhoh" {
if err != nil {
t.Fatal(err)
}
results := scanner.New(scanner.OptionExcludeRules(excludedChecksList)).Scan(blocks)
results := scanner.New(scanner.OptionExcludeRules(excludedChecksList), scanner.OptionIgnoreCheckErrors(false)).Scan(blocks)
assertCheckCode(t, test.mustIncludeResultCode, test.mustExcludeResultCode, results)
})
}
Expand Down
4 changes: 2 additions & 2 deletions internal/app/tfsec/test/setup_test.go
Expand Up @@ -64,12 +64,12 @@ resource "problem" "x" {

func scanHCL(source string, t *testing.T) []result.Result {
blocks := createBlocksFromSource(source, ".tf", t)
return scanner.New(scanner.OptionExcludeRules(excludedChecksList)).Scan(blocks)
return scanner.New(scanner.OptionExcludeRules(excludedChecksList), scanner.OptionIgnoreCheckErrors(false)).Scan(blocks)
}

func scanJSON(source string, t *testing.T) []result.Result {
blocks := createBlocksFromSource(source, ".tf.json", t)
return scanner.New(scanner.OptionExcludeRules(excludedChecksList)).Scan(blocks)
return scanner.New(scanner.OptionExcludeRules(excludedChecksList), scanner.OptionIgnoreCheckErrors(false)).Scan(blocks)
}

func createBlocksFromSource(source string, ext string, t *testing.T) []block.Block {
Expand Down
16 changes: 9 additions & 7 deletions pkg/rule/check.go
Expand Up @@ -17,13 +17,15 @@ import (
)

// CheckRule the provided HCL block against the rule
func CheckRule(r *Rule, block block.Block, ctx *hclcontext.Context) result.Set {
defer func() {
if err := recover(); err != nil {
_, _ = fmt.Fprintf(os.Stderr, "WARNING: skipped %s due to error(s): %s\n", r.ID, err)
debug.Log("Stack trace for failed %s r:\n%s\n\n", r.ID, string(runtimeDebug.Stack()))
}
}()
func CheckRule(r *Rule, block block.Block, ctx *hclcontext.Context, ignoreErrors bool) result.Set {
if ignoreErrors {
defer func() {
if err := recover(); err != nil {
_, _ = fmt.Fprintf(os.Stderr, "WARNING: skipped %s due to error(s): %s\n", r.ID, err)
debug.Log("Stack trace for failed %s r:\n%s\n\n", r.ID, string(runtimeDebug.Stack()))
}
}()
}

var links []string

Expand Down

0 comments on commit 490358b

Please sign in to comment.