harbor/src/controller/event/handler/p2p/preheat.go
Wang Yan 9ef50ed430
refactor notification (#14406)
* Refactor webhook

refactor notification to new programming model

Signed-off-by: wang yan <wangyan@vmware.com>
2021-03-22 17:27:23 +08:00

131 lines
3.7 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 p2p
import (
"context"
"github.com/goharbor/harbor/src/controller/tag"
"github.com/goharbor/harbor/src/controller/artifact"
"github.com/goharbor/harbor/src/controller/artifact/processor/image"
"github.com/goharbor/harbor/src/controller/event"
"github.com/goharbor/harbor/src/controller/p2p/preheat"
"github.com/goharbor/harbor/src/lib/errors"
"github.com/goharbor/harbor/src/lib/log"
)
// Handler ...
type Handler struct {
}
// Name ...
func (p *Handler) Name() string {
return "P2PPreheat"
}
// Handle ...
func (p *Handler) Handle(ctx context.Context, value interface{}) error {
switch value.(type) {
case *event.PushArtifactEvent:
pushArtEvent, _ := value.(*event.PushArtifactEvent)
return p.handlePushArtifact(ctx, pushArtEvent)
case *event.ScanImageEvent:
scanImageEvent, _ := value.(*event.ScanImageEvent)
return p.handleImageScanned(ctx, scanImageEvent)
case *event.ArtifactLabeledEvent:
artifactLabeledEvent, _ := value.(*event.ArtifactLabeledEvent)
return p.handleArtifactLabeled(ctx, artifactLabeledEvent)
default:
return errors.New("unsupported type")
}
}
// IsStateful ...
func (p *Handler) IsStateful() bool {
return false
}
func (p *Handler) handlePushArtifact(ctx context.Context, event *event.PushArtifactEvent) error {
if event.Artifact.Type != image.ArtifactTypeImage {
return nil
}
// NOTES: So far, we only support artifact with tags
if len(event.Tags) == 0 {
return nil
}
log.Debugf("preheat: artifact pushed %s:%s@%s", event.Artifact.RepositoryName, event.Tags, event.Artifact.Digest)
art, err := artifact.Ctl.Get(ctx, event.Artifact.ID, &artifact.Option{
WithTag: true,
WithLabel: true,
})
if err != nil {
return err
}
// Only with the pushed tags, ignore other tags
pt := make([]*tag.Tag, 0)
for _, tg := range art.Tags {
if tg.Name == event.Tags[0] {
pt = append(pt, tg)
break
}
}
art.Tags = pt
_, err = preheat.Enf.PreheatArtifact(ctx, art)
return err
}
func (p *Handler) handleImageScanned(ctx context.Context, event *event.ScanImageEvent) error {
// TODO: If the scan is targeting an manifest list, here the artifacts we get are all the children
// artifacts of the manifest list. The children artifacts are high probably untagged ones that
// will be definitely ignored by the tag filter. We need to find a way to resolve this issue.
log.Debugf("preheat: image scanned %s:%s", event.Artifact.Repository, event.Artifact.Tag)
art, err := artifact.Ctl.GetByReference(ctx, event.Artifact.Repository, event.Artifact.Digest,
&artifact.Option{
WithTag: true,
WithLabel: true,
})
if err != nil {
return err
}
_, err = preheat.Enf.PreheatArtifact(ctx, art)
return err
}
func (p *Handler) handleArtifactLabeled(ctx context.Context, event *event.ArtifactLabeledEvent) error {
art, err := artifact.Ctl.Get(ctx, event.ArtifactID, &artifact.Option{
WithTag: true,
WithLabel: true,
})
if err != nil {
return err
}
// Only care image at this moment
if art.Type != image.ArtifactTypeImage {
return nil
}
log.Debugf("preheat: artifact labeled %s:%s", art.Artifact.RepositoryName, art.Artifact.Digest)
_, err = preheat.Enf.PreheatArtifact(ctx, art)
return err
}