Add the queries-path flag to the scanner binary#205
Conversation
This stack of pull requests is managed by Graphite. Learn more about stacking. |
|
🎯 Code Coverage (details) 🔗 Commit SHA: 2510df1 | Docs | Datadog PR Page | Give us feedback! |
09919ca to
fced47c
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fced47cbb6
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| queriesPath := c.StringSlice("queries-path") | ||
| changedDefaultQueryPath := len(queriesPath) > 0 | ||
| if !changedDefaultQueryPath { | ||
| queriesPath = []string{"./assets/queries"} | ||
| } |
There was a problem hiding this comment.
Validate custom query paths before disabling defaults
When a user supplies -q with a mistyped or empty directory, this marks the scan as using a custom ruleset and later causes createQuerySource to bypass the Datadog rule source. The filesystem loader only logs missing/unreadable query paths and returns an empty query list, so the scan can complete with zero rules and no findings instead of failing. Please validate the supplied paths or fail when no local queries are discovered for a custom queries-path.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Just updated the branch to fix this. The scan will now fail in (one of) the provided path(s) is invalid or not a directory
c1a0cdc to
ab97dfd
Compare
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ab97dfd288
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| var dirs []string | ||
| for _, src := range s.Source { | ||
| entries, err := os.ReadDir(src) | ||
| err := filepath.WalkDir(src, func(path string, d os.DirEntry, err error) error { |
There was a problem hiding this comment.
Follow symlinked query directories
When --queries-path points at a symlink to a directory, scan.go accepts it because os.Stat follows the symlink, but filepath.WalkDir does not follow symlinks and reports the root entry as non-directory. In that scenario no local rule directories are discovered, so the scan can proceed with zero custom queries and produce a false clean result; resolve the source path or handle a symlinked root before walking it.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
As we discussed on slack, should fix
whitemerch
left a comment
There was a problem hiding this comment.
It might be worth it overall some tests, either a table-driven test like in scan_test.go (or an E2E fixture similar to test/e2e/e2e_test.go) covering at least: valid dir, non-existent path, path-is-a-file, and symlink-to-dir. It's exhaustive, feel free to add more test gaps, but that's what code coverage is made for here, which is to make you assess if the changes you are introducing are safe enough
There was a problem hiding this comment.
--queries-path paths are not resolved to absolute paths, which is wrong.
Maybe you could do like the other params, and do something like:
queriesPath, err = getAbsolutePaths(queriesPath) if err != nil { return errorWithExitCode(fmt.Errorf("invalid queries path: %w", err), constants.InvalidConfigErrorCode) }
| datadog-iac-scanner scan -p REPODIR -o OUTPUTDIR -q QUERYDIR | ||
| ``` | ||
| The rule directories in the QUERYDIR directory must contain a 'query.rego' and a 'metadata.json' file. You can also specify multiple paths: | ||
| ```bash |
There was a problem hiding this comment.
There should be a blank line between the paragraph and the fence
| var dirs []string | ||
| for _, src := range s.Source { | ||
| entries, err := os.ReadDir(src) | ||
| err := filepath.WalkDir(src, func(path string, d os.DirEntry, err error) error { |
There was a problem hiding this comment.
As we discussed on slack, should fix
ab97dfd to
8637be8
Compare
| evaluated, err := filepath.EvalSymlinks(src) | ||
| if err != nil { | ||
| contextLogger.Debug().Msgf("localQueryDirs: skipping %s: %v", src, err) | ||
| continue |
There was a problem hiding this comment.
This part puzzled me. Apparently we used to just skip a directory if the path was invalid. To me, it makes more sense to stop there instead of just ignoring the directory, so I changed this part. Lmk if I should revert this
There was a problem hiding this comment.
With return nil, if you do -q path1 -q path2 and path1 fails EvalSymlinks, you lose all queries from path2 with no error propagated upward. That's the worst of both worlds: it silently drops valid sources without telling the caller anything failed
8637be8 to
fd6d7a5
Compare
| changedDefaultQueryPath := len(queriesPath) > 0 | ||
| if !changedDefaultQueryPath { | ||
| queriesPath = []string{"./assets/queries"} | ||
| } |
There was a problem hiding this comment.
validateQueriesPaths already calls getAbsolutePaths, then os.Stat on each result, then checks IsDir. The block immediately after in runScan repeats exactly those two checks on the already-validated queriesPath slice, so you are basically performing a second dead loop
| queriesPath := c.StringSlice("queries-path") | ||
| queriesPath, err = validateQueriesPaths(queriesPath) | ||
| if err != nil { | ||
| return errorWithExitCode(fmt.Errorf("invalid queries path %q", err), constants.InvalidConfigErrorCode) |
There was a problem hiding this comment.
err here is the error value returned by validateQueriesPaths, not a path string. %q formats its argument as a quoted Go string literal, so this would produce something like invalid queries path "invalid queries path "/some/path"", quoting the inner error message rather than wrapping it
| evaluated, err := filepath.EvalSymlinks(src) | ||
| if err != nil { | ||
| contextLogger.Debug().Msgf("localQueryDirs: skipping %s: %v", src, err) | ||
| continue |
There was a problem hiding this comment.
With return nil, if you do -q path1 -q path2 and path1 fails EvalSymlinks, you lose all queries from path2 with no error propagated upward. That's the worst of both worlds: it silently drops valid sources without telling the caller anything failed
| if err != nil { | ||
| contextLogger.Debug().Msgf("localQueryDirs: skipping %s: %v", src, err) | ||
| continue | ||
| contextLogger.Debug().Msgf("localQueryDirs: error evaluting %s: %v", src, err) |
There was a problem hiding this comment.
evaluating, not evaluting
| assert.True(t, filepath.IsAbs(got[0])) | ||
| }) | ||
| } | ||
| } |
There was a problem hiding this comment.
Missing newline at EOF, and there is an error on the diff actually
| } | ||
| } | ||
|
|
||
|
|
There was a problem hiding this comment.
nit: keep it one line in between the func, it's the convention
fb2dff3 to
39aba83
Compare
whitemerch
left a comment
There was a problem hiding this comment.
We are almost there!
An existing but empty --queries-path disables default Datadog rules and completes successfully with zero rules. I reproduced this locally with scanner, it exited 0 with 0 rules found 0 violations. That can create false-clean scans when users point at the wrong directory or an empty checkout. Maybe the custom path flow should fail when discovery finds no valid rule directories
|
|
||
| source := NewFilesystemSource(ctx, src, []string{""}, []string{""}, "", true) | ||
|
|
||
| got, _ := source.localQueryDirs(ctx) |
There was a problem hiding this comment.
The new localQueryDirs tests discard the returned error, so invalid-path and mixed-path cases don’t actually assert the error propagation this PR relies on. Add wantErr assertions, ideally through GetQueries if you want to lock public behavior
39aba83 to
da03d70
Compare
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: da03d709ed
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| QueriesPath: queriesPath, | ||
| ChangedDefaultQueryPath: changedDefaultQueryPath, | ||
| LibrariesPath: "./assets/libraries", | ||
| ReportFormats: []string{"sarif"}, | ||
| Platform: selectPlatforms(c.StringSlice("type")), |
There was a problem hiding this comment.
Preserve custom platforms when using local queries
When -q points at local rules whose metadata platform is supported by the engine but is not in pkg/platforms.Supported (for example OpenAPI, Pulumi, Buildah, or AzureResourceManager), the platform list here still goes through selectPlatforms, which intersects with only the published Datadog platform list and drops those values even if the user passes -t OpenAPI. Because ChangedDefaultQueryPath then switches the scan to FilesystemSource, those local rules are never loaded/scanned; preserve raw custom platform values or use the full parser/source platform set when local queries are selected.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Thoughts on this @whitemerch ? Not sure this is relevant. It's not really in the scope of this PR, but we could use it to decide if we want to gate the platforms to only the ones WE support, or if we want to allow for arbitrary platform. I'd personally choose the former, but I'm not sure
💡 Codex Reviewdatadog-iac-scanner/cmd/scanner/scan.go Lines 209 to 213 in da03d70 When ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
This allows the user to choose a local query repository to test their own rules.
da03d70 to
f4324d9
Compare
Change the createServices function to point to a directory containing queries. The localQueryDirs function now returns an error if no queries directory is found. Remove a capital letter from an error message Create custom error in localQueryDirs so that tests are not susceptible to os differences.
05001e3 to
2510df1
Compare

Motivation
This PR allows the user to define a local directory from which the IaC rules are fetched. This is useful for testing purposes when changing the rules.
Changes
Author Checklist
QA Instruction
Blast Radius
This change impacts the query fetching of the IaC scanner
Additional Notes
If you need to share anything else along with your PR, please do it here.
I submit this contribution under the Apache-2.0 license.