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

Issue 966: Extend HasSBOM to include references to included software … #1367

Merged
merged 2 commits into from
Oct 26, 2023
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
2 changes: 1 addition & 1 deletion internal/testing/e2e/e2e
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ diff -u "${SCRIPT_DIR}/expectPkgQ1.json" "${GUAC_DIR}/gotPkgQ1.json"
cat "$queries" | gql-cli http://localhost:8080/query -o PkgQ2 | jq ' .packages[].namespaces |= sort ' > "${GUAC_DIR}/gotPkgQ2.json"
diff -u "${SCRIPT_DIR}/expectPkgQ2.json" "${GUAC_DIR}/gotPkgQ2.json"

cat "$queries" | gql-cli http://localhost:8080/query -o PkgQ3 | jq ' del(.. | .id?) | .packages[].namespaces |= sort_by(.namespace) | .packages[].namespaces[].names[].versions |= sort_by(.version) | .packages[].namespaces[].names[].versions[].qualifiers |= sort_by(.key) ' > "${GUAC_DIR}/gotPkgQ3.json"
cat "$queries" | gql-cli http://localhost:8080/query -o PkgQ3 | jq ' .packages[].namespaces |= sort_by(.namespace) | .packages[].namespaces[].names[].versions |= sort_by(.id) | .packages[].namespaces[].names[].versions[].qualifiers |= sort_by(.key) | del(.. | .id?) ' > "${GUAC_DIR}/gotPkgQ3.json"
diff -u "${SCRIPT_DIR}/expectPkgQ3.json" "${GUAC_DIR}/gotPkgQ3.json"

cat "$queries" | gql-cli http://localhost:8080/query -o PkgQ4 | jq ' del(.. | .id?) '> "${GUAC_DIR}/gotPkgQ4.json"
Expand Down
16 changes: 8 additions & 8 deletions internal/testing/mocks/backend.go

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

3 changes: 2 additions & 1 deletion pkg/assembler/assembler.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,8 @@ type HasSBOMIngest struct {
Pkg *generated.PkgInputSpec `json:"pkg,omitempty"`
Artifact *generated.ArtifactInputSpec `json:"artifact,omitempty"`

HasSBOM *generated.HasSBOMInputSpec `json:"hasSbom,omitempty"`
HasSBOM *generated.HasSBOMInputSpec `json:"hasSbom,omitempty"`
Includes *generated.HasSBOMIncludesInputSpec `json:"includes,omitempty"`
}

type VexIngest struct {
Expand Down
6 changes: 4 additions & 2 deletions pkg/assembler/backends/arangodb/hasSBOM.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,8 @@ func getHasSBOMQueryValues(pkg *model.PkgInputSpec, artifact *model.ArtifactInpu
return values
}

func (c *arangoClient) IngestHasSBOMs(ctx context.Context, subjects model.PackageOrArtifactInputs, hasSBOMs []*model.HasSBOMInputSpec) ([]*model.HasSbom, error) {
func (c *arangoClient) IngestHasSBOMs(ctx context.Context, subjects model.PackageOrArtifactInputs, hasSBOMs []*model.HasSBOMInputSpec, includes []*model.HasSBOMIncludesInputSpec) ([]*model.HasSbom, error) {
// TODO(knrc) - handle includes
if len(subjects.Packages) > 0 {
var listOfValues []map[string]any

Expand Down Expand Up @@ -401,7 +402,8 @@ func (c *arangoClient) IngestHasSBOMs(ctx context.Context, subjects model.Packag
}
}

func (c *arangoClient) IngestHasSbom(ctx context.Context, subject model.PackageOrArtifactInput, hasSbom model.HasSBOMInputSpec) (*model.HasSbom, error) {
func (c *arangoClient) IngestHasSbom(ctx context.Context, subject model.PackageOrArtifactInput, hasSbom model.HasSBOMInputSpec, includes model.HasSBOMIncludesInputSpec) (*model.HasSbom, error) {
// TODO(knrc) - handle includes
pxp928 marked this conversation as resolved.
Show resolved Hide resolved
if subject.Artifact != nil {
query := `LET artifact = FIRST(FOR art IN artifacts FILTER art.algorithm == @art_algorithm FILTER art.digest == @art_digest RETURN art)

Expand Down
10 changes: 7 additions & 3 deletions pkg/assembler/backends/arangodb/hasSBOM_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ func TestHasSBOM(t *testing.T) {
type call struct {
Sub model.PackageOrArtifactInput
HS *model.HasSBOMInputSpec
Inc *model.HasSBOMIncludesInputSpec
}
tests := []struct {
Name string
Expand Down Expand Up @@ -577,7 +578,8 @@ func TestHasSBOM(t *testing.T) {
}
}
for _, o := range test.Calls {
found, err := b.IngestHasSbom(ctx, o.Sub, *o.HS)
// TODO (knrc) handle includes
found, err := b.IngestHasSbom(ctx, o.Sub, *o.HS, model.HasSBOMIncludesInputSpec{})
if (err != nil) != test.ExpIngestErr {
t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err)
}
Expand Down Expand Up @@ -640,6 +642,7 @@ func TestIngestHasSBOM(t *testing.T) {
type call struct {
Sub model.PackageOrArtifactInputs
HS []*model.HasSBOMInputSpec
Inc []*model.HasSBOMIncludesInputSpec
}
tests := []struct {
Name string
Expand Down Expand Up @@ -835,7 +838,7 @@ func TestIngestHasSBOM(t *testing.T) {
}
}
for _, o := range test.Calls {
_, err := b.IngestHasSBOMs(ctx, o.Sub, o.HS)
_, err := b.IngestHasSBOMs(ctx, o.Sub, o.HS, o.Inc)
if (err != nil) != test.ExpIngestErr {
t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err)
}
Expand Down Expand Up @@ -1031,7 +1034,8 @@ func Test_buildHasSbomByID(t *testing.T) {
}
}
for _, o := range test.Calls {
found, err := b.IngestHasSbom(ctx, o.Sub, *o.HS)
// TODO (knrc) handle includes
found, err := b.IngestHasSbom(ctx, o.Sub, *o.HS, model.HasSBOMIncludesInputSpec{})
if (err != nil) != test.ExpIngestErr {
t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err)
}
Expand Down
6 changes: 4 additions & 2 deletions pkg/assembler/backends/arangodb/path_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -883,7 +883,8 @@ func Test_Nodes(t *testing.T) {
nodeID = found.ID
}
if tt.hasSBOMCall != nil {
found, err := b.IngestHasSbom(ctx, tt.hasSBOMCall.Sub, *tt.hasSBOMCall.HS)
// TODO (knrc) handle includes
found, err := b.IngestHasSbom(ctx, tt.hasSBOMCall.Sub, *tt.hasSBOMCall.HS, model.HasSBOMIncludesInputSpec{})
if (err != nil) != tt.wantErr {
t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err)
}
Expand Down Expand Up @@ -3377,7 +3378,8 @@ func Test_Neighbors(t *testing.T) {
}
}
if tt.hasSBOMCall != nil {
found, err := b.IngestHasSbom(ctx, tt.hasSBOMCall.Sub, *tt.hasSBOMCall.HS)
// TODO (knrc) handle includes
found, err := b.IngestHasSbom(ctx, tt.hasSBOMCall.Sub, *tt.hasSBOMCall.HS, model.HasSBOMIncludesInputSpec{})
if (err != nil) != tt.wantErr {
t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err)
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/assembler/backends/backends.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ type Backend interface {
IngestCertifyLegals(ctx context.Context, subjects model.PackageOrSourceInputs, declaredLicensesList [][]*model.LicenseInputSpec, discoveredLicensesList [][]*model.LicenseInputSpec, certifyLegals []*model.CertifyLegalInputSpec) ([]*model.CertifyLegal, error)
IngestDependency(ctx context.Context, pkg model.PkgInputSpec, depPkg model.PkgInputSpec, depPkgMatchType model.MatchFlags, dependency model.IsDependencyInputSpec) (*model.IsDependency, error)
IngestDependencies(ctx context.Context, pkgs []*model.PkgInputSpec, depPkgs []*model.PkgInputSpec, depPkgMatchType model.MatchFlags, dependencies []*model.IsDependencyInputSpec) ([]*model.IsDependency, error)
IngestHasSbom(ctx context.Context, subject model.PackageOrArtifactInput, hasSbom model.HasSBOMInputSpec) (*model.HasSbom, error)
IngestHasSBOMs(ctx context.Context, subjects model.PackageOrArtifactInputs, hasSBOMs []*model.HasSBOMInputSpec) ([]*model.HasSbom, error)
IngestHasSbom(ctx context.Context, subject model.PackageOrArtifactInput, hasSbom model.HasSBOMInputSpec, includes model.HasSBOMIncludesInputSpec) (*model.HasSbom, error)
IngestHasSBOMs(ctx context.Context, subjects model.PackageOrArtifactInputs, hasSBOMs []*model.HasSBOMInputSpec, includes []*model.HasSBOMIncludesInputSpec) ([]*model.HasSbom, error)
IngestHasSourceAt(ctx context.Context, pkg model.PkgInputSpec, pkgMatchType model.MatchFlags, source model.SourceInputSpec, hasSourceAt model.HasSourceAtInputSpec) (*model.HasSourceAt, error)
IngestHasSourceAts(ctx context.Context, pkgs []*model.PkgInputSpec, pkgMatchType *model.MatchFlags, sources []*model.SourceInputSpec, hasSourceAts []*model.HasSourceAtInputSpec) ([]string, error)
IngestHasMetadata(ctx context.Context, subject model.PackageSourceOrArtifactInput, pkgMatchType *model.MatchFlags, hasMetadata model.HasMetadataInputSpec) (*model.HasMetadata, error)
Expand Down
8 changes: 5 additions & 3 deletions pkg/assembler/backends/ent/backend/sbom.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ func (b *EntBackend) HasSBOM(ctx context.Context, spec *model.HasSBOMSpec) ([]*m
return collect(records, toModelHasSBOM), nil
}

func (b *EntBackend) IngestHasSbom(ctx context.Context, subject model.PackageOrArtifactInput, spec model.HasSBOMInputSpec) (*model.HasSbom, error) {
func (b *EntBackend) IngestHasSbom(ctx context.Context, subject model.PackageOrArtifactInput, spec model.HasSBOMInputSpec, includes model.HasSBOMIncludesInputSpec) (*model.HasSbom, error) {
// TODO(knrc) - handle includes
funcName := "IngestHasSbom"

sbomId, err := WithinTX(ctx, b.client, func(ctx context.Context) (*int, error) {
Expand Down Expand Up @@ -158,7 +159,7 @@ func (b *EntBackend) IngestHasSbom(ctx context.Context, subject model.PackageOrA
return toModelHasSBOM(sbom), nil
}

func (b *EntBackend) IngestHasSBOMs(ctx context.Context, subjects model.PackageOrArtifactInputs, hasSBOMs []*model.HasSBOMInputSpec) ([]*model.HasSbom, error) {
func (b *EntBackend) IngestHasSBOMs(ctx context.Context, subjects model.PackageOrArtifactInputs, hasSBOMs []*model.HasSBOMInputSpec, includes []*model.HasSBOMIncludesInputSpec) ([]*model.HasSbom, error) {
var modelHasSboms []*model.HasSbom
for i, hasSbom := range hasSBOMs {
var subject model.PackageOrArtifactInput
Expand All @@ -167,7 +168,8 @@ func (b *EntBackend) IngestHasSBOMs(ctx context.Context, subjects model.PackageO
} else {
subject = model.PackageOrArtifactInput{Package: subjects.Packages[i]}
}
modelHasSbom, err := b.IngestHasSbom(ctx, subject, *hasSbom)
// TODO(knrc) - handle includes
modelHasSbom, err := b.IngestHasSbom(ctx, subject, *hasSbom, model.HasSBOMIncludesInputSpec{})
if err != nil {
return nil, gqlerror.Errorf("IngestHasSBOMs failed with err: %v", err)
}
Expand Down
7 changes: 5 additions & 2 deletions pkg/assembler/backends/ent/backend/sbom_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ func (s *Suite) Test_HasSBOM() {
type call struct {
Sub model.PackageOrArtifactInput
Spec *model.HasSBOMInputSpec
Inc *model.HasSBOMIncludesInputSpec
}
tests := []struct {
Name string
Expand Down Expand Up @@ -505,7 +506,8 @@ func (s *Suite) Test_HasSBOM() {

recordIDs := make([]string, len(test.Calls))
for i, o := range test.Calls {
dep, err := b.IngestHasSbom(ctx, o.Sub, *o.Spec)
// TODO (knrc) handle includes
dep, err := b.IngestHasSbom(ctx, o.Sub, *o.Spec, model.HasSBOMIncludesInputSpec{})
if (err != nil) != test.ExpIngestErr {
s.T().Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err)
}
Expand Down Expand Up @@ -545,6 +547,7 @@ func (s *Suite) TestIngestHasSBOMs() {
type call struct {
Sub model.PackageOrArtifactInputs
HS []*model.HasSBOMInputSpec
Inc []*model.HasSBOMIncludesInputSpec
}
tests := []struct {
Name string
Expand Down Expand Up @@ -768,7 +771,7 @@ func (s *Suite) TestIngestHasSBOMs() {
}
}
for _, o := range test.Calls {
_, err := b.IngestHasSBOMs(ctx, o.Sub, o.HS)
_, err := b.IngestHasSBOMs(ctx, o.Sub, o.HS, o.Inc)
if (err != nil) != test.ExpIngestErr {
t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err)
}
Expand Down
62 changes: 62 additions & 0 deletions pkg/assembler/backends/inmem/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ import (
"errors"
"fmt"
"math"
"reflect"
"slices"
"strconv"
"strings"
"sync"
"sync/atomic"
Expand Down Expand Up @@ -201,3 +204,62 @@ func unlock(m *sync.RWMutex, readOnly bool) {
m.Unlock()
}
}

func parseIDs(ids []string) ([]uint32, error) {
keys := make([]uint32, 0, len(ids))
for _, id := range ids {
if key, err := parseID(id); err != nil {
return nil, err
} else {
keys = append(keys, key)
}
}
return keys, nil
}

func parseID(id string) (uint32, error) {
id64, err := strconv.ParseUint(id, 10, 32)
return uint32(id64), err
}

func sortAndRemoveDups(ids []uint32) []uint32 {
numIDs := len(ids)
if numIDs > 1 {
slices.Sort(ids)
nextIndex := 1
for index := 1; index < numIDs; index++ {
currentVal := ids[index]
if ids[index-1] != currentVal {
ids[nextIndex] = currentVal
nextIndex++
}
}
ids = ids[:nextIndex]
}
return ids
}

func (c *demoClient) getPackageVersionAndArtifacts(pkgOrArt []uint32) (pkgs []uint32, arts []uint32, err error) {
for _, id := range pkgOrArt {
switch entry := c.index[id].(type) {
case *pkgVersionNode:
pkgs = append(pkgs, entry.id)
case *artStruct:
arts = append(arts, entry.id)
default:
return nil, nil, fmt.Errorf("unexpected type in package or artifact list: %s", reflect.TypeOf(entry))
}
}

return
}

// IDs should be sorted
func (c *demoClient) isIDPresent(id string, linkIDs []uint32) bool {
linkID, err := strconv.ParseUint(id, 10, 32)
if err != nil {
return false
}
_, found := slices.BinarySearch[[]uint32](linkIDs, uint32(linkID))
return found
}
Loading
Loading