Skip to content

Commit

Permalink
🐛 datapoints are conditional on providers
Browse files Browse the repository at this point in the history
The os provider may not exist on the run or on the system. In these cases, the method to determine the datapoint for vulnerability report or kernel info will fail. To better handle these errors, we abandon the previous approach of `MustGetOneDatapoint` via `MustCompile` and instead use the provider info to report back to users.

There may still be other reasons why the compile fails, but we will keep this focused on the primary reason in a tested environment with a working provider runtime that indicates why this fails: no provider for this code.

Signed-off-by: Dominik Richter <[email protected]>
  • Loading branch information
arlimus committed Sep 10, 2023
1 parent 7779bfa commit 1cac045
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 18 deletions.
15 changes: 11 additions & 4 deletions cli/reporter/junit.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ import (

"github.com/jstemmer/go-junit-report/v2/junit"
"github.com/mitchellh/mapstructure"
"github.com/rs/zerolog/log"
"go.mondoo.com/cnquery/explorer"
"go.mondoo.com/cnquery/providers"
"go.mondoo.com/cnquery/providers-sdk/v1/inventory"
"go.mondoo.com/cnquery/shared"
"go.mondoo.com/cnquery/providers-sdk/v1/upstream/mvd"
"go.mondoo.com/cnquery/shared"
"go.mondoo.com/cnspec/policy"
)

Expand Down Expand Up @@ -162,8 +164,14 @@ func assetMvdTests(r *policy.ReportCollection, assetMrn string, assetObj *invent
return nil
}

schema := providers.DefaultRuntime().Schema()
vulnChecksum, err := defaultChecksum(vulnReport, schema)
if err != nil {
log.Debug().Err(err).Msg("could not determine vulnerability report checksum")
}

rawResults := results.RawResults()
value, ok := rawResults[vulnReportDatapointChecksum]
value, ok := rawResults[vulnChecksum]
if !ok {
return nil
}
Expand Down Expand Up @@ -200,8 +208,7 @@ func assetMvdTests(r *policy.ReportCollection, assetMrn string, assetObj *invent
TagName: "json",
}
decoder, _ := mapstructure.NewDecoder(cfg)
err := decoder.Decode(rawData)
if err != nil {
if err = decoder.Decode(rawData); err != nil {
ts.Errors++
ts.Testcases = append(ts.Testcases, junit.Testcase{
Failure: &junit.Result{
Expand Down
16 changes: 12 additions & 4 deletions cli/reporter/print_compact.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ import (
"go.mondoo.com/cnquery/cli/components"
"go.mondoo.com/cnquery/explorer"
"go.mondoo.com/cnquery/llx"
"go.mondoo.com/cnquery/providers"
"go.mondoo.com/cnquery/providers-sdk/v1/inventory"
"go.mondoo.com/cnquery/utils/stringx"
"go.mondoo.com/cnquery/providers-sdk/v1/upstream/mvd"
"go.mondoo.com/cnquery/utils/stringx"
cnspecComponents "go.mondoo.com/cnspec/cli/components"
"go.mondoo.com/cnspec/policy"
)
Expand Down Expand Up @@ -583,7 +584,15 @@ func (r *defaultReporter) printCheck(score *policy.Score, query *explorer.Mquery
func (r *defaultReporter) printVulns(resolved *policy.ResolvedPolicy, report *policy.Report, results map[string]*llx.RawResult) {
print := r.Printer

value, ok := results[vulnReportDatapointChecksum]
schema := providers.DefaultRuntime().Schema()
vulnChecksum, err := defaultChecksum(vulnReport, schema)
if err != nil {
log.Debug().Err(err).Msg("could not determine vulnerability report checksum")
r.out.Write([]byte(print.Error("No vulnerabilities for this provider")))
return
}

value, ok := results[vulnChecksum]
if !ok {
return
}
Expand Down Expand Up @@ -611,8 +620,7 @@ func (r *defaultReporter) printVulns(resolved *policy.ResolvedPolicy, report *po
TagName: "json",
}
decoder, _ := mapstructure.NewDecoder(cfg)
err := decoder.Decode(rawData)
if err != nil {
if err = decoder.Decode(rawData); err != nil {
r.out.Write([]byte(print.Error("could not decode advisory report" + NewLineCharacter + NewLineCharacter)))
return
}
Expand Down
26 changes: 20 additions & 6 deletions cli/reporter/render_advisory_policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ import (

"github.com/mitchellh/mapstructure"
"github.com/muesli/termenv"
"github.com/rs/zerolog/log"
"go.mondoo.com/cnquery/cli/printer"
"go.mondoo.com/cnquery/cli/theme/colors"
"go.mondoo.com/cnquery/utils/stringx"
"go.mondoo.com/cnquery/providers"
"go.mondoo.com/cnquery/providers-sdk/v1/upstream/mvd"
"go.mondoo.com/cnquery/utils/stringx"
"go.mondoo.com/cnspec/cli/components"
"go.mondoo.com/cnspec/policy"
)
Expand All @@ -34,9 +36,16 @@ func renderAdvisoryPolicy(print *printer.Printer, policyObj *policy.Policy, repo
// render mini score card
score := report.Scores[policyObj.Mrn]

var vulnReport mvd.VulnReport
schema := providers.DefaultRuntime().Schema()
vulnCheckpoint, err := defaultChecksum(vulnReport, schema)
if err != nil {
log.Debug().Err(err).Msg("could not determine vulnerability report checksum")
b.WriteString(print.Error("no vulnerabilities for this provider"))
return b.String()
}

results := report.Data
value, ok := results[vulnReportDatapointChecksum]
value, ok := results[vulnCheckpoint]
if !ok {
b.WriteString(print.Error("could not find advisory report" + NewLineCharacter + NewLineCharacter))
return b.String()
Expand All @@ -54,14 +63,14 @@ func renderAdvisoryPolicy(print *printer.Printer, policyObj *policy.Policy, repo

rawData := value.Data.RawData().Value

var vulnReport mvd.VulnReport
cfg := &mapstructure.DecoderConfig{
Metadata: nil,
Result: &vulnReport,
TagName: "json",
}
decoder, _ := mapstructure.NewDecoder(cfg)
err := decoder.Decode(rawData)
if err != nil {
if err = decoder.Decode(rawData); err != nil {
b.WriteString(print.Error("could not decode advisory report" + NewLineCharacter + NewLineCharacter))
return b.String()
}
Expand All @@ -87,7 +96,12 @@ func renderAdvisoryPolicy(print *printer.Printer, policyObj *policy.Policy, repo
}

// render additional information
kernelDataValue, ok := results[kernelListDatapointChecksum]
kernelInstalledChecksum, err := defaultChecksum(kernelInstalled, schema)
if err != nil {
log.Debug().Err(err).Msg("could not determine installed kernel checksum")
}

kernelDataValue, ok := results[kernelInstalledChecksum]
if ok && kernelDataValue.Data != nil {
if kernelDataValue.Error != "" {
b.WriteString(print.Error(kernelDataValue.Error + NewLineCharacter))
Expand Down
41 changes: 37 additions & 4 deletions cli/reporter/reporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,53 @@ import (
"io"
"strings"

"go.mondoo.com/cnquery"
"go.mondoo.com/cnquery/cli/printer"
"go.mondoo.com/cnquery/cli/theme/colors"
ee "go.mondoo.com/cnquery/explorer/executor"
"go.mondoo.com/cnquery/llx"
"go.mondoo.com/cnquery/mqlc"
"go.mondoo.com/cnquery/providers-sdk/v1/upstream/mvd"
"go.mondoo.com/cnquery/shared"
"go.mondoo.com/cnspec/policy"
"sigs.k8s.io/yaml"
)

var (
vulnReportDatapointChecksum = ee.MustGetOneDatapoint(ee.MustCompile("asset.vulnerabilityReport"))
kernelListDatapointChecksum = ee.MustGetOneDatapoint(ee.MustCompile("kernel.installed"))
type mqlCode string

const (
vulnReport mqlCode = "asset.VulnerabilityReport"
kernelInstalled mqlCode = "kernel.installed"
)

var _defaultChecksums = map[mqlCode]struct {
sum string
err error
}{}

func defaultChecksum(code mqlCode, schema llx.Schema) (string, error) {
res, ok := _defaultChecksums[code]
if ok {
return res.sum, res.err
}

codeBundle, err := mqlc.Compile(string(code), nil,
mqlc.NewConfig(schema, cnquery.DefaultFeatures))
if err != nil {
res.err = err
} else if len(codeBundle.CodeV2.Entrypoints()) != 1 {
res.err = errors.New("code bundle should only have 1 entrypoint for: " + string(code))
} else {
entrypoint := codeBundle.CodeV2.Entrypoints()[0]
res.sum, ok = codeBundle.CodeV2.Checksums[entrypoint]
if !ok {
res.err = errors.New("could not find the datapoint for: " + string(code))
}
}

_defaultChecksums[code] = res
return res.sum, res.err
}

type Reporter struct {
Format Format
Printer *printer.Printer
Expand Down

0 comments on commit 1cac045

Please sign in to comment.