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
|
// processor to handle the rules with OR mapping ways
|
||||||
type processor struct {
|
type processor struct {
|
||||||
performer action.Performer
|
|
||||||
// keep evaluator and its related selector if existing
|
// keep evaluator and its related selector if existing
|
||||||
// attentions here, the selectors can be empty/nil, that means match all "**"
|
// attentions here, the selectors can be empty/nil, that means match all "**"
|
||||||
evaluators map[*rule.Evaluator][]res.Selector
|
evaluators map[*rule.Evaluator][]res.Selector
|
||||||
|
// action performer
|
||||||
|
performers map[string]action.Performer
|
||||||
}
|
}
|
||||||
|
|
||||||
// New processor
|
// New processor
|
||||||
func New() alg.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
|
// Process the candidates with the rules
|
||||||
@ -47,12 +51,17 @@ func (p *processor) Process(artifacts []*res.Candidate) ([]*res.Result, error) {
|
|||||||
var (
|
var (
|
||||||
// collect errors by wrapping
|
// collect errors by wrapping
|
||||||
err error
|
err error
|
||||||
// collect results
|
// collect processed candidates
|
||||||
retained = make([]*res.Candidate, 0)
|
processedCandidates = make(map[string][]*res.Candidate)
|
||||||
)
|
)
|
||||||
|
|
||||||
// for sync
|
// for sync
|
||||||
resChan := make(chan []*res.Candidate, 1)
|
type chanItem struct {
|
||||||
|
action string
|
||||||
|
processed []*res.Candidate
|
||||||
|
}
|
||||||
|
|
||||||
|
resChan := make(chan *chanItem, 1)
|
||||||
// handle error
|
// handle error
|
||||||
errChan := make(chan error, 1)
|
errChan := make(chan error, 1)
|
||||||
// control chan
|
// control chan
|
||||||
@ -67,8 +76,12 @@ func (p *processor) Process(artifacts []*res.Candidate) ([]*res.Result, error) {
|
|||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case retainedOnes := <-resChan:
|
case result := <-resChan:
|
||||||
retained = append(retained, retainedOnes...)
|
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:
|
case e := <-errChan:
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = errors.Wrap(e, "artifact processing error")
|
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 {
|
if len(processed) > 0 {
|
||||||
// Pass to the outside
|
// Pass to the outside
|
||||||
resChan <- processed
|
resChan <- &chanItem{
|
||||||
|
action: evaluator.Action(),
|
||||||
|
processed: processed,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}(evaluator, selectors)
|
}(evaluator, selectors)
|
||||||
}
|
}
|
||||||
@ -132,7 +148,32 @@ func (p *processor) Process(artifacts []*res.Candidate) ([]*res.Result, error) {
|
|||||||
return nil, err
|
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
|
// 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
|
// SetPerformer sets a action performer to the processor
|
||||||
func (p *processor) SetPerformer(performer action.Performer) {
|
func (p *processor) AddActionPerformer(action string, performer action.Performer) {
|
||||||
p.performer = performer
|
p.performers[action] = performer
|
||||||
}
|
}
|
||||||
|
@ -41,9 +41,10 @@ type Processor interface {
|
|||||||
// selectors []res.Selector : selectors to narrow down the scope (&& adopted), optional
|
// selectors []res.Selector : selectors to narrow down the scope (&& adopted), optional
|
||||||
AddEvaluator(evaluator rule.Evaluator, selectors []res.Selector)
|
AddEvaluator(evaluator rule.Evaluator, selectors []res.Selector)
|
||||||
|
|
||||||
// Set performer for the processor
|
// Add performer for the related action to the processor
|
||||||
//
|
//
|
||||||
// Arguments:
|
// Arguments:
|
||||||
|
// action string : action name
|
||||||
// performer action.Performer : a performer implementation
|
// performer action.Performer : a performer implementation
|
||||||
SetPerformer(performer action.Performer)
|
AddActionPerformer(action string, performer action.Performer)
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,12 @@
|
|||||||
package policy
|
package policy
|
||||||
|
|
||||||
import (
|
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"
|
||||||
|
"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"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -32,8 +37,17 @@ type Builder interface {
|
|||||||
Build(rawPolicy string) (alg.Processor, error)
|
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
|
// basicBuilder is default implementation of Builder interface
|
||||||
type basicBuilder struct{}
|
type basicBuilder struct {
|
||||||
|
allCandidates []*res.Candidate
|
||||||
|
}
|
||||||
|
|
||||||
// Build policy processor from the raw policy
|
// Build policy processor from the raw policy
|
||||||
func (bb *basicBuilder) Build(rawPolicy string) (alg.Processor, error) {
|
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 {
|
switch liteMeta.Algorithm {
|
||||||
case AlgorithmOR:
|
case AlgorithmOR:
|
||||||
default:
|
// New OR processor
|
||||||
return nil, errors.Errorf("algorithm %s is not supported", liteMeta.Algorithm)
|
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
|
// []*res.Candidate : matched candidates for next stage
|
||||||
// error : common error object if any errors occurred
|
// error : common error object if any errors occurred
|
||||||
Process(artifacts []*res.Candidate) ([]*res.Candidate, error)
|
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
|
// 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
|
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
|
// New a Evaluator
|
||||||
func New(params rule.Parameters) rule.Evaluator {
|
func New(params rule.Parameters) rule.Evaluator {
|
||||||
if params != nil {
|
if params != nil {
|
||||||
|
@ -41,6 +41,11 @@ func (e *evaluator) Process(artifacts []*res.Candidate) ([]*res.Candidate, error
|
|||||||
return nil, nil
|
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
|
// New a Evaluator
|
||||||
func New(params rule.Parameters) rule.Evaluator {
|
func New(params rule.Parameters) rule.Evaluator {
|
||||||
if params != nil {
|
if params != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user