Skip to content

Commit

Permalink
Delete scan_report when accessory is removed (#20365)
Browse files Browse the repository at this point in the history
Signed-off-by: stonezdj <stone.zhang@broadcom.com>
  • Loading branch information
stonezdj committed Apr 27, 2024
1 parent 9471f5d commit fba4c40
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 2 deletions.
7 changes: 7 additions & 0 deletions src/controller/event/handler/internal/artifact.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"time"

"github.com/goharbor/harbor/src/controller/artifact"
"github.com/goharbor/harbor/src/controller/artifact/processor/sbom"
"github.com/goharbor/harbor/src/controller/event"
"github.com/goharbor/harbor/src/controller/event/operator"
"github.com/goharbor/harbor/src/controller/repository"
Expand All @@ -36,6 +37,7 @@ import (
"github.com/goharbor/harbor/src/pkg"
pkgArt "github.com/goharbor/harbor/src/pkg/artifact"
"github.com/goharbor/harbor/src/pkg/scan/report"
v1 "github.com/goharbor/harbor/src/pkg/scan/rest/v1"
"github.com/goharbor/harbor/src/pkg/task"
)

Expand Down Expand Up @@ -319,6 +321,11 @@ func (a *ArtifactEventHandler) onDelete(ctx context.Context, event *event.Artifa
log.Errorf("failed to delete scan reports of artifact %v, error: %v", unrefDigests, err)
}

if event.Artifact.Type == sbom.ArtifactTypeSBOM && len(event.Artifact.Digest) > 0 {
if err := reportMgr.DeleteByExtraAttr(ctx, v1.MimeTypeSBOMReport, "sbom_digest", event.Artifact.Digest); err != nil {
log.Errorf("failed to delete scan reports of with sbom digest %v, error: %v", event.Artifact.Digest, err)
}
}
return nil
}

Expand Down
14 changes: 14 additions & 0 deletions src/pkg/scan/dao/scan/report.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package scan

import (
"context"
"fmt"

"github.com/goharbor/harbor/src/lib/errors"
"github.com/goharbor/harbor/src/lib/orm"
Expand All @@ -38,6 +39,8 @@ type DAO interface {
UpdateReportData(ctx context.Context, uuid string, report string) error
// Update update report
Update(ctx context.Context, r *Report, cols ...string) error
// DeleteByExtraAttr delete the scan_report by mimeType and extra attribute
DeleteByExtraAttr(ctx context.Context, mimeType, attrName, attrValue string) error
}

// New returns an instance of the default DAO
Expand Down Expand Up @@ -110,3 +113,14 @@ func (d *dao) Update(ctx context.Context, r *Report, cols ...string) error {
}
return nil
}

func (d *dao) DeleteByExtraAttr(ctx context.Context, mimeType, attrName, attrValue string) error {
o, err := orm.FromContext(ctx)
if err != nil {
return err
}
delReportSQL := "delete from scan_report where mime_type = ? and report::jsonb @> ?"
dgstJSONStr := fmt.Sprintf(`{"%s":"%s"}`, attrName, attrValue)
_, err = o.Raw(delReportSQL, mimeType, dgstJSONStr).Exec()
return err
}
24 changes: 22 additions & 2 deletions src/pkg/scan/dao/scan/report_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,23 @@ func (suite *ReportTestSuite) SetupTest() {
RegistrationUUID: "ruuid",
MimeType: v1.MimeTypeNativeReport,
}

suite.create(r)
sbomReport := &Report{
UUID: "uuid3",
Digest: "digest1003",
RegistrationUUID: "ruuid",
MimeType: v1.MimeTypeSBOMReport,
Report: `{"sbom_digest": "sha256:abc"}`,
}
suite.create(sbomReport)
}

// TearDownTest clears enf for test case.
func (suite *ReportTestSuite) TearDownTest() {
_, err := suite.dao.DeleteMany(orm.Context(), q.Query{Keywords: q.KeyWords{"uuid": "uuid"}})
require.NoError(suite.T(), err)
_, err = suite.dao.DeleteMany(orm.Context(), q.Query{Keywords: q.KeyWords{"uuid": "uuid3"}})
require.NoError(suite.T(), err)
}

// TestReportList tests list reports with query parameters.
Expand Down Expand Up @@ -95,7 +104,7 @@ func (suite *ReportTestSuite) TestReportUpdateReportData() {
err := suite.dao.UpdateReportData(orm.Context(), "uuid", "{}")
suite.Require().NoError(err)

l, err := suite.dao.List(orm.Context(), nil)
l, err := suite.dao.List(orm.Context(), q.New(q.KeyWords{"uuid": "uuid"}))
suite.Require().NoError(err)
suite.Require().Equal(1, len(l))
suite.Equal("{}", l[0].Report)
Expand All @@ -104,6 +113,17 @@ func (suite *ReportTestSuite) TestReportUpdateReportData() {
suite.Require().NoError(err)
}

func (suite *ReportTestSuite) TestDeleteReportBySBOMDigest() {
l, err := suite.dao.List(orm.Context(), nil)
suite.Require().NoError(err)
suite.Equal(2, len(l))
err = suite.dao.DeleteByExtraAttr(orm.Context(), v1.MimeTypeSBOMReport, "sbom_digest", "sha256:abc")
suite.Require().NoError(err)
l2, err := suite.dao.List(orm.Context(), nil)
suite.Require().NoError(err)
suite.Equal(1, len(l2))
}

func (suite *ReportTestSuite) create(r *Report) {
id, err := suite.dao.Create(orm.Context(), r)
suite.Require().NoError(err)
Expand Down
6 changes: 6 additions & 0 deletions src/pkg/scan/report/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ type Manager interface {

// Update update report information
Update(ctx context.Context, r *scan.Report, cols ...string) error
// DeleteByExtraAttr delete scan_report by sbom_digest
DeleteByExtraAttr(ctx context.Context, mimeType, attrName, attrValue string) error
}

// basicManager is a default implementation of report manager.
Expand Down Expand Up @@ -226,3 +228,7 @@ func (bm *basicManager) List(ctx context.Context, query *q.Query) ([]*scan.Repor
func (bm *basicManager) Update(ctx context.Context, r *scan.Report, cols ...string) error {
return bm.dao.Update(ctx, r, cols...)
}

func (bm *basicManager) DeleteByExtraAttr(ctx context.Context, mimeType, attrName, attrValue string) error {
return bm.dao.DeleteByExtraAttr(ctx, mimeType, attrName, attrValue)
}
18 changes: 18 additions & 0 deletions src/testing/pkg/scan/report/manager.go

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

0 comments on commit fba4c40

Please sign in to comment.