From 8313600b0699f6c3e5af99afff57cabe8f0e17d5 Mon Sep 17 00:00:00 2001 From: Matthias Bertschy Date: Tue, 30 May 2023 11:01:44 +0200 Subject: [PATCH] rename crd Signed-off-by: Matthias Bertschy --- adapters/mocksbom.go | 4 +- adapters/mocksbom_test.go | 6 +-- adapters/v1/syft.go | 4 +- adapters/v1/syft_test.go | 2 +- controllers/http.go | 4 ++ core/domain/scan.go | 3 +- core/ports/providers.go | 2 +- core/services/scan.go | 54 +++++++++++++------------- core/services/scan_test.go | 8 ++-- go.mod | 2 +- go.sum | 4 +- repositories/apiserver.go | 69 +++------------------------------- repositories/apiserver_test.go | 48 ----------------------- 13 files changed, 55 insertions(+), 155 deletions(-) diff --git a/adapters/mocksbom.go b/adapters/mocksbom.go index 2e46998..c60c88c 100644 --- a/adapters/mocksbom.go +++ b/adapters/mocksbom.go @@ -35,7 +35,7 @@ func NewMockSBOMAdapter(error, timeout, toomanyrequests bool) *MockSBOMAdapter { } // CreateSBOM returns a dummy SBOM for the given imageID -func (m MockSBOMAdapter) CreateSBOM(_ context.Context, imageID string, _ domain.RegistryOptions) (domain.SBOM, error) { +func (m MockSBOMAdapter) CreateSBOM(_ context.Context, name, imageID string, _ domain.RegistryOptions) (domain.SBOM, error) { logger.L().Info("CreateSBOM") if m.error { return domain.SBOM{}, domain.ErrMockError @@ -48,7 +48,7 @@ func (m MockSBOMAdapter) CreateSBOM(_ context.Context, imageID string, _ domain. ) } sbom := domain.SBOM{ - ID: imageID, + ID: name, SBOMCreatorVersion: m.Version(), Annotations: map[string]string{ instanceidhandler.ImageIDMetadataKey: imageID, diff --git a/adapters/mocksbom_test.go b/adapters/mocksbom_test.go index 503552e..54df912 100644 --- a/adapters/mocksbom_test.go +++ b/adapters/mocksbom_test.go @@ -11,19 +11,19 @@ import ( func TestMockSBOMAdapter_CreateSBOM(t *testing.T) { m := NewMockSBOMAdapter(false, false, false) - sbom, _ := m.CreateSBOM(context.TODO(), "image", domain.RegistryOptions{}) + sbom, _ := m.CreateSBOM(context.TODO(), "name", "image", domain.RegistryOptions{}) assert.NotNil(t, sbom.Content) } func TestMockSBOMAdapter_CreateSBOM_Error(t *testing.T) { m := NewMockSBOMAdapter(true, false, false) - _, err := m.CreateSBOM(context.TODO(), "image", domain.RegistryOptions{}) + _, err := m.CreateSBOM(context.TODO(), "name", "image", domain.RegistryOptions{}) assert.Error(t, err) } func TestMockSBOMAdapter_CreateSBOM_Timeout(t *testing.T) { m := NewMockSBOMAdapter(false, true, false) - sbom, _ := m.CreateSBOM(context.TODO(), "image", domain.RegistryOptions{}) + sbom, _ := m.CreateSBOM(context.TODO(), "name", "image", domain.RegistryOptions{}) assert.Equal(t, sbom.Status, instanceidhandler.Incomplete) } diff --git a/adapters/v1/syft.go b/adapters/v1/syft.go index 25fbd8c..751ca13 100644 --- a/adapters/v1/syft.go +++ b/adapters/v1/syft.go @@ -54,12 +54,12 @@ func NewSyftAdapter(scanTimeout time.Duration, maxImageSize int64) *SyftAdapter // CreateSBOM creates an SBOM for a given imageID, restrict parallelism to prevent disk space issues, // a timeout prevents the process from hanging for too long. // Format is SPDX JSON and the resulting SBOM is tagged with the Syft version. -func (s *SyftAdapter) CreateSBOM(ctx context.Context, imageID string, options domain.RegistryOptions) (domain.SBOM, error) { +func (s *SyftAdapter) CreateSBOM(ctx context.Context, name, imageID string, options domain.RegistryOptions) (domain.SBOM, error) { ctx, span := otel.Tracer("").Start(ctx, "SyftAdapter.CreateSBOM") defer span.End() // prepare an SBOM and fill it progressively domainSBOM := domain.SBOM{ - ID: imageID, + ID: name, SBOMCreatorVersion: s.Version(), Annotations: map[string]string{ instanceidhandler.ImageIDMetadataKey: imageID, diff --git a/adapters/v1/syft_test.go b/adapters/v1/syft_test.go index 43a8060..3212615 100644 --- a/adapters/v1/syft_test.go +++ b/adapters/v1/syft_test.go @@ -75,7 +75,7 @@ func Test_syftAdapter_CreateSBOM(t *testing.T) { maxImageSize = tt.maxImageSize } s := NewSyftAdapter(5*time.Minute, maxImageSize) - got, err := s.CreateSBOM(context.TODO(), tt.imageID, tt.options) + got, err := s.CreateSBOM(context.TODO(), "name", tt.imageID, tt.options) if (err != nil) != tt.wantErr { t.Errorf("CreateSBOM() error = %v, wantErr %v", err, tt.wantErr) return diff --git a/controllers/http.go b/controllers/http.go index 496bbab..7d1d01e 100644 --- a/controllers/http.go +++ b/controllers/http.go @@ -9,6 +9,7 @@ import ( "github.com/gin-gonic/gin" "github.com/kubescape/go-logger" "github.com/kubescape/go-logger/helpers" + "github.com/kubescape/k8s-interface/names" "github.com/kubescape/kubevuln/core/domain" "github.com/kubescape/kubevuln/core/ports" "schneider.vip/problem" @@ -123,6 +124,9 @@ func websocketScanCommandToScanCommand(c wssc.WebsocketScanCommand) domain.ScanC Args: c.Args, Session: sessionChainToSession(c.Session), } + if slug, err := names.ImageInfoToSlug(c.ImageTag, c.ImageHash); err != nil { + command.ImageID = slug + } if c.InstanceID != nil { command.InstanceID = *c.InstanceID } diff --git a/core/domain/scan.go b/core/domain/scan.go index a9a01ab..17bf05d 100644 --- a/core/domain/scan.go +++ b/core/domain/scan.go @@ -16,7 +16,7 @@ var ( ErrExpectedError = errors.New("expected error") ErrInitVulnDB = errors.New("vulnerability DB is not initialized, run readiness probe") ErrIncompleteSBOM = errors.New("incomplete SBOM, skipping CVE scan") - ErrMissingImageID = errors.New("missing imageID") + ErrMissingImageInfo = errors.New("missing image information") ErrMissingScanID = errors.New("missing scanID") ErrMissingTimestamp = errors.New("missing timestamp") ErrMissingWorkload = errors.New("missing workload") @@ -31,6 +31,7 @@ type WorkloadKey struct{} type ScanCommand struct { Credentialslist []types.AuthConfig ImageHash string + ImageID string InstanceID string Wlid string ImageTag string diff --git a/core/ports/providers.go b/core/ports/providers.go index 3584691..00172a9 100644 --- a/core/ports/providers.go +++ b/core/ports/providers.go @@ -16,7 +16,7 @@ type CVEScanner interface { // SBOMCreator is the port implemented by adapters to be used in ScanService to generate SBOM type SBOMCreator interface { - CreateSBOM(ctx context.Context, imageID string, options domain.RegistryOptions) (domain.SBOM, error) + CreateSBOM(ctx context.Context, name, imageID string, options domain.RegistryOptions) (domain.SBOM, error) Version() string } diff --git a/core/services/scan.go b/core/services/scan.go index 78feeca..e713b48 100644 --- a/core/services/scan.go +++ b/core/services/scan.go @@ -80,16 +80,16 @@ func (s *ScanService) GenerateSBOM(ctx context.Context) error { sbom := domain.SBOM{} var err error if s.storage { - sbom, err = s.sbomRepository.GetSBOM(ctx, workload.ImageHash, s.sbomCreator.Version()) + sbom, err = s.sbomRepository.GetSBOM(ctx, workload.ImageID, s.sbomCreator.Version()) if err != nil { - logger.L().Ctx(ctx).Warning("error getting SBOM", helpers.Error(err), helpers.String("imageID", workload.ImageHash)) + logger.L().Ctx(ctx).Warning("error getting SBOM", helpers.Error(err), helpers.String("imageID", workload.ImageID)) } } // if SBOM is not available, create it if sbom.Content == nil { // create SBOM - sbom, err = s.sbomCreator.CreateSBOM(ctx, workload.ImageHash, optionsFromWorkload(workload)) + sbom, err = s.sbomCreator.CreateSBOM(ctx, workload.ImageID, workload.ImageHash, optionsFromWorkload(workload)) s.checkCreateSBOM(err, workload.ImageHash) if err != nil { return err @@ -124,20 +124,20 @@ func (s *ScanService) ScanCVE(ctx context.Context) error { if !ok { return domain.ErrMissingWorkload } - logger.L().Info("scan started", helpers.String("imageID", workload.ImageHash), helpers.String("jobID", workload.JobID)) + logger.L().Info("scan started", helpers.String("imageID", workload.ImageID), helpers.String("jobID", workload.JobID)) // report to platform err := s.platform.SendStatus(ctx, domain.Started) if err != nil { - logger.L().Ctx(ctx).Warning("telemetry error", helpers.Error(err), helpers.String("imageID", workload.ImageHash)) + logger.L().Ctx(ctx).Warning("telemetry error", helpers.Error(err), helpers.String("imageID", workload.ImageID)) } // check if CVE manifest is already available cve := domain.CVEManifest{} if s.storage { - cve, err = s.cveRepository.GetCVE(ctx, workload.ImageHash, s.sbomCreator.Version(), s.cveScanner.Version(ctx), s.cveScanner.DBVersion(ctx)) + cve, err = s.cveRepository.GetCVE(ctx, workload.ImageID, s.sbomCreator.Version(), s.cveScanner.Version(ctx), s.cveScanner.DBVersion(ctx)) if err != nil { - logger.L().Ctx(ctx).Warning("error getting CVE", helpers.Error(err), helpers.String("imageID", workload.ImageHash)) + logger.L().Ctx(ctx).Warning("error getting CVE", helpers.Error(err), helpers.String("imageID", workload.ImageID)) } } @@ -146,16 +146,16 @@ func (s *ScanService) ScanCVE(ctx context.Context) error { // check if SBOM is already available sbom := domain.SBOM{} if s.storage { - sbom, err = s.sbomRepository.GetSBOM(ctx, workload.ImageHash, s.sbomCreator.Version()) + sbom, err = s.sbomRepository.GetSBOM(ctx, workload.ImageID, s.sbomCreator.Version()) if err != nil { - logger.L().Ctx(ctx).Warning("error getting SBOM", helpers.Error(err), helpers.String("imageID", workload.ImageHash)) + logger.L().Ctx(ctx).Warning("error getting SBOM", helpers.Error(err), helpers.String("imageID", workload.ImageID)) } } // if SBOM is not available, create it if sbom.Content == nil { // create SBOM - sbom, err = s.sbomCreator.CreateSBOM(ctx, workload.ImageHash, optionsFromWorkload(workload)) + sbom, err = s.sbomCreator.CreateSBOM(ctx, workload.ImageID, workload.ImageHash, optionsFromWorkload(workload)) s.checkCreateSBOM(err, workload.ImageHash) if err != nil { return err @@ -164,7 +164,7 @@ func (s *ScanService) ScanCVE(ctx context.Context) error { if s.storage { err = s.sbomRepository.StoreSBOM(ctx, sbom) if err != nil { - logger.L().Ctx(ctx).Warning("error storing SBOM", helpers.Error(err), helpers.String("imageID", workload.ImageHash)) + logger.L().Ctx(ctx).Warning("error storing SBOM", helpers.Error(err), helpers.String("imageID", workload.ImageID)) } } } @@ -184,7 +184,7 @@ func (s *ScanService) ScanCVE(ctx context.Context) error { if s.storage { err = s.cveRepository.StoreCVE(ctx, cve, false) if err != nil { - logger.L().Ctx(ctx).Warning("error storing CVE", helpers.Error(err), helpers.String("imageID", workload.ImageHash)) + logger.L().Ctx(ctx).Warning("error storing CVE", helpers.Error(err), helpers.String("imageID", workload.ImageID)) } } } @@ -219,7 +219,7 @@ func (s *ScanService) ScanCVE(ctx context.Context) error { // report scan success to platform err = s.platform.SendStatus(ctx, domain.Success) if err != nil { - logger.L().Ctx(ctx).Warning("telemetry error", helpers.Error(err), helpers.String("imageID", workload.ImageHash)) + logger.L().Ctx(ctx).Warning("telemetry error", helpers.Error(err), helpers.String("imageID", workload.ImageID)) } // submit CVE manifest to platform err = s.platform.SubmitCVE(ctx, cve, cvep) @@ -229,10 +229,10 @@ func (s *ScanService) ScanCVE(ctx context.Context) error { // report submit success to platform err = s.platform.SendStatus(ctx, domain.Done) if err != nil { - logger.L().Ctx(ctx).Warning("telemetry error", helpers.Error(err), helpers.String("imageID", workload.ImageHash)) + logger.L().Ctx(ctx).Warning("telemetry error", helpers.Error(err), helpers.String("imageID", workload.ImageID)) } - logger.L().Info("scan complete", helpers.String("imageID", workload.ImageHash), helpers.String("jobID", workload.JobID)) + logger.L().Info("scan complete", helpers.String("imageID", workload.ImageID), helpers.String("jobID", workload.JobID)) return nil } @@ -247,16 +247,16 @@ func (s *ScanService) ScanRegistry(ctx context.Context) error { if !ok { return domain.ErrMissingWorkload } - logger.L().Info("registry scan started", helpers.String("imageID", workload.ImageTag), helpers.String("jobID", workload.JobID)) + logger.L().Info("registry scan started", helpers.String("imageID", workload.ImageID), helpers.String("jobID", workload.JobID)) // report to platform err := s.platform.SendStatus(ctx, domain.Started) if err != nil { - logger.L().Ctx(ctx).Warning("telemetry error", helpers.Error(err), helpers.String("imageID", workload.ImageTag)) + logger.L().Ctx(ctx).Warning("telemetry error", helpers.Error(err), helpers.String("imageID", workload.ImageID)) } // create SBOM - sbom, err := s.sbomCreator.CreateSBOM(ctx, workload.ImageTag, optionsFromWorkload(workload)) + sbom, err := s.sbomCreator.CreateSBOM(ctx, workload.ImageID, workload.ImageTag, optionsFromWorkload(workload)) s.checkCreateSBOM(err, workload.ImageTag) if err != nil { return err @@ -276,7 +276,7 @@ func (s *ScanService) ScanRegistry(ctx context.Context) error { // report scan success to platform err = s.platform.SendStatus(ctx, domain.Success) if err != nil { - logger.L().Ctx(ctx).Warning("telemetry error", helpers.Error(err), helpers.String("imageID", workload.ImageTag)) + logger.L().Ctx(ctx).Warning("telemetry error", helpers.Error(err), helpers.String("imageID", workload.ImageID)) } // submit CVE manifest to platform err = s.platform.SubmitCVE(ctx, cve, domain.CVEManifest{}) @@ -286,10 +286,10 @@ func (s *ScanService) ScanRegistry(ctx context.Context) error { // report submit success to platform err = s.platform.SendStatus(ctx, domain.Done) if err != nil { - logger.L().Ctx(ctx).Warning("telemetry error", helpers.Error(err), helpers.String("imageID", workload.ImageTag)) + logger.L().Ctx(ctx).Warning("telemetry error", helpers.Error(err), helpers.String("imageID", workload.ImageID)) } - logger.L().Info("registry scan complete", helpers.String("imageID", workload.ImageTag), helpers.String("jobID", workload.JobID)) + logger.L().Info("registry scan complete", helpers.String("imageID", workload.ImageID), helpers.String("jobID", workload.JobID)) return nil } @@ -346,11 +346,11 @@ func (s *ScanService) ValidateGenerateSBOM(ctx context.Context, workload domain. ctx = enrichContext(ctx, workload) // validate inputs if workload.ImageHash == "" { - return ctx, domain.ErrMissingImageID + return ctx, domain.ErrMissingImageInfo } // add imageID to parent span if parentSpan := trace.SpanFromContext(ctx); parentSpan != nil { - parentSpan.SetAttributes(attribute.String("imageID", workload.ImageHash)) + parentSpan.SetAttributes(attribute.String("imageID", workload.ImageID)) parentSpan.SetAttributes(attribute.String("version", os.Getenv("RELEASE"))) ctx = trace.ContextWithSpan(ctx, parentSpan) } @@ -368,14 +368,14 @@ func (s *ScanService) ValidateScanCVE(ctx context.Context, workload domain.ScanC ctx = enrichContext(ctx, workload) // validate inputs if workload.ImageHash == "" { - return ctx, domain.ErrMissingImageID + return ctx, domain.ErrMissingImageInfo } // add instanceID and imageID to parent span if parentSpan := trace.SpanFromContext(ctx); parentSpan != nil { if workload.InstanceID != "" { parentSpan.SetAttributes(attribute.String("instanceID", workload.InstanceID)) } - parentSpan.SetAttributes(attribute.String("imageID", workload.ImageHash)) + parentSpan.SetAttributes(attribute.String("imageID", workload.ImageID)) parentSpan.SetAttributes(attribute.String("version", os.Getenv("RELEASE"))) parentSpan.SetAttributes(attribute.String("wlid", workload.Wlid)) ctx = trace.ContextWithSpan(ctx, parentSpan) @@ -399,11 +399,11 @@ func (s *ScanService) ValidateScanRegistry(ctx context.Context, workload domain. ctx = enrichContext(ctx, workload) // validate inputs if workload.ImageTag == "" { - return ctx, domain.ErrMissingImageID + return ctx, domain.ErrMissingImageInfo } // add imageID to parent span if parentSpan := trace.SpanFromContext(ctx); parentSpan != nil { - parentSpan.SetAttributes(attribute.String("imageID", workload.ImageTag)) + parentSpan.SetAttributes(attribute.String("imageID", workload.ImageID)) parentSpan.SetAttributes(attribute.String("version", os.Getenv("RELEASE"))) ctx = trace.ContextWithSpan(ctx, parentSpan) } diff --git a/core/services/scan_test.go b/core/services/scan_test.go index f44b992..a7eec24 100644 --- a/core/services/scan_test.go +++ b/core/services/scan_test.go @@ -256,14 +256,14 @@ func TestScanService_ScanCVE(t *testing.T) { tools.EnsureSetup(t, err == nil) } if tt.sbom { - sbom, err := sbomAdapter.CreateSBOM(ctx, imageHash, domain.RegistryOptions{}) + sbom, err := sbomAdapter.CreateSBOM(ctx, "sbom", imageHash, domain.RegistryOptions{}) tools.EnsureSetup(t, err == nil) _ = storageSBOM.StoreSBOM(ctx, sbom) } var sbomp domain.SBOM if tt.instanceID != "" { var err error - sbomp, err = sbomAdapter.CreateSBOM(ctx, tt.instanceID, domain.RegistryOptions{}) + sbomp, err = sbomAdapter.CreateSBOM(ctx, tt.instanceID, tt.instanceID, domain.RegistryOptions{}) tools.EnsureSetup(t, err == nil) sbomp.Labels = map[string]string{"foo": "bar"} _ = storageSBOM.StoreSBOM(ctx, sbomp) @@ -297,6 +297,7 @@ func fileToSBOM(path string) *v1beta1.Document { func TestScanService_NginxTest(t *testing.T) { imageHash := "docker.io/library/nginx@sha256:32fdf92b4e986e109e4db0865758020cb0c3b70d6ba80d02fe87bad5cc3dc228" + imageID := "name" instanceID := "1c83b589d90ba26957627525e08124b1a24732755a330924f7987e9d9e3952c1" ctx := context.TODO() sbomAdapter := adapters.NewMockSBOMAdapter(false, false, false) @@ -312,13 +313,14 @@ func TestScanService_NginxTest(t *testing.T) { workload := domain.ScanCommand{ ContainerName: "nginx", ImageHash: imageHash, + ImageID: imageID, ImageTag: "docker.io/library/nginx:1.14.1", InstanceID: instanceID, Wlid: "wlid://cluster-minikube/namespace-default/deployment-nginx", } ctx, _ = s.ValidateScanCVE(ctx, workload) sbom := domain.SBOM{ - ID: imageHash, + ID: imageID, Content: fileToSBOM("../../adapters/v1/testdata/nginx-sbom.json"), SBOMCreatorVersion: sbomAdapter.Version(), } diff --git a/go.mod b/go.mod index a175153..44dc0ae 100644 --- a/go.mod +++ b/go.mod @@ -24,7 +24,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 github.com/kinbiko/jsonassert v1.1.1 github.com/kubescape/go-logger v0.0.11 - github.com/kubescape/k8s-interface v0.0.123 + github.com/kubescape/k8s-interface v0.0.125 github.com/kubescape/storage v0.2.0 github.com/spdx/tools-golang v0.5.0-rc1 github.com/spf13/viper v1.15.0 diff --git a/go.sum b/go.sum index 46460ce..efdf8d9 100644 --- a/go.sum +++ b/go.sum @@ -680,8 +680,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kubescape/go-logger v0.0.11 h1:oucpq2S7+DT7O+UclG5IrmHado/tj6+IkYf9czVk/aY= github.com/kubescape/go-logger v0.0.11/go.mod h1:yGiKBJ2lhq/kxzY/MVYDREL9fLV3RGD6gv+UFjslaew= -github.com/kubescape/k8s-interface v0.0.123 h1:7KjQ1bHoaggzAPcufdT6NZeffyL4t0WWZBoaJ1tCgmY= -github.com/kubescape/k8s-interface v0.0.123/go.mod h1:ENpA9SkkS6E3PIT+AaMu/JGkuyE04aUamY+a7WLqsJQ= +github.com/kubescape/k8s-interface v0.0.125 h1:s5+vEz/HxdhdlqtcFJLzu3jmBEK9OhSfo3/8ZanThg4= +github.com/kubescape/k8s-interface v0.0.125/go.mod h1:ENpA9SkkS6E3PIT+AaMu/JGkuyE04aUamY+a7WLqsJQ= github.com/kubescape/storage v0.2.0 h1:WZXy4Dyjf5ltEMtk0SOD9RFL1haS9ffFPGfs1gUV1aM= github.com/kubescape/storage v0.2.0/go.mod h1:sPE749pFNoxoskBn6JTpNQyguF2rv/u2kYqzRd3MvXw= github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= diff --git a/repositories/apiserver.go b/repositories/apiserver.go index 4291cb0..c73c82c 100644 --- a/repositories/apiserver.go +++ b/repositories/apiserver.go @@ -2,13 +2,9 @@ package repositories import ( "context" - "fmt" - "regexp" "strconv" - "strings" "time" - "github.com/distribution/distribution/reference" "github.com/kubescape/go-logger" "github.com/kubescape/go-logger/helpers" "github.com/kubescape/k8s-interface/instanceidhandler/v1" @@ -36,10 +32,6 @@ var _ ports.CVERepository = (*APIServerStore)(nil) var _ ports.SBOMRepository = (*APIServerStore)(nil) -var re = regexp.MustCompile(`([a-f0-9]{64})`) - -const ImageHashLength = 64 - // NewAPIServerStorage initializes the APIServerStore struct func NewAPIServerStorage(namespace string) (*APIServerStore, error) { config, err := rest.InClusterConfig() @@ -63,37 +55,6 @@ func NewFakeAPIServerStorage(namespace string) *APIServerStore { } } -func newImageHashError(imageID string) error { - return fmt.Errorf("failed to get image hash from imageID: %s", imageID) -} -func getImageHash(imageID string) (string, error) { - if match := re.FindStringSubmatch(imageID); len(match) > 1 { - return match[1], nil - } - return "", newImageHashError(imageID) -} - -func hashFromImageID(imageID string) (string, error) { - // Check if the imageID is a plain SHA256 hash - if len(imageID) == ImageHashLength && re.MatchString(imageID) { - return imageID, nil - } - - match := reference.ReferenceRegexp.FindStringSubmatch(imageID) - - if len(match) < 3 || match[3] == "" { - // Fall back to getImageHash if not enough submatches or if the third submatch is empty - return getImageHash(imageID) - } - - if s := strings.Split(match[3], ":"); len(s) > 1 { - // If there's a ":" in the third submatch, return the part after it - return s[1], nil - } - - return "", newImageHashError(imageID) -} - func (a *APIServerStore) GetCVE(ctx context.Context, imageID, SBOMCreatorVersion, CVEScannerVersion, CVEDBVersion string) (cve domain.CVEManifest, err error) { _, span := otel.Tracer("").Start(ctx, "APIServerStore.GetCVE") defer span.End() @@ -101,12 +62,7 @@ func (a *APIServerStore) GetCVE(ctx context.Context, imageID, SBOMCreatorVersion logger.L().Debug("empty image ID provided, skipping CVE retrieval") return domain.CVEManifest{}, nil } - imageHash, err := hashFromImageID(imageID) - if err != nil { - logger.L().Ctx(ctx).Warning("failed to get CVE manifest from apiserver", helpers.Error(err), helpers.String("ID", imageID)) - return domain.CVEManifest{}, nil - } - manifest, err := a.StorageClient.VulnerabilityManifests(a.Namespace).Get(context.Background(), imageHash, metav1.GetOptions{}) + manifest, err := a.StorageClient.VulnerabilityManifests(a.Namespace).Get(context.Background(), imageID, metav1.GetOptions{}) switch { case errors.IsNotFound(err): logger.L().Debug("CVE manifest not found in storage", helpers.String("ID", imageID)) @@ -148,14 +104,9 @@ func (a *APIServerStore) StoreCVE(ctx context.Context, cve domain.CVEManifest, w cve.Labels[v1.ContextMetadataKey] = v1.ContextMetadataKeyNonFiltered } - name, e := hashFromImageID(cve.ID) - if e != nil { - logger.L().Debug("skipping storing CVE manifest with unsupported ID", helpers.Error(e)) - return nil - } manifest := v1beta1.VulnerabilityManifest{ ObjectMeta: metav1.ObjectMeta{ - Name: name, + Name: cve.ID, Annotations: cve.Annotations, Labels: cve.Labels, }, @@ -179,7 +130,7 @@ func (a *APIServerStore) StoreCVE(ctx context.Context, cve domain.CVEManifest, w retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { // retrieve the latest version before attempting update // RetryOnConflict uses exponential backoff to avoid exhausting the apiserver - result, getErr := a.StorageClient.VulnerabilityManifests(a.Namespace).Get(context.Background(), name, metav1.GetOptions{}) + result, getErr := a.StorageClient.VulnerabilityManifests(a.Namespace).Get(context.Background(), cve.ID, metav1.GetOptions{}) if getErr != nil { return getErr } @@ -211,12 +162,7 @@ func (a *APIServerStore) GetSBOM(ctx context.Context, imageID, SBOMCreatorVersio logger.L().Debug("empty image ID provided, skipping SBOM retrieval") return domain.SBOM{}, nil } - imageHash, err := hashFromImageID(imageID) - if err != nil { - logger.L().Debug("unsupported image ID provided, skipping SBOM retrieval") - return domain.SBOM{}, nil - } - manifest, err := a.StorageClient.SBOMSPDXv2p3s(a.Namespace).Get(context.Background(), imageHash, metav1.GetOptions{}) + manifest, err := a.StorageClient.SBOMSPDXv2p3s(a.Namespace).Get(context.Background(), imageID, metav1.GetOptions{}) switch { case errors.IsNotFound(err): logger.L().Debug("SBOM manifest not found in storage", helpers.String("ID", imageID)) @@ -290,14 +236,9 @@ func (a *APIServerStore) StoreSBOM(ctx context.Context, sbom domain.SBOM) error logger.L().Debug("skipping storing SBOM with empty ID") return nil } - imageHash, e := hashFromImageID(sbom.ID) - if e != nil { - logger.L().Debug("skipping storing SBOM with unknown SBOM ID", helpers.String("ID", sbom.ID), helpers.Error(e)) - return nil - } manifest := v1beta1.SBOMSPDXv2p3{ ObjectMeta: metav1.ObjectMeta{ - Name: imageHash, + Name: sbom.ID, Annotations: sbom.Annotations, Labels: sbom.Labels, }, diff --git a/repositories/apiserver_test.go b/repositories/apiserver_test.go index 6e34194..967938c 100644 --- a/repositories/apiserver_test.go +++ b/repositories/apiserver_test.go @@ -351,51 +351,3 @@ func TestAPIServerStore_GetSBOMp(t *testing.T) { }) } } - -func Test_extractHashFromImageID(t *testing.T) { - tests := []struct { - name string - imageID string - want string - err bool - }{ - { - name: "no tag", - imageID: "k8s.gcr.io/kube-proxy@sha256:c1b135231b5b1a6799346cd701da4b59e5b7ef8e694ec7b04fb23b8dbe144137", - want: "c1b135231b5b1a6799346cd701da4b59e5b7ef8e694ec7b04fb23b8dbe144137", - }, - { - name: "with tag", - imageID: "library/nginx:v1.21.0@sha256:c1b135231b5b1a6799346cd701da4b59e5b7ef8e694ec7b04fb23b8dbe144137", - want: "c1b135231b5b1a6799346cd701da4b59e5b7ef8e694ec7b04fb23b8dbe144137", - }, - { - name: "only hash", - imageID: "c1b135231b5b1a6799346cd701da4b59e5b7ef8e694ec7b04fb23b8dbe144137", - want: "c1b135231b5b1a6799346cd701da4b59e5b7ef8e694ec7b04fb23b8dbe144137", - }, - { - name: "sha256 hash", - imageID: "sha256:c1b135231b5b1a6799346cd701da4b59e5b7ef8e694ec7b04fb23b8dbe144137", - want: "c1b135231b5b1a6799346cd701da4b59e5b7ef8e694ec7b04fb23b8dbe144137", - }, - { - name: "docker imageID", - imageID: "docker://sha256:c1b135231b5b1a6799346cd701da4b59e5b7ef8e694ec7b04fb23b8dbe144137", - want: "c1b135231b5b1a6799346cd701da4b59e5b7ef8e694ec7b04fb23b8dbe144137", - }, - { - name: "empty imageID", - imageID: "", - want: "", - err: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got, e := hashFromImageID(tt.imageID); got != tt.want || (e != nil) != tt.err { - t.Errorf("hashFromImageID() = %v, want %v", got, tt.want) - } - }) - } -}