Add scan type in webhook event (#20363)

fixes #20331

Signed-off-by: stonezdj <stone.zhang@broadcom.com>
This commit is contained in:
stonezdj(Daojun Zhang) 2024-04-29 21:51:09 +08:00 committed by GitHub
parent 9b5dd7951e
commit d154c27362
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 39 additions and 5 deletions

View File

@ -21,6 +21,7 @@ import (
"github.com/goharbor/harbor/src/controller/artifact" "github.com/goharbor/harbor/src/controller/artifact"
"github.com/goharbor/harbor/src/controller/event" "github.com/goharbor/harbor/src/controller/event"
"github.com/goharbor/harbor/src/controller/event/handler/util" "github.com/goharbor/harbor/src/controller/event/handler/util"
eventModel "github.com/goharbor/harbor/src/controller/event/model"
"github.com/goharbor/harbor/src/controller/project" "github.com/goharbor/harbor/src/controller/project"
"github.com/goharbor/harbor/src/controller/scan" "github.com/goharbor/harbor/src/controller/scan"
"github.com/goharbor/harbor/src/lib/errors" "github.com/goharbor/harbor/src/lib/errors"
@ -104,6 +105,9 @@ func constructScanImagePayload(ctx context.Context, event *event.ScanImageEvent,
RepoFullName: event.Artifact.Repository, RepoFullName: event.Artifact.Repository,
RepoType: repoType, RepoType: repoType,
}, },
Scan: &eventModel.Scan{
ScanType: event.ScanType,
},
}, },
Operator: event.Operator, Operator: event.Operator,
} }
@ -138,17 +142,29 @@ func constructScanImagePayload(ctx context.Context, event *event.ScanImageEvent,
time.Sleep(500 * time.Millisecond) time.Sleep(500 * time.Millisecond)
} }
// Add scan overview scanSummaries := map[string]interface{}{}
summaries, err := scan.DefaultController.GetSummary(ctx, art, []string{v1.MimeTypeNativeReport, v1.MimeTypeGenericVulnerabilityReport}) if event.ScanType == v1.ScanTypeVulnerability {
if err != nil { scanSummaries, err = scan.DefaultController.GetSummary(ctx, art, []string{v1.MimeTypeNativeReport, v1.MimeTypeGenericVulnerabilityReport})
return nil, errors.Wrap(err, "construct scan payload") if err != nil {
return nil, errors.Wrap(err, "construct scan payload")
}
} }
sbomOverview := map[string]interface{}{}
if event.ScanType == v1.ScanTypeSbom {
sbomOverview, err = scan.DefaultController.GetSummary(ctx, art, []string{v1.MimeTypeSBOMReport})
if err != nil {
return nil, errors.Wrap(err, "construct scan payload")
}
}
// Add scan overview and sbom overview
resource := &model.Resource{ resource := &model.Resource{
Tag: event.Artifact.Tag, Tag: event.Artifact.Tag,
Digest: event.Artifact.Digest, Digest: event.Artifact.Digest,
ResourceURL: resURL, ResourceURL: resURL,
ScanOverview: summaries, ScanOverview: scanSummaries,
SBOMOverview: sbomOverview,
} }
payload.EventData.Resources = append(payload.EventData.Resources, resource) payload.EventData.Resources = append(payload.EventData.Resources, resource)

View File

@ -27,6 +27,7 @@ import (
// ScanImageMetaData defines meta data of image scanning event // ScanImageMetaData defines meta data of image scanning event
type ScanImageMetaData struct { type ScanImageMetaData struct {
Artifact *v1.Artifact Artifact *v1.Artifact
ScanType string
Status string Status string
Operator string Operator string
} }
@ -55,6 +56,7 @@ func (si *ScanImageMetaData) Resolve(evt *event.Event) error {
Artifact: si.Artifact, Artifact: si.Artifact,
OccurAt: time.Now(), OccurAt: time.Now(),
Operator: si.Operator, Operator: si.Operator,
ScanType: si.ScanType,
} }
evt.Topic = topic evt.Topic = topic

View File

@ -74,3 +74,9 @@ type RetentionRule struct {
// Selector attached to the rule for filtering scope (e.g: repositories or namespaces) // Selector attached to the rule for filtering scope (e.g: repositories or namespaces)
ScopeSelectors map[string][]*rule.Selector `json:"scope_selectors,omitempty"` ScopeSelectors map[string][]*rule.Selector `json:"scope_selectors,omitempty"`
} }
// Scan describes scan infos
type Scan struct {
// ScanType the scan type
ScanType string `json:"scan_type,omitempty"`
}

View File

@ -289,6 +289,7 @@ func (d *DeleteTagEvent) String() string {
// ScanImageEvent is scanning image related event data to publish // ScanImageEvent is scanning image related event data to publish
type ScanImageEvent struct { type ScanImageEvent struct {
EventType string EventType string
ScanType string
Artifact *v1.Artifact Artifact *v1.Artifact
OccurAt time.Time OccurAt time.Time
Operator string Operator string

View File

@ -120,6 +120,13 @@ func scanTaskStatusChange(ctx context.Context, taskID int64, status string) (err
if operator, ok := exec.ExtraAttrs["operator"].(string); ok { if operator, ok := exec.ExtraAttrs["operator"].(string); ok {
e.Operator = operator e.Operator = operator
} }
// extract ScanType if exist in ExtraAttrs
if c, ok := exec.ExtraAttrs["enabled_capabilities"].(map[string]interface{}); ok {
if Type, ok := c["type"].(string); ok {
e.ScanType = Type
}
}
// fire event // fire event
notification.AddEvent(ctx, e) notification.AddEvent(ctx, e)
} }

View File

@ -42,6 +42,7 @@ type EventData struct {
Repository *Repository `json:"repository,omitempty"` Repository *Repository `json:"repository,omitempty"`
Replication *model.Replication `json:"replication,omitempty"` Replication *model.Replication `json:"replication,omitempty"`
Retention *model.Retention `json:"retention,omitempty"` Retention *model.Retention `json:"retention,omitempty"`
Scan *model.Scan `json:"scan,omitempty"`
Custom map[string]string `json:"custom_attributes,omitempty"` Custom map[string]string `json:"custom_attributes,omitempty"`
} }
@ -51,6 +52,7 @@ type Resource struct {
Tag string `json:"tag,omitempty"` Tag string `json:"tag,omitempty"`
ResourceURL string `json:"resource_url,omitempty"` ResourceURL string `json:"resource_url,omitempty"`
ScanOverview map[string]interface{} `json:"scan_overview,omitempty"` ScanOverview map[string]interface{} `json:"scan_overview,omitempty"`
SBOMOverview map[string]interface{} `json:"sbom_overview,omitempty"`
} }
// Repository info of notification event // Repository info of notification event