mirror of
https://github.com/goharbor/harbor.git
synced 2024-12-20 07:37:38 +01:00
refactor packages to resolve the cycle importing issue
Signed-off-by: Steven Zou <szou@vmware.com>
This commit is contained in:
parent
f0ea62caa9
commit
c76c5d7a1f
@ -14,10 +14,14 @@
|
||||
|
||||
package retention
|
||||
|
||||
import "github.com/goharbor/harbor/src/pkg/retention/dep"
|
||||
|
||||
// TODO: Move to api.Init()
|
||||
|
||||
// Init the retention components
|
||||
func Init() error {
|
||||
// New default retention client
|
||||
DefaultClient = NewClient()
|
||||
dep.DefaultClient = dep.NewClient()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -12,11 +12,12 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package retention
|
||||
package dep
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/goharbor/harbor/src/pkg/retention/policy/lwp"
|
||||
"net/http"
|
||||
|
||||
"github.com/goharbor/harbor/src/common/http/modifier/auth"
|
||||
@ -25,10 +26,18 @@ import (
|
||||
"github.com/goharbor/harbor/src/core/config"
|
||||
"github.com/goharbor/harbor/src/jobservice/job"
|
||||
"github.com/goharbor/harbor/src/pkg/clients/core"
|
||||
"github.com/goharbor/harbor/src/pkg/retention/policy"
|
||||
"github.com/goharbor/harbor/src/pkg/retention/res"
|
||||
)
|
||||
|
||||
const (
|
||||
// ParamRepo ...
|
||||
ParamRepo = "repository"
|
||||
// ParamMeta ...
|
||||
ParamMeta = "liteMeta"
|
||||
)
|
||||
|
||||
// TODO: Move to api.Base
|
||||
|
||||
// DefaultClient for the retention
|
||||
var DefaultClient Client
|
||||
|
||||
@ -58,12 +67,12 @@ type Client interface {
|
||||
// Arguments:
|
||||
// taskID : the ID of task
|
||||
// repository *res.Repository : repository info
|
||||
// meta *policy.LiteMeta : policy lite metadata
|
||||
// meta *lwp.Metadata : policy lightweight metadata
|
||||
//
|
||||
// Returns:
|
||||
// string : the job ID
|
||||
// error : common error if any errors occurred
|
||||
SubmitTask(taskID int64, repository *res.Repository, meta *policy.LiteMeta) (string, error)
|
||||
SubmitTask(taskID int64, repository *res.Repository, meta *lwp.Metadata) (string, error)
|
||||
}
|
||||
|
||||
// NewClient new a basic client
|
||||
@ -108,7 +117,7 @@ func (bc *basicClient) GetCandidates(repository *res.Repository) ([]*res.Candida
|
||||
}
|
||||
candidates := make([]*res.Candidate, 0)
|
||||
switch repository.Kind {
|
||||
case CandidateKindImage:
|
||||
case res.Image:
|
||||
images, err := bc.coreClient.ListAllImages(repository.Namespace, repository.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -119,7 +128,7 @@ func (bc *basicClient) GetCandidates(repository *res.Repository) ([]*res.Candida
|
||||
labels = append(labels, label.Name)
|
||||
}
|
||||
candidate := &res.Candidate{
|
||||
Kind: CandidateKindImage,
|
||||
Kind: res.Image,
|
||||
Namespace: repository.Namespace,
|
||||
Repository: repository.Name,
|
||||
Tag: image.Name,
|
||||
@ -131,7 +140,7 @@ func (bc *basicClient) GetCandidates(repository *res.Repository) ([]*res.Candida
|
||||
}
|
||||
candidates = append(candidates, candidate)
|
||||
}
|
||||
case CandidateKindChart:
|
||||
case res.Chart:
|
||||
charts, err := bc.coreClient.ListAllCharts(repository.Namespace, repository.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -142,7 +151,7 @@ func (bc *basicClient) GetCandidates(repository *res.Repository) ([]*res.Candida
|
||||
labels = append(labels, label.Name)
|
||||
}
|
||||
candidate := &res.Candidate{
|
||||
Kind: CandidateKindChart,
|
||||
Kind: res.Chart,
|
||||
Namespace: repository.Namespace,
|
||||
Repository: repository.Name,
|
||||
Tag: chart.Name,
|
||||
@ -166,9 +175,9 @@ func (bc *basicClient) Delete(candidate *res.Candidate) error {
|
||||
return errors.New("candidate is nil")
|
||||
}
|
||||
switch candidate.Kind {
|
||||
case CandidateKindImage:
|
||||
case res.Image:
|
||||
return bc.coreClient.DeleteImage(candidate.Namespace, candidate.Repository, candidate.Tag)
|
||||
case CandidateKindChart:
|
||||
case res.Chart:
|
||||
return bc.coreClient.DeleteChart(candidate.Namespace, candidate.Repository, candidate.Tag)
|
||||
default:
|
||||
return fmt.Errorf("unsupported candidate kind: %s", candidate.Kind)
|
||||
@ -176,7 +185,7 @@ func (bc *basicClient) Delete(candidate *res.Candidate) error {
|
||||
}
|
||||
|
||||
// SubmitTask to jobservice
|
||||
func (bc *basicClient) SubmitTask(taskID int64, repository *res.Repository, meta *policy.LiteMeta) (string, error) {
|
||||
func (bc *basicClient) SubmitTask(taskID int64, repository *res.Repository, meta *lwp.Metadata) (string, error) {
|
||||
j := &models.JobData{
|
||||
Metadata: &models.JobMetadata{
|
||||
JobKind: job.KindGeneric,
|
@ -12,7 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package retention
|
||||
package dep
|
||||
|
||||
import (
|
||||
"testing"
|
||||
@ -80,25 +80,25 @@ func (c *clientTestSuite) TestGetCandidates() {
|
||||
|
||||
// image repository
|
||||
repository = &res.Repository{}
|
||||
repository.Kind = CandidateKindImage
|
||||
repository.Kind = res.Image
|
||||
repository.Namespace = "library"
|
||||
repository.Name = "hello-world"
|
||||
candidates, err = client.GetCandidates(repository)
|
||||
require.Nil(c.T(), err)
|
||||
assert.Equal(c.T(), 1, len(candidates))
|
||||
assert.Equal(c.T(), CandidateKindImage, candidates[0].Kind)
|
||||
assert.Equal(c.T(), res.Image, candidates[0].Kind)
|
||||
assert.Equal(c.T(), "library", candidates[0].Namespace)
|
||||
assert.Equal(c.T(), "hello-world", candidates[0].Repository)
|
||||
assert.Equal(c.T(), "latest", candidates[0].Tag)
|
||||
|
||||
// chart repository
|
||||
repository.Kind = CandidateKindChart
|
||||
repository.Kind = res.Chart
|
||||
repository.Namespace = "goharbor"
|
||||
repository.Name = "harbor"
|
||||
candidates, err = client.GetCandidates(repository)
|
||||
require.Nil(c.T(), err)
|
||||
assert.Equal(c.T(), 1, len(candidates))
|
||||
assert.Equal(c.T(), CandidateKindChart, candidates[0].Kind)
|
||||
assert.Equal(c.T(), res.Chart, candidates[0].Kind)
|
||||
assert.Equal(c.T(), "goharbor", candidates[0].Namespace)
|
||||
assert.Equal(c.T(), "1.0", candidates[0].Tag)
|
||||
}
|
||||
@ -114,12 +114,12 @@ func (c *clientTestSuite) TestDelete() {
|
||||
|
||||
// image
|
||||
candidate = &res.Candidate{}
|
||||
candidate.Kind = CandidateKindImage
|
||||
candidate.Kind = res.Image
|
||||
err = client.Delete(candidate)
|
||||
require.Nil(c.T(), err)
|
||||
|
||||
// chart
|
||||
candidate.Kind = CandidateKindChart
|
||||
candidate.Kind = res.Chart
|
||||
err = client.Delete(candidate)
|
||||
require.Nil(c.T(), err)
|
||||
|
@ -18,22 +18,17 @@ import (
|
||||
"encoding/json"
|
||||
"github.com/goharbor/harbor/src/jobservice/job"
|
||||
"github.com/goharbor/harbor/src/jobservice/logger"
|
||||
"github.com/goharbor/harbor/src/pkg/retention/dep"
|
||||
"github.com/goharbor/harbor/src/pkg/retention/policy"
|
||||
"github.com/goharbor/harbor/src/pkg/retention/policy/lwp"
|
||||
"github.com/goharbor/harbor/src/pkg/retention/res"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
// ParamRepo ...
|
||||
ParamRepo = "repository"
|
||||
// ParamMeta ...
|
||||
ParamMeta = "liteMeta"
|
||||
)
|
||||
|
||||
// Job of running retention process
|
||||
type Job struct {
|
||||
// client used to talk to core
|
||||
client Client
|
||||
client dep.Client
|
||||
}
|
||||
|
||||
// MaxFails of the job
|
||||
@ -108,28 +103,28 @@ func logError(logger logger.Interface, err error) error {
|
||||
}
|
||||
|
||||
func getParamRepo(params job.Parameters) (*res.Repository, error) {
|
||||
v, ok := params[ParamRepo]
|
||||
v, ok := params[dep.ParamRepo]
|
||||
if !ok {
|
||||
return nil, errors.Errorf("missing parameter: %s", ParamRepo)
|
||||
return nil, errors.Errorf("missing parameter: %s", dep.ParamRepo)
|
||||
}
|
||||
|
||||
repo, ok := v.(*res.Repository)
|
||||
if !ok {
|
||||
return nil, errors.Errorf("invalid parameter: %s", ParamRepo)
|
||||
return nil, errors.Errorf("invalid parameter: %s", dep.ParamRepo)
|
||||
}
|
||||
|
||||
return repo, nil
|
||||
}
|
||||
|
||||
func getParamMeta(params job.Parameters) (*policy.LiteMeta, error) {
|
||||
v, ok := params[ParamMeta]
|
||||
func getParamMeta(params job.Parameters) (*lwp.Metadata, error) {
|
||||
v, ok := params[dep.ParamMeta]
|
||||
if !ok {
|
||||
return nil, errors.Errorf("missing parameter: %s", ParamMeta)
|
||||
return nil, errors.Errorf("missing parameter: %s", dep.ParamMeta)
|
||||
}
|
||||
|
||||
meta, ok := v.(*policy.LiteMeta)
|
||||
meta, ok := v.(*lwp.Metadata)
|
||||
if !ok {
|
||||
return nil, errors.Errorf("invalid parameter: %s", ParamMeta)
|
||||
return nil, errors.Errorf("invalid parameter: %s", dep.ParamMeta)
|
||||
}
|
||||
|
||||
return meta, nil
|
||||
|
@ -16,6 +16,8 @@ package retention
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/goharbor/harbor/src/pkg/retention/dep"
|
||||
"github.com/goharbor/harbor/src/pkg/retention/policy/lwp"
|
||||
|
||||
"github.com/goharbor/harbor/src/common/utils"
|
||||
"github.com/goharbor/harbor/src/common/utils/log"
|
||||
@ -29,7 +31,7 @@ import (
|
||||
|
||||
// TODO init the client
|
||||
var (
|
||||
client Client
|
||||
client dep.Client
|
||||
mgr Manager
|
||||
)
|
||||
|
||||
@ -58,7 +60,7 @@ type launcher struct {
|
||||
|
||||
type jobData struct {
|
||||
repository *res.Repository
|
||||
policy *policy.LiteMeta
|
||||
policy *lwp.Metadata
|
||||
taskID int64
|
||||
}
|
||||
|
||||
@ -75,7 +77,7 @@ func (l *launcher) Launch(ply *policy.Metadata, executionID int64) (int64, error
|
||||
return 0, launcherError(fmt.Errorf("the scope of policy is nil"))
|
||||
}
|
||||
|
||||
repositoryRules := make(map[res.Repository]*policy.LiteMeta, 0)
|
||||
repositoryRules := make(map[res.Repository]*lwp.Metadata, 0)
|
||||
level := scope.Level
|
||||
var projectCandidates []*res.Candidate
|
||||
var err error
|
||||
@ -137,7 +139,7 @@ func (l *launcher) Launch(ply *policy.Metadata, executionID int64) (int64, error
|
||||
Kind: repositoryCandidate.Kind,
|
||||
}
|
||||
if repositoryRules[repository] == nil {
|
||||
repositoryRules[repository] = &policy.LiteMeta{
|
||||
repositoryRules[repository] = &lwp.Metadata{
|
||||
Algorithm: ply.Algorithm,
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ package retention
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/goharbor/harbor/src/pkg/retention/policy/lwp"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
@ -85,7 +86,7 @@ func (f *fakeClient) GetCandidates(repo *res.Repository) ([]*res.Candidate, erro
|
||||
func (f *fakeClient) Delete(candidate *res.Candidate) error {
|
||||
return nil
|
||||
}
|
||||
func (f *fakeClient) SubmitTask(taskID int64, repository *res.Repository, meta *policy.LiteMeta) (string, error) {
|
||||
func (f *fakeClient) SubmitTask(taskID int64, repository *res.Repository, meta *lwp.Metadata) (string, error) {
|
||||
f.id++
|
||||
return strconv.Itoa(f.id), nil
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
package action
|
||||
|
||||
import (
|
||||
"github.com/goharbor/harbor/src/pkg/retention"
|
||||
"github.com/goharbor/harbor/src/pkg/retention/dep"
|
||||
"github.com/goharbor/harbor/src/pkg/retention/res"
|
||||
)
|
||||
|
||||
@ -60,7 +60,7 @@ func (ra *retainAction) Perform(candidates []*res.Candidate) (results []*res.Res
|
||||
Target: art,
|
||||
}
|
||||
|
||||
if err := retention.DefaultClient.Delete(art); err != nil {
|
||||
if err := dep.DefaultClient.Delete(art); err != nil {
|
||||
result.Error = err
|
||||
}
|
||||
|
||||
|
@ -15,8 +15,8 @@
|
||||
package action
|
||||
|
||||
import (
|
||||
"github.com/goharbor/harbor/src/pkg/retention"
|
||||
"github.com/goharbor/harbor/src/pkg/retention/policy"
|
||||
"github.com/goharbor/harbor/src/pkg/retention/dep"
|
||||
"github.com/goharbor/harbor/src/pkg/retention/policy/lwp"
|
||||
"github.com/goharbor/harbor/src/pkg/retention/res"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/stretchr/testify/assert"
|
||||
@ -30,7 +30,7 @@ import (
|
||||
type TestPerformerSuite struct {
|
||||
suite.Suite
|
||||
|
||||
oldClient retention.Client
|
||||
oldClient dep.Client
|
||||
all []*res.Candidate
|
||||
}
|
||||
|
||||
@ -60,13 +60,13 @@ func (suite *TestPerformerSuite) SetupSuite() {
|
||||
},
|
||||
}
|
||||
|
||||
suite.oldClient = retention.DefaultClient
|
||||
retention.DefaultClient = &fakeRetentionClient{}
|
||||
suite.oldClient = dep.DefaultClient
|
||||
dep.DefaultClient = &fakeRetentionClient{}
|
||||
}
|
||||
|
||||
// TearDownSuite ...
|
||||
func (suite *TestPerformerSuite) TearDownSuite() {
|
||||
retention.DefaultClient = suite.oldClient
|
||||
dep.DefaultClient = suite.oldClient
|
||||
}
|
||||
|
||||
// TestPerform tests Perform action
|
||||
@ -91,7 +91,7 @@ func (suite *TestPerformerSuite) TestPerform() {
|
||||
require.Equal(suite.T(), 1, len(results))
|
||||
require.NotNil(suite.T(), results[0].Target)
|
||||
assert.NoError(suite.T(), results[0].Error)
|
||||
assert.Equal(suite.T(), "latest", results[0].Target.Tag)
|
||||
assert.Equal(suite.T(), "dev", results[0].Target.Tag)
|
||||
}
|
||||
|
||||
type fakeRetentionClient struct{}
|
||||
@ -107,6 +107,6 @@ func (frc *fakeRetentionClient) Delete(candidate *res.Candidate) error {
|
||||
}
|
||||
|
||||
// SubmitTask ...
|
||||
func (frc *fakeRetentionClient) SubmitTask(taskID int64, repository *res.Repository, meta *policy.LiteMeta) (string, error) {
|
||||
func (frc *fakeRetentionClient) SubmitTask(taskID int64, repository *res.Repository, meta *lwp.Metadata) (string, error) {
|
||||
return "", errors.New("not implemented")
|
||||
}
|
||||
|
@ -15,6 +15,14 @@
|
||||
package or
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/goharbor/harbor/src/pkg/retention/dep"
|
||||
|
||||
"github.com/goharbor/harbor/src/pkg/retention/policy/lwp"
|
||||
|
||||
"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/rule"
|
||||
@ -26,8 +34,6 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/stretchr/testify/suite"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
// ProcessorTestSuite is suite for testing processor
|
||||
@ -36,6 +42,8 @@ type ProcessorTestSuite struct {
|
||||
|
||||
p alg.Processor
|
||||
all []*res.Candidate
|
||||
|
||||
oldClient dep.Client
|
||||
}
|
||||
|
||||
// TestProcessor is entrance for ProcessorTestSuite
|
||||
@ -93,10 +101,15 @@ func (suite *ProcessorTestSuite) SetupSuite() {
|
||||
require.NoError(suite.T(), err)
|
||||
|
||||
suite.p = p
|
||||
|
||||
suite.oldClient = dep.DefaultClient
|
||||
dep.DefaultClient = &fakeRetentionClient{}
|
||||
}
|
||||
|
||||
// TearDownSuite ...
|
||||
func (suite *ProcessorTestSuite) TearDownSuite() {}
|
||||
func (suite *ProcessorTestSuite) TearDownSuite() {
|
||||
dep.DefaultClient = suite.oldClient
|
||||
}
|
||||
|
||||
// TestProcess tests process method
|
||||
func (suite *ProcessorTestSuite) TestProcess() {
|
||||
@ -113,3 +126,20 @@ func (suite *ProcessorTestSuite) TestProcess() {
|
||||
return true
|
||||
}, "no errors in the returned result list")
|
||||
}
|
||||
|
||||
type fakeRetentionClient struct{}
|
||||
|
||||
// GetCandidates ...
|
||||
func (frc *fakeRetentionClient) GetCandidates(repo *res.Repository) ([]*res.Candidate, error) {
|
||||
return nil, errors.New("not implemented")
|
||||
}
|
||||
|
||||
// Delete ...
|
||||
func (frc *fakeRetentionClient) Delete(candidate *res.Candidate) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// SubmitTask ...
|
||||
func (frc *fakeRetentionClient) SubmitTask(taskID int64, repository *res.Repository, meta *lwp.Metadata) (string, error) {
|
||||
return "", errors.New("not implemented")
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ 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/lwp"
|
||||
"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"
|
||||
@ -29,12 +30,12 @@ type Builder interface {
|
||||
// Builds runnable processor
|
||||
//
|
||||
// Arguments:
|
||||
// policy *LiteMeta : the simple metadata of retention policy
|
||||
// policy *Metadata : the simple metadata of retention policy
|
||||
//
|
||||
// Returns:
|
||||
// Processor : a processor implementation to process the candidates
|
||||
// error : common error object if any errors occurred
|
||||
Build(policy *LiteMeta) (alg.Processor, error)
|
||||
Build(policy *lwp.Metadata) (alg.Processor, error)
|
||||
}
|
||||
|
||||
// NewBuilder news a basic builder
|
||||
@ -50,7 +51,7 @@ type basicBuilder struct {
|
||||
}
|
||||
|
||||
// Build policy processor from the raw policy
|
||||
func (bb *basicBuilder) Build(policy *LiteMeta) (alg.Processor, error) {
|
||||
func (bb *basicBuilder) Build(policy *lwp.Metadata) (alg.Processor, error) {
|
||||
if policy == nil {
|
||||
return nil, errors.New("nil policy to build processor")
|
||||
}
|
||||
|
29
src/pkg/retention/policy/lwp/models.go
Normal file
29
src/pkg/retention/policy/lwp/models.go
Normal file
@ -0,0 +1,29 @@
|
||||
// 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 lwp = lightweight policy
|
||||
package lwp
|
||||
|
||||
import "github.com/goharbor/harbor/src/pkg/retention/policy/rule"
|
||||
|
||||
// Metadata contains partial metadata of policy
|
||||
// It's a lightweight version of policy.Metadata
|
||||
type Metadata struct {
|
||||
// Algorithm applied to the rules
|
||||
// "OR" / "AND"
|
||||
Algorithm string `json:"algorithm"`
|
||||
|
||||
// Rule collection
|
||||
Rules []*rule.Metadata `json:"rules"`
|
||||
}
|
@ -70,13 +70,3 @@ type Scope struct {
|
||||
// 0 for 'system', project ID for 'project' and repo ID for 'repository'
|
||||
Reference int64 `json:"ref"`
|
||||
}
|
||||
|
||||
// LiteMeta contains partial metadata of policy
|
||||
type LiteMeta struct {
|
||||
// Algorithm applied to the rules
|
||||
// "OR" / "AND"
|
||||
Algorithm string `json:"algorithm"`
|
||||
|
||||
// Rule collection
|
||||
Rules []*rule.Metadata `json:"rules"`
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user