Skip to content

Commit

Permalink
feat(cli): parametrizing query execution timeout - closes #3047
Browse files Browse the repository at this point in the history
  • Loading branch information
rogeriopeixotocx committed Apr 29, 2021
1 parent bd4e347 commit 31318a2
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 45 deletions.
49 changes: 22 additions & 27 deletions internal/console/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ var (
queryPath string
reportFormats []string
types []string
queryExecTimeout int
)

const (
Expand Down Expand Up @@ -84,6 +85,7 @@ const (
scanCommandStr = "scan"
typeFlag = "type"
typeShorthand = "t"
queryExecTimeoutFlag = "timeout"
)

// NewScanCmd creates a new instance of the scan Command
Expand Down Expand Up @@ -223,19 +225,15 @@ func setBoundFlags(flagName string, val interface{}, cmd *cobra.Command) {

func initScanFlags(scanCmd *cobra.Command) {
scanCmd.Flags().StringSliceVarP(&path,
pathFlag,
pathFlagShorthand,
pathFlag, pathFlagShorthand,
[]string{},
"paths or directories to scan\nexample: \"./somepath,somefile.txt\"")
scanCmd.Flags().StringVarP(&cfgFile,
configFlag,
"",
"",
"", "",
"path to configuration file")
scanCmd.Flags().StringVarP(
&queryPath,
queriesPathCmdName,
queriesPathShorthand,
scanCmd.Flags().StringVarP(&queryPath,
queriesPathCmdName, queriesPathShorthand,
"./assets/queries",
"path to directory with queries",
)
Expand All @@ -256,36 +254,30 @@ func initScanFlags(scanCmd *cobra.Command) {
3,
"number of lines to be display in CLI results (min: 1, max: 30)")
scanCmd.Flags().StringVarP(&payloadPath,
payloadPathFlag,
payloadPathShorthand,
payloadPathFlag, payloadPathShorthand,
"",
"path to store internal representation JSON file")
scanCmd.Flags().StringSliceVarP(&excludePath,
excludePathsFlag,
excludePathsShorthand,
excludePathsFlag, excludePathsShorthand,
[]string{},
"exclude paths from scan\nsupports glob and can be provided multiple times or as a quoted comma separated string"+
"\nexample: './shouldNotScan/*,somefile.txt'",
)
scanCmd.Flags().BoolVarP(&min,
minimalUIFlag,
"",
minimalUIFlag, "",
false,
"simplified version of CLI output")
scanCmd.Flags().StringSliceVarP(&types,
typeFlag,
typeShorthand,
typeFlag, typeShorthand,
[]string{""},
"case insensitive list of platform types to scan\n"+
fmt.Sprintf("(%s)", strings.Join(source.ListSupportedPlatforms(), ", ")))
scanCmd.Flags().BoolVarP(&noProgress,
noProgressFlag,
"",
noProgressFlag, "",
false,
"hides the progress bar")
scanCmd.Flags().StringSliceVarP(&excludeIDs,
excludeQueriesFlag,
"",
excludeQueriesFlag, "",
[]string{},
"exclude queries by providing the query ID\n"+
"can be provided multiple times or as a comma separated string\n"+
Expand All @@ -300,28 +292,29 @@ func initScanFlags(scanCmd *cobra.Command) {
"example: 'fec62a97d569662093dbb9739360942f...,31263s5696620s93dbb973d9360942fc2a...'",
)
scanCmd.Flags().StringSliceVarP(&excludeCategories,
excludeCategoriesFlag,
"",
excludeCategoriesFlag, "",
[]string{},
"exclude categories by providing its name\n"+
"can be provided multiple times or as a comma separated string\n"+
"example: 'Access control,Best practices'",
)
scanCmd.Flags().StringSliceVarP(&failOn,
failOnFlag,
"",
failOnFlag, "",
[]string{"high", "medium", "low", "info"},
"which kind of results should return an exit code different from 0\n"+
"accetps: high, medium, low and info\n"+
"example: \"high,low\"",
)
scanCmd.Flags().StringVarP(&ignoreOnExit,
ignoreOnExitFlag,
"",
ignoreOnExitFlag, "",
"none",
"defines which kind of non-zero exits code should be ignored\n"+"accepts: all, results, errors, none\n"+
"example: if 'results' is set, only engine errors will make KICS exit code different from 0",
)
scanCmd.Flags().IntVarP(&queryExecTimeout,
queryExecTimeoutFlag, "",
60,
"number of seconds the query has to execute before being canceled")
}

func initScanCmd(scanCmd *cobra.Command) {
Expand Down Expand Up @@ -374,7 +367,9 @@ func createInspector(t engine.Tracker, querySource source.QueriesSource) (*engin
ByCategories: excludeCategories,
}

inspector, err := engine.NewInspector(ctx, querySource, engine.DefaultVulnerabilityBuilder, t, excludeQueries, excludeResultsMap)
inspector, err := engine.NewInspector(ctx,
querySource, engine.DefaultVulnerabilityBuilder,
t, excludeQueries, excludeResultsMap, queryExecTimeout)
if err != nil {
return nil, err
}
Expand Down
27 changes: 17 additions & 10 deletions pkg/engine/inspector.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,9 @@ type Inspector struct {
excludeResults map[string]bool
detector *detector.DetectLine

enableCoverageReport bool
coverageReport cover.Report
enableCoverageReport bool
coverageReport cover.Report
queryExecTimeoutSeconds time.Duration
}

// QueryContext contains the context where the query is executed, which scan it belongs, basic information of query,
Expand Down Expand Up @@ -104,7 +105,8 @@ func NewInspector(
vb VulnerabilityBuilder,
tracker Tracker,
excludeQueries source.ExcludeQueries,
excludeResults map[string]bool) (*Inspector, error) {
excludeResults map[string]bool,
queryTimeout int) (*Inspector, error) {
log.Debug().Msg("engine.NewInspector()")

metrics.Metric.Start("get_queries")
Expand Down Expand Up @@ -170,13 +172,17 @@ func NewInspector(
Add(helm.DetectKindLine{}, model.KindHELM).
Add(docker.DetectKindLine{}, model.KindDOCKER)

queryExecTimeout := time.Duration(queryTimeout) * time.Second
log.Info().Msgf("Query execution timeout=%v", queryExecTimeout)

return &Inspector{
queries: opaQueries,
vb: vb,
tracker: tracker,
failedQueries: failedQueries,
excludeResults: excludeResults,
detector: lineDetctor,
queries: opaQueries,
vb: vb,
tracker: tracker,
failedQueries: failedQueries,
excludeResults: excludeResults,
detector: lineDetctor,
queryExecTimeoutSeconds: queryExecTimeout,
}, nil
}

Expand Down Expand Up @@ -267,7 +273,8 @@ func (c *Inspector) GetFailedQueries() map[string]error {
}

func (c *Inspector) doRun(ctx *QueryContext) ([]model.Vulnerability, error) {
timeoutCtx, cancel := context.WithTimeout(ctx.ctx, executeTimeout)

timeoutCtx, cancel := context.WithTimeout(ctx.ctx, c.queryExecTimeoutSeconds)
defer cancel()

options := []rego.EvalOption{rego.EvalInput(ctx.payload)}
Expand Down
25 changes: 17 additions & 8 deletions pkg/engine/inspector_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -348,12 +348,13 @@ func TestNewInspector(t *testing.T) { // nolint
},
})
type args struct {
ctx context.Context
source source.QueriesSource
vb VulnerabilityBuilder
tracker Tracker
excludeQueries source.ExcludeQueries
excludeResults map[string]bool
ctx context.Context
source source.QueriesSource
vb VulnerabilityBuilder
tracker Tracker
excludeQueries source.ExcludeQueries
excludeResults map[string]bool
queryExecTimeout int
}
tests := []struct {
name string
Expand All @@ -372,7 +373,8 @@ func TestNewInspector(t *testing.T) { // nolint
ByIDs: []string{},
ByCategories: []string{},
},
excludeResults: map[string]bool{},
excludeResults: map[string]bool{},
queryExecTimeout: 60,
},
want: &Inspector{
vb: vbs,
Expand All @@ -384,7 +386,14 @@ func TestNewInspector(t *testing.T) { // nolint
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := NewInspector(tt.args.ctx, tt.args.source, tt.args.vb, tt.args.tracker, tt.args.excludeQueries, tt.args.excludeResults)
got, err := NewInspector(tt.args.ctx,
tt.args.source,
tt.args.vb,
tt.args.tracker,
tt.args.excludeQueries,
tt.args.excludeResults,
tt.args.queryExecTimeout)

if (err != nil) != tt.wantErr {
t.Errorf("NewInspector() error: got = %v,\n wantErr = %v", err, tt.wantErr)
return
Expand Down

0 comments on commit 31318a2

Please sign in to comment.