mirror of
https://github.com/goharbor/harbor.git
synced 2024-12-22 16:48:30 +01:00
Refactor event model (#10876)
Move src/pkg/notification/model/const.go to src/pkg/notifier/model/const.go Add auditlog handler to log project event, repo event, artifact event and tag event. Signed-off-by: stonezdj <stonezdj@gmail.com>
This commit is contained in:
parent
f49994d81d
commit
c7fd3bdfc5
@ -7,7 +7,7 @@ import (
|
||||
|
||||
"github.com/goharbor/harbor/src/common/models"
|
||||
"github.com/goharbor/harbor/src/pkg/notification"
|
||||
"github.com/goharbor/harbor/src/pkg/notification/model"
|
||||
"github.com/goharbor/harbor/src/pkg/notifier/model"
|
||||
)
|
||||
|
||||
type fakedNotificationJobMgr struct {
|
||||
|
@ -6,7 +6,7 @@ import (
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/goharbor/harbor/src/pkg/notification/model"
|
||||
"github.com/goharbor/harbor/src/pkg/notifier/model"
|
||||
|
||||
"github.com/goharbor/harbor/src/common/models"
|
||||
"github.com/goharbor/harbor/src/pkg/notification"
|
||||
|
@ -12,7 +12,7 @@ func init() {
|
||||
// AuditLog ...
|
||||
type AuditLog struct {
|
||||
ID int64 `orm:"pk;auto;column(id)" json:"id"`
|
||||
ProjectID int `orm:"column(project_id)" json:"project_id"`
|
||||
ProjectID int64 `orm:"column(project_id)" json:"project_id"`
|
||||
Operation string `orm:"column(operation)" json:"operation"`
|
||||
ResourceType string `orm:"column(resource_type)" json:"resource_type"`
|
||||
Resource string `orm:"column(resource)" json:"resource"`
|
||||
|
@ -5,9 +5,9 @@ import (
|
||||
"github.com/goharbor/harbor/src/pkg/notification/hook"
|
||||
"github.com/goharbor/harbor/src/pkg/notification/job"
|
||||
jobMgr "github.com/goharbor/harbor/src/pkg/notification/job/manager"
|
||||
"github.com/goharbor/harbor/src/pkg/notification/model"
|
||||
"github.com/goharbor/harbor/src/pkg/notification/policy"
|
||||
"github.com/goharbor/harbor/src/pkg/notification/policy/manager"
|
||||
"github.com/goharbor/harbor/src/pkg/notifier/model"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -10,7 +10,7 @@ import (
|
||||
commonhttp "github.com/goharbor/harbor/src/common/http"
|
||||
"github.com/goharbor/harbor/src/common/models"
|
||||
"github.com/goharbor/harbor/src/common/utils/log"
|
||||
"github.com/goharbor/harbor/src/pkg/notification/model"
|
||||
"github.com/goharbor/harbor/src/pkg/notifier/model"
|
||||
notifierModel "github.com/goharbor/harbor/src/pkg/notifier/model"
|
||||
)
|
||||
|
||||
|
@ -5,9 +5,9 @@ import (
|
||||
|
||||
"github.com/goharbor/harbor/src/common/models"
|
||||
"github.com/goharbor/harbor/src/common/utils/log"
|
||||
notifyModel "github.com/goharbor/harbor/src/pkg/notification/model"
|
||||
"github.com/goharbor/harbor/src/pkg/notifier"
|
||||
"github.com/goharbor/harbor/src/pkg/notifier/model"
|
||||
notifyModel "github.com/goharbor/harbor/src/pkg/notifier/model"
|
||||
v1 "github.com/goharbor/harbor/src/pkg/scan/rest/v1"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
@ -22,6 +22,43 @@ type Event struct {
|
||||
Data interface{}
|
||||
}
|
||||
|
||||
// TopicEvent - Events that contains topic information
|
||||
type TopicEvent interface {
|
||||
Topic() string
|
||||
}
|
||||
|
||||
// New ...
|
||||
func New() *Event {
|
||||
return &Event{}
|
||||
}
|
||||
|
||||
// WithTopicEvent - builder method
|
||||
func (e *Event) WithTopicEvent(topicEvent TopicEvent) *Event {
|
||||
e.Topic = topicEvent.Topic()
|
||||
e.Data = topicEvent
|
||||
return e
|
||||
}
|
||||
|
||||
// Build an event by metadata
|
||||
func (e *Event) Build(metadata ...Metadata) error {
|
||||
for _, md := range metadata {
|
||||
if err := md.Resolve(e); err != nil {
|
||||
log.Debugf("failed to resolve event metadata: %v", md)
|
||||
return errors.Wrap(err, "failed to resolve event metadata")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Publish an event
|
||||
func (e *Event) Publish() error {
|
||||
if err := notifier.Publish(e.Topic, e.Data); err != nil {
|
||||
log.Debugf("failed to publish topic %s with event: %v", e.Topic, e.Data)
|
||||
return errors.Wrap(err, "failed to publish event")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Metadata is the event raw data to be processed
|
||||
type Metadata interface {
|
||||
Resolve(event *Event) error
|
||||
@ -285,23 +322,3 @@ func (h *HookMetaData) Resolve(evt *Event) error {
|
||||
evt.Data = data
|
||||
return nil
|
||||
}
|
||||
|
||||
// Build an event by metadata
|
||||
func (e *Event) Build(metadata ...Metadata) error {
|
||||
for _, md := range metadata {
|
||||
if err := md.Resolve(e); err != nil {
|
||||
log.Debugf("failed to resolve event metadata: %v", md)
|
||||
return errors.Wrap(err, "failed to resolve event metadata")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Publish an event
|
||||
func (e *Event) Publish() error {
|
||||
if err := notifier.Publish(e.Topic, e.Data); err != nil {
|
||||
log.Debugf("failed to publish topic %s with event: %v", e.Topic, e.Data)
|
||||
return errors.Wrap(err, "failed to publish event")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
50
src/pkg/notifier/handler/auditlog/handler.go
Normal file
50
src/pkg/notifier/handler/auditlog/handler.go
Normal file
@ -0,0 +1,50 @@
|
||||
package auditlog
|
||||
|
||||
import (
|
||||
beegoorm "github.com/astaxie/beego/orm"
|
||||
"github.com/goharbor/harbor/src/common/utils/log"
|
||||
"github.com/goharbor/harbor/src/internal/orm"
|
||||
"github.com/goharbor/harbor/src/pkg/audit"
|
||||
am "github.com/goharbor/harbor/src/pkg/audit/model"
|
||||
"github.com/goharbor/harbor/src/pkg/notifier/model"
|
||||
)
|
||||
|
||||
// Handler - audit log handler
|
||||
type Handler struct {
|
||||
AuditLogMgr audit.Manager
|
||||
}
|
||||
|
||||
// AuditResolver - interface to resolve to AuditLog
|
||||
type AuditResolver interface {
|
||||
ResolveToAuditLog() (*am.AuditLog, error)
|
||||
}
|
||||
|
||||
// AuditHandler ...
|
||||
var AuditHandler = Handler{AuditLogMgr: audit.Mgr}
|
||||
|
||||
// Handle ...
|
||||
func (h *Handler) Handle(value interface{}) error {
|
||||
ctx := orm.NewContext(nil, beegoorm.NewOrm())
|
||||
var auditLog *am.AuditLog
|
||||
switch v := value.(type) {
|
||||
case *model.ProjectEvent, *model.RepositoryEvent, *model.ArtifactEvent, *model.TagEvent:
|
||||
resolver := value.(AuditResolver)
|
||||
al, err := resolver.ResolveToAuditLog()
|
||||
if err != nil {
|
||||
log.Errorf("failed to handler event %v", err)
|
||||
return err
|
||||
}
|
||||
auditLog = al
|
||||
default:
|
||||
log.Errorf("Can not handler this event type! %#v", v)
|
||||
}
|
||||
if auditLog != nil {
|
||||
h.AuditLogMgr.Create(ctx, auditLog)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// IsStateful ...
|
||||
func (h *Handler) IsStateful() bool {
|
||||
return false
|
||||
}
|
98
src/pkg/notifier/handler/auditlog/handler_test.go
Normal file
98
src/pkg/notifier/handler/auditlog/handler_test.go
Normal file
@ -0,0 +1,98 @@
|
||||
package auditlog
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
common_dao "github.com/goharbor/harbor/src/common/dao"
|
||||
"github.com/goharbor/harbor/src/common/models"
|
||||
"github.com/goharbor/harbor/src/common/utils/log"
|
||||
"github.com/goharbor/harbor/src/pkg/audit/model"
|
||||
"github.com/goharbor/harbor/src/pkg/notifier"
|
||||
"github.com/goharbor/harbor/src/pkg/notifier/event"
|
||||
nm "github.com/goharbor/harbor/src/pkg/notifier/model"
|
||||
"github.com/goharbor/harbor/src/pkg/q"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/suite"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
type MockAuditLogManager struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
func (m *MockAuditLogManager) Count(ctx context.Context, query *q.Query) (total int64, err error) {
|
||||
args := m.Called()
|
||||
return int64(args.Int(0)), args.Error(1)
|
||||
}
|
||||
|
||||
func (m *MockAuditLogManager) Create(ctx context.Context, audit *model.AuditLog) (id int64, err error) {
|
||||
args := m.Called()
|
||||
return int64(args.Int(0)), args.Error(1)
|
||||
}
|
||||
|
||||
func (m *MockAuditLogManager) Delete(ctx context.Context, id int64) (err error) {
|
||||
args := m.Called()
|
||||
return args.Error(0)
|
||||
}
|
||||
|
||||
func (m *MockAuditLogManager) Get(ctx context.Context, id int64) (audit *model.AuditLog, err error) {
|
||||
args := m.Called()
|
||||
return args.Get(0).(*model.AuditLog), args.Error(1)
|
||||
}
|
||||
|
||||
func (m *MockAuditLogManager) List(ctx context.Context, query *q.Query) (audits []*model.AuditLog, err error) {
|
||||
args := m.Called()
|
||||
return args.Get(0).([]*model.AuditLog), args.Error(1)
|
||||
}
|
||||
|
||||
type AuditLogHandlerTestSuite struct {
|
||||
suite.Suite
|
||||
auditLogHandler *Handler
|
||||
logMgr *MockAuditLogManager
|
||||
}
|
||||
|
||||
func (suite *AuditLogHandlerTestSuite) SetupSuite() {
|
||||
common_dao.PrepareTestForPostgresSQL()
|
||||
suite.logMgr = &MockAuditLogManager{}
|
||||
suite.auditLogHandler = &Handler{AuditLogMgr: suite.logMgr}
|
||||
log.SetLevel(log.DebugLevel)
|
||||
}
|
||||
|
||||
func (suite *AuditLogHandlerTestSuite) TestSubscribeTagEvent() {
|
||||
|
||||
suite.logMgr.On("Create", mock.Anything).Return(1, nil)
|
||||
suite.logMgr.On("Count", mock.Anything).Return(1, nil)
|
||||
|
||||
// sample code to use the event framework.
|
||||
|
||||
notifier.Subscribe(nm.PushTagTopic, suite.auditLogHandler)
|
||||
// event data should implement the interface TopicEvent
|
||||
data := &nm.TagEvent{
|
||||
TargetTopic: nm.PushTagTopic, // Topic is a attribute of event
|
||||
Project: &models.Project{
|
||||
ProjectID: 1,
|
||||
Name: "library",
|
||||
},
|
||||
RepoName: "busybox",
|
||||
Digest: "abcdef",
|
||||
TagName: "dev",
|
||||
OccurAt: time.Now(),
|
||||
Operator: "admin",
|
||||
Operation: "push", // Use Operation instead of event type.
|
||||
}
|
||||
// No EventMetadata anymore and there is no need to call resolve
|
||||
// The handler receives the TagEvent
|
||||
// The handler should use switch type interface to get TagEvent
|
||||
event.New().WithTopicEvent(data).Publish()
|
||||
|
||||
cnt, err := suite.logMgr.Count(nil, nil)
|
||||
|
||||
suite.Nil(err)
|
||||
suite.Equal(int64(1), cnt)
|
||||
|
||||
}
|
||||
|
||||
func TestAuditLogHandlerTestSuite(t *testing.T) {
|
||||
suite.Run(t, &AuditLogHandlerTestSuite{})
|
||||
}
|
@ -6,7 +6,6 @@ import (
|
||||
"github.com/goharbor/harbor/src/common/models"
|
||||
"github.com/goharbor/harbor/src/core/config"
|
||||
"github.com/goharbor/harbor/src/pkg/notification"
|
||||
notificationModel "github.com/goharbor/harbor/src/pkg/notification/model"
|
||||
"github.com/goharbor/harbor/src/pkg/notifier/model"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
@ -48,11 +47,11 @@ func (f *fakedPolicyMgr) GetRelatedPolices(id int64, eventType string) ([]*model
|
||||
{
|
||||
ID: 1,
|
||||
EventTypes: []string{
|
||||
notificationModel.EventTypeUploadChart,
|
||||
notificationModel.EventTypeDownloadChart,
|
||||
notificationModel.EventTypeDeleteChart,
|
||||
notificationModel.EventTypeScanningCompleted,
|
||||
notificationModel.EventTypeScanningFailed,
|
||||
model.EventTypeUploadChart,
|
||||
model.EventTypeDownloadChart,
|
||||
model.EventTypeDeleteChart,
|
||||
model.EventTypeScanningCompleted,
|
||||
model.EventTypeScanningFailed,
|
||||
},
|
||||
Targets: []models.EventTarget{
|
||||
{
|
||||
|
@ -10,7 +10,6 @@ import (
|
||||
"github.com/goharbor/harbor/src/common/models"
|
||||
"github.com/goharbor/harbor/src/core/config"
|
||||
"github.com/goharbor/harbor/src/pkg/notification"
|
||||
notificationModel "github.com/goharbor/harbor/src/pkg/notification/model"
|
||||
"github.com/goharbor/harbor/src/pkg/notifier/model"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/stretchr/testify/require"
|
||||
@ -53,8 +52,8 @@ func (f *fakedNotificationPlyMgr) GetRelatedPolices(id int64, eventType string)
|
||||
{
|
||||
ID: 1,
|
||||
EventTypes: []string{
|
||||
notificationModel.EventTypePullImage,
|
||||
notificationModel.EventTypePushImage,
|
||||
model.EventTypePullImage,
|
||||
model.EventTypePushImage,
|
||||
},
|
||||
Targets: []models.EventTarget{
|
||||
{
|
||||
|
@ -140,6 +140,24 @@ func resolveImageEventData(value interface{}) (*notifyModel.ImageEvent, error) {
|
||||
return imgEvent, nil
|
||||
}
|
||||
|
||||
func resolveTagEventToImageEvent(value interface{}) (*notifyModel.ImageEvent, error) {
|
||||
tagEvent, ok := value.(*notifyModel.TagEvent)
|
||||
if !ok || tagEvent == nil {
|
||||
return nil, errors.New("invalid image event")
|
||||
}
|
||||
imageEvent := notifyModel.ImageEvent{
|
||||
EventType: notifyModel.PushImageTopic,
|
||||
Project: tagEvent.Project,
|
||||
RepoName: tagEvent.RepoName,
|
||||
Resource: []*notifyModel.ImgResource{
|
||||
{Tag: tagEvent.TagName},
|
||||
},
|
||||
OccurAt: tagEvent.OccurAt,
|
||||
Operator: tagEvent.Operator,
|
||||
}
|
||||
return &imageEvent, nil
|
||||
}
|
||||
|
||||
// preprocessAndSendImageHook preprocess image event data and send hook by notification policy target
|
||||
func preprocessAndSendImageHook(value interface{}) error {
|
||||
// if global notification configured disabled, return directly
|
||||
|
@ -8,7 +8,6 @@ import (
|
||||
"github.com/goharbor/harbor/src/common/models"
|
||||
"github.com/goharbor/harbor/src/core/config"
|
||||
"github.com/goharbor/harbor/src/pkg/notification"
|
||||
nm "github.com/goharbor/harbor/src/pkg/notification/model"
|
||||
"github.com/goharbor/harbor/src/pkg/notification/policy"
|
||||
"github.com/goharbor/harbor/src/pkg/notifier"
|
||||
"github.com/goharbor/harbor/src/pkg/notifier/model"
|
||||
@ -40,7 +39,7 @@ func (suite *QuotaPreprocessHandlerSuite) SetupSuite() {
|
||||
Tag: "latest",
|
||||
}
|
||||
suite.evt = &model.QuotaEvent{
|
||||
EventType: nm.EventTypeProjectQuota,
|
||||
EventType: model.EventTypeProjectQuota,
|
||||
OccurAt: time.Now().UTC(),
|
||||
RepoName: "hello-world",
|
||||
Resource: res,
|
||||
|
@ -11,13 +11,12 @@ import (
|
||||
"github.com/goharbor/harbor/src/core/config"
|
||||
"github.com/goharbor/harbor/src/jobservice/job"
|
||||
"github.com/goharbor/harbor/src/pkg/notification"
|
||||
nm "github.com/goharbor/harbor/src/pkg/notification/model"
|
||||
"github.com/goharbor/harbor/src/pkg/notification/policy"
|
||||
"github.com/goharbor/harbor/src/pkg/notifier"
|
||||
"github.com/goharbor/harbor/src/pkg/notifier/model"
|
||||
"github.com/goharbor/harbor/src/pkg/scan/dao/scan"
|
||||
"github.com/goharbor/harbor/src/pkg/scan/report"
|
||||
v1 "github.com/goharbor/harbor/src/pkg/scan/rest/v1"
|
||||
"github.com/goharbor/harbor/src/pkg/scan/rest/v1"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/stretchr/testify/suite"
|
||||
@ -53,7 +52,7 @@ func (suite *ScanImagePreprocessHandlerSuite) SetupSuite() {
|
||||
MimeType: v1.MimeTypeDockerArtifact,
|
||||
}
|
||||
suite.evt = &model.ScanImageEvent{
|
||||
EventType: nm.EventTypeScanningCompleted,
|
||||
EventType: model.EventTypeScanningCompleted,
|
||||
OccurAt: time.Now().UTC(),
|
||||
Operator: "admin",
|
||||
Artifact: a,
|
||||
|
@ -3,7 +3,11 @@ package model
|
||||
import (
|
||||
"time"
|
||||
|
||||
"fmt"
|
||||
|
||||
"github.com/goharbor/harbor/src/common/models"
|
||||
"github.com/goharbor/harbor/src/common/utils/log"
|
||||
"github.com/goharbor/harbor/src/pkg/audit/model"
|
||||
v1 "github.com/goharbor/harbor/src/pkg/scan/rest/v1"
|
||||
)
|
||||
|
||||
@ -59,6 +63,144 @@ type HookEvent struct {
|
||||
Payload *Payload
|
||||
}
|
||||
|
||||
// ProjectEvent info of Project related event
|
||||
type ProjectEvent struct {
|
||||
// EventType - create/delete event
|
||||
TargetTopic string
|
||||
Project *models.Project
|
||||
OccurAt time.Time
|
||||
Operator string
|
||||
Operation string
|
||||
}
|
||||
|
||||
// ResolveToAuditLog ...
|
||||
func (p *ProjectEvent) ResolveToAuditLog() (*model.AuditLog, error) {
|
||||
auditLog := &model.AuditLog{
|
||||
ProjectID: p.Project.ProjectID,
|
||||
OpTime: p.OccurAt,
|
||||
Operation: p.Operation,
|
||||
Username: p.Operator,
|
||||
ResourceType: "project",
|
||||
Resource: fmt.Sprintf("/api/project/%v",
|
||||
p.Project.ProjectID)}
|
||||
return auditLog, nil
|
||||
}
|
||||
|
||||
// Topic ...
|
||||
func (p *ProjectEvent) Topic() string {
|
||||
return p.TargetTopic
|
||||
}
|
||||
|
||||
// RepositoryEvent info of repository related event
|
||||
type RepositoryEvent struct {
|
||||
TargetTopic string
|
||||
Project *models.Project
|
||||
RepoName string
|
||||
OccurAt time.Time
|
||||
Operator string
|
||||
Operation string
|
||||
}
|
||||
|
||||
// ResolveToAuditLog ...
|
||||
func (r *RepositoryEvent) ResolveToAuditLog() (*model.AuditLog, error) {
|
||||
auditLog := &model.AuditLog{
|
||||
ProjectID: r.Project.ProjectID,
|
||||
OpTime: r.OccurAt,
|
||||
Operation: r.Operation,
|
||||
Username: r.Operator,
|
||||
ResourceType: "repository",
|
||||
Resource: fmt.Sprintf("/api/project/%v/repository/%v",
|
||||
r.Project.ProjectID, r.RepoName)}
|
||||
return auditLog, nil
|
||||
}
|
||||
|
||||
// Topic ...
|
||||
func (r *RepositoryEvent) Topic() string {
|
||||
return r.TargetTopic
|
||||
}
|
||||
|
||||
// ArtifactEvent info of artifact related event
|
||||
type ArtifactEvent struct {
|
||||
TargetTopic string
|
||||
Project *models.Project
|
||||
RepoName string
|
||||
Digest string
|
||||
OccurAt time.Time
|
||||
Operator string
|
||||
Operation string
|
||||
}
|
||||
|
||||
// ResolveToAuditLog ...
|
||||
func (a *ArtifactEvent) ResolveToAuditLog() (*model.AuditLog, error) {
|
||||
auditLog := &model.AuditLog{
|
||||
ProjectID: a.Project.ProjectID,
|
||||
OpTime: a.OccurAt,
|
||||
Operation: a.Operation,
|
||||
Username: a.Operator,
|
||||
ResourceType: "artifact",
|
||||
Resource: fmt.Sprintf("/api/project/%v/repository/%v/artifact/%v",
|
||||
a.Project.ProjectID, a.RepoName, a.Digest)}
|
||||
return auditLog, nil
|
||||
}
|
||||
|
||||
// Topic ...
|
||||
func (a *ArtifactEvent) Topic() string {
|
||||
return a.TargetTopic
|
||||
}
|
||||
|
||||
// TagEvent info of tag related event
|
||||
type TagEvent struct {
|
||||
TargetTopic string
|
||||
Project *models.Project
|
||||
RepoName string
|
||||
TagName string
|
||||
Digest string
|
||||
OccurAt time.Time
|
||||
Operation string
|
||||
Operator string
|
||||
}
|
||||
|
||||
// ResolveToAuditLog ...
|
||||
func (t *TagEvent) ResolveToAuditLog() (*model.AuditLog, error) {
|
||||
auditLog := &model.AuditLog{
|
||||
ProjectID: t.Project.ProjectID,
|
||||
OpTime: t.OccurAt,
|
||||
Operation: t.Operation,
|
||||
Username: t.Operator,
|
||||
ResourceType: "tag",
|
||||
Resource: fmt.Sprintf("/api/project/%v/repository/%v/tag/%v",
|
||||
t.Project.ProjectID, t.RepoName, t.TagName)}
|
||||
log.Infof("create audit log %+v", auditLog)
|
||||
return auditLog, nil
|
||||
}
|
||||
|
||||
// Topic ...
|
||||
func (t *TagEvent) Topic() string {
|
||||
return t.TargetTopic
|
||||
}
|
||||
|
||||
// ToImageEvent ...
|
||||
func (t *TagEvent) ToImageEvent() *ImageEvent {
|
||||
var eventType string
|
||||
// convert tag operation to previous event type so that webhook can handle it
|
||||
if t.Operation == "push" {
|
||||
eventType = EventTypePushImage
|
||||
} else if t.Operation == "pull" {
|
||||
eventType = EventTypePullImage
|
||||
} else if t.Operation == "delete" {
|
||||
eventType = EventTypeDeleteImage
|
||||
}
|
||||
imgEvent := &ImageEvent{
|
||||
EventType: eventType,
|
||||
Project: t.Project,
|
||||
Resource: []*ImgResource{{Tag: t.TagName}},
|
||||
Operator: t.Operator,
|
||||
OccurAt: t.OccurAt,
|
||||
RepoName: t.RepoName,
|
||||
}
|
||||
return imgEvent
|
||||
}
|
||||
|
||||
// Payload of notification event
|
||||
type Payload struct {
|
||||
Type string `json:"type"`
|
||||
|
@ -2,6 +2,23 @@ package model
|
||||
|
||||
// Define global topic names
|
||||
const (
|
||||
// TagTopic
|
||||
PushTagTopic = "PushTagTopic"
|
||||
PullTagTopic = "PullTagTopic"
|
||||
DeleteTagTopic = "DeleteTagTopic"
|
||||
|
||||
// ProjectTopic ...
|
||||
CreateProjectTopic = "CreateProjectTopic"
|
||||
DeleteProjectTopic = "DeleteProjectTopic"
|
||||
|
||||
// RepositoryTopic ...
|
||||
CreateRepositoryTopic = "CreateRepositoryTopic"
|
||||
DeleteRepositoryTopic = "DeleteRepositoryTopic"
|
||||
|
||||
// ArtifactTopic
|
||||
CreateArtifactTopic = "CreateArtifactTopic"
|
||||
DeleteArtifactTopic = "DeleteArtifactTopic"
|
||||
|
||||
// PushImageTopic is topic for push image event
|
||||
PushImageTopic = "OnPushImage"
|
||||
// PullImageTopic is topic for pull image event
|
||||
|
@ -3,6 +3,7 @@ package topic
|
||||
import (
|
||||
"github.com/goharbor/harbor/src/common/utils/log"
|
||||
"github.com/goharbor/harbor/src/pkg/notifier"
|
||||
"github.com/goharbor/harbor/src/pkg/notifier/handler/auditlog"
|
||||
"github.com/goharbor/harbor/src/pkg/notifier/handler/notification"
|
||||
"github.com/goharbor/harbor/src/pkg/notifier/model"
|
||||
)
|
||||
@ -10,9 +11,19 @@ import (
|
||||
// Subscribe topics
|
||||
func init() {
|
||||
handlersMap := map[string][]notifier.NotificationHandler{
|
||||
model.PushImageTopic: {¬ification.ImagePreprocessHandler{}},
|
||||
model.PullImageTopic: {¬ification.ImagePreprocessHandler{}},
|
||||
model.DeleteImageTopic: {¬ification.ImagePreprocessHandler{}},
|
||||
model.PushTagTopic: {&auditlog.AuditHandler},
|
||||
model.PullTagTopic: {&auditlog.AuditHandler},
|
||||
model.DeleteTagTopic: {&auditlog.AuditHandler},
|
||||
|
||||
model.CreateProjectTopic: {&auditlog.AuditHandler},
|
||||
model.DeleteProjectTopic: {&auditlog.AuditHandler},
|
||||
|
||||
model.CreateRepositoryTopic: {&auditlog.AuditHandler},
|
||||
model.DeleteRepositoryTopic: {&auditlog.AuditHandler},
|
||||
|
||||
model.CreateArtifactTopic: {&auditlog.AuditHandler},
|
||||
model.DeleteArtifactTopic: {&auditlog.AuditHandler},
|
||||
|
||||
model.WebhookTopic: {¬ification.HTTPHandler{}},
|
||||
model.UploadChartTopic: {¬ification.ChartPreprocessHandler{}},
|
||||
model.DownloadChartTopic: {¬ification.ChartPreprocessHandler{}},
|
||||
|
Loading…
Reference in New Issue
Block a user