Skip to content

Commit

Permalink
✨ lint error when query is used both as check and data query
Browse files Browse the repository at this point in the history
Signed-off-by: Ivan Milchev <[email protected]>
  • Loading branch information
imilchev committed Jul 22, 2024
1 parent e03ced3 commit 28610de
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 0 deletions.
31 changes: 31 additions & 0 deletions internal/bundle/lint.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const (
queryTitle = "query-name"
queryUidUnique = "query-uid-unique"
queryUnassigned = "query-unassigned"
queryUsedAsDifferentTypes = "query-used-as-different-types"
)

type Rule struct {
Expand Down Expand Up @@ -229,6 +230,8 @@ func lintFile(file string) (*Results, error) {
// index global queries that are not embedded
globalQueriesUids := map[string]int{}
globalQueriesByUid := map[string]*Mquery{}
checks := map[string]struct{}{}
dataQueries := map[string]struct{}{}
// child to parent mapping
variantMapping := map[string]string{}
for i := range policyBundle.Queries {
Expand Down Expand Up @@ -419,6 +422,20 @@ func lintFile(file string) (*Results, error) {
// NOTE: embedded queries do not need a uid
lintQuery(check, file, globalQueriesUids, assignedQueries, variantMapping, false)
} else {
checks[uid] = struct{}{}
if _, ok := dataQueries[uid]; ok {
res.Entries = append(res.Entries, Entry{
RuleID: queryUsedAsDifferentTypes,
Message: fmt.Sprintf("query %s is used as a check and data query", uid),
Level: levelError,
Location: []Location{{
File: file,
Line: group.FileContext.Line,
Column: group.FileContext.Column,
}},
})
}

// if the query is not embedded, then it needs to be available globally
_, ok := globalQueriesUids[uid]
if !ok {
Expand Down Expand Up @@ -447,6 +464,20 @@ func lintFile(file string) (*Results, error) {
// NOTE: embedded queries do not need a uid
lintQuery(query, file, globalQueriesUids, assignedQueries, variantMapping, false)
} else {
dataQueries[uid] = struct{}{}
if _, ok := checks[uid]; ok {
res.Entries = append(res.Entries, Entry{
RuleID: queryUsedAsDifferentTypes,
Message: fmt.Sprintf("query %s is used as a check and data query", uid),
Level: levelError,
Location: []Location{{
File: file,
Line: group.FileContext.Line,
Column: group.FileContext.Column,
}},
})
}

// if the query is not embedded, then it needs to be available globally
_, ok := globalQueriesUids[uid]
if !ok {
Expand Down
14 changes: 14 additions & 0 deletions internal/bundle/lint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,17 @@ func TestLintFail(t *testing.T) {
require.NoError(t, err)
assert.True(t, len(data) > 0)
}

func TestLintFail_MixQueries(t *testing.T) {
file := "./testdata/mixing-queries.mql.yaml"
results, err := bundle.Lint(schema, file)
require.NoError(t, err)

assert.Equal(t, 1, len(results.BundleLocations))
assert.Equal(t, 1, len(results.Entries))
assert.True(t, results.HasError())

entry := results.Entries[0]
assert.Equal(t, "query-used-as-different-types", entry.RuleID)
assert.Equal(t, "query sshd-sshd-01 is used as a check and data query", entry.Message)
}
22 changes: 22 additions & 0 deletions internal/bundle/testdata/mixing-queries.mql.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
policies:
- uid: data-queries-mix
name: Test data SSH Policy
version: "1.0.0"
owner_mrn: ""
is_public: true
authors:
- name: Mondoo, Inc.
email: [email protected]
groups:
- title: group 01
checks:
- uid: sshd-sshd-01
queries:
- uid: sshd-sshd-01
filters: |
asset.family.contains(_ == 'unix')
queries:
- uid: sshd-sshd-01
title: Asset name is "test"
query: asset.name == "test"

0 comments on commit 28610de

Please sign in to comment.