mirror of
https://github.com/goharbor/harbor.git
synced 2025-02-02 21:11:37 +01:00
Support replication all projects in Harbor
Support replication all projects in Harbor Signed-off-by: Wenkai Yin <yinw@vmware.com>
This commit is contained in:
parent
2e83175ce3
commit
ba038eb883
@ -146,21 +146,6 @@ func TestReplicationPolicyAPICreate(t *testing.T) {
|
|||||||
},
|
},
|
||||||
code: http.StatusBadRequest,
|
code: http.StatusBadRequest,
|
||||||
},
|
},
|
||||||
// 400 empty source namespaces
|
|
||||||
{
|
|
||||||
request: &testingRequest{
|
|
||||||
method: http.MethodPost,
|
|
||||||
url: "/api/replication/policies",
|
|
||||||
credential: sysAdmin,
|
|
||||||
bodyJSON: &model.Policy{
|
|
||||||
Name: "policy01",
|
|
||||||
SrcRegistry: &model.Registry{
|
|
||||||
ID: 1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
code: http.StatusBadRequest,
|
|
||||||
},
|
|
||||||
// 409, duplicate policy name
|
// 409, duplicate policy name
|
||||||
{
|
{
|
||||||
request: &testingRequest{
|
request: &testingRequest{
|
||||||
|
@ -130,22 +130,25 @@ func (a *adapter) Info() (*model.RegistryInfo, error) {
|
|||||||
return info, nil
|
return info, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *adapter) ListNamespaces(npQuery *model.NamespaceQuery) ([]*model.Namespace, error) {
|
func (a *adapter) ListNamespaces(query *model.NamespaceQuery) ([]*model.Namespace, error) {
|
||||||
var nps []*model.Namespace
|
var namespaces []*model.Namespace
|
||||||
projects, err := a.getProjects(npQuery.Name)
|
name := ""
|
||||||
|
if query != nil {
|
||||||
|
name = query.Name
|
||||||
|
}
|
||||||
|
projects, err := a.getProjects(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, pro := range projects {
|
for _, project := range projects {
|
||||||
nps = append(nps, &model.Namespace{
|
namespaces = append(namespaces, &model.Namespace{
|
||||||
Name: pro.Name,
|
Name: project.Name,
|
||||||
Metadata: pro.Metadata,
|
Metadata: project.Metadata,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return nps, nil
|
return namespaces, nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *adapter) ConvertResourceMetadata(metadata *model.ResourceMetadata, namespace *model.Namespace) (*model.ResourceMetadata, error) {
|
func (a *adapter) ConvertResourceMetadata(metadata *model.ResourceMetadata, namespace *model.Namespace) (*model.ResourceMetadata, error) {
|
||||||
|
@ -59,6 +59,15 @@ func (t *tag) Match(filters []*model.Filter) (bool, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *adapter) FetchImages(namespaces []string, filters []*model.Filter) ([]*model.Resource, error) {
|
func (a *adapter) FetchImages(namespaces []string, filters []*model.Filter) ([]*model.Resource, error) {
|
||||||
|
if len(namespaces) == 0 {
|
||||||
|
nms, err := a.ListNamespaces(nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, nm := range nms {
|
||||||
|
namespaces = append(namespaces, nm.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
resources := []*model.Resource{}
|
resources := []*model.Resource{}
|
||||||
for _, namespace := range namespaces {
|
for _, namespace := range namespaces {
|
||||||
project, err := a.getProject(namespace)
|
project, err := a.getProject(namespace)
|
||||||
|
@ -33,7 +33,6 @@ func TestFetchImages(t *testing.T) {
|
|||||||
data := `[{
|
data := `[{
|
||||||
"name": "library",
|
"name": "library",
|
||||||
"metadata": {"public":true}
|
"metadata": {"public":true}
|
||||||
|
|
||||||
}]`
|
}]`
|
||||||
w.Write([]byte(data))
|
w.Write([]byte(data))
|
||||||
},
|
},
|
||||||
@ -43,10 +42,10 @@ func TestFetchImages(t *testing.T) {
|
|||||||
Pattern: "/api/repositories/library/hello-world/tags",
|
Pattern: "/api/repositories/library/hello-world/tags",
|
||||||
Handler: func(w http.ResponseWriter, r *http.Request) {
|
Handler: func(w http.ResponseWriter, r *http.Request) {
|
||||||
data := `[{
|
data := `[{
|
||||||
"name": "1.0"
|
"name": "1.0"
|
||||||
},{
|
},{
|
||||||
"name": "2.0"
|
"name": "2.0"
|
||||||
}]`
|
}]`
|
||||||
w.Write([]byte(data))
|
w.Write([]byte(data))
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -55,8 +54,8 @@ func TestFetchImages(t *testing.T) {
|
|||||||
Pattern: "/api/repositories",
|
Pattern: "/api/repositories",
|
||||||
Handler: func(w http.ResponseWriter, r *http.Request) {
|
Handler: func(w http.ResponseWriter, r *http.Request) {
|
||||||
data := `[{
|
data := `[{
|
||||||
"name": "library/hello-world"
|
"name": "library/hello-world"
|
||||||
}]`
|
}]`
|
||||||
w.Write([]byte(data))
|
w.Write([]byte(data))
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -67,6 +66,7 @@ func TestFetchImages(t *testing.T) {
|
|||||||
}
|
}
|
||||||
adapter, err := newAdapter(registry)
|
adapter, err := newAdapter(registry)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
// not nil namespaces
|
||||||
resources, err := adapter.FetchImages([]string{"library"}, nil)
|
resources, err := adapter.FetchImages([]string{"library"}, nil)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
assert.Equal(t, 1, len(resources))
|
assert.Equal(t, 1, len(resources))
|
||||||
@ -76,6 +76,16 @@ func TestFetchImages(t *testing.T) {
|
|||||||
assert.Equal(t, 2, len(resources[0].Metadata.Vtags))
|
assert.Equal(t, 2, len(resources[0].Metadata.Vtags))
|
||||||
assert.Equal(t, "1.0", resources[0].Metadata.Vtags[0])
|
assert.Equal(t, "1.0", resources[0].Metadata.Vtags[0])
|
||||||
assert.Equal(t, "2.0", resources[0].Metadata.Vtags[1])
|
assert.Equal(t, "2.0", resources[0].Metadata.Vtags[1])
|
||||||
|
// nil namespaces
|
||||||
|
resources, err = adapter.FetchImages(nil, nil)
|
||||||
|
require.Nil(t, err)
|
||||||
|
assert.Equal(t, 1, len(resources))
|
||||||
|
assert.Equal(t, model.ResourceTypeRepository, resources[0].Type)
|
||||||
|
assert.Equal(t, "hello-world", resources[0].Metadata.Repository.Name)
|
||||||
|
assert.Equal(t, "library", resources[0].Metadata.Namespace.Name)
|
||||||
|
assert.Equal(t, 2, len(resources[0].Metadata.Vtags))
|
||||||
|
assert.Equal(t, "1.0", resources[0].Metadata.Vtags[0])
|
||||||
|
assert.Equal(t, "2.0", resources[0].Metadata.Vtags[1])
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDeleteManifest(t *testing.T) {
|
func TestDeleteManifest(t *testing.T) {
|
||||||
|
@ -87,18 +87,6 @@ func (p *Policy) Valid(v *validation.Validation) {
|
|||||||
v.SetError("src_registry, dest_registry", "one of them should be empty and the other one shouldn't be empty")
|
v.SetError("src_registry, dest_registry", "one of them should be empty and the other one shouldn't be empty")
|
||||||
}
|
}
|
||||||
|
|
||||||
// source namespaces cannot be empty
|
|
||||||
if len(p.SrcNamespaces) == 0 {
|
|
||||||
v.SetError("src_namespaces", "cannot be empty")
|
|
||||||
} else {
|
|
||||||
for _, namespace := range p.SrcNamespaces {
|
|
||||||
if len(namespace) == 0 {
|
|
||||||
v.SetError("src_namespaces", "cannot contain empty namespace")
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// valid the filters
|
// valid the filters
|
||||||
for _, filter := range p.Filters {
|
for _, filter := range p.Filters {
|
||||||
if filter.Type != FilterTypeResource &&
|
if filter.Type != FilterTypeResource &&
|
||||||
|
@ -51,34 +51,6 @@ func TestValidOfPolicy(t *testing.T) {
|
|||||||
},
|
},
|
||||||
pass: false,
|
pass: false,
|
||||||
},
|
},
|
||||||
// empty source namespaces
|
|
||||||
{
|
|
||||||
policy: &Policy{
|
|
||||||
Name: "policy01",
|
|
||||||
SrcRegistry: &Registry{
|
|
||||||
ID: 0,
|
|
||||||
},
|
|
||||||
DestRegistry: &Registry{
|
|
||||||
ID: 1,
|
|
||||||
},
|
|
||||||
SrcNamespaces: []string{},
|
|
||||||
},
|
|
||||||
pass: false,
|
|
||||||
},
|
|
||||||
// empty source namespaces
|
|
||||||
{
|
|
||||||
policy: &Policy{
|
|
||||||
Name: "policy01",
|
|
||||||
SrcRegistry: &Registry{
|
|
||||||
ID: 0,
|
|
||||||
},
|
|
||||||
DestRegistry: &Registry{
|
|
||||||
ID: 1,
|
|
||||||
},
|
|
||||||
SrcNamespaces: []string{""},
|
|
||||||
},
|
|
||||||
pass: false,
|
|
||||||
},
|
|
||||||
// invalid filter
|
// invalid filter
|
||||||
{
|
{
|
||||||
policy: &Policy{
|
policy: &Policy{
|
||||||
|
Loading…
Reference in New Issue
Block a user