mirror of
https://github.com/goharbor/harbor.git
synced 2025-02-17 04:11:24 +01:00
refactor the processor interface
Signed-off-by: Steven Zou <szou@vmware.com>
This commit is contained in:
parent
9756195496
commit
52ca6de22a
49
src/pkg/retention/policy/alg/index.go
Normal file
49
src/pkg/retention/policy/alg/index.go
Normal file
@ -0,0 +1,49 @@
|
||||
// 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 alg
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
"sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// AlgorithmOR for || algorithm
|
||||
AlgorithmOR = "or"
|
||||
)
|
||||
|
||||
// index for keeping the mapping between algorithm and its processor
|
||||
var index sync.Map
|
||||
|
||||
// Register processor with the algorithm
|
||||
func Register(algorithm string, processor Factory) {
|
||||
if len(algorithm) > 0 && processor != nil {
|
||||
index.Store(algorithm, processor)
|
||||
}
|
||||
}
|
||||
|
||||
// Get Processor
|
||||
func Get(algorithm string, params []*Parameter) (Processor, error) {
|
||||
v, ok := index.Load(algorithm)
|
||||
if !ok {
|
||||
return nil, errors.Errorf("no processor registered with algorithm: %s", algorithm)
|
||||
}
|
||||
|
||||
if fac, ok := v.(Factory); ok {
|
||||
return fac(params), nil
|
||||
}
|
||||
|
||||
return nil, errors.Errorf("no valid processor registered for algorithm: %s", algorithm)
|
||||
}
|
@ -34,11 +34,27 @@ type processor struct {
|
||||
}
|
||||
|
||||
// New processor
|
||||
func New() alg.Processor {
|
||||
return &processor{
|
||||
func New(parameters []*alg.Parameter) alg.Processor {
|
||||
p := &processor{
|
||||
evaluators: make(map[*rule.Evaluator][]res.Selector),
|
||||
performers: make(map[string]action.Performer),
|
||||
}
|
||||
|
||||
if len(parameters) > 0 {
|
||||
for _, param := range parameters {
|
||||
if param.Evaluator != nil {
|
||||
if len(param.Selectors) > 0 {
|
||||
p.evaluators[¶m.Evaluator] = param.Selectors
|
||||
}
|
||||
|
||||
if param.Performer != nil {
|
||||
p.performers[param.Evaluator.Action()] = param.Performer
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
// Process the candidates with the rules
|
||||
@ -188,16 +204,8 @@ func (p *processor) Process(artifacts []*res.Candidate) ([]*res.Result, error) {
|
||||
return results, nil
|
||||
}
|
||||
|
||||
// AddEvaluator appends a rule evaluator for processing
|
||||
func (p *processor) AddEvaluator(evaluator rule.Evaluator, selectors []res.Selector) {
|
||||
if evaluator != nil {
|
||||
p.evaluators[&evaluator] = selectors
|
||||
}
|
||||
}
|
||||
|
||||
// SetPerformer sets a action performer to the processor
|
||||
func (p *processor) AddActionPerformer(action string, performer action.Performer) {
|
||||
p.performers[action] = performer
|
||||
func init() {
|
||||
alg.Register(alg.AlgorithmOR, New)
|
||||
}
|
||||
|
||||
type cHash map[string]*res.Candidate
|
||||
|
@ -64,22 +64,34 @@ func (suite *ProcessorTestSuite) SetupSuite() {
|
||||
},
|
||||
}
|
||||
|
||||
p := New()
|
||||
p.AddActionPerformer(action.Retain, action.NewRetainAction(suite.all))
|
||||
params := make([]*alg.Parameter, 0)
|
||||
|
||||
perf := action.NewRetainAction(suite.all)
|
||||
|
||||
lastxParams := make(map[string]rule.Parameter)
|
||||
lastxParams[lastx.ParameterX] = 10
|
||||
p.AddEvaluator(lastx.New(lastxParams), []res.Selector{
|
||||
regexp.New(regexp.Matches, "*dev*"),
|
||||
label.New(label.With, "L1,L2"),
|
||||
params = append(params, &alg.Parameter{
|
||||
Evaluator: lastx.New(lastxParams),
|
||||
Selectors: []res.Selector{
|
||||
regexp.New(regexp.Matches, "*dev*"),
|
||||
label.New(label.With, "L1,L2"),
|
||||
},
|
||||
Performer: perf,
|
||||
})
|
||||
|
||||
latestKParams := make(map[string]rule.Parameter)
|
||||
latestKParams[latestk.ParameterK] = 10
|
||||
p.AddEvaluator(latestk.New(latestKParams), []res.Selector{
|
||||
label.New(label.With, "L3"),
|
||||
params = append(params, &alg.Parameter{
|
||||
Evaluator: latestk.New(latestKParams),
|
||||
Selectors: []res.Selector{
|
||||
label.New(label.With, "L3"),
|
||||
},
|
||||
Performer: perf,
|
||||
})
|
||||
|
||||
p, err := alg.Get(alg.AlgorithmOR, params)
|
||||
require.NoError(suite.T(), err)
|
||||
|
||||
suite.p = p
|
||||
}
|
||||
|
||||
|
@ -33,18 +33,20 @@ type Processor interface {
|
||||
// []*res.Result : the processed results
|
||||
// error : common error object if any errors occurred
|
||||
Process(artifacts []*res.Candidate) ([]*res.Result, error)
|
||||
|
||||
// Add a rule evaluator for the processor
|
||||
//
|
||||
// Arguments:
|
||||
// evaluator rule.Evaluator : a rule evaluator
|
||||
// selectors []res.Selector : selectors to narrow down the scope (&& adopted), optional
|
||||
AddEvaluator(evaluator rule.Evaluator, selectors []res.Selector)
|
||||
|
||||
// Add performer for the related action to the processor
|
||||
//
|
||||
// Arguments:
|
||||
// action string : action name
|
||||
// performer action.Performer : a performer implementation
|
||||
AddActionPerformer(action string, performer action.Performer)
|
||||
}
|
||||
|
||||
// Parameter for constructing a processor
|
||||
// Represents one rule
|
||||
type Parameter struct {
|
||||
// Evaluator for the rule
|
||||
Evaluator rule.Evaluator
|
||||
|
||||
// Selectors for the rule
|
||||
Selectors []res.Selector
|
||||
|
||||
// Performer for the rule evaluator
|
||||
Performer action.Performer
|
||||
}
|
||||
|
||||
// Factory for creating processor
|
||||
type Factory func([]*Parameter) Processor
|
||||
|
@ -15,9 +15,9 @@
|
||||
package policy
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"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"
|
||||
@ -55,38 +55,40 @@ func (bb *basicBuilder) Build(policy *LiteMeta) (alg.Processor, error) {
|
||||
return nil, errors.New("nil policy to build processor")
|
||||
}
|
||||
|
||||
switch policy.Algorithm {
|
||||
case AlgorithmOR:
|
||||
// New OR processor
|
||||
p := or.New()
|
||||
for _, r := range policy.Rules {
|
||||
evaluator, err := rule.Get(r.Template, r.Parameters)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
params := make([]*alg.Parameter, 0)
|
||||
|
||||
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
|
||||
for _, r := range policy.Rules {
|
||||
evaluator, err := rule.Get(r.Template, r.Parameters)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
default:
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
params = append(params, &alg.Parameter{
|
||||
Evaluator: evaluator,
|
||||
Selectors: sl,
|
||||
Performer: perf,
|
||||
})
|
||||
}
|
||||
|
||||
return nil, errors.Errorf("algorithm %s is not supported", policy.Algorithm)
|
||||
p, err := alg.Get(policy.Algorithm, params)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, fmt.Sprintf("get processor for algorithm: %s", policy.Algorithm))
|
||||
}
|
||||
|
||||
return p, nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user