Use policy controller in registry deletion

Signed-off-by: cd1989 <chende@caicloud.io>
This commit is contained in:
cd1989 2019-04-04 17:45:24 +08:00
parent 4116433de8
commit 2450dacecb
5 changed files with 89 additions and 77 deletions

View File

@ -12,13 +12,15 @@ import (
"github.com/goharbor/harbor/src/replication/ng"
"github.com/goharbor/harbor/src/replication/ng/adapter"
"github.com/goharbor/harbor/src/replication/ng/model"
"github.com/goharbor/harbor/src/replication/ng/policy"
"github.com/goharbor/harbor/src/replication/ng/registry"
)
// RegistryAPI handles requests to /api/registries/{}. It manages registries integrated to Harbor.
type RegistryAPI struct {
BaseController
manager registry.Manager
manager registry.Manager
policyCtl policy.Controller
}
// Prepare validates the user
@ -35,6 +37,7 @@ func (t *RegistryAPI) Prepare() {
}
t.manager = ng.RegistryMgr
t.policyCtl = ng.PolicyCtl
}
// Get gets a registry by id.
@ -193,21 +196,39 @@ func (t *RegistryAPI) Delete() {
}
if registry == nil {
t.HandleNotFound(fmt.Sprintf("registry %d not found", id))
t.HandleNotFound(fmt.Sprintf("Registry %d not found", id))
return
}
// TODO: filter the policies by registry ID
_, policies, err := ng.PolicyCtl.List()
// Check whether there are replication policies that use this registry as source registry.
total, _, err := t.policyCtl.List([]*model.PolicyQuery{
{
SrcRegistry: id,
},
}...)
if err != nil {
msg := fmt.Sprintf("Get policies related to registry %d error: %v", id, err)
t.HandleInternalServerError(fmt.Sprintf("List replication policies with source registry %d error: %v", id, err))
return
}
if total > 0 {
msg := fmt.Sprintf("Can't delete registry %d, %d replication policies use it as source registry", id, total)
log.Error(msg)
t.HandleInternalServerError(msg)
t.HandleStatusPreconditionFailed(msg)
return
}
if len(policies) > 0 {
msg := fmt.Sprintf("Can't delete registry with replication policies, %d found", len(policies))
// Check whether there are replication policies that use this registry as destination registry.
total, _, err = t.policyCtl.List([]*model.PolicyQuery{
{
DestRegistry: id,
},
}...)
if err != nil {
t.HandleInternalServerError(fmt.Sprintf("List replication policies with destination registry %d error: %v", id, err))
return
}
if total > 0 {
msg := fmt.Sprintf("Can't delete registry %d, %d replication policies use it as destination registry", id, total)
log.Error(msg)
t.HandleStatusPreconditionFailed(msg)
return

View File

@ -5,8 +5,10 @@ import (
"time"
"github.com/astaxie/beego/orm"
common_dao "github.com/goharbor/harbor/src/common/dao"
"github.com/goharbor/harbor/src/replication/ng/dao/models"
"github.com/goharbor/harbor/src/replication/ng/model"
)
// AddRepPolicy insert new policy to DB.
@ -19,33 +21,53 @@ func AddRepPolicy(policy *models.RepPolicy) (int64, error) {
return o.Insert(policy)
}
func filteredRepPolicyQuerySeter(name, namespace string) orm.QuerySeter {
// GetPolicies list polices with given query parameters.
func GetPolicies(queries ...*model.PolicyQuery) (int64, []*models.RepPolicy, error) {
var qs = common_dao.GetOrmer().QueryTable(new(models.RepPolicy))
var policies []*models.RepPolicy
// TODO: just filter polices by name now, and need consider how to filter namespace.
qs = qs.Filter("name__icontains", name)
if len(queries) == 0 {
total, err := qs.Count()
if err != nil {
return -1, nil, err
}
return qs
}
_, err = qs.All(&policies)
if err != nil {
return total, nil, err
}
// GetTotalOfRepPolicies returns the total count of replication policies
func GetTotalOfRepPolicies(name, namespace string) (int64, error) {
var qs = filteredRepPolicyQuerySeter(name, namespace)
return qs.Count()
}
// GetPolicies filter policies and pagination.
func GetPolicies(name, namespace string, page, pageSize int64) (policies []*models.RepPolicy, err error) {
var qs = filteredRepPolicyQuerySeter(name, namespace)
// Paginate
if page > 0 && pageSize > 0 {
qs = qs.Limit(pageSize, (page-1)*pageSize)
return total, policies, nil
}
_, err = qs.All(&policies)
query := queries[0]
if len(query.Name) != 0 {
qs = qs.Filter("Name__icontains", query.Name)
}
if len(query.Namespace) != 0 {
// TODO: Namespace filter not implemented yet
}
if query.SrcRegistry > 0 {
qs = qs.Filter("SrcRegistryID__exact", query.SrcRegistry)
}
if query.DestRegistry > 0 {
qs = qs.Filter("DestRegistryID__exact", query.DestRegistry)
}
return
total, err := qs.Count()
if err != nil {
return -1, nil, err
}
if query.Page > 0 && query.Size > 0 {
qs = qs.Limit(query.Size, (query.Page-1)*query.Size)
}
_, err = qs.All(&policies)
if err != nil {
return total, nil, err
}
return total, policies, nil
}
// GetRepPolicy return special policy by id.

View File

@ -3,9 +3,12 @@ package dao
import (
"testing"
"github.com/goharbor/harbor/src/replication/ng/dao/models"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
common_models "github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/replication/ng/dao/models"
"github.com/goharbor/harbor/src/replication/ng/model"
)
var (
@ -84,34 +87,6 @@ func TestAddRepPolicy(t *testing.T) {
}
}
func TestGetTotalOfRepPolicies(t *testing.T) {
type args struct {
name string
namespace string
}
tests := []struct {
name string
args args
want int64
wantErr bool
}{
{name: "GetTotalOfRepPolicies 1", args: args{name: "Test 1"}, want: 1},
{name: "GetTotalOfRepPolicies 2", args: args{name: "Test"}, want: 3},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := GetTotalOfRepPolicies(tt.args.name, tt.args.namespace)
if tt.wantErr {
require.NotNil(t, err, "wantErr: %s", err)
return
}
require.Nil(t, err)
assert.Equal(t, tt.want, got)
})
}
}
func TestGetPolicies(t *testing.T) {
type args struct {
name string
@ -131,7 +106,16 @@ func TestGetPolicies(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotPolicies, err := GetPolicies(tt.args.name, tt.args.namespace, tt.args.page, tt.args.pageSize)
_, gotPolicies, err := GetPolicies([]*model.PolicyQuery{
{
Name: tt.args.name,
Namespace: tt.args.namespace,
Pagination: common_models.Pagination{
Page: tt.args.page,
Size: tt.args.pageSize,
},
},
}...)
if tt.wantErr {
require.NotNil(t, err, "wantErr: %s", err)
return

View File

@ -152,6 +152,8 @@ type PolicyQuery struct {
Name string
// TODO: need to consider how to support listing the policies
// of one namespace in both pull and push modes
Namespace string
Namespace string
SrcRegistry int64
DestRegistry int64
models.Pagination
}

View File

@ -156,25 +156,8 @@ func (m *DefaultManager) Create(policy *model.Policy) (int64, error) {
// List returns all the policies
func (m *DefaultManager) List(queries ...*model.PolicyQuery) (total int64, policies []*model.Policy, err error) {
// default query parameters
var name = ""
var namespace = ""
var page int64 = 1
var pageSize int64 = 15
if len(queries) > 0 {
name = queries[0].Name
namespace = queries[0].Namespace
page = queries[0].Pagination.Page
pageSize = queries[0].Pagination.Size
}
var persistPolicies []*persist_models.RepPolicy
persistPolicies, err = dao.GetPolicies(name, namespace, page, pageSize)
if err != nil {
return
}
total, err = dao.GetTotalOfRepPolicies(name, namespace)
total, persistPolicies, err = dao.GetPolicies(queries...)
if err != nil {
return
}