Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🐛 Find variant checks by parent MRN #1408

Merged
merged 5 commits into from
Sep 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions policy/bundle.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,11 @@ func BundleExecutionChecksum(policy *Policy, framework *Framework) string {
if framework != nil {
res = res.Add(framework.GraphExecutionChecksum)
}
// So far the checksum only includes the policy and the framework
// It does not change if any of the jobs changes, only if the policy or the framework changes
// To update the resolved policy, when we change how it is generated, change the incoporated version of the resolver
res = res.Add(RESOLVER_VERSION)

return res.String()
}

Expand Down
1 change: 1 addition & 0 deletions policy/reportingjob.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,6 @@ func (r *ReportingJob) RefreshChecksum() {
checksum = checksum.Add(notify[i])
}
}

r.Checksum = checksum.String()
}
40 changes: 36 additions & 4 deletions policy/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"encoding/base64"
"encoding/binary"
"math/rand"
"slices"
"sort"
"time"

Expand All @@ -28,6 +29,10 @@ import (

const (
POLICY_SERVICE_NAME = "policy.api.mondoo.com"
// This is used to change the checksum of the resolved policy when we want it to be recalculated
// This can be updated, e.g., when we change how the report jobs are generated
// A change of this string will force an update of all the stored resolved policies
RESOLVER_VERSION = "v2024-08-29"
)

type AssetMutation struct {
Expand Down Expand Up @@ -1160,10 +1165,21 @@ func (cache *policyResolverCache) addCheckJob(ctx context.Context, check *explor
Type: ReportingJob_CHECK,
Mrns: []string{},
}
// We don't track the MRNs for variant queries through the cachem, since variant queries
// We don't track the MRNs for variant queries through the cache, since variant queries
// have no MQL, meaning they get the same code ID
if len(check.Variants) == 0 {
cache.global.codeIdToMrn[check.CodeId] = append(cache.global.codeIdToMrn[check.CodeId], check.Mrn)
// Because we have no variants, we might have to add the MRN of the parent job
if ownerJob != nil && ownerJob.Type == ReportingJob_CHECK && len(ownerJob.Mrns) > 0 {
// We might have variants, where multiple variant queries apply
// Don't save the same MRNs multiple times
for _, mrn := range ownerJob.Mrns {
if slices.Contains(cache.global.codeIdToMrn[check.CodeId], mrn) {
continue
}
cache.global.codeIdToMrn[check.CodeId] = append(cache.global.codeIdToMrn[check.CodeId], mrn)
}
}
}
cache.global.reportingJobsByUUID[uuid] = rj
cache.global.reportingJobsByMsum[check.Checksum] = append(cache.global.reportingJobsByMsum[check.Checksum], rj)
Expand All @@ -1183,12 +1199,14 @@ func (cache *policyResolverCache) addCheckJob(ctx context.Context, check *explor
rj.Notify = append(rj.Notify, ownerJob.Uuid)

if len(check.Variants) != 0 {
// Add parent MRN, so we can later also query the result by the variants parent MRN
// //.../queries/parent-check
// //.../queries/variant-1
rj.Mrns = []string{check.Mrn}
err := cache.addCheckJobVariants(ctx, check, rj)
if err != nil {
log.Error().Err(err).Str("checkMrn", check.Mrn).Msg("failed to add data query variants")
}
// If this is avariant query, its MRN is only the MRN of the check.
rj.Mrns = []string{check.Mrn}
} else {
// we set a placeholder for the execution query, just to indicate it will be added
cache.global.executionQueries[check.Checksum] = nil
Expand Down Expand Up @@ -1255,6 +1273,17 @@ func (cache *policyResolverCache) addDataQueryJob(ctx context.Context, query *ex
// have no MQL, meaning they get the same code ID
if len(query.Variants) == 0 {
cache.global.codeIdToMrn[query.CodeId] = append(cache.global.codeIdToMrn[query.CodeId], query.Mrn)
// Because we have no variants, we might have to add the MRN of the parent job
if ownerJob != nil && ownerJob.Type == ReportingJob_DATA_QUERY && len(ownerJob.Mrns) > 0 {
// We might have variants, where multiple variant queries apply
// Don't save the same MRNs multiple times
for _, mrn := range ownerJob.Mrns {
if slices.Contains(cache.global.codeIdToMrn[query.CodeId], mrn) {
continue
}
cache.global.codeIdToMrn[query.CodeId] = append(cache.global.codeIdToMrn[query.CodeId], mrn)
}
}
}
cache.global.reportingJobsByUUID[uuid] = rj
cache.global.reportingJobsByMsum[query.Checksum] = append(cache.global.reportingJobsByMsum[query.Checksum], rj)
Expand All @@ -1272,11 +1301,14 @@ func (cache *policyResolverCache) addDataQueryJob(ctx context.Context, query *ex
ownerJob.ChildJobs[rj.Uuid] = query.Impact
}
if len(query.Variants) != 0 {
// Add parent MRN, so we can later also query the result by the variants parent MRN
// //.../queries/parent-check
// //.../queries/variant-1
rj.Mrns = []string{query.Mrn}
err := cache.addDataQueryVariants(ctx, query, rj)
if err != nil {
log.Error().Err(err).Str("queryMrn", query.Mrn).Msg("failed to add data query variants")
}
rj.Mrns = []string{query.Mrn}
} else {
// we set a placeholder for the execution query, just to indicate it will be added
cache.global.executionQueries[query.Checksum] = nil
Expand Down
30 changes: 19 additions & 11 deletions policy/resolver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,9 +234,9 @@ policies:
require.NoError(t, err)
require.NotNil(t, rp)
require.Len(t, rp.CollectorJob.ReportingJobs, 5)
ignoreJob := rp.CollectorJob.ReportingJobs["8Sis0SvMbtI="]
ignoreJob := rp.CollectorJob.ReportingJobs["q7gxFtwx4zg="]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These UUIDs changed, because the new BundleExecutionChecksum is included in the UUIDs: https://github.com/mondoohq/cnspec/blob/main/policy/resolver.go#L536

require.NotNil(t, ignoreJob)
childJob := ignoreJob.ChildJobs["YCeU4NjbMe0="]
childJob := ignoreJob.ChildJobs["GhqR9OVIDVM="]
require.NotNil(t, childJob)
require.Equal(t, explorer.ScoringSystem_IGNORE_SCORE, childJob.Scoring)
})
Expand Down Expand Up @@ -291,12 +291,12 @@ policies:
require.NoError(t, err)
require.NotNil(t, rp)
require.Len(t, rp.CollectorJob.ReportingJobs, 5)
ignoreJob := rp.CollectorJob.ReportingJobs["WVDbd6CWW30="]
ignoreJob := rp.CollectorJob.ReportingJobs["gqNWe4GO+UA="]
require.NotNil(t, ignoreJob)
childJob := ignoreJob.ChildJobs["7Q8ymKH8W5c="]
childJob := ignoreJob.ChildJobs["LrvWHNnWZNQ="]
require.NotNil(t, childJob)
require.Equal(t, explorer.ScoringSystem_IGNORE_SCORE, childJob.Scoring)
activeJob := rp.CollectorJob.ReportingJobs["/w4u/z6FEsI="]
activeJob := rp.CollectorJob.ReportingJobs["+KeXN9zwDzA="]
require.NotNil(t, activeJob)
require.Equal(t, explorer.ScoringSystem_BANDED, activeJob.ScoringSystem)
})
Expand Down Expand Up @@ -1709,13 +1709,15 @@ queries:
}
// scoring queries report by code id
require.NotNil(t, qrIdToRj[b.Queries[1].CodeId])
require.Len(t, qrIdToRj[b.Queries[1].CodeId].Mrns, 2)
require.Len(t, qrIdToRj[b.Queries[1].CodeId].Mrns, 3)
require.Equal(t, queryMrn("variant1"), qrIdToRj[b.Queries[1].CodeId].Mrns[0])
require.Equal(t, queryMrn("variant2"), qrIdToRj[b.Queries[1].CodeId].Mrns[1])
require.Equal(t, queryMrn("check-variants"), qrIdToRj[b.Queries[1].CodeId].Mrns[1])
require.Equal(t, queryMrn("variant2"), qrIdToRj[b.Queries[1].CodeId].Mrns[2])

require.Len(t, qrIdToRj[b.Queries[2].CodeId].Mrns, 2)
require.Len(t, qrIdToRj[b.Queries[2].CodeId].Mrns, 3)
require.Equal(t, queryMrn("variant1"), qrIdToRj[b.Queries[2].CodeId].Mrns[0])
require.Equal(t, queryMrn("variant2"), qrIdToRj[b.Queries[2].CodeId].Mrns[1])
require.Equal(t, queryMrn("check-variants"), qrIdToRj[b.Queries[2].CodeId].Mrns[1])
require.Equal(t, queryMrn("variant2"), qrIdToRj[b.Queries[2].CodeId].Mrns[2])
})
}

Expand Down Expand Up @@ -1881,7 +1883,10 @@ queries:

rj = qrIdToRj["//test.sth/queries/windows-uname"]
require.NotNil(t, rj)
assert.ElementsMatch(t, []string{"//test.sth/queries/windows-uname"}, rj.Mrns)
assert.ElementsMatch(t, []string{
"//test.sth/queries/windows-uname",
"//test.sth/queries/uname",
}, rj.Mrns)
})

t.Run("resolve variant checks", func(t *testing.T) {
Expand All @@ -1891,6 +1896,9 @@ queries:

rj = qrIdToRj["eUdVwVDNIGA="]
require.NotNil(t, rj)
assert.ElementsMatch(t, []string{"//test.sth/queries/check-os-windows"}, rj.Mrns)
assert.ElementsMatch(t, []string{
"//test.sth/queries/check-os-windows",
"//test.sth/queries/check-os",
}, rj.Mrns)
})
}
Loading