mirror of
https://github.com/goharbor/harbor.git
synced 2024-09-27 13:02:59 +02:00
91efec1e2a
Signed-off-by: Shengwen Yu <yshengwen@vmware.com>
371 lines
10 KiB
Go
371 lines
10 KiB
Go
// Copyright Project Harbor Authors
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package event
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/goharbor/harbor/src/common/rbac"
|
|
"github.com/goharbor/harbor/src/lib/selector"
|
|
"github.com/goharbor/harbor/src/pkg/artifact"
|
|
"github.com/goharbor/harbor/src/pkg/audit/model"
|
|
proModels "github.com/goharbor/harbor/src/pkg/project/models"
|
|
v1 "github.com/goharbor/harbor/src/pkg/scan/rest/v1"
|
|
)
|
|
|
|
// the event consumers can refer to this file to find all topics and the corresponding event structures
|
|
|
|
// const definition
|
|
const (
|
|
TopicCreateProject = "CREATE_PROJECT"
|
|
TopicDeleteProject = "DELETE_PROJECT"
|
|
TopicPushArtifact = "PUSH_ARTIFACT"
|
|
TopicPullArtifact = "PULL_ARTIFACT"
|
|
TopicDeleteArtifact = "DELETE_ARTIFACT"
|
|
TopicDeleteRepository = "DELETE_REPOSITORY"
|
|
TopicCreateTag = "CREATE_TAG"
|
|
TopicDeleteTag = "DELETE_TAG"
|
|
TopicScanningFailed = "SCANNING_FAILED"
|
|
TopicScanningStopped = "SCANNING_STOPPED"
|
|
TopicScanningCompleted = "SCANNING_COMPLETED"
|
|
// QuotaExceedTopic is topic for quota warning event, the usage reaches the warning bar of limitation, like 85%
|
|
TopicQuotaWarning = "QUOTA_WARNING"
|
|
TopicQuotaExceed = "QUOTA_EXCEED"
|
|
TopicReplication = "REPLICATION"
|
|
TopicArtifactLabeled = "ARTIFACT_LABELED"
|
|
TopicTagRetention = "TAG_RETENTION"
|
|
)
|
|
|
|
// CreateProjectEvent is the creating project event
|
|
type CreateProjectEvent struct {
|
|
EventType string
|
|
ProjectID int64
|
|
Project string
|
|
Operator string
|
|
OccurAt time.Time
|
|
}
|
|
|
|
// ResolveToAuditLog ...
|
|
func (c *CreateProjectEvent) ResolveToAuditLog() (*model.AuditLog, error) {
|
|
auditLog := &model.AuditLog{
|
|
ProjectID: c.ProjectID,
|
|
OpTime: c.OccurAt,
|
|
Operation: rbac.ActionCreate.String(),
|
|
Username: c.Operator,
|
|
ResourceType: "project",
|
|
Resource: c.Project}
|
|
return auditLog, nil
|
|
}
|
|
|
|
func (c *CreateProjectEvent) String() string {
|
|
return fmt.Sprintf("ID-%d Name-%s Operator-%s OccurAt-%s",
|
|
c.ProjectID, c.Project, c.Operator, c.OccurAt.Format("2006-01-02 15:04:05"))
|
|
}
|
|
|
|
// DeleteProjectEvent is the deleting project event
|
|
type DeleteProjectEvent struct {
|
|
EventType string
|
|
ProjectID int64
|
|
Project string
|
|
Operator string
|
|
OccurAt time.Time
|
|
}
|
|
|
|
// ResolveToAuditLog ...
|
|
func (d *DeleteProjectEvent) ResolveToAuditLog() (*model.AuditLog, error) {
|
|
auditLog := &model.AuditLog{
|
|
ProjectID: d.ProjectID,
|
|
OpTime: d.OccurAt,
|
|
Operation: rbac.ActionDelete.String(),
|
|
Username: d.Operator,
|
|
ResourceType: "project",
|
|
Resource: d.Project}
|
|
return auditLog, nil
|
|
}
|
|
|
|
func (d *DeleteProjectEvent) String() string {
|
|
return fmt.Sprintf("ID-%d Name-%s Operator-%s OccurAt-%s",
|
|
d.ProjectID, d.Project, d.Operator, d.OccurAt.Format("2006-01-02 15:04:05"))
|
|
}
|
|
|
|
// DeleteRepositoryEvent is the deleting repository event
|
|
type DeleteRepositoryEvent struct {
|
|
EventType string
|
|
ProjectID int64
|
|
Repository string
|
|
Operator string
|
|
OccurAt time.Time
|
|
}
|
|
|
|
// ResolveToAuditLog ...
|
|
func (d *DeleteRepositoryEvent) ResolveToAuditLog() (*model.AuditLog, error) {
|
|
auditLog := &model.AuditLog{
|
|
ProjectID: d.ProjectID,
|
|
OpTime: d.OccurAt,
|
|
Operation: rbac.ActionDelete.String(),
|
|
Username: d.Operator,
|
|
ResourceType: "repository",
|
|
Resource: d.Repository,
|
|
}
|
|
return auditLog, nil
|
|
}
|
|
|
|
func (d *DeleteRepositoryEvent) String() string {
|
|
return fmt.Sprintf("ID-%d Repository-%s Operator-%s OccurAt-%s",
|
|
d.ProjectID, d.Repository, d.Operator, d.OccurAt.Format("2006-01-02 15:04:05"))
|
|
}
|
|
|
|
// ArtifactEvent is the pushing/pulling artifact event
|
|
type ArtifactEvent struct {
|
|
EventType string
|
|
Repository string
|
|
Artifact *artifact.Artifact
|
|
Tags []string // when the artifact is pushed by digest, the tag here will be null
|
|
Operator string
|
|
OccurAt time.Time
|
|
}
|
|
|
|
func (a *ArtifactEvent) String() string {
|
|
return fmt.Sprintf("ID-%d, Repository-%s Tags-%s Digest-%s Operator-%s OccurAt-%s",
|
|
a.Artifact.ID, a.Repository, a.Tags, a.Artifact.Digest, a.Operator,
|
|
a.OccurAt.Format("2006-01-02 15:04:05"))
|
|
}
|
|
|
|
// PushArtifactEvent is the pushing artifact event
|
|
type PushArtifactEvent struct {
|
|
*ArtifactEvent
|
|
}
|
|
|
|
// ResolveToAuditLog ...
|
|
func (p *PushArtifactEvent) ResolveToAuditLog() (*model.AuditLog, error) {
|
|
auditLog := &model.AuditLog{
|
|
ProjectID: p.Artifact.ProjectID,
|
|
OpTime: p.OccurAt,
|
|
Operation: rbac.ActionCreate.String(),
|
|
Username: p.Operator,
|
|
ResourceType: "artifact"}
|
|
|
|
if len(p.Tags) == 0 {
|
|
auditLog.Resource = fmt.Sprintf("%s:%s",
|
|
p.Artifact.RepositoryName, p.Artifact.Digest)
|
|
} else {
|
|
auditLog.Resource = fmt.Sprintf("%s:%s",
|
|
p.Artifact.RepositoryName, p.Tags[0])
|
|
}
|
|
|
|
return auditLog, nil
|
|
}
|
|
|
|
func (p *PushArtifactEvent) String() string {
|
|
return p.ArtifactEvent.String()
|
|
}
|
|
|
|
// PullArtifactEvent is the pulling artifact event
|
|
type PullArtifactEvent struct {
|
|
*ArtifactEvent
|
|
}
|
|
|
|
// ResolveToAuditLog ...
|
|
func (p *PullArtifactEvent) ResolveToAuditLog() (*model.AuditLog, error) {
|
|
auditLog := &model.AuditLog{
|
|
ProjectID: p.Artifact.ProjectID,
|
|
OpTime: p.OccurAt,
|
|
Operation: rbac.ActionPull.String(),
|
|
Username: p.Operator,
|
|
ResourceType: "artifact"}
|
|
|
|
if len(p.Tags) == 0 {
|
|
auditLog.Resource = fmt.Sprintf("%s@%s",
|
|
p.Artifact.RepositoryName, p.Artifact.Digest)
|
|
} else {
|
|
auditLog.Resource = fmt.Sprintf("%s:%s",
|
|
p.Artifact.RepositoryName, p.Tags[0])
|
|
}
|
|
|
|
// for pull public resource
|
|
if p.Operator == "" {
|
|
auditLog.Username = "anonymous"
|
|
} else {
|
|
auditLog.Username = p.Operator
|
|
}
|
|
|
|
return auditLog, nil
|
|
}
|
|
|
|
func (p *PullArtifactEvent) String() string {
|
|
return p.ArtifactEvent.String()
|
|
}
|
|
|
|
// DeleteArtifactEvent is the deleting artifact event
|
|
type DeleteArtifactEvent struct {
|
|
*ArtifactEvent
|
|
}
|
|
|
|
// ResolveToAuditLog ...
|
|
func (d *DeleteArtifactEvent) ResolveToAuditLog() (*model.AuditLog, error) {
|
|
auditLog := &model.AuditLog{
|
|
ProjectID: d.Artifact.ProjectID,
|
|
OpTime: d.OccurAt,
|
|
Operation: rbac.ActionDelete.String(),
|
|
Username: d.Operator,
|
|
ResourceType: "artifact",
|
|
Resource: fmt.Sprintf("%s:%s", d.Artifact.RepositoryName, d.Artifact.Digest)}
|
|
return auditLog, nil
|
|
}
|
|
|
|
func (d *DeleteArtifactEvent) String() string {
|
|
return d.ArtifactEvent.String()
|
|
}
|
|
|
|
// CreateTagEvent is the creating tag event
|
|
type CreateTagEvent struct {
|
|
EventType string
|
|
Repository string
|
|
Tag string
|
|
AttachedArtifact *artifact.Artifact
|
|
Operator string
|
|
OccurAt time.Time
|
|
}
|
|
|
|
// ResolveToAuditLog ...
|
|
func (c *CreateTagEvent) ResolveToAuditLog() (*model.AuditLog, error) {
|
|
auditLog := &model.AuditLog{
|
|
ProjectID: c.AttachedArtifact.ProjectID,
|
|
OpTime: c.OccurAt,
|
|
Operation: rbac.ActionCreate.String(),
|
|
Username: c.Operator,
|
|
ResourceType: "tag",
|
|
Resource: fmt.Sprintf("%s:%s", c.Repository, c.Tag)}
|
|
return auditLog, nil
|
|
}
|
|
|
|
func (c *CreateTagEvent) String() string {
|
|
return fmt.Sprintf("ArtifactID-%d, Repository-%s Tag-%s Digest-%s Operator-%s OccurAt-%s",
|
|
c.AttachedArtifact.ID, c.Repository, c.Tag, c.AttachedArtifact.Digest, c.Operator,
|
|
c.OccurAt.Format("2006-01-02 15:04:05"))
|
|
}
|
|
|
|
// DeleteTagEvent is the deleting tag event
|
|
type DeleteTagEvent struct {
|
|
EventType string
|
|
Repository string
|
|
Tag string
|
|
AttachedArtifact *artifact.Artifact
|
|
Operator string
|
|
OccurAt time.Time
|
|
}
|
|
|
|
// ResolveToAuditLog ...
|
|
func (d *DeleteTagEvent) ResolveToAuditLog() (*model.AuditLog, error) {
|
|
auditLog := &model.AuditLog{
|
|
ProjectID: d.AttachedArtifact.ProjectID,
|
|
OpTime: d.OccurAt,
|
|
Operation: rbac.ActionDelete.String(),
|
|
Username: d.Operator,
|
|
ResourceType: "tag",
|
|
Resource: fmt.Sprintf("%s:%s", d.Repository, d.Tag)}
|
|
return auditLog, nil
|
|
}
|
|
|
|
func (d *DeleteTagEvent) String() string {
|
|
return fmt.Sprintf("ArtifactID-%d, Repository-%s Tag-%s Digest-%s Operator-%s OccurAt-%s",
|
|
d.AttachedArtifact.ID, d.Repository, d.Tag, d.AttachedArtifact.Digest, d.Operator,
|
|
d.OccurAt.Format("2006-01-02 15:04:05"))
|
|
}
|
|
|
|
// ScanImageEvent is scanning image related event data to publish
|
|
type ScanImageEvent struct {
|
|
EventType string
|
|
Artifact *v1.Artifact
|
|
OccurAt time.Time
|
|
Operator string
|
|
}
|
|
|
|
func (s *ScanImageEvent) String() string {
|
|
return fmt.Sprintf("Artifact-%+v Operator-%s OccurAt-%s",
|
|
s.Artifact, s.Operator, s.OccurAt.Format("2006-01-02 15:04:05"))
|
|
}
|
|
|
|
// QuotaEvent is project quota related event data to publish
|
|
type QuotaEvent struct {
|
|
EventType string
|
|
Project *proModels.Project
|
|
Resource *ImgResource
|
|
OccurAt time.Time
|
|
RepoName string
|
|
Msg string
|
|
Operator string
|
|
}
|
|
|
|
func (q *QuotaEvent) String() string {
|
|
return fmt.Sprintf("ProjectID-%d RepoName-%s Resource-%+v Msg-%s OccurAt-%s",
|
|
q.Project.ProjectID, q.RepoName, q.Resource, q.Msg, q.OccurAt.Format("2006-01-02 15:04:05"))
|
|
}
|
|
|
|
// ImgResource include image digest and tag
|
|
type ImgResource struct {
|
|
Digest string
|
|
Tag string
|
|
}
|
|
|
|
// ReplicationEvent is replication related event data to publish
|
|
type ReplicationEvent struct {
|
|
EventType string
|
|
ReplicationTaskID int64
|
|
OccurAt time.Time
|
|
Status string
|
|
}
|
|
|
|
func (r *ReplicationEvent) String() string {
|
|
return fmt.Sprintf("ReplicationTaskID-%d Status-%s OccurAt-%s",
|
|
r.ReplicationTaskID, r.Status, r.OccurAt.Format("2006-01-02 15:04:05"))
|
|
}
|
|
|
|
// ArtifactLabeledEvent is event data of artifact labeled
|
|
type ArtifactLabeledEvent struct {
|
|
ArtifactID int64
|
|
LabelID int64
|
|
OccurAt time.Time
|
|
Operator string
|
|
}
|
|
|
|
func (al *ArtifactLabeledEvent) String() string {
|
|
return fmt.Sprintf("ArtifactID-%d LabelID-%d Operator-%s OccurAt-%s",
|
|
al.ArtifactID, al.LabelID, al.Operator, al.OccurAt.Format("2006-01-02 15:04:05"))
|
|
}
|
|
|
|
// RetentionEvent is tag retention related event data to publish
|
|
type RetentionEvent struct {
|
|
TaskID int64
|
|
EventType string
|
|
OccurAt time.Time
|
|
Status string
|
|
Deleted []*selector.Result
|
|
Total int
|
|
Retained int
|
|
}
|
|
|
|
func (r *RetentionEvent) String() string {
|
|
candidates := []string{}
|
|
for _, candidate := range r.Deleted {
|
|
candidates = append(candidates, fmt.Sprintf("%s:%s:%s", candidate.Target.Namespace,
|
|
candidate.Target.Repository, candidate.Target.Tags))
|
|
}
|
|
|
|
return fmt.Sprintf("TaskID-%d Status-%s Deleted-%s OccurAt-%s",
|
|
r.TaskID, r.Status, candidates, r.OccurAt.Format("2006-01-02 15:04:05"))
|
|
}
|