refact replication adapter

Change-Id: Ic28854089b8dcfcbc7e42065df5c19c64d5b85e7
Signed-off-by: Ziming Zhang <zziming@vmware.com>
This commit is contained in:
Ziming Zhang 2019-10-22 17:53:53 +08:00
parent 5419e1a844
commit 1801bac03d
31 changed files with 421 additions and 202 deletions

View File

@ -407,7 +407,7 @@ func (t *RegistryAPI) GetInfo() {
t.SendInternalServerError(fmt.Errorf("failed to get the adapter factory for registry type %s: %v", registry.Type, err)) t.SendInternalServerError(fmt.Errorf("failed to get the adapter factory for registry type %s: %v", registry.Type, err))
return return
} }
adp, err := factory(registry) adp, err := factory.Create(registry)
if err != nil { if err != nil {
t.SendInternalServerError(fmt.Errorf("failed to create the adapter for registry %d: %v", registry.ID, err)) t.SendInternalServerError(fmt.Errorf("failed to create the adapter for registry %d: %v", registry.ID, err))
return return

View File

@ -23,12 +23,19 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func fakedFactory(*model.Registry) (adapter.Adapter, error) { type fakedFactory struct {
}
func (fakedFactory) Create(*model.Registry) (adapter.Adapter, error) {
return nil, nil return nil, nil
} }
func (fakedFactory) AdapterPattern() *model.AdapterPattern {
return nil
}
func TestReplicationAdapterAPIList(t *testing.T) { func TestReplicationAdapterAPIList(t *testing.T) {
err := adapter.RegisterFactory("test", fakedFactory, nil) err := adapter.RegisterFactory("test", new(fakedFactory))
require.Nil(t, err) require.Nil(t, err)
cases := []*codeCheckingCase{ cases := []*codeCheckingCase{
// 401 // 401

View File

@ -31,10 +31,13 @@ const (
) )
var registry = map[model.RegistryType]Factory{} var registry = map[model.RegistryType]Factory{}
var adapterInfoMap = map[model.RegistryType]*model.AdapterInfo{} var adapterInfoMap = map[model.RegistryType]*model.AdapterPattern{}
// Factory creates a specific Adapter according to the params // Factory creates a specific Adapter according to the params
type Factory func(*model.Registry) (Adapter, error) type Factory interface {
Create(*model.Registry) (Adapter, error)
AdapterPattern() *model.AdapterPattern
}
// Adapter interface defines the capabilities of registry // Adapter interface defines the capabilities of registry
type Adapter interface { type Adapter interface {
@ -123,7 +126,7 @@ func (v *VTag) GetLabels() []string {
} }
// RegisterFactory registers one adapter factory to the registry // RegisterFactory registers one adapter factory to the registry
func RegisterFactory(t model.RegistryType, factory Factory, adapterInfo *model.AdapterInfo) error { func RegisterFactory(t model.RegistryType, factory Factory) error {
if len(t) == 0 { if len(t) == 0 {
return errors.New("invalid registry type") return errors.New("invalid registry type")
} }
@ -135,6 +138,7 @@ func RegisterFactory(t model.RegistryType, factory Factory, adapterInfo *model.A
return fmt.Errorf("adapter factory for %s already exists", t) return fmt.Errorf("adapter factory for %s already exists", t)
} }
registry[t] = factory registry[t] = factory
adapterInfo := factory.AdapterPattern()
if adapterInfo != nil { if adapterInfo != nil {
adapterInfoMap[t] = adapterInfo adapterInfoMap[t] = adapterInfo
} }
@ -166,6 +170,6 @@ func ListRegisteredAdapterTypes() []model.RegistryType {
} }
// ListAdapterInfos list the adapter infos // ListAdapterInfos list the adapter infos
func ListAdapterInfos() map[model.RegistryType]*model.AdapterInfo { func ListAdapterInfos() map[model.RegistryType]*model.AdapterPattern {
return adapterInfoMap return adapterInfoMap
} }

View File

@ -22,24 +22,31 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func fakedFactory(*model.Registry) (Adapter, error) { type fakedFactory struct {
}
func (fakedFactory) Create(*model.Registry) (Adapter, error) {
return nil, nil return nil, nil
} }
func (fakedFactory) AdapterPattern() *model.AdapterPattern {
return nil
}
func TestRegisterFactory(t *testing.T) { func TestRegisterFactory(t *testing.T) {
// empty type // empty type
assert.NotNil(t, RegisterFactory("", nil, nil)) assert.NotNil(t, RegisterFactory("", nil))
// empty factory // empty factory
assert.NotNil(t, RegisterFactory("harbor", nil, nil)) assert.NotNil(t, RegisterFactory("harbor", nil))
// pass // pass
assert.Nil(t, RegisterFactory("harbor", fakedFactory, nil)) assert.Nil(t, RegisterFactory("harbor", new(fakedFactory)))
// already exists // already exists
assert.NotNil(t, RegisterFactory("harbor", fakedFactory, nil)) assert.NotNil(t, RegisterFactory("harbor", new(fakedFactory)))
} }
func TestGetFactory(t *testing.T) { func TestGetFactory(t *testing.T) {
registry = map[model.RegistryType]Factory{} registry = map[model.RegistryType]Factory{}
require.Nil(t, RegisterFactory("harbor", fakedFactory, nil)) require.Nil(t, RegisterFactory("harbor", new(fakedFactory)))
// doesn't exist // doesn't exist
_, err := GetFactory("gcr") _, err := GetFactory("gcr")
assert.NotNil(t, err) assert.NotNil(t, err)
@ -55,7 +62,7 @@ func TestListRegisteredAdapterTypes(t *testing.T) {
assert.Equal(t, 0, len(types)) assert.Equal(t, 0, len(types))
// register one factory // register one factory
require.Nil(t, RegisterFactory("harbor", fakedFactory, nil)) require.Nil(t, RegisterFactory("harbor", new(fakedFactory)))
types = ListRegisteredAdapterTypes() types = ListRegisteredAdapterTypes()
require.Equal(t, 1, len(types)) require.Equal(t, 1, len(types))

View File

@ -19,9 +19,7 @@ import (
) )
func init() { func init() {
if err := adp.RegisterFactory(model.RegistryTypeAliAcr, func(registry *model.Registry) (adp.Adapter, error) { if err := adp.RegisterFactory(model.RegistryTypeAliAcr, new(factory)); err != nil {
return newAdapter(registry)
}, getAdapterInfo()); err != nil {
log.Errorf("failed to register factory for %s: %v", model.RegistryTypeAliAcr, err) log.Errorf("failed to register factory for %s: %v", model.RegistryTypeAliAcr, err)
return return
} }
@ -70,6 +68,19 @@ func newAdapter(registry *model.Registry) (*adapter, error) {
}, nil }, nil
} }
type factory struct {
}
// Create ...
func (f *factory) Create(r *model.Registry) (adp.Adapter, error) {
return newAdapter(r)
}
// AdapterPattern ...
func (f *factory) AdapterPattern() *model.AdapterPattern {
return getAdapterInfo()
}
// adapter for to aliyun docker registry // adapter for to aliyun docker registry
type adapter struct { type adapter struct {
*native.Adapter *native.Adapter
@ -105,29 +116,32 @@ func (a *adapter) Info() (info *model.RegistryInfo, err error) {
return return
} }
func getAdapterInfo() *model.AdapterInfo { func getAdapterInfo() *model.AdapterPattern {
info := &model.AdapterInfo{ info := &model.AdapterPattern{
SpecialEndpoints: []*model.Endpoint{ EndpointPattern: &model.EndpointPattern{
{Key: "cn-hangzhou", Value: "https://registry.cn-hangzhou.aliyuncs.com"}, EndpointType: model.EndpointPatternTypeList,
{Key: "cn-shanghai", Value: "https://registry.cn-shanghai.aliyuncs.com"}, Endpoints: []*model.Endpoint{
{Key: "cn-qingdao", Value: "https://registry.cn-qingdao.aliyuncs.com"}, {Key: "cn-hangzhou", Value: "https://registry.cn-hangzhou.aliyuncs.com"},
{Key: "cn-beijing", Value: "https://registry.cn-beijing.aliyuncs.com"}, {Key: "cn-shanghai", Value: "https://registry.cn-shanghai.aliyuncs.com"},
{Key: "cn-zhangjiakou", Value: "https://registry.cn-zhangjiakou.aliyuncs.com"}, {Key: "cn-qingdao", Value: "https://registry.cn-qingdao.aliyuncs.com"},
{Key: "cn-huhehaote", Value: "https://registry.cn-huhehaote.aliyuncs.com"}, {Key: "cn-beijing", Value: "https://registry.cn-beijing.aliyuncs.com"},
{Key: "cn-shenzhen", Value: "https://registry.cn-shenzhen.aliyuncs.com"}, {Key: "cn-zhangjiakou", Value: "https://registry.cn-zhangjiakou.aliyuncs.com"},
{Key: "cn-chengdu", Value: "https://registry.cn-chengdu.aliyuncs.com"}, {Key: "cn-huhehaote", Value: "https://registry.cn-huhehaote.aliyuncs.com"},
{Key: "cn-hongkong", Value: "https://registry.cn-hongkong.aliyuncs.com"}, {Key: "cn-shenzhen", Value: "https://registry.cn-shenzhen.aliyuncs.com"},
{Key: "ap-southeast-1", Value: "https://registry.ap-southeast-1.aliyuncs.com"}, {Key: "cn-chengdu", Value: "https://registry.cn-chengdu.aliyuncs.com"},
{Key: "ap-southeast-2", Value: "https://registry.ap-southeast-2.aliyuncs.com"}, {Key: "cn-hongkong", Value: "https://registry.cn-hongkong.aliyuncs.com"},
{Key: "ap-southeast-3", Value: "https://registry.ap-southeast-3.aliyuncs.com"}, {Key: "ap-southeast-1", Value: "https://registry.ap-southeast-1.aliyuncs.com"},
{Key: "ap-southeast-5", Value: "https://registry.ap-southeast-5.aliyuncs.com"}, {Key: "ap-southeast-2", Value: "https://registry.ap-southeast-2.aliyuncs.com"},
{Key: "ap-northeast-1", Value: "https://registry.ap-northeast-1.aliyuncs.com"}, {Key: "ap-southeast-3", Value: "https://registry.ap-southeast-3.aliyuncs.com"},
{Key: "ap-south-1", Value: "https://registry.ap-south-1.aliyuncs.com"}, {Key: "ap-southeast-5", Value: "https://registry.ap-southeast-5.aliyuncs.com"},
{Key: "eu-central-1", Value: "https://registry.eu-central-1.aliyuncs.com"}, {Key: "ap-northeast-1", Value: "https://registry.ap-northeast-1.aliyuncs.com"},
{Key: "eu-west-1", Value: "https://registry.eu-west-1.aliyuncs.com"}, {Key: "ap-south-1", Value: "https://registry.ap-south-1.aliyuncs.com"},
{Key: "us-west-1", Value: "https://registry.us-west-1.aliyuncs.com"}, {Key: "eu-central-1", Value: "https://registry.eu-central-1.aliyuncs.com"},
{Key: "us-east-1", Value: "https://registry.us-east-1.aliyuncs.com"}, {Key: "eu-west-1", Value: "https://registry.eu-west-1.aliyuncs.com"},
{Key: "me-east-1", Value: "https://registry.me-east-1.aliyuncs.com"}, {Key: "us-west-1", Value: "https://registry.us-west-1.aliyuncs.com"},
{Key: "us-east-1", Value: "https://registry.us-east-1.aliyuncs.com"},
{Key: "me-east-1", Value: "https://registry.me-east-1.aliyuncs.com"},
},
}, },
} }
return info return info

View File

@ -26,7 +26,7 @@ func TestAdapter_NewAdapter(t *testing.T) {
assert.NotNil(t, factory) assert.NotNil(t, factory)
// test case for URL is registry. // test case for URL is registry.
adapter, err := factory(&model.Registry{ adapter, err := newAdapter(&model.Registry{
Type: model.RegistryTypeAliAcr, Type: model.RegistryTypeAliAcr,
Credential: &model.Credential{ Credential: &model.Credential{
AccessKey: "MockAccessKey", AccessKey: "MockAccessKey",
@ -38,7 +38,7 @@ func TestAdapter_NewAdapter(t *testing.T) {
assert.NotNil(t, adapter) assert.NotNil(t, adapter)
// test case for URL is cr service. // test case for URL is cr service.
adapter, err = factory(&model.Registry{ adapter, err = newAdapter(&model.Registry{
Type: model.RegistryTypeAliAcr, Type: model.RegistryTypeAliAcr,
Credential: &model.Credential{ Credential: &model.Credential{
AccessKey: "MockAccessKey", AccessKey: "MockAccessKey",

View File

@ -40,9 +40,7 @@ var (
) )
func init() { func init() {
if err := adp.RegisterFactory(model.RegistryTypeAwsEcr, func(registry *model.Registry) (adp.Adapter, error) { if err := adp.RegisterFactory(model.RegistryTypeAwsEcr, new(factory)); err != nil {
return newAdapter(registry)
}, getAdapterInfo()); err != nil {
log.Errorf("failed to register factory for %s: %v", model.RegistryTypeAwsEcr, err) log.Errorf("failed to register factory for %s: %v", model.RegistryTypeAwsEcr, err)
return return
} }
@ -74,6 +72,19 @@ func parseRegion(url string) (string, error) {
return rs[1], nil return rs[1], nil
} }
type factory struct {
}
// Create ...
func (f *factory) Create(r *model.Registry) (adp.Adapter, error) {
return newAdapter(r)
}
// AdapterPattern ...
func (f *factory) AdapterPattern() *model.AdapterPattern {
return getAdapterInfo()
}
type adapter struct { type adapter struct {
*native.Adapter *native.Adapter
registry *model.Registry registry *model.Registry
@ -104,76 +115,79 @@ func (*adapter) Info() (info *model.RegistryInfo, err error) {
}, nil }, nil
} }
func getAdapterInfo() *model.AdapterInfo { func getAdapterInfo() *model.AdapterPattern {
info := &model.AdapterInfo{ info := &model.AdapterPattern{
SpecialEndpoints: []*model.Endpoint{ EndpointPattern: &model.EndpointPattern{
{ EndpointType: model.EndpointPatternTypeList,
Key: "ap-northeast-1", Endpoints: []*model.Endpoint{
Value: "https://api.ecr.ap-northeast-1.amazonaws.com", {
}, Key: "ap-northeast-1",
{ Value: "https://api.ecr.ap-northeast-1.amazonaws.com",
Key: "us-east-1", },
Value: "https://api.ecr.us-east-1.amazonaws.com", {
}, Key: "us-east-1",
{ Value: "https://api.ecr.us-east-1.amazonaws.com",
Key: "us-east-2", },
Value: "https://api.ecr.us-east-2.amazonaws.com", {
}, Key: "us-east-2",
{ Value: "https://api.ecr.us-east-2.amazonaws.com",
Key: "us-west-1", },
Value: "https://api.ecr.us-west-1.amazonaws.com", {
}, Key: "us-west-1",
{ Value: "https://api.ecr.us-west-1.amazonaws.com",
Key: "us-west-2", },
Value: "https://api.ecr.us-west-2.amazonaws.com", {
}, Key: "us-west-2",
{ Value: "https://api.ecr.us-west-2.amazonaws.com",
Key: "ap-east-1", },
Value: "https://api.ecr.ap-east-1.amazonaws.com", {
}, Key: "ap-east-1",
{ Value: "https://api.ecr.ap-east-1.amazonaws.com",
Key: "ap-south-1", },
Value: "https://api.ecr.ap-south-1.amazonaws.com", {
}, Key: "ap-south-1",
{ Value: "https://api.ecr.ap-south-1.amazonaws.com",
Key: "ap-northeast-2", },
Value: "https://api.ecr.ap-northeast-2.amazonaws.com", {
}, Key: "ap-northeast-2",
{ Value: "https://api.ecr.ap-northeast-2.amazonaws.com",
Key: "ap-southeast-1", },
Value: "https://api.ecr.ap-southeast-1.amazonaws.com", {
}, Key: "ap-southeast-1",
{ Value: "https://api.ecr.ap-southeast-1.amazonaws.com",
Key: "ap-southeast-2", },
Value: "https://api.ecr.ap-southeast-2.amazonaws.com", {
}, Key: "ap-southeast-2",
{ Value: "https://api.ecr.ap-southeast-2.amazonaws.com",
Key: "ca-central-1", },
Value: "https://api.ecr.ca-central-1.amazonaws.com", {
}, Key: "ca-central-1",
{ Value: "https://api.ecr.ca-central-1.amazonaws.com",
Key: "eu-central-1", },
Value: "https://api.ecr.eu-central-1.amazonaws.com", {
}, Key: "eu-central-1",
{ Value: "https://api.ecr.eu-central-1.amazonaws.com",
Key: "eu-west-1", },
Value: "https://api.ecr.eu-west-1.amazonaws.com", {
}, Key: "eu-west-1",
{ Value: "https://api.ecr.eu-west-1.amazonaws.com",
Key: "eu-west-2", },
Value: "https://api.ecr.eu-west-2.amazonaws.com", {
}, Key: "eu-west-2",
{ Value: "https://api.ecr.eu-west-2.amazonaws.com",
Key: "eu-west-3", },
Value: "https://api.ecr.eu-west-3.amazonaws.com", {
}, Key: "eu-west-3",
{ Value: "https://api.ecr.eu-west-3.amazonaws.com",
Key: "eu-north-1", },
Value: "https://api.ecr.eu-north-1.amazonaws.com", {
}, Key: "eu-north-1",
{ Value: "https://api.ecr.eu-north-1.amazonaws.com",
Key: "sa-east-1", },
Value: "https://api.ecr.sa-east-1.amazonaws.com", {
Key: "sa-east-1",
Value: "https://api.ecr.sa-east-1.amazonaws.com",
},
}, },
}, },
} }

View File

@ -27,7 +27,7 @@ func TestAdapter_NewAdapter(t *testing.T) {
assert.Nil(t, err) assert.Nil(t, err)
assert.NotNil(t, factory) assert.NotNil(t, factory)
adapter, err := factory(&model.Registry{ adapter, err := newAdapter(&model.Registry{
Type: model.RegistryTypeAwsEcr, Type: model.RegistryTypeAwsEcr,
Credential: &model.Credential{ Credential: &model.Credential{
AccessKey: "xxx", AccessKey: "xxx",
@ -38,7 +38,7 @@ func TestAdapter_NewAdapter(t *testing.T) {
assert.Nil(t, err) assert.Nil(t, err)
assert.NotNil(t, adapter) assert.NotNil(t, adapter)
adapter, err = factory(&model.Registry{ adapter, err = newAdapter(&model.Registry{
Type: model.RegistryTypeAwsEcr, Type: model.RegistryTypeAwsEcr,
Credential: &model.Credential{ Credential: &model.Credential{
AccessKey: "xxx", AccessKey: "xxx",
@ -49,7 +49,7 @@ func TestAdapter_NewAdapter(t *testing.T) {
assert.Nil(t, err) assert.Nil(t, err)
assert.NotNil(t, adapter) assert.NotNil(t, adapter)
adapter, err = factory(&model.Registry{ adapter, err = newAdapter(&model.Registry{
Type: model.RegistryTypeAwsEcr, Type: model.RegistryTypeAwsEcr,
Credential: &model.Credential{ Credential: &model.Credential{
AccessKey: "xxx", AccessKey: "xxx",

View File

@ -8,14 +8,14 @@ import (
) )
func init() { func init() {
if err := adp.RegisterFactory(model.RegistryTypeAzureAcr, factory, nil); err != nil { if err := adp.RegisterFactory(model.RegistryTypeAzureAcr, new(factory)); err != nil {
log.Errorf("Register adapter factory for %s error: %v", model.RegistryTypeAzureAcr, err) log.Errorf("Register adapter factory for %s error: %v", model.RegistryTypeAzureAcr, err)
return return
} }
log.Infof("Factory for adapter %s registered", model.RegistryTypeAzureAcr) log.Infof("Factory for adapter %s registered", model.RegistryTypeAzureAcr)
} }
func factory(registry *model.Registry) (adp.Adapter, error) { func newAdapter(registry *model.Registry) (adp.Adapter, error) {
dockerRegistryAdapter, err := native.NewAdapter(registry) dockerRegistryAdapter, err := native.NewAdapter(registry)
if err != nil { if err != nil {
return nil, err return nil, err
@ -25,6 +25,19 @@ func factory(registry *model.Registry) (adp.Adapter, error) {
}, nil }, nil
} }
type factory struct {
}
// Create ...
func (f *factory) Create(r *model.Registry) (adp.Adapter, error) {
return newAdapter(r)
}
// AdapterPattern ...
func (f *factory) AdapterPattern() *model.AdapterPattern {
return nil
}
type adapter struct { type adapter struct {
*native.Adapter *native.Adapter
} }

View File

@ -18,14 +18,14 @@ import (
) )
func init() { func init() {
if err := adp.RegisterFactory(model.RegistryTypeDockerHub, factory, getAdapterInfo()); err != nil { if err := adp.RegisterFactory(model.RegistryTypeDockerHub, new(factory)); err != nil {
log.Errorf("Register adapter factory for %s error: %v", model.RegistryTypeDockerHub, err) log.Errorf("Register adapter factory for %s error: %v", model.RegistryTypeDockerHub, err)
return return
} }
log.Infof("Factory for adapter %s registered", model.RegistryTypeDockerHub) log.Infof("Factory for adapter %s registered", model.RegistryTypeDockerHub)
} }
func factory(registry *model.Registry) (adp.Adapter, error) { func newAdapter(registry *model.Registry) (adp.Adapter, error) {
client, err := NewClient(registry) client, err := NewClient(registry)
if err != nil { if err != nil {
return nil, err return nil, err
@ -47,6 +47,19 @@ func factory(registry *model.Registry) (adp.Adapter, error) {
}, nil }, nil
} }
type factory struct {
}
// Create ...
func (f *factory) Create(r *model.Registry) (adp.Adapter, error) {
return newAdapter(r)
}
// AdapterPattern ...
func (f *factory) AdapterPattern() *model.AdapterPattern {
return getAdapterInfo()
}
type adapter struct { type adapter struct {
*native.Adapter *native.Adapter
registry *model.Registry registry *model.Registry
@ -80,12 +93,15 @@ func (a *adapter) Info() (*model.RegistryInfo, error) {
}, nil }, nil
} }
func getAdapterInfo() *model.AdapterInfo { func getAdapterInfo() *model.AdapterPattern {
info := &model.AdapterInfo{ info := &model.AdapterPattern{
SpecialEndpoints: []*model.Endpoint{ EndpointPattern: &model.EndpointPattern{
{ EndpointType: model.EndpointPatternTypeFix,
Key: "hub.docker.com", Endpoints: []*model.Endpoint{
Value: "https://hub.docker.com", {
Key: "hub.docker.com",
Value: "https://hub.docker.com",
},
}, },
}, },
} }

View File

@ -21,7 +21,7 @@ func getAdapter(t *testing.T) adp.Adapter {
assert.Nil(err) assert.Nil(err)
assert.NotNil(factory) assert.NotNil(factory)
adapter, err := factory(&model.Registry{ adapter, err := newAdapter(&model.Registry{
Type: model.RegistryTypeDockerHub, Type: model.RegistryTypeDockerHub,
URL: baseURL, URL: baseURL,
Credential: &model.Credential{ Credential: &model.Credential{

View File

@ -12,15 +12,26 @@ import (
) )
func init() { func init() {
if err := adp.RegisterFactory(model.RegistryTypeGitLab, func(registry *model.Registry) (adp.Adapter, error) { if err := adp.RegisterFactory(model.RegistryTypeGitLab, new(factory)); err != nil {
return newAdapter(registry)
}, nil); err != nil {
log.Errorf("failed to register factory for %s: %v", model.RegistryTypeGitLab, err) log.Errorf("failed to register factory for %s: %v", model.RegistryTypeGitLab, err)
return return
} }
log.Infof("the factory for adapter %s registered", model.RegistryTypeGitLab) log.Infof("the factory for adapter %s registered", model.RegistryTypeGitLab)
} }
type factory struct {
}
// Create ...
func (f *factory) Create(r *model.Registry) (adp.Adapter, error) {
return newAdapter(r)
}
// AdapterPattern ...
func (f *factory) AdapterPattern() *model.AdapterPattern {
return nil
}
type adapter struct { type adapter struct {
*native.Adapter *native.Adapter
registry *model.Registry registry *model.Registry
@ -31,7 +42,6 @@ type adapter struct {
} }
func newAdapter(registry *model.Registry) (*adapter, error) { func newAdapter(registry *model.Registry) (*adapter, error) {
var credential auth.Credential var credential auth.Credential
if registry.Credential != nil && len(registry.Credential.AccessSecret) != 0 { if registry.Credential != nil && len(registry.Credential.AccessSecret) != 0 {
credential = auth.NewBasicAuthCredential( credential = auth.NewBasicAuthCredential(

View File

@ -22,9 +22,7 @@ import (
) )
func init() { func init() {
if err := adp.RegisterFactory(model.RegistryTypeGoogleGcr, func(registry *model.Registry) (adp.Adapter, error) { if err := adp.RegisterFactory(model.RegistryTypeGoogleGcr, new(factory)); err != nil {
return newAdapter(registry)
}, getAdapterInfo()); err != nil {
log.Errorf("failed to register factory for %s: %v", model.RegistryTypeGoogleGcr, err) log.Errorf("failed to register factory for %s: %v", model.RegistryTypeGoogleGcr, err)
return return
} }
@ -43,6 +41,19 @@ func newAdapter(registry *model.Registry) (*adapter, error) {
}, nil }, nil
} }
type factory struct {
}
// Create ...
func (f *factory) Create(r *model.Registry) (adp.Adapter, error) {
return newAdapter(r)
}
// AdapterPattern ...
func (f *factory) AdapterPattern() *model.AdapterPattern {
return getAdapterInfo()
}
type adapter struct { type adapter struct {
*native.Adapter *native.Adapter
registry *model.Registry registry *model.Registry
@ -73,28 +84,30 @@ func (adapter) Info() (info *model.RegistryInfo, err error) {
}, nil }, nil
} }
func getAdapterInfo() *model.AdapterInfo { func getAdapterInfo() *model.AdapterPattern {
info := &model.AdapterInfo{ info := &model.AdapterPattern{
SpecialEndpoints: []*model.Endpoint{ EndpointPattern: &model.EndpointPattern{
{ EndpointType: model.EndpointPatternTypeList,
Key: "gcr.io", Endpoints: []*model.Endpoint{
Value: "https://gcr.io", {
}, Key: "gcr.io",
{ Value: "https://gcr.io",
Key: "us.gcr.io", },
Value: "https://us.gcr.io", {
}, Key: "us.gcr.io",
{ Value: "https://us.gcr.io",
Key: "eu.gcr.io", },
Value: "https://eu.gcr.io", {
}, Key: "eu.gcr.io",
{ Value: "https://eu.gcr.io",
Key: "asia.gcr.io", },
Value: "https://asia.gcr.io", {
Key: "asia.gcr.io",
Value: "https://asia.gcr.io",
},
}, },
}, },
SpecialCredential: &model.CredentialInfo{ CredentialPattern: &model.CredentialPattern{
AccessKeyType: model.AccessKeyTypeFix, AccessKeyType: model.AccessKeyTypeFix,
AccessKeyData: "_json_key", AccessKeyData: "_json_key",
AccessSecretType: model.AccessSecretTypeFile, AccessSecretType: model.AccessSecretTypeFile,

View File

@ -88,10 +88,10 @@ func getMockAdapter(t *testing.T, hasCred, health bool) (*adapter, *httptest.Ser
factory, err := adp.GetFactory(model.RegistryTypeGoogleGcr) factory, err := adp.GetFactory(model.RegistryTypeGoogleGcr)
assert.Nil(t, err) assert.Nil(t, err)
assert.NotNil(t, factory) assert.NotNil(t, factory)
a, err := factory(registry) a, err := newAdapter(registry)
assert.Nil(t, err) assert.Nil(t, err)
return a.(*adapter), server return a, server
} }
func TestAdapter_Info(t *testing.T) { func TestAdapter_Info(t *testing.T) {

View File

@ -33,15 +33,26 @@ import (
) )
func init() { func init() {
if err := adp.RegisterFactory(model.RegistryTypeHarbor, func(registry *model.Registry) (adp.Adapter, error) { if err := adp.RegisterFactory(model.RegistryTypeHarbor, new(factory)); err != nil {
return newAdapter(registry)
}, nil); err != nil {
log.Errorf("failed to register factory for %s: %v", model.RegistryTypeHarbor, err) log.Errorf("failed to register factory for %s: %v", model.RegistryTypeHarbor, err)
return return
} }
log.Infof("the factory for adapter %s registered", model.RegistryTypeHarbor) log.Infof("the factory for adapter %s registered", model.RegistryTypeHarbor)
} }
type factory struct {
}
// Create ...
func (f *factory) Create(r *model.Registry) (adp.Adapter, error) {
return newAdapter(r)
}
// AdapterPattern ...
func (f *factory) AdapterPattern() *model.AdapterPattern {
return nil
}
type adapter struct { type adapter struct {
*native.Adapter *native.Adapter
registry *model.Registry registry *model.Registry

View File

@ -22,15 +22,26 @@ import (
) )
func init() { func init() {
if err := adp.RegisterFactory(model.RegistryTypeHelmHub, func(registry *model.Registry) (adp.Adapter, error) { if err := adp.RegisterFactory(model.RegistryTypeHelmHub, new(factory)); err != nil {
return newAdapter(registry)
}, nil); err != nil {
log.Errorf("failed to register factory for %s: %v", model.RegistryTypeHelmHub, err) log.Errorf("failed to register factory for %s: %v", model.RegistryTypeHelmHub, err)
return return
} }
log.Infof("the factory for adapter %s registered", model.RegistryTypeHelmHub) log.Infof("the factory for adapter %s registered", model.RegistryTypeHelmHub)
} }
type factory struct {
}
// Create ...
func (f *factory) Create(r *model.Registry) (adp.Adapter, error) {
return newAdapter(r)
}
// AdapterPattern ...
func (f *factory) AdapterPattern() *model.AdapterPattern {
return nil
}
type adapter struct { type adapter struct {
registry *model.Registry registry *model.Registry
client *Client client *Client

View File

@ -19,7 +19,7 @@ import (
) )
func init() { func init() {
err := adp.RegisterFactory(model.RegistryTypeHuawei, AdapterFactory, nil) err := adp.RegisterFactory(model.RegistryTypeHuawei, new(factory))
if err != nil { if err != nil {
log.Errorf("failed to register factory for Huawei: %v", err) log.Errorf("failed to register factory for Huawei: %v", err)
return return
@ -27,6 +27,19 @@ func init() {
log.Infof("the factory of Huawei adapter was registered") log.Infof("the factory of Huawei adapter was registered")
} }
type factory struct {
}
// Create ...
func (f *factory) Create(r *model.Registry) (adp.Adapter, error) {
return newAdapter(r)
}
// AdapterPattern ...
func (f *factory) AdapterPattern() *model.AdapterPattern {
return nil
}
// Adapter is for images replications between harbor and Huawei image repository(SWR) // Adapter is for images replications between harbor and Huawei image repository(SWR)
type adapter struct { type adapter struct {
*native.Adapter *native.Adapter
@ -210,8 +223,7 @@ func (a *adapter) HealthCheck() (model.HealthStatus, error) {
return model.Healthy, nil return model.Healthy, nil
} }
// AdapterFactory is the factory for huawei adapter func newAdapter(registry *model.Registry) (adp.Adapter, error) {
func AdapterFactory(registry *model.Registry) (adp.Adapter, error) {
dockerRegistryAdapter, err := native.NewAdapter(registry) dockerRegistryAdapter, err := native.NewAdapter(registry)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -24,7 +24,7 @@ func init() {
Status: "", Status: "",
} }
hwAdapter, err = AdapterFactory(hwRegistry) hwAdapter, err = newAdapter(hwRegistry)
if err != nil { if err != nil {
os.Exit(1) os.Exit(1)
} }

View File

@ -21,7 +21,7 @@ func init() {
Insecure: false, Insecure: false,
Status: "", Status: "",
} }
adp, err := AdapterFactory(hwRegistry) adp, err := newAdapter(hwRegistry)
if err != nil { if err != nil {
os.Exit(1) os.Exit(1)
} }

View File

@ -22,7 +22,7 @@ import (
) )
func init() { func init() {
err := adp.RegisterFactory(model.RegistryTypeJfrogArtifactory, AdapterFactory, nil) err := adp.RegisterFactory(model.RegistryTypeJfrogArtifactory, new(factory))
if err != nil { if err != nil {
log.Errorf("failed to register factory for jfrog artifactory: %v", err) log.Errorf("failed to register factory for jfrog artifactory: %v", err)
return return
@ -30,6 +30,19 @@ func init() {
log.Infof("the factory of jfrog artifactory adapter was registered") log.Infof("the factory of jfrog artifactory adapter was registered")
} }
type factory struct {
}
// Create ...
func (f *factory) Create(r *model.Registry) (adp.Adapter, error) {
return newAdapter(r)
}
// AdapterPattern ...
func (f *factory) AdapterPattern() *model.AdapterPattern {
return nil
}
// Adapter is for images replications between harbor and jfrog artifactory image repository // Adapter is for images replications between harbor and jfrog artifactory image repository
type adapter struct { type adapter struct {
*native.Adapter *native.Adapter
@ -64,8 +77,7 @@ func (a *adapter) Info() (info *model.RegistryInfo, err error) {
return return
} }
// AdapterFactory is the factory for jfrog artifactory adapter func newAdapter(registry *model.Registry) (adp.Adapter, error) {
func AdapterFactory(registry *model.Registry) (adp.Adapter, error) {
dockerRegistryAdapter, err := native.NewAdapter(registry) dockerRegistryAdapter, err := native.NewAdapter(registry)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -91,7 +91,7 @@ func getMockAdapter(t *testing.T, hasCred, health bool) (*adapter, *httptest.Ser
factory, err := adp.GetFactory(model.RegistryTypeJfrogArtifactory) factory, err := adp.GetFactory(model.RegistryTypeJfrogArtifactory)
assert.Nil(t, err) assert.Nil(t, err)
assert.NotNil(t, factory) assert.NotNil(t, factory)
a, err := factory(registry) a, err := newAdapter(registry)
assert.Nil(t, err) assert.Nil(t, err)
return a.(*adapter), server return a.(*adapter), server

View File

@ -35,9 +35,7 @@ import (
) )
func init() { func init() {
if err := adp.RegisterFactory(model.RegistryTypeDockerRegistry, func(registry *model.Registry) (adp.Adapter, error) { if err := adp.RegisterFactory(model.RegistryTypeDockerRegistry, new(factory)); err != nil {
return NewAdapter(registry)
}, nil); err != nil {
log.Errorf("failed to register factory for %s: %v", model.RegistryTypeDockerRegistry, err) log.Errorf("failed to register factory for %s: %v", model.RegistryTypeDockerRegistry, err)
return return
} }
@ -46,6 +44,19 @@ func init() {
var _ adp.Adapter = &Adapter{} var _ adp.Adapter = &Adapter{}
type factory struct {
}
// Create ...
func (f *factory) Create(r *model.Registry) (adp.Adapter, error) {
return NewAdapter(r)
}
// AdapterPattern ...
func (f *factory) AdapterPattern() *model.AdapterPattern {
return nil
}
// Adapter implements an adapter for Docker registry. It can be used to all registries // Adapter implements an adapter for Docker registry. It can be used to all registries
// that implement the registry V2 API // that implement the registry V2 API
type Adapter struct { type Adapter struct {

View File

@ -26,9 +26,7 @@ type adapter struct {
} }
func init() { func init() {
err := adp.RegisterFactory(model.RegistryTypeQuayio, func(registry *model.Registry) (adp.Adapter, error) { err := adp.RegisterFactory(model.RegistryTypeQuayio, new(factory))
return newAdapter(registry)
}, nil)
if err != nil { if err != nil {
log.Errorf("failed to register factory for Quay.io: %v", err) log.Errorf("failed to register factory for Quay.io: %v", err)
return return
@ -68,6 +66,19 @@ func newAdapter(registry *model.Registry) (*adapter, error) {
}, nil }, nil
} }
type factory struct {
}
// Create ...
func (f *factory) Create(r *model.Registry) (adp.Adapter, error) {
return newAdapter(r)
}
// AdapterPattern ...
func (f *factory) AdapterPattern() *model.AdapterPattern {
return nil
}
// Info returns information of the registry // Info returns information of the registry
func (a *adapter) Info() (*model.RegistryInfo, error) { func (a *adapter) Info() (*model.RegistryInfo, error) {
return &model.RegistryInfo{ return &model.RegistryInfo{

View File

@ -10,7 +10,7 @@ import (
func getMockAdapter(t *testing.T) adp.Adapter { func getMockAdapter(t *testing.T) adp.Adapter {
factory, _ := adp.GetFactory(model.RegistryTypeQuayio) factory, _ := adp.GetFactory(model.RegistryTypeQuayio)
adapter, err := factory(&model.Registry{ adapter, err := factory.Create(&model.Registry{
Type: model.RegistryTypeQuayio, Type: model.RegistryTypeQuayio,
URL: "https://quay.io", URL: "https://quay.io",
}) })

View File

@ -116,14 +116,32 @@ type FilterStyle struct {
Values []string `json:"values,omitempty"` Values []string `json:"values,omitempty"`
} }
// EndpointPattern ...
type EndpointPattern struct {
EndpointType EndpointType `json:"endpoint_type"`
Endpoints []*Endpoint `json:"endpoints"`
}
// EndpointType ..
type EndpointType string
const (
// EndpointPatternTypeStandard ...
EndpointPatternTypeStandard EndpointType = "EndpointPatternTypeStandard"
// EndpointPatternTypeFix ...
EndpointPatternTypeFix EndpointType = "EndpointPatternTypeFix"
// EndpointPatternTypeList ...
EndpointPatternTypeList EndpointType = "EndpointPatternTypeList"
)
// Endpoint ... // Endpoint ...
type Endpoint struct { type Endpoint struct {
Key string `json:"key"` Key string `json:"key"`
Value string `json:"value"` Value string `json:"value"`
} }
// CredentialInfo ... // CredentialPattern ...
type CredentialInfo struct { type CredentialPattern struct {
AccessKeyType AccessKeyType `json:"access_key_type"` AccessKeyType AccessKeyType `json:"access_key_type"`
AccessKeyData string `json:"access_key_data"` AccessKeyData string `json:"access_key_data"`
AccessSecretType AccessSecretType `json:"access_secret_type"` AccessSecretType AccessSecretType `json:"access_secret_type"`
@ -152,17 +170,38 @@ const (
// RegistryInfo provides base info and capability declarations of the registry // RegistryInfo provides base info and capability declarations of the registry
type RegistryInfo struct { type RegistryInfo struct {
Type RegistryType `json:"type"` Type RegistryType `json:"type"`
Description string `json:"description"` Description string `json:"description"`
SupportedResourceTypes []ResourceType `json:"-"` SupportedResourceTypes []ResourceType `json:"-"`
SupportedResourceFilters []*FilterStyle `json:"supported_resource_filters"` SupportedResourceFilters []*FilterStyle `json:"supported_resource_filters"`
SupportedTriggers []TriggerType `json:"supported_triggers"` SupportedTriggers []TriggerType `json:"supported_triggers"`
SpecialEndpoints []*Endpoint `json:"special_endpoints"`
SpecialCredential *CredentialInfo `json:"special_credential"`
} }
// AdapterInfo provides base info and capability declarations of the registry // AdapterPattern provides base info and capability declarations of the registry
type AdapterInfo struct { type AdapterPattern struct {
SpecialEndpoints []*Endpoint `json:"special_endpoints"` EndpointPattern *EndpointPattern `json:"endpoint_pattern"`
SpecialCredential *CredentialInfo `json:"special_credential"` CredentialPattern *CredentialPattern `json:"credential_pattern"`
}
// NewDefaultAdapterPattern ...
func NewDefaultAdapterPattern() *AdapterPattern {
return &AdapterPattern{
EndpointPattern: NewDefaultEndpointPattern(),
CredentialPattern: NewDefaultCredentialPattern(),
}
}
// NewDefaultEndpointPattern ...
func NewDefaultEndpointPattern() *EndpointPattern {
return &EndpointPattern{
EndpointType: EndpointPatternTypeStandard,
}
}
// NewDefaultCredentialPattern ...
func NewDefaultCredentialPattern() *CredentialPattern {
return &CredentialPattern{
AccessKeyType: AccessKeyTypeStandard,
AccessSecretType: AccessSecretTypeStandard,
}
} }

View File

@ -113,10 +113,17 @@ func (f *fakedScheduler) Stop(id string) error {
return nil return nil
} }
func fakedAdapterFactory(*model.Registry) (adapter.Adapter, error) { type fakedFactory struct {
}
func (fakedFactory) Create(*model.Registry) (adapter.Adapter, error) {
return &fakedAdapter{}, nil return &fakedAdapter{}, nil
} }
func (fakedFactory) AdapterPattern() *model.AdapterPattern {
return nil
}
type fakedAdapter struct{} type fakedAdapter struct{}
func (f *fakedAdapter) Info() (*model.RegistryInfo, error) { func (f *fakedAdapter) Info() (*model.RegistryInfo, error) {
@ -212,7 +219,7 @@ func TestMain(m *testing.M) {
} }
func TestStartReplication(t *testing.T) { func TestStartReplication(t *testing.T) {
err := adapter.RegisterFactory(model.RegistryTypeHarbor, fakedAdapterFactory, nil) err := adapter.RegisterFactory(model.RegistryTypeHarbor, new(fakedFactory))
require.Nil(t, err) require.Nil(t, err)
config.Config = &config.Configuration{} config.Config = &config.Configuration{}

View File

@ -38,7 +38,7 @@ func initialize(policy *model.Policy) (adp.Adapter, adp.Adapter, error) {
if err != nil { if err != nil {
return nil, nil, fmt.Errorf("failed to get adapter factory for registry type %s: %v", policy.SrcRegistry.Type, err) return nil, nil, fmt.Errorf("failed to get adapter factory for registry type %s: %v", policy.SrcRegistry.Type, err)
} }
srcAdapter, err = srcFactory(policy.SrcRegistry) srcAdapter, err = srcFactory.Create(policy.SrcRegistry)
if err != nil { if err != nil {
return nil, nil, fmt.Errorf("failed to create adapter for source registry %s: %v", policy.SrcRegistry.URL, err) return nil, nil, fmt.Errorf("failed to create adapter for source registry %s: %v", policy.SrcRegistry.URL, err)
} }
@ -48,7 +48,7 @@ func initialize(policy *model.Policy) (adp.Adapter, adp.Adapter, error) {
if err != nil { if err != nil {
return nil, nil, fmt.Errorf("failed to get adapter factory for registry type %s: %v", policy.DestRegistry.Type, err) return nil, nil, fmt.Errorf("failed to get adapter factory for registry type %s: %v", policy.DestRegistry.Type, err)
} }
dstAdapter, err = dstFactory(policy.DestRegistry) dstAdapter, err = dstFactory.Create(policy.DestRegistry)
if err != nil { if err != nil {
return nil, nil, fmt.Errorf("failed to create adapter for destination registry %s: %v", policy.DestRegistry.URL, err) return nil, nil, fmt.Errorf("failed to create adapter for destination registry %s: %v", policy.DestRegistry.URL, err)
} }

View File

@ -29,10 +29,17 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func fakedAdapterFactory(*model.Registry) (adapter.Adapter, error) { type fakedFactory struct {
}
func (fakedFactory) Create(*model.Registry) (adapter.Adapter, error) {
return &fakedAdapter{}, nil return &fakedAdapter{}, nil
} }
func (fakedFactory) AdapterPattern() *model.AdapterPattern {
return nil
}
type fakedAdapter struct{} type fakedAdapter struct{}
func (f *fakedAdapter) Info() (*model.RegistryInfo, error) { func (f *fakedAdapter) Info() (*model.RegistryInfo, error) {
@ -194,7 +201,7 @@ func TestMain(m *testing.M) {
config.Config = &config.Configuration{ config.Config = &config.Configuration{
CoreURL: url, CoreURL: url,
} }
if err := adapter.RegisterFactory(model.RegistryTypeHarbor, fakedAdapterFactory, nil); err != nil { if err := adapter.RegisterFactory(model.RegistryTypeHarbor, new(fakedFactory)); err != nil {
os.Exit(1) os.Exit(1)
} }
os.Exit(m.Run()) os.Exit(m.Run())

View File

@ -195,7 +195,7 @@ func CheckHealthStatus(r *model.Registry) (model.HealthStatus, error) {
return model.Unknown, fmt.Errorf("get adaper for type '%s' error: %v", r.Type, err) return model.Unknown, fmt.Errorf("get adaper for type '%s' error: %v", r.Type, err)
} }
rAdapter, err := factory(r) rAdapter, err := factory.Create(r)
if err != nil { if err != nil {
return model.Unknown, fmt.Errorf("generate '%s' type adapter form factory error: %v", r.Type, err) return model.Unknown, fmt.Errorf("generate '%s' type adapter form factory error: %v", r.Type, err)
} }

View File

@ -106,7 +106,7 @@ func createRegistry(reg *model.Registry) (adapter.ChartRegistry, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
ad, err := factory(reg) ad, err := factory.Create(reg)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -113,7 +113,7 @@ func createRegistry(reg *model.Registry) (adapter.ImageRegistry, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
ad, err := factory(reg) ad, err := factory.Create(reg)
if err != nil { if err != nil {
return nil, err return nil, err
} }