mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-22 02:05:41 +01:00
Add scanner info and report_id to sbom_overview on listing artifact (#20358)
Add scan_status and report_id when scan has a failed task Signed-off-by: stonezdj <stone.zhang@broadcom.com>
This commit is contained in:
parent
2af02f3b25
commit
ec8d692fe6
@ -6816,6 +6816,8 @@ definitions:
|
||||
format: int64
|
||||
description: 'Time in seconds required to create the report'
|
||||
example: 300
|
||||
scanner:
|
||||
$ref: '#/definitions/Scanner'
|
||||
NativeReportSummary:
|
||||
type: object
|
||||
description: 'The summary for the native report'
|
||||
|
@ -751,6 +751,11 @@ func (bc *basicController) GetSBOMSummary(ctx context.Context, art *ar.Artifact,
|
||||
reportContent := reports[0].Report
|
||||
result := map[string]interface{}{}
|
||||
if len(reportContent) == 0 {
|
||||
status := bc.retrieveStatusFromTask(ctx, reports[0].UUID)
|
||||
if len(status) > 0 {
|
||||
result[sbomModel.ReportID] = reports[0].UUID
|
||||
result[sbomModel.ScanStatus] = status
|
||||
}
|
||||
log.Debug("no content for current report")
|
||||
return result, nil
|
||||
}
|
||||
@ -758,6 +763,22 @@ func (bc *basicController) GetSBOMSummary(ctx context.Context, art *ar.Artifact,
|
||||
return result, err
|
||||
}
|
||||
|
||||
// retrieve the status from task
|
||||
func (bc *basicController) retrieveStatusFromTask(ctx context.Context, reportID string) string {
|
||||
if len(reportID) == 0 {
|
||||
return ""
|
||||
}
|
||||
tasks, err := bc.taskMgr.ListScanTasksByReportUUID(ctx, reportID)
|
||||
if err != nil {
|
||||
log.Warningf("can not find the task with report UUID %v, error %v", reportID, err)
|
||||
return ""
|
||||
}
|
||||
if len(tasks) > 0 {
|
||||
return tasks[0].Status
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// GetScanLog ...
|
||||
func (bc *basicController) GetScanLog(ctx context.Context, artifact *ar.Artifact, uuid string) ([]byte, error) {
|
||||
if len(uuid) == 0 {
|
||||
|
@ -70,9 +70,10 @@ type ControllerTestSuite struct {
|
||||
|
||||
tagCtl *tagtesting.FakeController
|
||||
|
||||
registration *scanner.Registration
|
||||
artifact *artifact.Artifact
|
||||
rawReport string
|
||||
registration *scanner.Registration
|
||||
artifact *artifact.Artifact
|
||||
wrongArtifact *artifact.Artifact
|
||||
rawReport string
|
||||
|
||||
execMgr *tasktesting.ExecutionManager
|
||||
taskMgr *tasktesting.Manager
|
||||
@ -101,6 +102,9 @@ func (suite *ControllerTestSuite) SetupSuite() {
|
||||
suite.artifact.Digest = "digest-code"
|
||||
suite.artifact.ManifestMediaType = v1.MimeTypeDockerArtifact
|
||||
|
||||
suite.wrongArtifact = &artifact.Artifact{Artifact: art.Artifact{ID: 2, ProjectID: 1}}
|
||||
suite.wrongArtifact.Digest = "digest-wrong"
|
||||
|
||||
m := &v1.ScannerAdapterMetadata{
|
||||
Scanner: &v1.Scanner{
|
||||
Name: "Trivy",
|
||||
@ -202,8 +206,11 @@ func (suite *ControllerTestSuite) SetupSuite() {
|
||||
Report: `{"sbom_digest": "sha256:1234567890", "scan_status": "Success", "duration": 3, "start_time": "2021-09-01T00:00:00Z", "end_time": "2021-09-01T00:00:03Z"}`,
|
||||
},
|
||||
}
|
||||
|
||||
emptySBOMReport := []*scan.Report{{Report: ``, UUID: "rp-uuid-004"}}
|
||||
mgr.On("GetBy", mock.Anything, suite.artifact.Digest, suite.registration.UUID, []string{v1.MimeTypeNativeReport}).Return(reports, nil)
|
||||
mgr.On("GetBy", mock.Anything, suite.artifact.Digest, suite.registration.UUID, []string{v1.MimeTypeSBOMReport}).Return(sbomReport, nil)
|
||||
mgr.On("GetBy", mock.Anything, suite.wrongArtifact.Digest, suite.registration.UUID, []string{v1.MimeTypeSBOMReport}).Return(emptySBOMReport, nil)
|
||||
mgr.On("Get", mock.Anything, "rp-uuid-001").Return(reports[0], nil)
|
||||
mgr.On("UpdateReportData", "rp-uuid-001", suite.rawReport, (int64)(10000)).Return(nil)
|
||||
mgr.On("UpdateStatus", "the-uuid-123", "Success", (int64)(10000)).Return(nil)
|
||||
@ -654,6 +661,12 @@ func (suite *ControllerTestSuite) TestGenerateSBOMSummary() {
|
||||
suite.NotNil(dgst)
|
||||
suite.Equal("Success", status)
|
||||
suite.Equal("sha256:1234567890", dgst)
|
||||
tasks := []*task.Task{{Status: "Error"}}
|
||||
suite.taskMgr.On("ListScanTasksByReportUUID", mock.Anything, "rp-uuid-004").Return(tasks, nil).Once()
|
||||
sum2, err := suite.c.GetSummary(context.TODO(), suite.wrongArtifact, []string{v1.MimeTypeSBOMReport})
|
||||
suite.Nil(err)
|
||||
suite.NotNil(sum2)
|
||||
|
||||
}
|
||||
|
||||
func TestIsSBOMMimeTypes(t *testing.T) {
|
||||
@ -683,5 +696,11 @@ func (suite *ControllerTestSuite) TestDeleteArtifactAccessories() {
|
||||
}
|
||||
ctx := orm.NewContext(nil, &ormtesting.FakeOrmer{})
|
||||
suite.NoError(suite.c.deleteArtifactAccessories(ctx, reports))
|
||||
|
||||
}
|
||||
|
||||
func (suite *ControllerTestSuite) TestRetrieveStatusFromTask() {
|
||||
tasks := []*task.Task{{Status: "Error"}}
|
||||
suite.taskMgr.On("ListScanTasksByReportUUID", mock.Anything, "rp-uuid-004").Return(tasks, nil).Once()
|
||||
status := suite.c.retrieveStatusFromTask(nil, "rp-uuid-004")
|
||||
suite.Equal("Error", status)
|
||||
}
|
||||
|
@ -27,6 +27,10 @@ const (
|
||||
Duration = "duration"
|
||||
// ScanStatus ...
|
||||
ScanStatus = "scan_status"
|
||||
// ReportID ...
|
||||
ReportID = "report_id"
|
||||
// Scanner ...
|
||||
Scanner = "scanner"
|
||||
)
|
||||
|
||||
// Summary includes the sbom summary information
|
||||
|
@ -87,7 +87,7 @@ func (v *scanHandler) RequiredPermissions() []*types.Policy {
|
||||
|
||||
// PostScan defines task specific operations after the scan is complete
|
||||
func (v *scanHandler) PostScan(ctx job.Context, sr *v1.ScanRequest, _ *scanModel.Report, rawReport string, startTime time.Time, robot *model.Robot) (string, error) {
|
||||
sbomContent, err := retrieveSBOMContent(rawReport)
|
||||
sbomContent, s, err := retrieveSBOMContent(rawReport)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@ -107,7 +107,7 @@ func (v *scanHandler) PostScan(ctx job.Context, sr *v1.ScanRequest, _ *scanModel
|
||||
myLogger.Errorf("error when create accessory from image %v", err)
|
||||
return "", err
|
||||
}
|
||||
return v.generateReport(startTime, sr.Artifact.Repository, dgst, "Success")
|
||||
return v.generateReport(startTime, sr.Artifact.Repository, dgst, "Success", s)
|
||||
}
|
||||
|
||||
// annotations defines the annotations for the accessory artifact
|
||||
@ -121,7 +121,7 @@ func (v *scanHandler) annotations() map[string]string {
|
||||
}
|
||||
}
|
||||
|
||||
func (v *scanHandler) generateReport(startTime time.Time, repository, digest, status string) (string, error) {
|
||||
func (v *scanHandler) generateReport(startTime time.Time, repository, digest, status string, scanner *v1.Scanner) (string, error) {
|
||||
summary := sbom.Summary{}
|
||||
endTime := time.Now()
|
||||
summary[sbom.StartTime] = startTime
|
||||
@ -130,6 +130,7 @@ func (v *scanHandler) generateReport(startTime time.Time, repository, digest, st
|
||||
summary[sbom.SBOMRepository] = repository
|
||||
summary[sbom.SBOMDigest] = digest
|
||||
summary[sbom.ScanStatus] = status
|
||||
summary[sbom.Scanner] = scanner
|
||||
rep, err := json.Marshal(summary)
|
||||
if err != nil {
|
||||
return "", err
|
||||
@ -150,15 +151,15 @@ func registryFQDN(ctx context.Context) string {
|
||||
}
|
||||
|
||||
// retrieveSBOMContent retrieves the "sbom" field from the raw report
|
||||
func retrieveSBOMContent(rawReport string) ([]byte, error) {
|
||||
func retrieveSBOMContent(rawReport string) ([]byte, *v1.Scanner, error) {
|
||||
rpt := vuln.Report{}
|
||||
err := json.Unmarshal([]byte(rawReport), &rpt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
sbomContent, err := json.Marshal(rpt.SBOM)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
return sbomContent, nil
|
||||
return sbomContent, rpt.Scanner, nil
|
||||
}
|
||||
|
@ -21,16 +21,12 @@ import (
|
||||
"github.com/goharbor/harbor/src/lib"
|
||||
"github.com/goharbor/harbor/src/lib/log"
|
||||
v1 "github.com/goharbor/harbor/src/pkg/scan/rest/v1"
|
||||
sbomModel "github.com/goharbor/harbor/src/pkg/scan/sbom/model"
|
||||
"github.com/goharbor/harbor/src/server/v2.0/handler/model"
|
||||
)
|
||||
|
||||
const (
|
||||
vulnerabilitiesAddition = "vulnerabilities"
|
||||
startTime = "start_time"
|
||||
endTime = "end_time"
|
||||
scanStatus = "scan_status"
|
||||
sbomDigest = "sbom_digest"
|
||||
duration = "duration"
|
||||
)
|
||||
|
||||
// NewScanReportAssembler returns vul assembler
|
||||
@ -92,17 +88,19 @@ func (assembler *ScanReportAssembler) Assemble(ctx context.Context) error {
|
||||
overview, err := assembler.scanCtl.GetSummary(ctx, &artifact.Artifact, []string{v1.MimeTypeSBOMReport})
|
||||
if err != nil {
|
||||
log.Warningf("get scan summary of artifact %s@%s for %s failed, error:%v", artifact.RepositoryName, artifact.Digest, v1.MimeTypeSBOMReport, err)
|
||||
} else if len(overview) > 0 {
|
||||
}
|
||||
if len(overview) > 0 {
|
||||
artifact.SBOMOverView = map[string]interface{}{
|
||||
startTime: overview[startTime],
|
||||
endTime: overview[endTime],
|
||||
scanStatus: overview[scanStatus],
|
||||
sbomDigest: overview[sbomDigest],
|
||||
duration: overview[duration],
|
||||
sbomModel.StartTime: overview[sbomModel.StartTime],
|
||||
sbomModel.EndTime: overview[sbomModel.EndTime],
|
||||
sbomModel.ScanStatus: overview[sbomModel.ScanStatus],
|
||||
sbomModel.SBOMDigest: overview[sbomModel.SBOMDigest],
|
||||
sbomModel.Duration: overview[sbomModel.Duration],
|
||||
sbomModel.ReportID: overview[sbomModel.ReportID],
|
||||
sbomModel.Scanner: overview[sbomModel.Scanner],
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user