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

discard relevant SBOM based on validating func #98

Merged
merged 1 commit into from
Apr 17, 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
14 changes: 11 additions & 3 deletions repositories/apiserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package repositories

import (
"context"
"fmt"
"strconv"
"strings"
"time"
Expand Down Expand Up @@ -190,6 +191,13 @@ func (a *APIServerStore) GetSBOM(ctx context.Context, imageID, SBOMCreatorVersio
return result, nil
}

func validateSBOMp(manifest *v1beta1.SBOMSPDXv2p3Filtered) error {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@dwertent this is where you should make your changes

if status, ok := manifest.Annotations[instanceidhandler.StatusMetadataKey]; ok && status == domain.SBOMStatusIncomplete {
return fmt.Errorf("relevant SBOM is incomplete")
}
return nil
}

func (a *APIServerStore) GetSBOMp(ctx context.Context, instanceID, SBOMCreatorVersion string) (sbom domain.SBOM, err error) {
_, span := otel.Tracer("").Start(ctx, "APIServerStore.GetSBOMp")
defer span.End()
Expand All @@ -206,9 +214,9 @@ func (a *APIServerStore) GetSBOMp(ctx context.Context, instanceID, SBOMCreatorVe
logger.L().Ctx(ctx).Warning("failed to get relevant SBOM from apiserver", helpers.Error(err), helpers.String("ID", instanceID))
return domain.SBOM{}, nil
}
// discard the manifest if it was created by an older version of the scanner
if manifest.Spec.Metadata.Tool.Version != SBOMCreatorVersion {
logger.L().Debug("discarding relevant SBOM with outdated scanner version", helpers.String("ID", instanceID), helpers.String("manifest scanner version", manifest.Spec.Metadata.Tool.Version), helpers.String("wanted scanner version", SBOMCreatorVersion))
// validate SBOMp manifest
if err := validateSBOMp(manifest); err != nil {
logger.L().Debug("discarding relevant SBOM", helpers.Error(err), helpers.String("ID", instanceID))
return domain.SBOM{}, nil
}
result := domain.SBOM{
Expand Down
55 changes: 37 additions & 18 deletions repositories/apiserver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import (
const imageID = "k8s.gcr.io/kube-proxy@sha256:c1b135231b5b1a6799346cd701da4b59e5b7ef8e694ec7b04fb23b8dbe144137"
const instanceID = "ee9bdd0adec9ce004572faf3492f583aa82042a8b3a9d5c7d9179dc03c531eef"

func (a *APIServerStore) storeSBOMp(ctx context.Context, sbom domain.SBOM) error {
func (a *APIServerStore) storeSBOMp(ctx context.Context, sbom domain.SBOM, incomplete bool) error {
manifest := v1beta1.SBOMSPDXv2p3Filtered{
ObjectMeta: metav1.ObjectMeta{
Name: sbom.ID,
Expand All @@ -29,6 +29,9 @@ func (a *APIServerStore) storeSBOMp(ctx context.Context, sbom domain.SBOM) error
if sbom.Content != nil {
manifest.Spec.SPDX = *sbom.Content
}
if incomplete {
manifest.Annotations[instanceidhandler.StatusMetadataKey] = domain.SBOMStatusIncomplete
}
_, err := a.StorageClient.SBOMSPDXv2p3Filtereds(a.Namespace).Create(ctx, &manifest, metav1.CreateOptions{})
return err
}
Expand Down Expand Up @@ -246,48 +249,47 @@ func TestAPIServerStore_GetSBOMp(t *testing.T) {
name string
args args
sbom domain.SBOM
incomplete bool
wantEmptySBOM bool
}{
{
"valid SBOMp is retrieved",
args{
name: "valid SBOMp is retrieved",
args: args{
ctx: context.TODO(),
instanceID: instanceID,
},
domain.SBOM{
sbom: domain.SBOM{
ID: instanceID,
Content: &v1beta1.Document{
CreationInfo: &v1beta1.CreationInfo{
Created: time.Now().Format(time.RFC3339),
},
},
},
false,
},
{
"invalid timestamp, SBOMp is still retrieved",
args{
name: "invalid timestamp, SBOMp is still retrieved",
args: args{
ctx: context.TODO(),
instanceID: instanceID,
},
domain.SBOM{
sbom: domain.SBOM{
ID: instanceID,
Content: &v1beta1.Document{
CreationInfo: &v1beta1.CreationInfo{
Created: "invalid timestamp",
},
},
},
false,
},
{
"SBOMCreatorVersion mismatch",
args{
name: "SBOMCreatorVersion mismatch",
args: args{
ctx: context.TODO(),
instanceID: instanceID,
SBOMCreatorVersion: "v1.1.0",
},
domain.SBOM{
sbom: domain.SBOM{
ID: instanceID,
SBOMCreatorVersion: "v1.0.0",
Content: &v1beta1.Document{
Expand All @@ -296,16 +298,16 @@ func TestAPIServerStore_GetSBOMp(t *testing.T) {
},
},
},
true,
wantEmptySBOM: false, // SBOMp is not versioned
},
{
"empty imageID",
args{
name: "empty imageID",
args: args{
ctx: context.TODO(),
instanceID: "",
SBOMCreatorVersion: "v1.1.0",
},
domain.SBOM{
sbom: domain.SBOM{
ID: "",
SBOMCreatorVersion: "v1.0.0",
Content: &v1beta1.Document{
Expand All @@ -314,15 +316,32 @@ func TestAPIServerStore_GetSBOMp(t *testing.T) {
},
},
},
true,
wantEmptySBOM: true,
},
{
name: "incomplete SBOMp is retrieved",
args: args{
ctx: context.TODO(),
instanceID: instanceID,
},
sbom: domain.SBOM{
ID: instanceID,
Content: &v1beta1.Document{
CreationInfo: &v1beta1.CreationInfo{
Created: time.Now().Format(time.RFC3339),
},
},
},
incomplete: true,
wantEmptySBOM: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
a := NewFakeAPIServerStorage("kubescape")
_, err := a.GetSBOMp(tt.args.ctx, tt.args.instanceID, tt.args.SBOMCreatorVersion)
tools.EnsureSetup(t, err == nil)
err = a.storeSBOMp(tt.args.ctx, tt.sbom)
err = a.storeSBOMp(tt.args.ctx, tt.sbom, tt.incomplete)
tools.EnsureSetup(t, err == nil)
gotSbom, _ := a.GetSBOMp(tt.args.ctx, tt.args.instanceID, tt.args.SBOMCreatorVersion)
if (gotSbom.Content == nil) != tt.wantEmptySBOM {
Expand Down