Skip to content

Commit 0e5e909

Browse files
authored
perf(misconf): parse input for Rego once (#8483)
Signed-off-by: nikpivkin <[email protected]>
1 parent 529957e commit 0e5e909

File tree

1 file changed

+20
-11
lines changed

1 file changed

+20
-11
lines changed

pkg/iac/rego/scanner.go

+20-11
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"github.com/open-policy-agent/opa/rego"
1414
"github.com/open-policy-agent/opa/storage"
1515
"github.com/open-policy-agent/opa/util"
16+
"github.com/samber/lo"
1617

1718
"github.com/aquasecurity/trivy/pkg/iac/framework"
1819
"github.com/aquasecurity/trivy/pkg/iac/providers"
@@ -145,6 +146,9 @@ type Input struct {
145146
Path string `json:"path"`
146147
FS fs.FS `json:"-"`
147148
Contents any `json:"contents"`
149+
150+
// parsed is the parsed input value for the rego query
151+
parsed ast.Value
148152
}
149153

150154
func GetInputsContents(inputs []Input) []any {
@@ -159,6 +163,21 @@ func (s *Scanner) ScanInput(ctx context.Context, sourceType types.Source, inputs
159163

160164
s.logger.Debug("Scanning inputs", "count", len(inputs))
161165

166+
if len(inputs) == 0 {
167+
return nil, nil
168+
}
169+
170+
inputs = lo.FilterMap(inputs, func(input Input, _ int) (Input, bool) {
171+
s.trace("INPUT", input)
172+
parsed, err := parseRawInput(input.Contents)
173+
if err != nil {
174+
s.logger.Error("Failed to parse input", log.FilePath(input.Path), log.Err(err))
175+
return input, false
176+
}
177+
input.parsed = parsed
178+
return input, true
179+
})
180+
162181
var results scan.Results
163182

164183
for _, module := range s.policies {
@@ -194,10 +213,6 @@ func (s *Scanner) ScanInput(ctx context.Context, sourceType types.Source, inputs
194213
continue
195214
}
196215

197-
if len(inputs) == 0 {
198-
continue
199-
}
200-
201216
usedRules := set.New[string]()
202217

203218
// all rules
@@ -302,14 +317,8 @@ func (s *Scanner) applyRule(ctx context.Context, namespace, rule string, inputs
302317
var results scan.Results
303318
qualified := fmt.Sprintf("data.%s.%s", namespace, rule)
304319
for _, input := range inputs {
305-
s.trace("INPUT", input)
306-
parsedInput, err := parseRawInput(input.Contents)
307-
if err != nil {
308-
s.logger.Error("Error occurred while parsing input", log.Err(err))
309-
continue
310-
}
311320

312-
resultSet, traces, err := s.runQuery(ctx, qualified, parsedInput, false)
321+
resultSet, traces, err := s.runQuery(ctx, qualified, input.parsed, false)
313322
if err != nil {
314323
return nil, err
315324
}

0 commit comments

Comments
 (0)