diff --git a/src/core/api/registry.go b/src/core/api/registry.go index 3885e11a0..8973eb3bd 100644 --- a/src/core/api/registry.go +++ b/src/core/api/registry.go @@ -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)) return } - adp, err := factory(registry) + adp, err := factory.Create(registry) if err != nil { t.SendInternalServerError(fmt.Errorf("failed to create the adapter for registry %d: %v", registry.ID, err)) return diff --git a/src/core/api/replication_adapter_test.go b/src/core/api/replication_adapter_test.go index 26ef0e984..786bcd19f 100644 --- a/src/core/api/replication_adapter_test.go +++ b/src/core/api/replication_adapter_test.go @@ -23,12 +23,19 @@ import ( "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 } +func (fakedFactory) AdapterPattern() *model.AdapterPattern { + return nil +} + func TestReplicationAdapterAPIList(t *testing.T) { - err := adapter.RegisterFactory("test", fakedFactory, nil) + err := adapter.RegisterFactory("test", new(fakedFactory)) require.Nil(t, err) cases := []*codeCheckingCase{ // 401 diff --git a/src/replication/adapter/adapter.go b/src/replication/adapter/adapter.go index 692941dd0..1e7f7865c 100644 --- a/src/replication/adapter/adapter.go +++ b/src/replication/adapter/adapter.go @@ -31,10 +31,13 @@ const ( ) 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 -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 type Adapter interface { @@ -123,7 +126,7 @@ func (v *VTag) GetLabels() []string { } // 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 { 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) } registry[t] = factory + adapterInfo := factory.AdapterPattern() if adapterInfo != nil { adapterInfoMap[t] = adapterInfo } @@ -166,6 +170,6 @@ func ListRegisteredAdapterTypes() []model.RegistryType { } // ListAdapterInfos list the adapter infos -func ListAdapterInfos() map[model.RegistryType]*model.AdapterInfo { +func ListAdapterInfos() map[model.RegistryType]*model.AdapterPattern { return adapterInfoMap } diff --git a/src/replication/adapter/adapter_test.go b/src/replication/adapter/adapter_test.go index 4d4a3f446..cfb999b61 100644 --- a/src/replication/adapter/adapter_test.go +++ b/src/replication/adapter/adapter_test.go @@ -22,24 +22,31 @@ import ( "github.com/stretchr/testify/require" ) -func fakedFactory(*model.Registry) (Adapter, error) { +type fakedFactory struct { +} + +func (fakedFactory) Create(*model.Registry) (Adapter, error) { return nil, nil } +func (fakedFactory) AdapterPattern() *model.AdapterPattern { + return nil +} + func TestRegisterFactory(t *testing.T) { // empty type - assert.NotNil(t, RegisterFactory("", nil, nil)) + assert.NotNil(t, RegisterFactory("", nil)) // empty factory - assert.NotNil(t, RegisterFactory("harbor", nil, nil)) + assert.NotNil(t, RegisterFactory("harbor", nil)) // pass - assert.Nil(t, RegisterFactory("harbor", fakedFactory, nil)) + assert.Nil(t, RegisterFactory("harbor", new(fakedFactory))) // already exists - assert.NotNil(t, RegisterFactory("harbor", fakedFactory, nil)) + assert.NotNil(t, RegisterFactory("harbor", new(fakedFactory))) } func TestGetFactory(t *testing.T) { registry = map[model.RegistryType]Factory{} - require.Nil(t, RegisterFactory("harbor", fakedFactory, nil)) + require.Nil(t, RegisterFactory("harbor", new(fakedFactory))) // doesn't exist _, err := GetFactory("gcr") assert.NotNil(t, err) @@ -55,7 +62,7 @@ func TestListRegisteredAdapterTypes(t *testing.T) { assert.Equal(t, 0, len(types)) // register one factory - require.Nil(t, RegisterFactory("harbor", fakedFactory, nil)) + require.Nil(t, RegisterFactory("harbor", new(fakedFactory))) types = ListRegisteredAdapterTypes() require.Equal(t, 1, len(types)) diff --git a/src/replication/adapter/aliacr/adapter.go b/src/replication/adapter/aliacr/adapter.go index d576457f1..e50750b6f 100644 --- a/src/replication/adapter/aliacr/adapter.go +++ b/src/replication/adapter/aliacr/adapter.go @@ -19,9 +19,7 @@ import ( ) func init() { - if err := adp.RegisterFactory(model.RegistryTypeAliAcr, func(registry *model.Registry) (adp.Adapter, error) { - return newAdapter(registry) - }, getAdapterInfo()); err != nil { + if err := adp.RegisterFactory(model.RegistryTypeAliAcr, new(factory)); err != nil { log.Errorf("failed to register factory for %s: %v", model.RegistryTypeAliAcr, err) return } @@ -70,6 +68,19 @@ func newAdapter(registry *model.Registry) (*adapter, error) { }, 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 type adapter struct { *native.Adapter @@ -105,29 +116,32 @@ func (a *adapter) Info() (info *model.RegistryInfo, err error) { return } -func getAdapterInfo() *model.AdapterInfo { - info := &model.AdapterInfo{ - SpecialEndpoints: []*model.Endpoint{ - {Key: "cn-hangzhou", Value: "https://registry.cn-hangzhou.aliyuncs.com"}, - {Key: "cn-shanghai", Value: "https://registry.cn-shanghai.aliyuncs.com"}, - {Key: "cn-qingdao", Value: "https://registry.cn-qingdao.aliyuncs.com"}, - {Key: "cn-beijing", Value: "https://registry.cn-beijing.aliyuncs.com"}, - {Key: "cn-zhangjiakou", Value: "https://registry.cn-zhangjiakou.aliyuncs.com"}, - {Key: "cn-huhehaote", Value: "https://registry.cn-huhehaote.aliyuncs.com"}, - {Key: "cn-shenzhen", Value: "https://registry.cn-shenzhen.aliyuncs.com"}, - {Key: "cn-chengdu", Value: "https://registry.cn-chengdu.aliyuncs.com"}, - {Key: "cn-hongkong", Value: "https://registry.cn-hongkong.aliyuncs.com"}, - {Key: "ap-southeast-1", Value: "https://registry.ap-southeast-1.aliyuncs.com"}, - {Key: "ap-southeast-2", Value: "https://registry.ap-southeast-2.aliyuncs.com"}, - {Key: "ap-southeast-3", Value: "https://registry.ap-southeast-3.aliyuncs.com"}, - {Key: "ap-southeast-5", Value: "https://registry.ap-southeast-5.aliyuncs.com"}, - {Key: "ap-northeast-1", Value: "https://registry.ap-northeast-1.aliyuncs.com"}, - {Key: "ap-south-1", Value: "https://registry.ap-south-1.aliyuncs.com"}, - {Key: "eu-central-1", Value: "https://registry.eu-central-1.aliyuncs.com"}, - {Key: "eu-west-1", Value: "https://registry.eu-west-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"}, +func getAdapterInfo() *model.AdapterPattern { + info := &model.AdapterPattern{ + EndpointPattern: &model.EndpointPattern{ + EndpointType: model.EndpointPatternTypeList, + Endpoints: []*model.Endpoint{ + {Key: "cn-hangzhou", Value: "https://registry.cn-hangzhou.aliyuncs.com"}, + {Key: "cn-shanghai", Value: "https://registry.cn-shanghai.aliyuncs.com"}, + {Key: "cn-qingdao", Value: "https://registry.cn-qingdao.aliyuncs.com"}, + {Key: "cn-beijing", Value: "https://registry.cn-beijing.aliyuncs.com"}, + {Key: "cn-zhangjiakou", Value: "https://registry.cn-zhangjiakou.aliyuncs.com"}, + {Key: "cn-huhehaote", Value: "https://registry.cn-huhehaote.aliyuncs.com"}, + {Key: "cn-shenzhen", Value: "https://registry.cn-shenzhen.aliyuncs.com"}, + {Key: "cn-chengdu", Value: "https://registry.cn-chengdu.aliyuncs.com"}, + {Key: "cn-hongkong", Value: "https://registry.cn-hongkong.aliyuncs.com"}, + {Key: "ap-southeast-1", Value: "https://registry.ap-southeast-1.aliyuncs.com"}, + {Key: "ap-southeast-2", Value: "https://registry.ap-southeast-2.aliyuncs.com"}, + {Key: "ap-southeast-3", Value: "https://registry.ap-southeast-3.aliyuncs.com"}, + {Key: "ap-southeast-5", Value: "https://registry.ap-southeast-5.aliyuncs.com"}, + {Key: "ap-northeast-1", Value: "https://registry.ap-northeast-1.aliyuncs.com"}, + {Key: "ap-south-1", Value: "https://registry.ap-south-1.aliyuncs.com"}, + {Key: "eu-central-1", Value: "https://registry.eu-central-1.aliyuncs.com"}, + {Key: "eu-west-1", Value: "https://registry.eu-west-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 diff --git a/src/replication/adapter/aliacr/adapter_test.go b/src/replication/adapter/aliacr/adapter_test.go index 94fd41eb3..9f8212ead 100644 --- a/src/replication/adapter/aliacr/adapter_test.go +++ b/src/replication/adapter/aliacr/adapter_test.go @@ -26,7 +26,7 @@ func TestAdapter_NewAdapter(t *testing.T) { assert.NotNil(t, factory) // test case for URL is registry. - adapter, err := factory(&model.Registry{ + adapter, err := newAdapter(&model.Registry{ Type: model.RegistryTypeAliAcr, Credential: &model.Credential{ AccessKey: "MockAccessKey", @@ -38,7 +38,7 @@ func TestAdapter_NewAdapter(t *testing.T) { assert.NotNil(t, adapter) // test case for URL is cr service. - adapter, err = factory(&model.Registry{ + adapter, err = newAdapter(&model.Registry{ Type: model.RegistryTypeAliAcr, Credential: &model.Credential{ AccessKey: "MockAccessKey", diff --git a/src/replication/adapter/awsecr/adapter.go b/src/replication/adapter/awsecr/adapter.go index 3a494ab36..e2ed93d02 100644 --- a/src/replication/adapter/awsecr/adapter.go +++ b/src/replication/adapter/awsecr/adapter.go @@ -40,9 +40,7 @@ var ( ) func init() { - if err := adp.RegisterFactory(model.RegistryTypeAwsEcr, func(registry *model.Registry) (adp.Adapter, error) { - return newAdapter(registry) - }, getAdapterInfo()); err != nil { + if err := adp.RegisterFactory(model.RegistryTypeAwsEcr, new(factory)); err != nil { log.Errorf("failed to register factory for %s: %v", model.RegistryTypeAwsEcr, err) return } @@ -74,6 +72,19 @@ func parseRegion(url string) (string, error) { 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 { *native.Adapter registry *model.Registry @@ -104,76 +115,79 @@ func (*adapter) Info() (info *model.RegistryInfo, err error) { }, nil } -func getAdapterInfo() *model.AdapterInfo { - info := &model.AdapterInfo{ - SpecialEndpoints: []*model.Endpoint{ - { - 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-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-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-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-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: "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-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-3", - Value: "https://api.ecr.eu-west-3.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", +func getAdapterInfo() *model.AdapterPattern { + info := &model.AdapterPattern{ + EndpointPattern: &model.EndpointPattern{ + EndpointType: model.EndpointPatternTypeList, + Endpoints: []*model.Endpoint{ + { + 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-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-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-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-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: "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-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-3", + Value: "https://api.ecr.eu-west-3.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", + }, }, }, } diff --git a/src/replication/adapter/awsecr/adapter_test.go b/src/replication/adapter/awsecr/adapter_test.go index 206e35673..0f186b5f5 100644 --- a/src/replication/adapter/awsecr/adapter_test.go +++ b/src/replication/adapter/awsecr/adapter_test.go @@ -27,7 +27,7 @@ func TestAdapter_NewAdapter(t *testing.T) { assert.Nil(t, err) assert.NotNil(t, factory) - adapter, err := factory(&model.Registry{ + adapter, err := newAdapter(&model.Registry{ Type: model.RegistryTypeAwsEcr, Credential: &model.Credential{ AccessKey: "xxx", @@ -38,7 +38,7 @@ func TestAdapter_NewAdapter(t *testing.T) { assert.Nil(t, err) assert.NotNil(t, adapter) - adapter, err = factory(&model.Registry{ + adapter, err = newAdapter(&model.Registry{ Type: model.RegistryTypeAwsEcr, Credential: &model.Credential{ AccessKey: "xxx", @@ -49,7 +49,7 @@ func TestAdapter_NewAdapter(t *testing.T) { assert.Nil(t, err) assert.NotNil(t, adapter) - adapter, err = factory(&model.Registry{ + adapter, err = newAdapter(&model.Registry{ Type: model.RegistryTypeAwsEcr, Credential: &model.Credential{ AccessKey: "xxx", diff --git a/src/replication/adapter/azurecr/adapter.go b/src/replication/adapter/azurecr/adapter.go index b10b92bb9..b11d71708 100644 --- a/src/replication/adapter/azurecr/adapter.go +++ b/src/replication/adapter/azurecr/adapter.go @@ -8,14 +8,14 @@ import ( ) 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) return } 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) if err != nil { return nil, err @@ -25,6 +25,19 @@ func factory(registry *model.Registry) (adp.Adapter, error) { }, 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 { *native.Adapter } diff --git a/src/replication/adapter/dockerhub/adapter.go b/src/replication/adapter/dockerhub/adapter.go index 4b19ff7b3..490d42c5a 100644 --- a/src/replication/adapter/dockerhub/adapter.go +++ b/src/replication/adapter/dockerhub/adapter.go @@ -18,14 +18,14 @@ import ( ) 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) return } 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) if err != nil { return nil, err @@ -47,6 +47,19 @@ func factory(registry *model.Registry) (adp.Adapter, error) { }, 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 { *native.Adapter registry *model.Registry @@ -80,12 +93,15 @@ func (a *adapter) Info() (*model.RegistryInfo, error) { }, nil } -func getAdapterInfo() *model.AdapterInfo { - info := &model.AdapterInfo{ - SpecialEndpoints: []*model.Endpoint{ - { - Key: "hub.docker.com", - Value: "https://hub.docker.com", +func getAdapterInfo() *model.AdapterPattern { + info := &model.AdapterPattern{ + EndpointPattern: &model.EndpointPattern{ + EndpointType: model.EndpointPatternTypeFix, + Endpoints: []*model.Endpoint{ + { + Key: "hub.docker.com", + Value: "https://hub.docker.com", + }, }, }, } diff --git a/src/replication/adapter/dockerhub/adapter_test.go b/src/replication/adapter/dockerhub/adapter_test.go index 9cf9ed650..dda533d54 100644 --- a/src/replication/adapter/dockerhub/adapter_test.go +++ b/src/replication/adapter/dockerhub/adapter_test.go @@ -21,7 +21,7 @@ func getAdapter(t *testing.T) adp.Adapter { assert.Nil(err) assert.NotNil(factory) - adapter, err := factory(&model.Registry{ + adapter, err := newAdapter(&model.Registry{ Type: model.RegistryTypeDockerHub, URL: baseURL, Credential: &model.Credential{ diff --git a/src/replication/adapter/gitlab/adapter.go b/src/replication/adapter/gitlab/adapter.go index 0f4d994ab..50c674ade 100644 --- a/src/replication/adapter/gitlab/adapter.go +++ b/src/replication/adapter/gitlab/adapter.go @@ -12,15 +12,26 @@ import ( ) func init() { - if err := adp.RegisterFactory(model.RegistryTypeGitLab, func(registry *model.Registry) (adp.Adapter, error) { - return newAdapter(registry) - }, nil); err != nil { + if err := adp.RegisterFactory(model.RegistryTypeGitLab, new(factory)); err != nil { log.Errorf("failed to register factory for %s: %v", model.RegistryTypeGitLab, err) return } 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 { *native.Adapter registry *model.Registry @@ -31,7 +42,6 @@ type adapter struct { } func newAdapter(registry *model.Registry) (*adapter, error) { - var credential auth.Credential if registry.Credential != nil && len(registry.Credential.AccessSecret) != 0 { credential = auth.NewBasicAuthCredential( diff --git a/src/replication/adapter/googlegcr/adapter.go b/src/replication/adapter/googlegcr/adapter.go index 438a6b3af..a5174962d 100644 --- a/src/replication/adapter/googlegcr/adapter.go +++ b/src/replication/adapter/googlegcr/adapter.go @@ -22,9 +22,7 @@ import ( ) func init() { - if err := adp.RegisterFactory(model.RegistryTypeGoogleGcr, func(registry *model.Registry) (adp.Adapter, error) { - return newAdapter(registry) - }, getAdapterInfo()); err != nil { + if err := adp.RegisterFactory(model.RegistryTypeGoogleGcr, new(factory)); err != nil { log.Errorf("failed to register factory for %s: %v", model.RegistryTypeGoogleGcr, err) return } @@ -43,6 +41,19 @@ func newAdapter(registry *model.Registry) (*adapter, error) { }, 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 { *native.Adapter registry *model.Registry @@ -73,28 +84,30 @@ func (adapter) Info() (info *model.RegistryInfo, err error) { }, nil } -func getAdapterInfo() *model.AdapterInfo { - info := &model.AdapterInfo{ - SpecialEndpoints: []*model.Endpoint{ - { - Key: "gcr.io", - Value: "https://gcr.io", - }, - { - Key: "us.gcr.io", - Value: "https://us.gcr.io", - }, - { - Key: "eu.gcr.io", - Value: "https://eu.gcr.io", - }, - { - Key: "asia.gcr.io", - Value: "https://asia.gcr.io", +func getAdapterInfo() *model.AdapterPattern { + info := &model.AdapterPattern{ + EndpointPattern: &model.EndpointPattern{ + EndpointType: model.EndpointPatternTypeList, + Endpoints: []*model.Endpoint{ + { + Key: "gcr.io", + Value: "https://gcr.io", + }, + { + Key: "us.gcr.io", + Value: "https://us.gcr.io", + }, + { + Key: "eu.gcr.io", + Value: "https://eu.gcr.io", + }, + { + Key: "asia.gcr.io", + Value: "https://asia.gcr.io", + }, }, }, - SpecialCredential: &model.CredentialInfo{ - + CredentialPattern: &model.CredentialPattern{ AccessKeyType: model.AccessKeyTypeFix, AccessKeyData: "_json_key", AccessSecretType: model.AccessSecretTypeFile, diff --git a/src/replication/adapter/googlegcr/adapter_test.go b/src/replication/adapter/googlegcr/adapter_test.go index a2acefabd..08e0ef2c8 100644 --- a/src/replication/adapter/googlegcr/adapter_test.go +++ b/src/replication/adapter/googlegcr/adapter_test.go @@ -88,10 +88,10 @@ func getMockAdapter(t *testing.T, hasCred, health bool) (*adapter, *httptest.Ser factory, err := adp.GetFactory(model.RegistryTypeGoogleGcr) assert.Nil(t, err) assert.NotNil(t, factory) - a, err := factory(registry) + a, err := newAdapter(registry) assert.Nil(t, err) - return a.(*adapter), server + return a, server } func TestAdapter_Info(t *testing.T) { diff --git a/src/replication/adapter/harbor/adapter.go b/src/replication/adapter/harbor/adapter.go index 15cf1934a..41c823c5c 100644 --- a/src/replication/adapter/harbor/adapter.go +++ b/src/replication/adapter/harbor/adapter.go @@ -33,15 +33,26 @@ import ( ) func init() { - if err := adp.RegisterFactory(model.RegistryTypeHarbor, func(registry *model.Registry) (adp.Adapter, error) { - return newAdapter(registry) - }, nil); err != nil { + if err := adp.RegisterFactory(model.RegistryTypeHarbor, new(factory)); err != nil { log.Errorf("failed to register factory for %s: %v", model.RegistryTypeHarbor, err) return } 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 { *native.Adapter registry *model.Registry diff --git a/src/replication/adapter/helmhub/adapter.go b/src/replication/adapter/helmhub/adapter.go index 752582141..e0d027d81 100644 --- a/src/replication/adapter/helmhub/adapter.go +++ b/src/replication/adapter/helmhub/adapter.go @@ -22,15 +22,26 @@ import ( ) func init() { - if err := adp.RegisterFactory(model.RegistryTypeHelmHub, func(registry *model.Registry) (adp.Adapter, error) { - return newAdapter(registry) - }, nil); err != nil { + if err := adp.RegisterFactory(model.RegistryTypeHelmHub, new(factory)); err != nil { log.Errorf("failed to register factory for %s: %v", model.RegistryTypeHelmHub, err) return } 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 { registry *model.Registry client *Client diff --git a/src/replication/adapter/huawei/huawei_adapter.go b/src/replication/adapter/huawei/huawei_adapter.go index 136079947..7d647176b 100644 --- a/src/replication/adapter/huawei/huawei_adapter.go +++ b/src/replication/adapter/huawei/huawei_adapter.go @@ -19,7 +19,7 @@ import ( ) func init() { - err := adp.RegisterFactory(model.RegistryTypeHuawei, AdapterFactory, nil) + err := adp.RegisterFactory(model.RegistryTypeHuawei, new(factory)) if err != nil { log.Errorf("failed to register factory for Huawei: %v", err) return @@ -27,6 +27,19 @@ func init() { 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) type adapter struct { *native.Adapter @@ -210,8 +223,7 @@ func (a *adapter) HealthCheck() (model.HealthStatus, error) { return model.Healthy, nil } -// AdapterFactory is the factory for huawei adapter -func AdapterFactory(registry *model.Registry) (adp.Adapter, error) { +func newAdapter(registry *model.Registry) (adp.Adapter, error) { dockerRegistryAdapter, err := native.NewAdapter(registry) if err != nil { return nil, err diff --git a/src/replication/adapter/huawei/huawei_adapter_test.go b/src/replication/adapter/huawei/huawei_adapter_test.go index 9c25c8a30..7cfd835b2 100644 --- a/src/replication/adapter/huawei/huawei_adapter_test.go +++ b/src/replication/adapter/huawei/huawei_adapter_test.go @@ -24,7 +24,7 @@ func init() { Status: "", } - hwAdapter, err = AdapterFactory(hwRegistry) + hwAdapter, err = newAdapter(hwRegistry) if err != nil { os.Exit(1) } diff --git a/src/replication/adapter/huawei/image_registry_test.go b/src/replication/adapter/huawei/image_registry_test.go index 94e38908a..b61a50722 100644 --- a/src/replication/adapter/huawei/image_registry_test.go +++ b/src/replication/adapter/huawei/image_registry_test.go @@ -21,7 +21,7 @@ func init() { Insecure: false, Status: "", } - adp, err := AdapterFactory(hwRegistry) + adp, err := newAdapter(hwRegistry) if err != nil { os.Exit(1) } diff --git a/src/replication/adapter/jfrog/adapter.go b/src/replication/adapter/jfrog/adapter.go index 8da68ba14..ab17712f0 100644 --- a/src/replication/adapter/jfrog/adapter.go +++ b/src/replication/adapter/jfrog/adapter.go @@ -22,7 +22,7 @@ import ( ) func init() { - err := adp.RegisterFactory(model.RegistryTypeJfrogArtifactory, AdapterFactory, nil) + err := adp.RegisterFactory(model.RegistryTypeJfrogArtifactory, new(factory)) if err != nil { log.Errorf("failed to register factory for jfrog artifactory: %v", err) return @@ -30,6 +30,19 @@ func init() { 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 type adapter struct { *native.Adapter @@ -64,8 +77,7 @@ func (a *adapter) Info() (info *model.RegistryInfo, err error) { return } -// AdapterFactory is the factory for jfrog artifactory adapter -func AdapterFactory(registry *model.Registry) (adp.Adapter, error) { +func newAdapter(registry *model.Registry) (adp.Adapter, error) { dockerRegistryAdapter, err := native.NewAdapter(registry) if err != nil { return nil, err diff --git a/src/replication/adapter/jfrog/adapter_test.go b/src/replication/adapter/jfrog/adapter_test.go index 1f62a62f4..8d49a9317 100644 --- a/src/replication/adapter/jfrog/adapter_test.go +++ b/src/replication/adapter/jfrog/adapter_test.go @@ -91,7 +91,7 @@ func getMockAdapter(t *testing.T, hasCred, health bool) (*adapter, *httptest.Ser factory, err := adp.GetFactory(model.RegistryTypeJfrogArtifactory) assert.Nil(t, err) assert.NotNil(t, factory) - a, err := factory(registry) + a, err := newAdapter(registry) assert.Nil(t, err) return a.(*adapter), server diff --git a/src/replication/adapter/native/adapter.go b/src/replication/adapter/native/adapter.go index 47493f39d..64c8e9cb7 100644 --- a/src/replication/adapter/native/adapter.go +++ b/src/replication/adapter/native/adapter.go @@ -35,9 +35,7 @@ import ( ) func init() { - if err := adp.RegisterFactory(model.RegistryTypeDockerRegistry, func(registry *model.Registry) (adp.Adapter, error) { - return NewAdapter(registry) - }, nil); err != nil { + if err := adp.RegisterFactory(model.RegistryTypeDockerRegistry, new(factory)); err != nil { log.Errorf("failed to register factory for %s: %v", model.RegistryTypeDockerRegistry, err) return } @@ -46,6 +44,19 @@ func init() { 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 // that implement the registry V2 API type Adapter struct { diff --git a/src/replication/adapter/quayio/adapter.go b/src/replication/adapter/quayio/adapter.go index 6f3a23da5..cf775ca73 100644 --- a/src/replication/adapter/quayio/adapter.go +++ b/src/replication/adapter/quayio/adapter.go @@ -26,9 +26,7 @@ type adapter struct { } func init() { - err := adp.RegisterFactory(model.RegistryTypeQuayio, func(registry *model.Registry) (adp.Adapter, error) { - return newAdapter(registry) - }, nil) + err := adp.RegisterFactory(model.RegistryTypeQuayio, new(factory)) if err != nil { log.Errorf("failed to register factory for Quay.io: %v", err) return @@ -68,6 +66,19 @@ func newAdapter(registry *model.Registry) (*adapter, error) { }, 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 func (a *adapter) Info() (*model.RegistryInfo, error) { return &model.RegistryInfo{ diff --git a/src/replication/adapter/quayio/adapter_test.go b/src/replication/adapter/quayio/adapter_test.go index a77218c0b..5bbe70b15 100644 --- a/src/replication/adapter/quayio/adapter_test.go +++ b/src/replication/adapter/quayio/adapter_test.go @@ -10,7 +10,7 @@ import ( func getMockAdapter(t *testing.T) adp.Adapter { factory, _ := adp.GetFactory(model.RegistryTypeQuayio) - adapter, err := factory(&model.Registry{ + adapter, err := factory.Create(&model.Registry{ Type: model.RegistryTypeQuayio, URL: "https://quay.io", }) diff --git a/src/replication/model/registry.go b/src/replication/model/registry.go index e6393e388..1a0ef85e0 100644 --- a/src/replication/model/registry.go +++ b/src/replication/model/registry.go @@ -116,14 +116,32 @@ type FilterStyle struct { 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 ... type Endpoint struct { Key string `json:"key"` Value string `json:"value"` } -// CredentialInfo ... -type CredentialInfo struct { +// CredentialPattern ... +type CredentialPattern struct { AccessKeyType AccessKeyType `json:"access_key_type"` AccessKeyData string `json:"access_key_data"` AccessSecretType AccessSecretType `json:"access_secret_type"` @@ -152,17 +170,38 @@ const ( // RegistryInfo provides base info and capability declarations of the registry type RegistryInfo struct { - Type RegistryType `json:"type"` - Description string `json:"description"` - SupportedResourceTypes []ResourceType `json:"-"` - SupportedResourceFilters []*FilterStyle `json:"supported_resource_filters"` - SupportedTriggers []TriggerType `json:"supported_triggers"` - SpecialEndpoints []*Endpoint `json:"special_endpoints"` - SpecialCredential *CredentialInfo `json:"special_credential"` + Type RegistryType `json:"type"` + Description string `json:"description"` + SupportedResourceTypes []ResourceType `json:"-"` + SupportedResourceFilters []*FilterStyle `json:"supported_resource_filters"` + SupportedTriggers []TriggerType `json:"supported_triggers"` } -// AdapterInfo provides base info and capability declarations of the registry -type AdapterInfo struct { - SpecialEndpoints []*Endpoint `json:"special_endpoints"` - SpecialCredential *CredentialInfo `json:"special_credential"` +// AdapterPattern provides base info and capability declarations of the registry +type AdapterPattern struct { + EndpointPattern *EndpointPattern `json:"endpoint_pattern"` + 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, + } } diff --git a/src/replication/operation/controller_test.go b/src/replication/operation/controller_test.go index 538905565..7c39bbfef 100644 --- a/src/replication/operation/controller_test.go +++ b/src/replication/operation/controller_test.go @@ -113,10 +113,17 @@ func (f *fakedScheduler) Stop(id string) error { return nil } -func fakedAdapterFactory(*model.Registry) (adapter.Adapter, error) { +type fakedFactory struct { +} + +func (fakedFactory) Create(*model.Registry) (adapter.Adapter, error) { return &fakedAdapter{}, nil } +func (fakedFactory) AdapterPattern() *model.AdapterPattern { + return nil +} + type fakedAdapter struct{} func (f *fakedAdapter) Info() (*model.RegistryInfo, error) { @@ -212,7 +219,7 @@ func TestMain(m *testing.M) { } func TestStartReplication(t *testing.T) { - err := adapter.RegisterFactory(model.RegistryTypeHarbor, fakedAdapterFactory, nil) + err := adapter.RegisterFactory(model.RegistryTypeHarbor, new(fakedFactory)) require.Nil(t, err) config.Config = &config.Configuration{} diff --git a/src/replication/operation/flow/stage.go b/src/replication/operation/flow/stage.go index 0e49f4820..f9e064d83 100644 --- a/src/replication/operation/flow/stage.go +++ b/src/replication/operation/flow/stage.go @@ -38,7 +38,7 @@ func initialize(policy *model.Policy) (adp.Adapter, adp.Adapter, error) { if err != nil { 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 { 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 { 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 { return nil, nil, fmt.Errorf("failed to create adapter for destination registry %s: %v", policy.DestRegistry.URL, err) } diff --git a/src/replication/operation/flow/stage_test.go b/src/replication/operation/flow/stage_test.go index b1b967fc0..be03b220b 100644 --- a/src/replication/operation/flow/stage_test.go +++ b/src/replication/operation/flow/stage_test.go @@ -29,10 +29,17 @@ import ( "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 } +func (fakedFactory) AdapterPattern() *model.AdapterPattern { + return nil +} + type fakedAdapter struct{} func (f *fakedAdapter) Info() (*model.RegistryInfo, error) { @@ -194,7 +201,7 @@ func TestMain(m *testing.M) { config.Config = &config.Configuration{ 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(m.Run()) diff --git a/src/replication/registry/manager.go b/src/replication/registry/manager.go index d29f69244..34628f2e8 100644 --- a/src/replication/registry/manager.go +++ b/src/replication/registry/manager.go @@ -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) } - rAdapter, err := factory(r) + rAdapter, err := factory.Create(r) if err != nil { return model.Unknown, fmt.Errorf("generate '%s' type adapter form factory error: %v", r.Type, err) } diff --git a/src/replication/transfer/chart/transfer.go b/src/replication/transfer/chart/transfer.go index 3a7604374..08facf6c7 100644 --- a/src/replication/transfer/chart/transfer.go +++ b/src/replication/transfer/chart/transfer.go @@ -106,7 +106,7 @@ func createRegistry(reg *model.Registry) (adapter.ChartRegistry, error) { if err != nil { return nil, err } - ad, err := factory(reg) + ad, err := factory.Create(reg) if err != nil { return nil, err } diff --git a/src/replication/transfer/image/transfer.go b/src/replication/transfer/image/transfer.go index 898eebb8f..8a31b0ed0 100644 --- a/src/replication/transfer/image/transfer.go +++ b/src/replication/transfer/image/transfer.go @@ -113,7 +113,7 @@ func createRegistry(reg *model.Registry) (adapter.ImageRegistry, error) { if err != nil { return nil, err } - ad, err := factory(reg) + ad, err := factory.Create(reg) if err != nil { return nil, err }