Skip to content

Commit

Permalink
🧹 use new proto report format for sbom
Browse files Browse the repository at this point in the history
  • Loading branch information
chris-rock committed Apr 3, 2024
1 parent a4ba716 commit 1c9af12
Show file tree
Hide file tree
Showing 9 changed files with 367 additions and 411 deletions.
11 changes: 5 additions & 6 deletions apps/cnquery/cmd/sbom.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import (
"go.mondoo.com/cnquery/v10/providers"
"go.mondoo.com/cnquery/v10/providers-sdk/v1/plugin"
sbom "go.mondoo.com/cnquery/v10/sbom"
"go.mondoo.com/cnquery/v10/shared"
)

func init() {
Expand Down Expand Up @@ -87,14 +86,14 @@ var sbomCmdRun = func(cmd *cobra.Command, runtime *providers.Runtime, cliRes *pl
log.Fatal().Err(err).Msg("failed to run scan")
}

buf := bytes.Buffer{}
w := shared.IOWriter{Writer: &buf}
err = reporter.ConvertToJSON(report, &w)
cnspecReport, err := reporter.ConvertToProto(report)
if err == nil {
logger.DebugDumpJSON("mondoo-sbom-report", buf.Bytes())
log.Debug().Msg("converted report to proto")
data, _ := cnspecReport.ToJSON()
logger.DebugDumpJSON("mondoo-sbom-report", data)
}

boms, err := sbom.NewBom(buf.Bytes())
boms, err := sbom.NewBom(cnspecReport)
if err != nil {
log.Fatal().Err(err).Msg("failed to parse bom")
}
Expand Down
4 changes: 1 addition & 3 deletions sbom/cnquery_bom_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ import (
)

func TestSimpleBom(t *testing.T) {
r, err := NewReportCollectionJsonFromSingleFile("./testdata/alpine.json")
require.NoError(t, err)

r := loadTestReport(t)
sboms, err := GenerateBom(r)
require.NoError(t, err)

Expand Down
4 changes: 1 addition & 3 deletions sbom/cyclonedx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ import (
)

func TestCycloneDX(t *testing.T) {
r, err := NewReportCollectionJsonFromSingleFile("./testdata/alpine.json")
require.NoError(t, err)

r := loadTestReport(t)
sboms, err := GenerateBom(r)
require.NoError(t, err)

Expand Down
63 changes: 2 additions & 61 deletions sbom/report_collection.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,8 @@ package sbom

import (
"encoding/json"
"errors"
"os"
"sigs.k8s.io/yaml"
)

type ReportCollectionJsonAsset struct {
Mrn string `json:"mrn"`
Name string `json:"name"`
PlatformName string `json:"platform_name"`
}

type ReportCollectionJsonScore struct {
Score int `json:"score"`
Status string `json:"status"`
}

type ReportCollectionJson struct {
Assets map[string]ReportCollectionJsonAsset `json:"assets"`
Data map[string]map[string]json.RawMessage `json:"data"`
Scores map[string]map[string]ReportCollectionJsonScore `json:"scores"`
}

// Structures to parse the data from cnquery report
type BomAsset struct {
Name string `json:"name,omitempty"`
Expand Down Expand Up @@ -59,53 +39,14 @@ type KernelInstalled struct {
Version string
}

type BomReport struct {
type BomFields struct {
Asset *BomAsset `json:"asset,omitempty"`
Packages []BomPackage `json:"packages.list,omitempty"`
PythonPackages []BomPackage `json:"python.packages,omitempty"`
NpmPackages []BomPackage `json:"npm.packages.list,omitempty"`
KernelInstalled []KernelInstalled `json:"kernel.installed,omitempty"`
}

func (b *BomReport) ToJSON() ([]byte, error) {
func (b *BomFields) ToJSON() ([]byte, error) {
return json.Marshal(b)
}

// AssetMrn returns the MRN of the asset if there is only one
func (r ReportCollectionJson) AssetMrn() (string, error) {
if len(r.Assets) > 1 {
return "", errors.New("report contains more than one asset")
}

if len(r.Assets) == 0 {
return "", errors.New("report contains no assets")
}

for _, asset := range r.Assets {
return asset.Mrn, nil
}

// should not happen
return "", errors.New("report contains no assets")
}

// NewReportCollectionJsonFromSingleFile loads a cnspec report bundle from a single file
func NewReportCollectionJsonFromSingleFile(path string) (*ReportCollectionJson, error) {
reportData, err := os.ReadFile(path)
if err != nil {
return nil, err
}

return NewReportCollectionJson(reportData)
}

// NewReportCollectionJson creates a cnspec report from json contents
func NewReportCollectionJson(data []byte) (*ReportCollectionJson, error) {
var res ReportCollectionJson
err := yaml.Unmarshal(data, &res)
return &res, err
}

func (p *ReportCollectionJson) ToYAML() ([]byte, error) {
return yaml.Marshal(p)
}
22 changes: 12 additions & 10 deletions sbom/sbom.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
_ "embed"
"encoding/json"
"fmt"
"go.mondoo.com/cnquery/v10/cli/reporter"
"strings"
"time"

Expand All @@ -30,16 +31,12 @@ func QueryPack() (*explorer.Bundle, error) {
}

// NewBom creates a BOM from a json report collection
func NewBom(data []byte) ([]Sbom, error) {
jr, err := NewReportCollectionJson(data)
if err != nil {
return nil, err
}
return GenerateBom(jr)
func NewBom(report *reporter.Report) ([]Sbom, error) {
return GenerateBom(report)
}

// GenerateBom generates a BOM from a cnspec json report collection
func GenerateBom(r *ReportCollectionJson) ([]Sbom, error) {
func GenerateBom(r *reporter.Report) ([]Sbom, error) {
if r == nil {
return nil, nil
}
Expand Down Expand Up @@ -74,9 +71,14 @@ func GenerateBom(r *ReportCollectionJson) ([]Sbom, error) {

// extract os packages and python packages
dataPoints := r.Data[mrn]
for k := range dataPoints {
rb := BomReport{}
err := json.Unmarshal(dataPoints[k], &rb)
for k := range dataPoints.Values {
dataValue := dataPoints.Values[k]
jsondata, err := reporter.JsonValue(dataValue.Content)
if err != nil {
return nil, err
}
rb := BomFields{}
err = json.Unmarshal(jsondata, &rb)
if err != nil {
return nil, err
}
Expand Down
8 changes: 4 additions & 4 deletions sbom/sbom.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 12 additions & 2 deletions sbom/sbom_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,23 @@ package sbom
import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.mondoo.com/cnquery/v10/cli/reporter"
"os"
"sigs.k8s.io/yaml"
"testing"
)

func TestSbomParsing(t *testing.T) {
r, err := NewReportCollectionJsonFromSingleFile("./testdata/alpine.json")
func loadTestReport(t *testing.T) *reporter.Report {
data, err := os.ReadFile("./testdata/alpine.json")
require.NoError(t, err)
var report *reporter.Report
err = yaml.Unmarshal(data, &report)
require.NoError(t, err)
return report
}

func TestSbomParsing(t *testing.T) {
r := loadTestReport(t)
sboms, err := GenerateBom(r)
require.NoError(t, err)

Expand Down
4 changes: 1 addition & 3 deletions sbom/spdx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ import (
)

func TestSpdx(t *testing.T) {
r, err := NewReportCollectionJsonFromSingleFile("./testdata/alpine.json")
require.NoError(t, err)

r := loadTestReport(t)
sboms, err := GenerateBom(r)
require.NoError(t, err)

Expand Down
Loading

0 comments on commit 1c9af12

Please sign in to comment.