mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-23 18:55:18 +01:00
implement policy builder
Signed-off-by: Steven Zou <szou@vmware.com>
This commit is contained in:
parent
c36afcd07d
commit
3409065438
@ -26,15 +26,19 @@ import (
|
||||
|
||||
// processor to handle the rules with OR mapping ways
|
||||
type processor struct {
|
||||
performer action.Performer
|
||||
// keep evaluator and its related selector if existing
|
||||
// attentions here, the selectors can be empty/nil, that means match all "**"
|
||||
evaluators map[*rule.Evaluator][]res.Selector
|
||||
// action performer
|
||||
performers map[string]action.Performer
|
||||
}
|
||||
|
||||
// New processor
|
||||
func New() alg.Processor {
|
||||
return &processor{}
|
||||
return &processor{
|
||||
evaluators: make(map[*rule.Evaluator][]res.Selector),
|
||||
performers: make(map[string]action.Performer),
|
||||
}
|
||||
}
|
||||
|
||||
// Process the candidates with the rules
|
||||
@ -47,12 +51,17 @@ func (p *processor) Process(artifacts []*res.Candidate) ([]*res.Result, error) {
|
||||
var (
|
||||
// collect errors by wrapping
|
||||
err error
|
||||
// collect results
|
||||
retained = make([]*res.Candidate, 0)
|
||||
// collect processed candidates
|
||||
processedCandidates = make(map[string][]*res.Candidate)
|
||||
)
|
||||
|
||||
// for sync
|
||||
resChan := make(chan []*res.Candidate, 1)
|
||||
type chanItem struct {
|
||||
action string
|
||||
processed []*res.Candidate
|
||||
}
|
||||
|
||||
resChan := make(chan *chanItem, 1)
|
||||
// handle error
|
||||
errChan := make(chan error, 1)
|
||||
// control chan
|
||||
@ -67,8 +76,12 @@ func (p *processor) Process(artifacts []*res.Candidate) ([]*res.Result, error) {
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case retainedOnes := <-resChan:
|
||||
retained = append(retained, retainedOnes...)
|
||||
case result := <-resChan:
|
||||
if _, ok := processedCandidates[result.action]; !ok {
|
||||
processedCandidates[result.action] = make([]*res.Candidate, 0)
|
||||
}
|
||||
|
||||
processedCandidates[result.action] = append(processedCandidates[result.action], result.processed...)
|
||||
case e := <-errChan:
|
||||
if err == nil {
|
||||
err = errors.Wrap(e, "artifact processing error")
|
||||
@ -120,7 +133,10 @@ func (p *processor) Process(artifacts []*res.Candidate) ([]*res.Result, error) {
|
||||
|
||||
if len(processed) > 0 {
|
||||
// Pass to the outside
|
||||
resChan <- processed
|
||||
resChan <- &chanItem{
|
||||
action: evaluator.Action(),
|
||||
processed: processed,
|
||||
}
|
||||
}
|
||||
}(evaluator, selectors)
|
||||
}
|
||||
@ -132,7 +148,32 @@ func (p *processor) Process(artifacts []*res.Candidate) ([]*res.Result, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return p.performer.Perform(retained)
|
||||
results := make([]*res.Result, 0)
|
||||
// Perform actions
|
||||
for act, candidates := range processedCandidates {
|
||||
var attachedErr error
|
||||
|
||||
if pf, ok := p.performers[act]; ok {
|
||||
if theRes, err := pf.Perform(candidates); err != nil {
|
||||
attachedErr = err
|
||||
} else {
|
||||
results = append(results, theRes...)
|
||||
}
|
||||
} else {
|
||||
attachedErr = errors.Errorf("no performer added for action %s in OR processor", act)
|
||||
}
|
||||
|
||||
if attachedErr != nil {
|
||||
for _, c := range candidates {
|
||||
results = append(results, &res.Result{
|
||||
Target: c,
|
||||
Error: attachedErr,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
// AddEvaluator appends a rule evaluator for processing
|
||||
@ -143,6 +184,6 @@ func (p *processor) AddEvaluator(evaluator rule.Evaluator, selectors []res.Selec
|
||||
}
|
||||
|
||||
// SetPerformer sets a action performer to the processor
|
||||
func (p *processor) SetPerformer(performer action.Performer) {
|
||||
p.performer = performer
|
||||
func (p *processor) AddActionPerformer(action string, performer action.Performer) {
|
||||
p.performers[action] = performer
|
||||
}
|
||||
|
@ -41,9 +41,10 @@ type Processor interface {
|
||||
// selectors []res.Selector : selectors to narrow down the scope (&& adopted), optional
|
||||
AddEvaluator(evaluator rule.Evaluator, selectors []res.Selector)
|
||||
|
||||
// Set performer for the processor
|
||||
// Add performer for the related action to the processor
|
||||
//
|
||||
// Arguments:
|
||||
// action string : action name
|
||||
// performer action.Performer : a performer implementation
|
||||
SetPerformer(performer action.Performer)
|
||||
AddActionPerformer(action string, performer action.Performer)
|
||||
}
|
||||
|
@ -15,7 +15,12 @@
|
||||
package policy
|
||||
|
||||
import (
|
||||
"github.com/goharbor/harbor/src/pkg/retention/policy/action"
|
||||
"github.com/goharbor/harbor/src/pkg/retention/policy/alg"
|
||||
"github.com/goharbor/harbor/src/pkg/retention/policy/alg/or"
|
||||
"github.com/goharbor/harbor/src/pkg/retention/policy/rule"
|
||||
"github.com/goharbor/harbor/src/pkg/retention/res"
|
||||
"github.com/goharbor/harbor/src/pkg/retention/res/selectors"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
@ -32,8 +37,17 @@ type Builder interface {
|
||||
Build(rawPolicy string) (alg.Processor, error)
|
||||
}
|
||||
|
||||
// NewBuilder news a basic builder
|
||||
func NewBuilder(all []*res.Candidate) Builder {
|
||||
return &basicBuilder{
|
||||
allCandidates: all,
|
||||
}
|
||||
}
|
||||
|
||||
// basicBuilder is default implementation of Builder interface
|
||||
type basicBuilder struct{}
|
||||
type basicBuilder struct {
|
||||
allCandidates []*res.Candidate
|
||||
}
|
||||
|
||||
// Build policy processor from the raw policy
|
||||
func (bb *basicBuilder) Build(rawPolicy string) (alg.Processor, error) {
|
||||
@ -49,9 +63,36 @@ func (bb *basicBuilder) Build(rawPolicy string) (alg.Processor, error) {
|
||||
|
||||
switch liteMeta.Algorithm {
|
||||
case AlgorithmOR:
|
||||
default:
|
||||
return nil, errors.Errorf("algorithm %s is not supported", liteMeta.Algorithm)
|
||||
// New OR processor
|
||||
p := or.New()
|
||||
for _, r := range liteMeta.Rules {
|
||||
evaluator, err := rule.Get(r.Template, r.Parameters)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return nil, errors.New("not implemented")
|
||||
perf, err := action.Get(r.Action, bb.allCandidates)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "get action performer by metadata")
|
||||
}
|
||||
|
||||
sl := make([]res.Selector, 0)
|
||||
for _, s := range r.TagSelectors {
|
||||
sel, err := selectors.Get(s.Kind, s.Decoration, s.Pattern)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "get selector by metadata")
|
||||
}
|
||||
|
||||
sl = append(sl, sel)
|
||||
}
|
||||
|
||||
p.AddEvaluator(evaluator, sl)
|
||||
p.AddActionPerformer(r.Action, perf)
|
||||
|
||||
return p, nil
|
||||
}
|
||||
default:
|
||||
}
|
||||
|
||||
return nil, errors.Errorf("algorithm %s is not supported", liteMeta.Algorithm)
|
||||
}
|
||||
|
@ -27,6 +27,9 @@ type Evaluator interface {
|
||||
// []*res.Candidate : matched candidates for next stage
|
||||
// error : common error object if any errors occurred
|
||||
Process(artifacts []*res.Candidate) ([]*res.Candidate, error)
|
||||
|
||||
// Specify what action is performed to the candidates processed by this evaluator
|
||||
Action() string
|
||||
}
|
||||
|
||||
// RuleFactory defines a factory method for creating rule evaluator
|
||||
|
@ -41,6 +41,11 @@ func (e *evaluator) Process(artifacts []*res.Candidate) ([]*res.Candidate, error
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Specify what action is performed to the candidates processed by this evaluator
|
||||
func (e *evaluator) Action() string {
|
||||
return action.Retain
|
||||
}
|
||||
|
||||
// New a Evaluator
|
||||
func New(params rule.Parameters) rule.Evaluator {
|
||||
if params != nil {
|
||||
|
@ -41,6 +41,11 @@ func (e *evaluator) Process(artifacts []*res.Candidate) ([]*res.Candidate, error
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Specify what action is performed to the candidates processed by this evaluator
|
||||
func (e *evaluator) Action() string {
|
||||
return action.Retain
|
||||
}
|
||||
|
||||
// New a Evaluator
|
||||
func New(params rule.Parameters) rule.Evaluator {
|
||||
if params != nil {
|
||||
|
Loading…
Reference in New Issue
Block a user