mirror of
https://github.com/goharbor/harbor.git
synced 2025-01-10 09:57:42 +01:00
Merge pull request #10756 from ywk253100/200218_repo_api
Implement delete/update repository API
This commit is contained in:
commit
beddef6873
@ -16,6 +16,100 @@ securityDefinitions:
|
|||||||
basicAuth:
|
basicAuth:
|
||||||
type: basic
|
type: basic
|
||||||
paths:
|
paths:
|
||||||
|
/projects/{project_name}/repositories:
|
||||||
|
get:
|
||||||
|
summary: List repositories
|
||||||
|
description: List repositories of the specified project
|
||||||
|
tags:
|
||||||
|
- repository
|
||||||
|
operationId: listRepositories
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/parameters/requestId'
|
||||||
|
- $ref: '#/parameters/projectName'
|
||||||
|
- $ref: '#/parameters/page'
|
||||||
|
- $ref: '#/parameters/pageSize'
|
||||||
|
- name: name
|
||||||
|
in: query
|
||||||
|
description: Query the repositories by name
|
||||||
|
type: string
|
||||||
|
required: false
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Success
|
||||||
|
headers:
|
||||||
|
X-Total-Count:
|
||||||
|
description: The total count of repositories
|
||||||
|
type: integer
|
||||||
|
Link:
|
||||||
|
description: Link refers to the previous page and next page
|
||||||
|
type: string
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/Repository'
|
||||||
|
'400':
|
||||||
|
$ref: '#/responses/400'
|
||||||
|
'401':
|
||||||
|
$ref: '#/responses/401'
|
||||||
|
'403':
|
||||||
|
$ref: '#/responses/403'
|
||||||
|
'404':
|
||||||
|
$ref: '#/responses/404'
|
||||||
|
'500':
|
||||||
|
$ref: '#/responses/500'
|
||||||
|
/projects/{project_name}/repositories/{repository_name}:
|
||||||
|
put:
|
||||||
|
summary: Update repository
|
||||||
|
description: Update the repository specified by name
|
||||||
|
tags:
|
||||||
|
- repository
|
||||||
|
operationId: updateRepository
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/parameters/requestId'
|
||||||
|
- $ref: '#/parameters/projectName'
|
||||||
|
- $ref: '#/parameters/repositoryName'
|
||||||
|
- name: repository
|
||||||
|
in: body
|
||||||
|
description: The JSON object of repository.
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/Repository'
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
$ref: '#/responses/200'
|
||||||
|
'400':
|
||||||
|
$ref: '#/responses/400'
|
||||||
|
'401':
|
||||||
|
$ref: '#/responses/401'
|
||||||
|
'403':
|
||||||
|
$ref: '#/responses/403'
|
||||||
|
'404':
|
||||||
|
$ref: '#/responses/404'
|
||||||
|
'500':
|
||||||
|
$ref: '#/responses/500'
|
||||||
|
delete:
|
||||||
|
summary: Delete repository
|
||||||
|
description: Delete the repository specified by name
|
||||||
|
tags:
|
||||||
|
- repository
|
||||||
|
operationId: deleteRepository
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/parameters/requestId'
|
||||||
|
- $ref: '#/parameters/projectName'
|
||||||
|
- $ref: '#/parameters/repositoryName'
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
$ref: '#/responses/200'
|
||||||
|
'400':
|
||||||
|
$ref: '#/responses/400'
|
||||||
|
'401':
|
||||||
|
$ref: '#/responses/401'
|
||||||
|
'403':
|
||||||
|
$ref: '#/responses/403'
|
||||||
|
'404':
|
||||||
|
$ref: '#/responses/404'
|
||||||
|
'500':
|
||||||
|
$ref: '#/responses/500'
|
||||||
/projects/{project_name}/repositories/{repository_name}/artifacts:
|
/projects/{project_name}/repositories/{repository_name}/artifacts:
|
||||||
get:
|
get:
|
||||||
summary: List artifacts
|
summary: List artifacts
|
||||||
@ -57,10 +151,9 @@ paths:
|
|||||||
type: boolean
|
type: boolean
|
||||||
required: false
|
required: false
|
||||||
default: false
|
default: false
|
||||||
# should be in tag level
|
|
||||||
- name: with_signature
|
- name: with_signature
|
||||||
in: query
|
in: query
|
||||||
description: Specify whether the signature is inclued inside the returning artifacts
|
description: Specify whether the signature is inclued inside the tags of the returning artifacts. Only works when setting "with_tag=true"
|
||||||
type: boolean
|
type: boolean
|
||||||
required: false
|
required: false
|
||||||
default: false
|
default: false
|
||||||
@ -70,7 +163,6 @@ paths:
|
|||||||
type: boolean
|
type: boolean
|
||||||
required: false
|
required: false
|
||||||
default: false
|
default: false
|
||||||
# TODO add other query string: type, ....
|
|
||||||
responses:
|
responses:
|
||||||
'200':
|
'200':
|
||||||
description: Success
|
description: Success
|
||||||
@ -234,28 +326,6 @@ paths:
|
|||||||
$ref: '#/responses/404'
|
$ref: '#/responses/404'
|
||||||
'500':
|
'500':
|
||||||
$ref: '#/responses/500'
|
$ref: '#/responses/500'
|
||||||
/projects/{project_name}/repositories/{repository_name}:
|
|
||||||
delete:
|
|
||||||
summary: Delete repository
|
|
||||||
description: Delete the repository specified by name
|
|
||||||
tags:
|
|
||||||
- repository
|
|
||||||
operationId: deleteRepository
|
|
||||||
parameters:
|
|
||||||
- $ref: '#/parameters/requestId'
|
|
||||||
- $ref: '#/parameters/projectName'
|
|
||||||
- $ref: '#/parameters/repositoryName'
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
$ref: '#/responses/200'
|
|
||||||
'401':
|
|
||||||
$ref: '#/responses/401'
|
|
||||||
'403':
|
|
||||||
$ref: '#/responses/403'
|
|
||||||
'404':
|
|
||||||
$ref: '#/responses/404'
|
|
||||||
'500':
|
|
||||||
$ref: '#/responses/500'
|
|
||||||
/projects/{project_name}/repositories/{repository_name}/artifacts/{reference}/additions/{addition}:
|
/projects/{project_name}/repositories/{repository_name}/artifacts/{reference}/additions/{addition}:
|
||||||
get:
|
get:
|
||||||
summary: Get the addition of the specific artifact
|
summary: Get the addition of the specific artifact
|
||||||
@ -476,6 +546,39 @@ definitions:
|
|||||||
message:
|
message:
|
||||||
type: string
|
type: string
|
||||||
description: The error message
|
description: The error message
|
||||||
|
Repository:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
description: The ID of the repository
|
||||||
|
project_id:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
description: The ID of the project that the repository belongs to
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
description: The name of the repository
|
||||||
|
description:
|
||||||
|
type: string
|
||||||
|
description: The description of the repository
|
||||||
|
artifact_count:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
description: The count of the artifacts inside the repository
|
||||||
|
pull_count:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
description: The count that the artifact inside the repository pulled
|
||||||
|
creation_time:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
description: The creation time of the repository
|
||||||
|
update_time:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
description: The update time of the repository
|
||||||
Artifact:
|
Artifact:
|
||||||
type: object
|
type: object
|
||||||
x-go-type:
|
x-go-type:
|
||||||
|
@ -58,8 +58,12 @@ type Controller interface {
|
|||||||
// and are attached to the artifact. If the tags don't exist, create them first.
|
// and are attached to the artifact. If the tags don't exist, create them first.
|
||||||
// The "created" will be set as true when the artifact is created
|
// The "created" will be set as true when the artifact is created
|
||||||
Ensure(ctx context.Context, repositoryID int64, digest string, tags ...string) (created bool, id int64, err error)
|
Ensure(ctx context.Context, repositoryID int64, digest string, tags ...string) (created bool, id int64, err error)
|
||||||
|
// Count returns the total count of artifacts according to the query.
|
||||||
|
// The artifacts that referenced by others and without tags are not counted
|
||||||
|
Count(ctx context.Context, query *q.Query) (total int64, err error)
|
||||||
// List artifacts according to the query, specify the properties returned with option
|
// List artifacts according to the query, specify the properties returned with option
|
||||||
List(ctx context.Context, query *q.Query, option *Option) (total int64, artifacts []*Artifact, err error)
|
// The artifacts that referenced by others and without tags are not returned
|
||||||
|
List(ctx context.Context, query *q.Query, option *Option) (artifacts []*Artifact, err error)
|
||||||
// Get the artifact specified by ID, specify the properties returned with option
|
// Get the artifact specified by ID, specify the properties returned with option
|
||||||
Get(ctx context.Context, id int64, option *Option) (artifact *Artifact, err error)
|
Get(ctx context.Context, id int64, option *Option) (artifact *Artifact, err error)
|
||||||
// Get the artifact specified by repository name and reference, the reference can be tag or digest,
|
// Get the artifact specified by repository name and reference, the reference can be tag or digest,
|
||||||
@ -68,7 +72,7 @@ type Controller interface {
|
|||||||
// Delete the artifact specified by ID. All tags attached to the artifact are deleted as well
|
// Delete the artifact specified by ID. All tags attached to the artifact are deleted as well
|
||||||
Delete(ctx context.Context, id int64) (err error)
|
Delete(ctx context.Context, id int64) (err error)
|
||||||
// ListTags lists the tags according to the query, specify the properties returned with option
|
// ListTags lists the tags according to the query, specify the properties returned with option
|
||||||
ListTags(ctx context.Context, query *q.Query, option *TagOption) (total int64, tags []*Tag, err error)
|
ListTags(ctx context.Context, query *q.Query, option *TagOption) (tags []*Tag, err error)
|
||||||
// CreateTag creates a tag
|
// CreateTag creates a tag
|
||||||
CreateTag(ctx context.Context, tag *Tag) (id int64, err error)
|
CreateTag(ctx context.Context, tag *Tag) (id int64, err error)
|
||||||
// DeleteTag deletes the tag specified by tagID
|
// DeleteTag deletes the tag specified by tagID
|
||||||
@ -185,7 +189,7 @@ func (c *controller) ensureTag(ctx context.Context, repositoryID, artifactID int
|
|||||||
"name": name,
|
"name": name,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
_, tags, err := c.tagMgr.List(ctx, query)
|
tags, err := c.tagMgr.List(ctx, query)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -216,17 +220,22 @@ func (c *controller) ensureTag(ctx context.Context, repositoryID, artifactID int
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *controller) List(ctx context.Context, query *q.Query, option *Option) (int64, []*Artifact, error) {
|
func (c *controller) Count(ctx context.Context, query *q.Query) (int64, error) {
|
||||||
total, arts, err := c.artMgr.List(ctx, query)
|
return c.artMgr.Count(ctx, query)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *controller) List(ctx context.Context, query *q.Query, option *Option) ([]*Artifact, error) {
|
||||||
|
arts, err := c.artMgr.List(ctx, query)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var artifacts []*Artifact
|
var artifacts []*Artifact
|
||||||
for _, art := range arts {
|
for _, art := range arts {
|
||||||
artifacts = append(artifacts, c.assembleArtifact(ctx, art, option))
|
artifacts = append(artifacts, c.assembleArtifact(ctx, art, option))
|
||||||
}
|
}
|
||||||
return total, artifacts, nil
|
return artifacts, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *controller) Get(ctx context.Context, id int64, option *Option) (*Artifact, error) {
|
func (c *controller) Get(ctx context.Context, id int64, option *Option) (*Artifact, error) {
|
||||||
art, err := c.artMgr.Get(ctx, id)
|
art, err := c.artMgr.Get(ctx, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -261,7 +270,7 @@ func (c *controller) getByTag(ctx context.Context, repository, tag string, optio
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
_, tags, err := c.tagMgr.List(ctx, &q.Query{
|
tags, err := c.tagMgr.List(ctx, &q.Query{
|
||||||
Keywords: map[string]interface{}{
|
Keywords: map[string]interface{}{
|
||||||
"RepositoryID": repo.RepositoryID,
|
"RepositoryID": repo.RepositoryID,
|
||||||
"Name": tag,
|
"Name": tag,
|
||||||
@ -369,16 +378,16 @@ func (c *controller) CreateTag(ctx context.Context, tag *Tag) (int64, error) {
|
|||||||
// TODO fire event
|
// TODO fire event
|
||||||
return c.tagMgr.Create(ctx, &(tag.Tag))
|
return c.tagMgr.Create(ctx, &(tag.Tag))
|
||||||
}
|
}
|
||||||
func (c *controller) ListTags(ctx context.Context, query *q.Query, option *TagOption) (int64, []*Tag, error) {
|
func (c *controller) ListTags(ctx context.Context, query *q.Query, option *TagOption) ([]*Tag, error) {
|
||||||
total, tgs, err := c.tagMgr.List(ctx, query)
|
tgs, err := c.tagMgr.List(ctx, query)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var tags []*Tag
|
var tags []*Tag
|
||||||
for _, tg := range tgs {
|
for _, tg := range tgs {
|
||||||
tags = append(tags, c.assembleTag(ctx, tg, option))
|
tags = append(tags, c.assembleTag(ctx, tg, option))
|
||||||
}
|
}
|
||||||
return total, tags, nil
|
return tags, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *controller) DeleteTag(ctx context.Context, tagID int64) error {
|
func (c *controller) DeleteTag(ctx context.Context, tagID int64) error {
|
||||||
@ -442,7 +451,7 @@ func (c *controller) assembleArtifact(ctx context.Context, art *artifact.Artifac
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *controller) populateTags(ctx context.Context, art *Artifact, option *TagOption) {
|
func (c *controller) populateTags(ctx context.Context, art *Artifact, option *TagOption) {
|
||||||
_, tags, err := c.tagMgr.List(ctx, &q.Query{
|
tags, err := c.tagMgr.List(ctx, &q.Query{
|
||||||
Keywords: map[string]interface{}{
|
Keywords: map[string]interface{}{
|
||||||
"artifact_id": art.ID,
|
"artifact_id": art.ID,
|
||||||
},
|
},
|
||||||
|
@ -143,7 +143,7 @@ func (c *controllerTestSuite) TestAssembleArtifact() {
|
|||||||
PushTime: time.Now(),
|
PushTime: time.Now(),
|
||||||
PullTime: time.Now(),
|
PullTime: time.Now(),
|
||||||
}
|
}
|
||||||
c.tagMgr.On("List").Return(1, []*tag.Tag{tg}, nil)
|
c.tagMgr.On("List").Return([]*tag.Tag{tg}, nil)
|
||||||
c.repoMgr.On("Get").Return(&models.RepoRecord{
|
c.repoMgr.On("Get").Return(&models.RepoRecord{
|
||||||
Name: "library/hello-world",
|
Name: "library/hello-world",
|
||||||
}, nil)
|
}, nil)
|
||||||
@ -198,7 +198,7 @@ func (c *controllerTestSuite) TestEnsureArtifact() {
|
|||||||
|
|
||||||
func (c *controllerTestSuite) TestEnsureTag() {
|
func (c *controllerTestSuite) TestEnsureTag() {
|
||||||
// the tag already exists under the repository and is attached to the artifact
|
// the tag already exists under the repository and is attached to the artifact
|
||||||
c.tagMgr.On("List").Return(1, []*tag.Tag{
|
c.tagMgr.On("List").Return([]*tag.Tag{
|
||||||
{
|
{
|
||||||
ID: 1,
|
ID: 1,
|
||||||
RepositoryID: 1,
|
RepositoryID: 1,
|
||||||
@ -214,7 +214,7 @@ func (c *controllerTestSuite) TestEnsureTag() {
|
|||||||
c.SetupTest()
|
c.SetupTest()
|
||||||
|
|
||||||
// the tag exists under the repository, but it is attached to other artifact
|
// the tag exists under the repository, but it is attached to other artifact
|
||||||
c.tagMgr.On("List").Return(1, []*tag.Tag{
|
c.tagMgr.On("List").Return([]*tag.Tag{
|
||||||
{
|
{
|
||||||
ID: 1,
|
ID: 1,
|
||||||
RepositoryID: 1,
|
RepositoryID: 1,
|
||||||
@ -231,7 +231,7 @@ func (c *controllerTestSuite) TestEnsureTag() {
|
|||||||
c.SetupTest()
|
c.SetupTest()
|
||||||
|
|
||||||
// the tag doesn't exist under the repository, create it
|
// the tag doesn't exist under the repository, create it
|
||||||
c.tagMgr.On("List").Return(1, []*tag.Tag{}, nil)
|
c.tagMgr.On("List").Return([]*tag.Tag{}, nil)
|
||||||
c.tagMgr.On("Create").Return(1, nil)
|
c.tagMgr.On("Create").Return(1, nil)
|
||||||
err = c.ctl.ensureTag(nil, 1, 1, "latest")
|
err = c.ctl.ensureTag(nil, 1, 1, "latest")
|
||||||
c.Require().Nil(err)
|
c.Require().Nil(err)
|
||||||
@ -247,7 +247,7 @@ func (c *controllerTestSuite) TestEnsure() {
|
|||||||
}, nil)
|
}, nil)
|
||||||
c.artMgr.On("GetByDigest").Return(nil, ierror.NotFoundError(nil))
|
c.artMgr.On("GetByDigest").Return(nil, ierror.NotFoundError(nil))
|
||||||
c.artMgr.On("Create").Return(1, nil)
|
c.artMgr.On("Create").Return(1, nil)
|
||||||
c.tagMgr.On("List").Return(1, []*tag.Tag{}, nil)
|
c.tagMgr.On("List").Return([]*tag.Tag{}, nil)
|
||||||
c.tagMgr.On("Create").Return(1, nil)
|
c.tagMgr.On("Create").Return(1, nil)
|
||||||
c.abstractor.On("AbstractMetadata").Return(nil)
|
c.abstractor.On("AbstractMetadata").Return(nil)
|
||||||
_, id, err := c.ctl.Ensure(nil, 1, digest, "latest")
|
_, id, err := c.ctl.Ensure(nil, 1, digest, "latest")
|
||||||
@ -259,18 +259,25 @@ func (c *controllerTestSuite) TestEnsure() {
|
|||||||
c.Equal(int64(1), id)
|
c.Equal(int64(1), id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *controllerTestSuite) TestCount() {
|
||||||
|
c.artMgr.On("Count").Return(1, nil)
|
||||||
|
total, err := c.ctl.Count(nil, nil)
|
||||||
|
c.Require().Nil(err)
|
||||||
|
c.Equal(int64(1), total)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *controllerTestSuite) TestList() {
|
func (c *controllerTestSuite) TestList() {
|
||||||
query := &q.Query{}
|
query := &q.Query{}
|
||||||
option := &Option{
|
option := &Option{
|
||||||
WithTag: true,
|
WithTag: true,
|
||||||
}
|
}
|
||||||
c.artMgr.On("List").Return(1, []*artifact.Artifact{
|
c.artMgr.On("List").Return([]*artifact.Artifact{
|
||||||
{
|
{
|
||||||
ID: 1,
|
ID: 1,
|
||||||
RepositoryID: 1,
|
RepositoryID: 1,
|
||||||
},
|
},
|
||||||
}, nil)
|
}, nil)
|
||||||
c.tagMgr.On("List").Return(1, []*tag.Tag{
|
c.tagMgr.On("List").Return([]*tag.Tag{
|
||||||
{
|
{
|
||||||
ID: 1,
|
ID: 1,
|
||||||
RepositoryID: 1,
|
RepositoryID: 1,
|
||||||
@ -281,9 +288,8 @@ func (c *controllerTestSuite) TestList() {
|
|||||||
c.repoMgr.On("Get").Return(&models.RepoRecord{
|
c.repoMgr.On("Get").Return(&models.RepoRecord{
|
||||||
Name: "library/hello-world",
|
Name: "library/hello-world",
|
||||||
}, nil)
|
}, nil)
|
||||||
total, artifacts, err := c.ctl.List(nil, query, option)
|
artifacts, err := c.ctl.List(nil, query, option)
|
||||||
c.Require().Nil(err)
|
c.Require().Nil(err)
|
||||||
c.Equal(int64(1), total)
|
|
||||||
c.Require().Len(artifacts, 1)
|
c.Require().Len(artifacts, 1)
|
||||||
c.Equal(int64(1), artifacts[0].ID)
|
c.Equal(int64(1), artifacts[0].ID)
|
||||||
c.Require().Len(artifacts[0].Tags, 1)
|
c.Require().Len(artifacts[0].Tags, 1)
|
||||||
@ -337,7 +343,7 @@ func (c *controllerTestSuite) TestGetByTag() {
|
|||||||
c.repoMgr.On("GetByName").Return(&models.RepoRecord{
|
c.repoMgr.On("GetByName").Return(&models.RepoRecord{
|
||||||
RepositoryID: 1,
|
RepositoryID: 1,
|
||||||
}, nil)
|
}, nil)
|
||||||
c.tagMgr.On("List").Return(0, nil, nil)
|
c.tagMgr.On("List").Return(nil, nil)
|
||||||
art, err := c.ctl.getByTag(nil, "library/hello-world", "latest", nil)
|
art, err := c.ctl.getByTag(nil, "library/hello-world", "latest", nil)
|
||||||
c.Require().NotNil(err)
|
c.Require().NotNil(err)
|
||||||
c.True(ierror.IsErr(err, ierror.NotFoundCode))
|
c.True(ierror.IsErr(err, ierror.NotFoundCode))
|
||||||
@ -349,7 +355,7 @@ func (c *controllerTestSuite) TestGetByTag() {
|
|||||||
c.repoMgr.On("GetByName").Return(&models.RepoRecord{
|
c.repoMgr.On("GetByName").Return(&models.RepoRecord{
|
||||||
RepositoryID: 1,
|
RepositoryID: 1,
|
||||||
}, nil)
|
}, nil)
|
||||||
c.tagMgr.On("List").Return(1, []*tag.Tag{
|
c.tagMgr.On("List").Return([]*tag.Tag{
|
||||||
{
|
{
|
||||||
ID: 1,
|
ID: 1,
|
||||||
RepositoryID: 1,
|
RepositoryID: 1,
|
||||||
@ -390,7 +396,7 @@ func (c *controllerTestSuite) TestGetByReference() {
|
|||||||
c.repoMgr.On("GetByName").Return(&models.RepoRecord{
|
c.repoMgr.On("GetByName").Return(&models.RepoRecord{
|
||||||
RepositoryID: 1,
|
RepositoryID: 1,
|
||||||
}, nil)
|
}, nil)
|
||||||
c.tagMgr.On("List").Return(1, []*tag.Tag{
|
c.tagMgr.On("List").Return([]*tag.Tag{
|
||||||
{
|
{
|
||||||
ID: 1,
|
ID: 1,
|
||||||
RepositoryID: 1,
|
RepositoryID: 1,
|
||||||
@ -429,7 +435,7 @@ func (c *controllerTestSuite) TestDeleteDeeply() {
|
|||||||
// child artifact and contains tags
|
// child artifact and contains tags
|
||||||
c.artMgr.On("Get").Return(&artifact.Artifact{ID: 1}, nil)
|
c.artMgr.On("Get").Return(&artifact.Artifact{ID: 1}, nil)
|
||||||
c.artMgr.On("Delete").Return(nil)
|
c.artMgr.On("Delete").Return(nil)
|
||||||
c.tagMgr.On("List").Return(0, []*tag.Tag{
|
c.tagMgr.On("List").Return([]*tag.Tag{
|
||||||
{
|
{
|
||||||
ID: 1,
|
ID: 1,
|
||||||
},
|
},
|
||||||
@ -444,7 +450,7 @@ func (c *controllerTestSuite) TestDeleteDeeply() {
|
|||||||
|
|
||||||
// root artifact is referenced by other artifacts
|
// root artifact is referenced by other artifacts
|
||||||
c.artMgr.On("Get").Return(&artifact.Artifact{ID: 1}, nil)
|
c.artMgr.On("Get").Return(&artifact.Artifact{ID: 1}, nil)
|
||||||
c.tagMgr.On("List").Return(0, nil, nil)
|
c.tagMgr.On("List").Return(nil, nil)
|
||||||
c.repoMgr.On("Get").Return(&models.RepoRecord{}, nil)
|
c.repoMgr.On("Get").Return(&models.RepoRecord{}, nil)
|
||||||
c.artMgr.On("ListReferences").Return([]*artifact.Reference{
|
c.artMgr.On("ListReferences").Return([]*artifact.Reference{
|
||||||
{
|
{
|
||||||
@ -459,7 +465,7 @@ func (c *controllerTestSuite) TestDeleteDeeply() {
|
|||||||
|
|
||||||
// child artifact contains no tag but referenced by other artifacts
|
// child artifact contains no tag but referenced by other artifacts
|
||||||
c.artMgr.On("Get").Return(&artifact.Artifact{ID: 1}, nil)
|
c.artMgr.On("Get").Return(&artifact.Artifact{ID: 1}, nil)
|
||||||
c.tagMgr.On("List").Return(0, nil, nil)
|
c.tagMgr.On("List").Return(nil, nil)
|
||||||
c.repoMgr.On("Get").Return(&models.RepoRecord{}, nil)
|
c.repoMgr.On("Get").Return(&models.RepoRecord{}, nil)
|
||||||
c.artMgr.On("ListReferences").Return([]*artifact.Reference{
|
c.artMgr.On("ListReferences").Return([]*artifact.Reference{
|
||||||
{
|
{
|
||||||
@ -474,7 +480,7 @@ func (c *controllerTestSuite) TestDeleteDeeply() {
|
|||||||
|
|
||||||
// root artifact is referenced by other artifacts
|
// root artifact is referenced by other artifacts
|
||||||
c.artMgr.On("Get").Return(&artifact.Artifact{ID: 1}, nil)
|
c.artMgr.On("Get").Return(&artifact.Artifact{ID: 1}, nil)
|
||||||
c.tagMgr.On("List").Return(0, nil, nil)
|
c.tagMgr.On("List").Return(nil, nil)
|
||||||
c.repoMgr.On("Get").Return(&models.RepoRecord{}, nil)
|
c.repoMgr.On("Get").Return(&models.RepoRecord{}, nil)
|
||||||
c.artMgr.On("ListReferences").Return(nil, nil)
|
c.artMgr.On("ListReferences").Return(nil, nil)
|
||||||
c.tagMgr.On("DeleteOfArtifact").Return(nil)
|
c.tagMgr.On("DeleteOfArtifact").Return(nil)
|
||||||
@ -486,7 +492,7 @@ func (c *controllerTestSuite) TestDeleteDeeply() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *controllerTestSuite) TestListTags() {
|
func (c *controllerTestSuite) TestListTags() {
|
||||||
c.tagMgr.On("List").Return(1, []*tag.Tag{
|
c.tagMgr.On("List").Return([]*tag.Tag{
|
||||||
{
|
{
|
||||||
ID: 1,
|
ID: 1,
|
||||||
RepositoryID: 1,
|
RepositoryID: 1,
|
||||||
@ -494,9 +500,8 @@ func (c *controllerTestSuite) TestListTags() {
|
|||||||
ArtifactID: 1,
|
ArtifactID: 1,
|
||||||
},
|
},
|
||||||
}, nil)
|
}, nil)
|
||||||
total, tags, err := c.ctl.ListTags(nil, nil, nil)
|
tags, err := c.ctl.ListTags(nil, nil, nil)
|
||||||
c.Require().Nil(err)
|
c.Require().Nil(err)
|
||||||
c.Equal(int64(1), total)
|
|
||||||
c.Len(tags, 1)
|
c.Len(tags, 1)
|
||||||
c.tagMgr.AssertExpectations(c.T())
|
c.tagMgr.AssertExpectations(c.T())
|
||||||
c.Equal(tags[0].Immutable, false)
|
c.Equal(tags[0].Immutable, false)
|
||||||
|
@ -36,14 +36,18 @@ type Controller interface {
|
|||||||
// The "name" should contain the namespace part. The "created" will be set as true
|
// The "name" should contain the namespace part. The "created" will be set as true
|
||||||
// when the repository is created
|
// when the repository is created
|
||||||
Ensure(ctx context.Context, name string) (created bool, id int64, err error)
|
Ensure(ctx context.Context, name string) (created bool, id int64, err error)
|
||||||
|
// Count returns the total count of repositories according to the query
|
||||||
|
Count(ctx context.Context, query *q.Query) (total int64, err error)
|
||||||
// List repositories according to the query
|
// List repositories according to the query
|
||||||
List(ctx context.Context, query *q.Query) (total int64, repositories []*models.RepoRecord, err error)
|
List(ctx context.Context, query *q.Query) (repositories []*models.RepoRecord, err error)
|
||||||
// Get the repository specified by ID
|
// Get the repository specified by ID
|
||||||
Get(ctx context.Context, id int64) (repository *models.RepoRecord, err error)
|
Get(ctx context.Context, id int64) (repository *models.RepoRecord, err error)
|
||||||
// GetByName gets the repository specified by name
|
// GetByName gets the repository specified by name
|
||||||
GetByName(ctx context.Context, name string) (repository *models.RepoRecord, err error)
|
GetByName(ctx context.Context, name string) (repository *models.RepoRecord, err error)
|
||||||
// Delete the repository specified by ID
|
// Delete the repository specified by ID
|
||||||
Delete(ctx context.Context, id int64) (err error)
|
Delete(ctx context.Context, id int64) (err error)
|
||||||
|
// Update the repository. Specify the properties or all properties will be updated
|
||||||
|
Update(ctx context.Context, repository *models.RepoRecord, properties ...string) (err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewController creates an instance of the default repository controller
|
// NewController creates an instance of the default repository controller
|
||||||
@ -67,7 +71,7 @@ func (c *controller) Ensure(ctx context.Context, name string) (bool, int64, erro
|
|||||||
"name": name,
|
"name": name,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
_, repositories, err := c.repoMgr.List(ctx, query)
|
repositories, err := c.repoMgr.List(ctx, query)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, 0, err
|
return false, 0, err
|
||||||
}
|
}
|
||||||
@ -89,7 +93,7 @@ func (c *controller) Ensure(ctx context.Context, name string) (bool, int64, erro
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
// if got conflict error, try to get again
|
// if got conflict error, try to get again
|
||||||
if ierror.IsConflictErr(err) {
|
if ierror.IsConflictErr(err) {
|
||||||
_, repositories, err = c.repoMgr.List(ctx, query)
|
repositories, err = c.repoMgr.List(ctx, query)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, 0, err
|
return false, 0, err
|
||||||
}
|
}
|
||||||
@ -102,7 +106,11 @@ func (c *controller) Ensure(ctx context.Context, name string) (bool, int64, erro
|
|||||||
return true, id, nil
|
return true, id, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *controller) List(ctx context.Context, query *q.Query) (int64, []*models.RepoRecord, error) {
|
func (c *controller) Count(ctx context.Context, query *q.Query) (int64, error) {
|
||||||
|
return c.repoMgr.Count(ctx, query)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *controller) List(ctx context.Context, query *q.Query) ([]*models.RepoRecord, error) {
|
||||||
return c.repoMgr.List(ctx, query)
|
return c.repoMgr.List(ctx, query)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,7 +126,7 @@ func (c *controller) Delete(ctx context.Context, id int64) error {
|
|||||||
// TODO auth
|
// TODO auth
|
||||||
// TODO how to make sure the logic included by middlewares(immutable, readonly, quota, etc)
|
// TODO how to make sure the logic included by middlewares(immutable, readonly, quota, etc)
|
||||||
// TODO is covered when deleting the artifacts of the repository
|
// TODO is covered when deleting the artifacts of the repository
|
||||||
_, artifacts, err := c.artCtl.List(ctx, &q.Query{
|
artifacts, err := c.artCtl.List(ctx, &q.Query{
|
||||||
Keywords: map[string]interface{}{
|
Keywords: map[string]interface{}{
|
||||||
"RepositoryID": id,
|
"RepositoryID": id,
|
||||||
},
|
},
|
||||||
@ -135,3 +143,7 @@ func (c *controller) Delete(ctx context.Context, id int64) error {
|
|||||||
|
|
||||||
// TODO fire event
|
// TODO fire event
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *controller) Update(ctx context.Context, repository *models.RepoRecord, properties ...string) error {
|
||||||
|
return c.repoMgr.Update(ctx, repository, properties...)
|
||||||
|
}
|
||||||
|
@ -45,7 +45,7 @@ func (c *controllerTestSuite) SetupTest() {
|
|||||||
|
|
||||||
func (c *controllerTestSuite) TestEnsure() {
|
func (c *controllerTestSuite) TestEnsure() {
|
||||||
// already exists
|
// already exists
|
||||||
c.repoMgr.On("List").Return(0, []*models.RepoRecord{
|
c.repoMgr.On("List").Return([]*models.RepoRecord{
|
||||||
{
|
{
|
||||||
RepositoryID: 1,
|
RepositoryID: 1,
|
||||||
ProjectID: 1,
|
ProjectID: 1,
|
||||||
@ -62,7 +62,7 @@ func (c *controllerTestSuite) TestEnsure() {
|
|||||||
c.SetupTest()
|
c.SetupTest()
|
||||||
|
|
||||||
// doesn't exist
|
// doesn't exist
|
||||||
c.repoMgr.On("List").Return(0, []*models.RepoRecord{}, nil)
|
c.repoMgr.On("List").Return([]*models.RepoRecord{}, nil)
|
||||||
c.proMgr.On("Get").Return(&models.Project{
|
c.proMgr.On("Get").Return(&models.Project{
|
||||||
ProjectID: 1,
|
ProjectID: 1,
|
||||||
}, nil)
|
}, nil)
|
||||||
@ -75,16 +75,21 @@ func (c *controllerTestSuite) TestEnsure() {
|
|||||||
c.Equal(int64(1), id)
|
c.Equal(int64(1), id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *controllerTestSuite) TestCount() {
|
||||||
|
c.repoMgr.On("Count").Return(1, nil)
|
||||||
|
total, err := c.ctl.Count(nil, nil)
|
||||||
|
c.Require().Nil(err)
|
||||||
|
c.Equal(int64(1), total)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *controllerTestSuite) TestList() {
|
func (c *controllerTestSuite) TestList() {
|
||||||
c.repoMgr.On("List").Return(1, []*models.RepoRecord{
|
c.repoMgr.On("List").Return([]*models.RepoRecord{
|
||||||
{
|
{
|
||||||
RepositoryID: 1,
|
RepositoryID: 1,
|
||||||
},
|
},
|
||||||
}, nil)
|
}, nil)
|
||||||
total, repositories, err := c.ctl.List(nil, nil)
|
repositories, err := c.ctl.List(nil, nil)
|
||||||
c.Require().Nil(err)
|
c.Require().Nil(err)
|
||||||
c.repoMgr.AssertExpectations(c.T())
|
|
||||||
c.Equal(int64(1), total)
|
|
||||||
c.Require().Len(repositories, 1)
|
c.Require().Len(repositories, 1)
|
||||||
c.Equal(int64(1), repositories[0].RepositoryID)
|
c.Equal(int64(1), repositories[0].RepositoryID)
|
||||||
}
|
}
|
||||||
@ -112,13 +117,22 @@ func (c *controllerTestSuite) TestGetByName() {
|
|||||||
func (c *controllerTestSuite) TestDelete() {
|
func (c *controllerTestSuite) TestDelete() {
|
||||||
art := &artifact.Artifact{}
|
art := &artifact.Artifact{}
|
||||||
art.ID = 1
|
art.ID = 1
|
||||||
c.artCtl.On("List").Return(1, []*artifact.Artifact{art}, nil)
|
c.artCtl.On("List").Return([]*artifact.Artifact{art}, nil)
|
||||||
c.artCtl.On("Delete").Return(nil)
|
c.artCtl.On("Delete").Return(nil)
|
||||||
c.repoMgr.On("Delete").Return(nil)
|
c.repoMgr.On("Delete").Return(nil)
|
||||||
err := c.ctl.Delete(nil, 1)
|
err := c.ctl.Delete(nil, 1)
|
||||||
c.Require().Nil(err)
|
c.Require().Nil(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *controllerTestSuite) TestUpdate() {
|
||||||
|
c.repoMgr.On("Update").Return(nil)
|
||||||
|
err := c.ctl.Update(nil, &models.RepoRecord{
|
||||||
|
RepositoryID: 1,
|
||||||
|
Description: "description",
|
||||||
|
}, "Description")
|
||||||
|
c.Require().Nil(err)
|
||||||
|
}
|
||||||
|
|
||||||
func TestControllerTestSuite(t *testing.T) {
|
func TestControllerTestSuite(t *testing.T) {
|
||||||
suite.Run(t, &controllerTestSuite{})
|
suite.Run(t, &controllerTestSuite{})
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ func fetchArtifacts(ctx context.Context, repositoryID int64, chunkSize int) <-ch
|
|||||||
}
|
}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
_, artifacts, err := artifact.Ctl.List(ctx, query, &artifact.Option{WithTag: true})
|
artifacts, err := artifact.Ctl.List(ctx, query, &artifact.Option{WithTag: true})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("[scan all]: list artifacts failed, error: %v", err)
|
log.Errorf("[scan all]: list artifacts failed, error: %v", err)
|
||||||
return
|
return
|
||||||
@ -100,7 +100,7 @@ func fetchRepositories(ctx context.Context, chunkSize int) <-chan *models.RepoRe
|
|||||||
}
|
}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
_, repositories, err := repository.Ctl.List(ctx, query)
|
repositories, err := repository.Ctl.List(ctx, query)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warningf("[scan all]: list repositories failed, error: %v", err)
|
log.Warningf("[scan all]: list repositories failed, error: %v", err)
|
||||||
break
|
break
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/go-openapi/strfmt"
|
||||||
|
"github.com/goharbor/harbor/src/server/v2.0/models"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/goharbor/harbor/src/pkg/signature/notary/model"
|
"github.com/goharbor/harbor/src/pkg/signature/notary/model"
|
||||||
@ -24,6 +26,8 @@ import (
|
|||||||
// RepoTable is the table name for repository
|
// RepoTable is the table name for repository
|
||||||
const RepoTable = "repository"
|
const RepoTable = "repository"
|
||||||
|
|
||||||
|
// TODO move the model into pkg/repository
|
||||||
|
|
||||||
// RepoRecord holds the record of an repository in DB, all the infors are from the registry notification event.
|
// RepoRecord holds the record of an repository in DB, all the infors are from the registry notification event.
|
||||||
type RepoRecord struct {
|
type RepoRecord struct {
|
||||||
RepositoryID int64 `orm:"pk;auto;column(repository_id)" json:"repository_id"`
|
RepositoryID int64 `orm:"pk;auto;column(repository_id)" json:"repository_id"`
|
||||||
@ -36,8 +40,21 @@ type RepoRecord struct {
|
|||||||
UpdateTime time.Time `orm:"column(update_time);auto_now" json:"update_time"`
|
UpdateTime time.Time `orm:"column(update_time);auto_now" json:"update_time"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ToSwagger converts the repository into the swagger model
|
||||||
|
func (r *RepoRecord) ToSwagger() *models.Repository {
|
||||||
|
return &models.Repository{
|
||||||
|
CreationTime: strfmt.DateTime(r.CreationTime),
|
||||||
|
Description: r.Description,
|
||||||
|
ID: r.RepositoryID,
|
||||||
|
Name: r.Name,
|
||||||
|
ProjectID: r.ProjectID,
|
||||||
|
PullCount: r.PullCount,
|
||||||
|
UpdateTime: strfmt.DateTime(r.UpdateTime),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TableName is required by by beego orm to map RepoRecord to table repository
|
// TableName is required by by beego orm to map RepoRecord to table repository
|
||||||
func (rp *RepoRecord) TableName() string {
|
func (r *RepoRecord) TableName() string {
|
||||||
return RepoTable
|
return RepoTable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,6 +77,7 @@ require (
|
|||||||
github.com/stretchr/testify v1.4.0
|
github.com/stretchr/testify v1.4.0
|
||||||
github.com/theupdateframework/notary v0.6.1
|
github.com/theupdateframework/notary v0.6.1
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550
|
||||||
|
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421
|
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421
|
||||||
gopkg.in/asn1-ber.v1 v1.0.0-20150924051756-4e86f4367175 // indirect
|
gopkg.in/asn1-ber.v1 v1.0.0-20150924051756-4e86f4367175 // indirect
|
||||||
gopkg.in/dancannon/gorethink.v3 v3.0.5 // indirect
|
gopkg.in/dancannon/gorethink.v3 v3.0.5 // indirect
|
||||||
|
@ -29,9 +29,12 @@ var (
|
|||||||
|
|
||||||
// Manager is the only interface of artifact module to provide the management functions for artifacts
|
// Manager is the only interface of artifact module to provide the management functions for artifacts
|
||||||
type Manager interface {
|
type Manager interface {
|
||||||
|
// Count returns the total count of artifacts according to the query.
|
||||||
|
// The artifacts that referenced by others and without tags are not counted
|
||||||
|
Count(ctx context.Context, query *q.Query) (total int64, err error)
|
||||||
// List artifacts according to the query. The artifacts that referenced by others and
|
// List artifacts according to the query. The artifacts that referenced by others and
|
||||||
// without tags are not returned
|
// without tags are not returned
|
||||||
List(ctx context.Context, query *q.Query) (total int64, artifacts []*Artifact, err error)
|
List(ctx context.Context, query *q.Query) (artifacts []*Artifact, err error)
|
||||||
// Get the artifact specified by the ID
|
// Get the artifact specified by the ID
|
||||||
Get(ctx context.Context, id int64) (artifact *Artifact, err error)
|
Get(ctx context.Context, id int64) (artifact *Artifact, err error)
|
||||||
// GetByDigest returns the artifact specified by repository ID and digest
|
// GetByDigest returns the artifact specified by repository ID and digest
|
||||||
@ -63,24 +66,24 @@ type manager struct {
|
|||||||
dao dao.DAO
|
dao dao.DAO
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *manager) List(ctx context.Context, query *q.Query) (int64, []*Artifact, error) {
|
func (m *manager) Count(ctx context.Context, query *q.Query) (int64, error) {
|
||||||
total, err := m.dao.Count(ctx, query)
|
return m.dao.Count(ctx, query)
|
||||||
if err != nil {
|
|
||||||
return 0, nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *manager) List(ctx context.Context, query *q.Query) ([]*Artifact, error) {
|
||||||
arts, err := m.dao.List(ctx, query)
|
arts, err := m.dao.List(ctx, query)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var artifacts []*Artifact
|
var artifacts []*Artifact
|
||||||
for _, art := range arts {
|
for _, art := range arts {
|
||||||
artifact, err := m.assemble(ctx, art)
|
artifact, err := m.assemble(ctx, art)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
artifacts = append(artifacts, artifact)
|
artifacts = append(artifacts, artifact)
|
||||||
}
|
}
|
||||||
return total, artifacts, nil
|
return artifacts, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *manager) Get(ctx context.Context, id int64) (*Artifact, error) {
|
func (m *manager) Get(ctx context.Context, id int64) (*Artifact, error) {
|
||||||
|
@ -86,6 +86,13 @@ func (m *managerTestSuite) SetupTest() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *managerTestSuite) TestCount() {
|
||||||
|
m.dao.On("Count", mock.Anything).Return(1, nil)
|
||||||
|
total, err := m.mgr.Count(nil, nil)
|
||||||
|
m.Require().Nil(err)
|
||||||
|
m.Equal(int64(1), total)
|
||||||
|
}
|
||||||
|
|
||||||
func (m *managerTestSuite) TestAssemble() {
|
func (m *managerTestSuite) TestAssemble() {
|
||||||
art := &dao.Artifact{
|
art := &dao.Artifact{
|
||||||
ID: 1,
|
ID: 1,
|
||||||
@ -139,13 +146,10 @@ func (m *managerTestSuite) TestList() {
|
|||||||
ExtraAttrs: `{"attr1":"value1"}`,
|
ExtraAttrs: `{"attr1":"value1"}`,
|
||||||
Annotations: `{"anno1":"value1"}`,
|
Annotations: `{"anno1":"value1"}`,
|
||||||
}
|
}
|
||||||
m.dao.On("Count", mock.Anything).Return(1, nil)
|
|
||||||
m.dao.On("List", mock.Anything).Return([]*dao.Artifact{art}, nil)
|
m.dao.On("List", mock.Anything).Return([]*dao.Artifact{art}, nil)
|
||||||
m.dao.On("ListReferences").Return([]*dao.ArtifactReference{}, nil)
|
m.dao.On("ListReferences").Return([]*dao.ArtifactReference{}, nil)
|
||||||
total, artifacts, err := m.mgr.List(nil, nil)
|
artifacts, err := m.mgr.List(nil, nil)
|
||||||
m.Require().Nil(err)
|
m.Require().Nil(err)
|
||||||
m.dao.AssertExpectations(m.T())
|
|
||||||
m.Equal(int64(1), total)
|
|
||||||
m.Equal(1, len(artifacts))
|
m.Equal(1, len(artifacts))
|
||||||
m.Equal(art.ID, artifacts[0].ID)
|
m.Equal(art.ID, artifacts[0].ID)
|
||||||
}
|
}
|
||||||
|
@ -27,8 +27,10 @@ var Mgr = New()
|
|||||||
|
|
||||||
// Manager is used for repository management
|
// Manager is used for repository management
|
||||||
type Manager interface {
|
type Manager interface {
|
||||||
|
// Count returns the total count of repositories according to the query
|
||||||
|
Count(ctx context.Context, query *q.Query) (total int64, err error)
|
||||||
// List repositories according to the query
|
// List repositories according to the query
|
||||||
List(ctx context.Context, query *q.Query) (total int64, repositories []*models.RepoRecord, err error)
|
List(ctx context.Context, query *q.Query) (repositories []*models.RepoRecord, err error)
|
||||||
// Get the repository specified by ID
|
// Get the repository specified by ID
|
||||||
Get(ctx context.Context, id int64) (repository *models.RepoRecord, err error)
|
Get(ctx context.Context, id int64) (repository *models.RepoRecord, err error)
|
||||||
// GetByName gets the repository specified by name
|
// GetByName gets the repository specified by name
|
||||||
@ -52,16 +54,16 @@ type manager struct {
|
|||||||
dao dao.DAO
|
dao dao.DAO
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *manager) List(ctx context.Context, query *q.Query) (int64, []*models.RepoRecord, error) {
|
func (m *manager) Count(ctx context.Context, query *q.Query) (int64, error) {
|
||||||
total, err := m.dao.Count(ctx, query)
|
return m.dao.Count(ctx, query)
|
||||||
if err != nil {
|
|
||||||
return 0, nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *manager) List(ctx context.Context, query *q.Query) ([]*models.RepoRecord, error) {
|
||||||
repositories, err := m.dao.List(ctx, query)
|
repositories, err := m.dao.List(ctx, query)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return total, repositories, nil
|
return repositories, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *manager) Get(ctx context.Context, id int64) (*models.RepoRecord, error) {
|
func (m *manager) Get(ctx context.Context, id int64) (*models.RepoRecord, error) {
|
||||||
@ -69,7 +71,7 @@ func (m *manager) Get(ctx context.Context, id int64) (*models.RepoRecord, error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *manager) GetByName(ctx context.Context, name string) (repository *models.RepoRecord, err error) {
|
func (m *manager) GetByName(ctx context.Context, name string) (repository *models.RepoRecord, err error) {
|
||||||
_, repositories, err := m.List(ctx, &q.Query{
|
repositories, err := m.List(ctx, &q.Query{
|
||||||
Keywords: map[string]interface{}{
|
Keywords: map[string]interface{}{
|
||||||
"Name": name,
|
"Name": name,
|
||||||
},
|
},
|
||||||
@ -92,5 +94,5 @@ func (m *manager) Delete(ctx context.Context, id int64) error {
|
|||||||
return m.dao.Delete(ctx, id)
|
return m.dao.Delete(ctx, id)
|
||||||
}
|
}
|
||||||
func (m *manager) Update(ctx context.Context, repository *models.RepoRecord, props ...string) error {
|
func (m *manager) Update(ctx context.Context, repository *models.RepoRecord, props ...string) error {
|
||||||
return m.dao.Update(ctx, repository)
|
return m.dao.Update(ctx, repository, props...)
|
||||||
}
|
}
|
||||||
|
@ -65,18 +65,22 @@ func (m *managerTestSuite) SetupTest() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *managerTestSuite) TestCount() {
|
||||||
|
m.dao.On("Count", mock.Anything).Return(1, nil)
|
||||||
|
total, err := m.mgr.Count(nil, nil)
|
||||||
|
m.Require().Nil(err)
|
||||||
|
m.Equal(int64(1), total)
|
||||||
|
}
|
||||||
|
|
||||||
func (m *managerTestSuite) TestList() {
|
func (m *managerTestSuite) TestList() {
|
||||||
repository := &models.RepoRecord{
|
repository := &models.RepoRecord{
|
||||||
RepositoryID: 1,
|
RepositoryID: 1,
|
||||||
ProjectID: 1,
|
ProjectID: 1,
|
||||||
Name: "library/hello-world",
|
Name: "library/hello-world",
|
||||||
}
|
}
|
||||||
m.dao.On("Count", mock.Anything).Return(1, nil)
|
|
||||||
m.dao.On("List", mock.Anything).Return([]*models.RepoRecord{repository}, nil)
|
m.dao.On("List", mock.Anything).Return([]*models.RepoRecord{repository}, nil)
|
||||||
total, repositories, err := m.mgr.List(nil, nil)
|
repositories, err := m.mgr.List(nil, nil)
|
||||||
m.Require().Nil(err)
|
m.Require().Nil(err)
|
||||||
m.dao.AssertExpectations(m.T())
|
|
||||||
m.Equal(int64(1), total)
|
|
||||||
m.Equal(1, len(repositories))
|
m.Equal(1, len(repositories))
|
||||||
m.Equal(repository.RepositoryID, repositories[0].RepositoryID)
|
m.Equal(repository.RepositoryID, repositories[0].RepositoryID)
|
||||||
}
|
}
|
||||||
@ -101,7 +105,6 @@ func (m *managerTestSuite) TestGetByName() {
|
|||||||
ProjectID: 1,
|
ProjectID: 1,
|
||||||
Name: "library/hello-world",
|
Name: "library/hello-world",
|
||||||
}
|
}
|
||||||
m.dao.On("Count", mock.Anything).Return(1, nil)
|
|
||||||
m.dao.On("List", mock.Anything).Return([]*models.RepoRecord{repository}, nil)
|
m.dao.On("List", mock.Anything).Return([]*models.RepoRecord{repository}, nil)
|
||||||
repo, err := m.mgr.GetByName(nil, "library/hello-world")
|
repo, err := m.mgr.GetByName(nil, "library/hello-world")
|
||||||
m.Require().Nil(err)
|
m.Require().Nil(err)
|
||||||
|
@ -350,7 +350,7 @@ func getRepositories(projectMgr project.Manager, repositoryMgr repository.Manage
|
|||||||
*/
|
*/
|
||||||
// get image repositories
|
// get image repositories
|
||||||
// TODO set the context which contains the ORM
|
// TODO set the context which contains the ORM
|
||||||
_, imageRepositories, err := repositoryMgr.List(orm.NewContext(nil, beegoorm.NewOrm()), &pq.Query{
|
imageRepositories, err := repositoryMgr.List(orm.NewContext(nil, beegoorm.NewOrm()), &pq.Query{
|
||||||
Keywords: map[string]interface{}{
|
Keywords: map[string]interface{}{
|
||||||
"ProjectID": projectID,
|
"ProjectID": projectID,
|
||||||
},
|
},
|
||||||
|
@ -165,7 +165,7 @@ func (l *launchTestSuite) TestGetProjects() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (l *launchTestSuite) TestGetRepositories() {
|
func (l *launchTestSuite) TestGetRepositories() {
|
||||||
l.repositoryMgr.On("List").Return(1, []*models.RepoRecord{
|
l.repositoryMgr.On("List").Return([]*models.RepoRecord{
|
||||||
{
|
{
|
||||||
RepositoryID: 1,
|
RepositoryID: 1,
|
||||||
ProjectID: 1,
|
ProjectID: 1,
|
||||||
@ -211,7 +211,7 @@ func (l *launchTestSuite) TestLaunch() {
|
|||||||
require.NotNil(l.T(), err)
|
require.NotNil(l.T(), err)
|
||||||
|
|
||||||
// system scope
|
// system scope
|
||||||
l.repositoryMgr.On("List").Return(2, []*models.RepoRecord{
|
l.repositoryMgr.On("List").Return([]*models.RepoRecord{
|
||||||
{
|
{
|
||||||
RepositoryID: 1,
|
RepositoryID: 1,
|
||||||
ProjectID: 1,
|
ProjectID: 1,
|
||||||
|
@ -28,8 +28,10 @@ var (
|
|||||||
|
|
||||||
// Manager manages the tags
|
// Manager manages the tags
|
||||||
type Manager interface {
|
type Manager interface {
|
||||||
|
// Count returns the total count of tags according to the query.
|
||||||
|
Count(ctx context.Context, query *q.Query) (total int64, err error)
|
||||||
// List tags according to the query
|
// List tags according to the query
|
||||||
List(ctx context.Context, query *q.Query) (total int64, tags []*tag.Tag, err error)
|
List(ctx context.Context, query *q.Query) (tags []*tag.Tag, err error)
|
||||||
// Get the tag specified by ID
|
// Get the tag specified by ID
|
||||||
Get(ctx context.Context, id int64) (tag *tag.Tag, err error)
|
Get(ctx context.Context, id int64) (tag *tag.Tag, err error)
|
||||||
// Create the tag and returns the ID
|
// Create the tag and returns the ID
|
||||||
@ -53,16 +55,12 @@ type manager struct {
|
|||||||
dao dao.DAO
|
dao dao.DAO
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *manager) List(ctx context.Context, query *q.Query) (int64, []*tag.Tag, error) {
|
func (m *manager) Count(ctx context.Context, query *q.Query) (int64, error) {
|
||||||
total, err := m.dao.Count(ctx, query)
|
return m.dao.Count(ctx, query)
|
||||||
if err != nil {
|
|
||||||
return 0, nil, err
|
|
||||||
}
|
}
|
||||||
tags, err := m.dao.List(ctx, query)
|
|
||||||
if err != nil {
|
func (m *manager) List(ctx context.Context, query *q.Query) ([]*tag.Tag, error) {
|
||||||
return 0, nil, err
|
return m.dao.List(ctx, query)
|
||||||
}
|
|
||||||
return total, tags, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *manager) Get(ctx context.Context, id int64) (*tag.Tag, error) {
|
func (m *manager) Get(ctx context.Context, id int64) (*tag.Tag, error) {
|
||||||
|
@ -70,6 +70,13 @@ func (m *managerTestSuite) SetupTest() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *managerTestSuite) TestCount() {
|
||||||
|
m.dao.On("Count", mock.Anything).Return(1, nil)
|
||||||
|
total, err := m.mgr.Count(nil, nil)
|
||||||
|
m.Require().Nil(err)
|
||||||
|
m.Equal(int64(1), total)
|
||||||
|
}
|
||||||
|
|
||||||
func (m *managerTestSuite) TestList() {
|
func (m *managerTestSuite) TestList() {
|
||||||
tg := &tag.Tag{
|
tg := &tag.Tag{
|
||||||
ID: 1,
|
ID: 1,
|
||||||
@ -79,12 +86,9 @@ func (m *managerTestSuite) TestList() {
|
|||||||
PushTime: time.Now(),
|
PushTime: time.Now(),
|
||||||
PullTime: time.Now(),
|
PullTime: time.Now(),
|
||||||
}
|
}
|
||||||
m.dao.On("Count", mock.Anything).Return(1, nil)
|
|
||||||
m.dao.On("List", mock.Anything).Return([]*tag.Tag{tg}, nil)
|
m.dao.On("List", mock.Anything).Return([]*tag.Tag{tg}, nil)
|
||||||
total, tags, err := m.mgr.List(nil, nil)
|
tags, err := m.mgr.List(nil, nil)
|
||||||
m.Require().Nil(err)
|
m.Require().Nil(err)
|
||||||
m.dao.AssertExpectations(m.T())
|
|
||||||
m.Equal(int64(1), total)
|
|
||||||
m.Equal(1, len(tags))
|
m.Equal(1, len(tags))
|
||||||
m.Equal(tg.ID, tags[0].ID)
|
m.Equal(tg.ID, tags[0].ID)
|
||||||
}
|
}
|
||||||
|
@ -55,12 +55,12 @@ func (r *repositoryHandler) ServeHTTP(w http.ResponseWriter, req *http.Request)
|
|||||||
var repoNames []string
|
var repoNames []string
|
||||||
// get all repositories
|
// get all repositories
|
||||||
// ToDo filter out the untagged repos
|
// ToDo filter out the untagged repos
|
||||||
total, repoRecords, err := r.repoCtl.List(req.Context(), nil)
|
repoRecords, err := r.repoCtl.List(req.Context(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
serror.SendError(w, err)
|
serror.SendError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if total <= 0 {
|
if len(repoRecords) <= 0 {
|
||||||
r.sendResponse(w, req, repoNames)
|
r.sendResponse(w, req, repoNames)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,7 @@ func (c *catalogTestSuite) TestCatalog() {
|
|||||||
c.SetupTest()
|
c.SetupTest()
|
||||||
req := httptest.NewRequest(http.MethodGet, "/v2/_catalog", nil)
|
req := httptest.NewRequest(http.MethodGet, "/v2/_catalog", nil)
|
||||||
var w *httptest.ResponseRecorder
|
var w *httptest.ResponseRecorder
|
||||||
c.repoCtl.On("List").Return(2, []*models.RepoRecord{
|
c.repoCtl.On("List").Return([]*models.RepoRecord{
|
||||||
{
|
{
|
||||||
RepositoryID: 1,
|
RepositoryID: 1,
|
||||||
Name: "hello-world",
|
Name: "hello-world",
|
||||||
@ -77,7 +77,7 @@ func (c *catalogTestSuite) TestCatalogPaginationN1() {
|
|||||||
c.SetupTest()
|
c.SetupTest()
|
||||||
req := httptest.NewRequest(http.MethodGet, "/v2/_catalog?n=1", nil)
|
req := httptest.NewRequest(http.MethodGet, "/v2/_catalog?n=1", nil)
|
||||||
var w *httptest.ResponseRecorder
|
var w *httptest.ResponseRecorder
|
||||||
c.repoCtl.On("List").Return(2, []*models.RepoRecord{
|
c.repoCtl.On("List").Return([]*models.RepoRecord{
|
||||||
{
|
{
|
||||||
RepositoryID: 1,
|
RepositoryID: 1,
|
||||||
Name: "hello-world",
|
Name: "hello-world",
|
||||||
@ -104,7 +104,7 @@ func (c *catalogTestSuite) TestCatalogPaginationN2() {
|
|||||||
c.SetupTest()
|
c.SetupTest()
|
||||||
req := httptest.NewRequest(http.MethodGet, "/v2/_catalog?n=3", nil)
|
req := httptest.NewRequest(http.MethodGet, "/v2/_catalog?n=3", nil)
|
||||||
var w *httptest.ResponseRecorder
|
var w *httptest.ResponseRecorder
|
||||||
c.repoCtl.On("List").Return(2, []*models.RepoRecord{
|
c.repoCtl.On("List").Return([]*models.RepoRecord{
|
||||||
{
|
{
|
||||||
RepositoryID: 1,
|
RepositoryID: 1,
|
||||||
Name: "hello-world",
|
Name: "hello-world",
|
||||||
@ -131,7 +131,7 @@ func (c *catalogTestSuite) TestCatalogPaginationN3() {
|
|||||||
c.SetupTest()
|
c.SetupTest()
|
||||||
req := httptest.NewRequest(http.MethodGet, "/v2/_catalog?last=busybox&n=1", nil)
|
req := httptest.NewRequest(http.MethodGet, "/v2/_catalog?last=busybox&n=1", nil)
|
||||||
var w *httptest.ResponseRecorder
|
var w *httptest.ResponseRecorder
|
||||||
c.repoCtl.On("List").Return(2, []*models.RepoRecord{
|
c.repoCtl.On("List").Return([]*models.RepoRecord{
|
||||||
{
|
{
|
||||||
RepositoryID: 1,
|
RepositoryID: 1,
|
||||||
Name: "hello-world",
|
Name: "hello-world",
|
||||||
|
@ -80,7 +80,7 @@ func (t *tagHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get tags ...
|
// get tags ...
|
||||||
total, tags, err := t.artCtl.ListTags(req.Context(), &q.Query{
|
tags, err := t.artCtl.ListTags(req.Context(), &q.Query{
|
||||||
Keywords: map[string]interface{}{
|
Keywords: map[string]interface{}{
|
||||||
"RepositoryID": repository.RepositoryID,
|
"RepositoryID": repository.RepositoryID,
|
||||||
}}, nil)
|
}}, nil)
|
||||||
@ -88,7 +88,7 @@ func (t *tagHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||||||
serror.SendError(w, err)
|
serror.SendError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if total == 0 {
|
if len(tags) == 0 {
|
||||||
t.sendResponse(w, req, tagNames)
|
t.sendResponse(w, req, tagNames)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,7 @@ func (c *tagTestSuite) TestListTag() {
|
|||||||
RepositoryID: 1,
|
RepositoryID: 1,
|
||||||
Name: "library/hello-world",
|
Name: "library/hello-world",
|
||||||
}, nil)
|
}, nil)
|
||||||
c.artCtl.On("ListTags").Return(2, []*artifact.Tag{
|
c.artCtl.On("ListTags").Return([]*artifact.Tag{
|
||||||
{
|
{
|
||||||
Tag: tag.Tag{
|
Tag: tag.Tag{
|
||||||
RepositoryID: 1,
|
RepositoryID: 1,
|
||||||
@ -99,7 +99,7 @@ func (c *tagTestSuite) TestListTagPagination1() {
|
|||||||
RepositoryID: 1,
|
RepositoryID: 1,
|
||||||
Name: "hello-world",
|
Name: "hello-world",
|
||||||
}, nil)
|
}, nil)
|
||||||
c.artCtl.On("ListTags").Return(2, []*artifact.Tag{
|
c.artCtl.On("ListTags").Return([]*artifact.Tag{
|
||||||
{
|
{
|
||||||
Tag: tag.Tag{
|
Tag: tag.Tag{
|
||||||
RepositoryID: 1,
|
RepositoryID: 1,
|
||||||
@ -135,7 +135,7 @@ func (c *tagTestSuite) TestListTagPagination2() {
|
|||||||
RepositoryID: 1,
|
RepositoryID: 1,
|
||||||
Name: "hello-world",
|
Name: "hello-world",
|
||||||
}, nil)
|
}, nil)
|
||||||
c.artCtl.On("ListTags").Return(2, []*artifact.Tag{
|
c.artCtl.On("ListTags").Return([]*artifact.Tag{
|
||||||
{
|
{
|
||||||
Tag: tag.Tag{
|
Tag: tag.Tag{
|
||||||
RepositoryID: 1,
|
RepositoryID: 1,
|
||||||
@ -171,7 +171,7 @@ func (c *tagTestSuite) TestListTagPagination3() {
|
|||||||
RepositoryID: 1,
|
RepositoryID: 1,
|
||||||
Name: "hello-world",
|
Name: "hello-world",
|
||||||
}, nil)
|
}, nil)
|
||||||
c.artCtl.On("ListTags").Return(2, []*artifact.Tag{
|
c.artCtl.On("ListTags").Return([]*artifact.Tag{
|
||||||
{
|
{
|
||||||
Tag: tag.Tag{
|
Tag: tag.Tag{
|
||||||
RepositoryID: 1,
|
RepositoryID: 1,
|
||||||
|
@ -77,8 +77,13 @@ func (a *artifactAPI) ListArtifacts(ctx context.Context, params operation.ListAr
|
|||||||
option := option(params.WithTag, params.WithImmutableStatus,
|
option := option(params.WithTag, params.WithImmutableStatus,
|
||||||
params.WithLabel, params.WithSignature)
|
params.WithLabel, params.WithSignature)
|
||||||
|
|
||||||
|
// get the total count of artifacts
|
||||||
|
total, err := a.artCtl.Count(ctx, query)
|
||||||
|
if err != nil {
|
||||||
|
return a.SendError(ctx, err)
|
||||||
|
}
|
||||||
// list artifacts according to the query and option
|
// list artifacts according to the query and option
|
||||||
total, arts, err := a.artCtl.List(ctx, query, option)
|
arts, err := a.artCtl.List(ctx, query, option)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return a.SendError(ctx, err)
|
return a.SendError(ctx, err)
|
||||||
}
|
}
|
||||||
|
@ -18,20 +18,99 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/go-openapi/runtime/middleware"
|
"github.com/go-openapi/runtime/middleware"
|
||||||
|
"github.com/goharbor/harbor/src/api/artifact"
|
||||||
"github.com/goharbor/harbor/src/api/repository"
|
"github.com/goharbor/harbor/src/api/repository"
|
||||||
|
cmodels "github.com/goharbor/harbor/src/common/models"
|
||||||
"github.com/goharbor/harbor/src/common/rbac"
|
"github.com/goharbor/harbor/src/common/rbac"
|
||||||
|
"github.com/goharbor/harbor/src/common/utils/log"
|
||||||
|
"github.com/goharbor/harbor/src/pkg/project"
|
||||||
|
"github.com/goharbor/harbor/src/pkg/q"
|
||||||
|
"github.com/goharbor/harbor/src/server/v2.0/models"
|
||||||
operation "github.com/goharbor/harbor/src/server/v2.0/restapi/operations/repository"
|
operation "github.com/goharbor/harbor/src/server/v2.0/restapi/operations/repository"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newRepositoryAPI() *repositoryAPI {
|
func newRepositoryAPI() *repositoryAPI {
|
||||||
return &repositoryAPI{
|
return &repositoryAPI{
|
||||||
|
proMgr: project.Mgr,
|
||||||
repoCtl: repository.Ctl,
|
repoCtl: repository.Ctl,
|
||||||
|
artCtl: artifact.Ctl,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type repositoryAPI struct {
|
type repositoryAPI struct {
|
||||||
BaseAPI
|
BaseAPI
|
||||||
|
// TODO replace proMgr with proCtl
|
||||||
|
proMgr project.Manager
|
||||||
repoCtl repository.Controller
|
repoCtl repository.Controller
|
||||||
|
artCtl artifact.Controller
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *repositoryAPI) ListRepositories(ctx context.Context, params operation.ListRepositoriesParams) middleware.Responder {
|
||||||
|
if err := r.RequireProjectAccess(ctx, params.ProjectName, rbac.ActionList, rbac.ResourceRepository); err != nil {
|
||||||
|
return r.SendError(ctx, err)
|
||||||
|
}
|
||||||
|
project, err := r.proMgr.Get(params.ProjectName)
|
||||||
|
if err != nil {
|
||||||
|
return r.SendError(ctx, err)
|
||||||
|
}
|
||||||
|
// set query
|
||||||
|
query := &q.Query{
|
||||||
|
Keywords: map[string]interface{}{
|
||||||
|
"ProjectID": project.ProjectID,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
// TODO support fuzzy match
|
||||||
|
if params.Name != nil {
|
||||||
|
query.Keywords["Name"] = *(params.Name)
|
||||||
|
}
|
||||||
|
if params.Page != nil {
|
||||||
|
query.PageNumber = *(params.Page)
|
||||||
|
}
|
||||||
|
if params.PageSize != nil {
|
||||||
|
query.PageSize = *(params.PageSize)
|
||||||
|
}
|
||||||
|
total, err := r.repoCtl.Count(ctx, query)
|
||||||
|
if err != nil {
|
||||||
|
return r.SendError(ctx, err)
|
||||||
|
}
|
||||||
|
repositories, err := r.repoCtl.List(ctx, query)
|
||||||
|
if err != nil {
|
||||||
|
return r.SendError(ctx, err)
|
||||||
|
}
|
||||||
|
var repos []*models.Repository
|
||||||
|
for _, repository := range repositories {
|
||||||
|
repo := repository.ToSwagger()
|
||||||
|
total, err := r.artCtl.Count(ctx, &q.Query{
|
||||||
|
Keywords: map[string]interface{}{
|
||||||
|
"RepositoryID": repo.ID,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("failed to get the count of artifacts under the repository %s: %v",
|
||||||
|
repo.Name, err)
|
||||||
|
}
|
||||||
|
repo.ArtifactCount = total
|
||||||
|
repos = append(repos, repo)
|
||||||
|
}
|
||||||
|
// TODO add link header
|
||||||
|
return operation.NewListRepositoriesOK().WithXTotalCount(total).WithLink("").WithPayload(repos)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *repositoryAPI) UpdateRepository(ctx context.Context, params operation.UpdateRepositoryParams) middleware.Responder {
|
||||||
|
if err := r.RequireProjectAccess(ctx, params.ProjectName, rbac.ActionUpdate, rbac.ResourceRepository); err != nil {
|
||||||
|
return r.SendError(ctx, err)
|
||||||
|
}
|
||||||
|
repository, err := r.repoCtl.GetByName(ctx, fmt.Sprintf("%s/%s", params.ProjectName, params.RepositoryName))
|
||||||
|
if err != nil {
|
||||||
|
return r.SendError(ctx, err)
|
||||||
|
}
|
||||||
|
if err := r.repoCtl.Update(ctx, &cmodels.RepoRecord{
|
||||||
|
RepositoryID: repository.RepositoryID,
|
||||||
|
Description: params.Repository.Description,
|
||||||
|
}, "Description"); err != nil {
|
||||||
|
return r.SendError(ctx, err)
|
||||||
|
}
|
||||||
|
return operation.NewDeleteRepositoryOK()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *repositoryAPI) DeleteRepository(ctx context.Context, params operation.DeleteRepositoryParams) middleware.Responder {
|
func (r *repositoryAPI) DeleteRepository(ctx context.Context, params operation.DeleteRepositoryParams) middleware.Responder {
|
||||||
|
@ -34,14 +34,20 @@ func (f *FakeController) Ensure(ctx context.Context, repositoryID int64, digest
|
|||||||
return args.Bool(0), int64(args.Int(1)), args.Error(2)
|
return args.Bool(0), int64(args.Int(1)), args.Error(2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Count ...
|
||||||
|
func (f *FakeController) Count(ctx context.Context, query *q.Query) (int64, error) {
|
||||||
|
args := f.Called()
|
||||||
|
return int64(args.Int(0)), args.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
// List ...
|
// List ...
|
||||||
func (f *FakeController) List(ctx context.Context, query *q.Query, option *artifact.Option) (int64, []*artifact.Artifact, error) {
|
func (f *FakeController) List(ctx context.Context, query *q.Query, option *artifact.Option) ([]*artifact.Artifact, error) {
|
||||||
args := f.Called()
|
args := f.Called()
|
||||||
var artifacts []*artifact.Artifact
|
var artifacts []*artifact.Artifact
|
||||||
if args.Get(1) != nil {
|
if args.Get(0) != nil {
|
||||||
artifacts = args.Get(1).([]*artifact.Artifact)
|
artifacts = args.Get(0).([]*artifact.Artifact)
|
||||||
}
|
}
|
||||||
return int64(args.Int(0)), artifacts, args.Error(2)
|
return artifacts, args.Error(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get ...
|
// Get ...
|
||||||
@ -71,13 +77,13 @@ func (f *FakeController) Delete(ctx context.Context, id int64) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ListTags ...
|
// ListTags ...
|
||||||
func (f *FakeController) ListTags(ctx context.Context, query *q.Query, option *artifact.TagOption) (int64, []*artifact.Tag, error) {
|
func (f *FakeController) ListTags(ctx context.Context, query *q.Query, option *artifact.TagOption) ([]*artifact.Tag, error) {
|
||||||
args := f.Called()
|
args := f.Called()
|
||||||
var tags []*artifact.Tag
|
var tags []*artifact.Tag
|
||||||
if args.Get(1) != nil {
|
if args.Get(0) != nil {
|
||||||
tags = args.Get(1).([]*artifact.Tag)
|
tags = args.Get(0).([]*artifact.Tag)
|
||||||
}
|
}
|
||||||
return int64(args.Int(0)), tags, args.Error(2)
|
return tags, args.Error(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateTag ...
|
// CreateTag ...
|
||||||
|
@ -32,14 +32,21 @@ func (f *FakeController) Ensure(ctx context.Context, name string) (bool, int64,
|
|||||||
return args.Bool(0), int64(args.Int(1)), args.Error(2)
|
return args.Bool(0), int64(args.Int(1)), args.Error(2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Count ...
|
||||||
|
func (f *FakeController) Count(ctx context.Context, query *q.Query) (int64, error) {
|
||||||
|
args := f.Called()
|
||||||
|
return int64(args.Int(0)), args.Error(1)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// List ...
|
// List ...
|
||||||
func (f *FakeController) List(ctx context.Context, query *q.Query) (int64, []*models.RepoRecord, error) {
|
func (f *FakeController) List(ctx context.Context, query *q.Query) ([]*models.RepoRecord, error) {
|
||||||
args := f.Called()
|
args := f.Called()
|
||||||
var repositories []*models.RepoRecord
|
var repositories []*models.RepoRecord
|
||||||
if args.Get(1) != nil {
|
if args.Get(0) != nil {
|
||||||
repositories = args.Get(1).([]*models.RepoRecord)
|
repositories = args.Get(0).([]*models.RepoRecord)
|
||||||
}
|
}
|
||||||
return int64(args.Int(0)), repositories, args.Error(2)
|
return repositories, args.Error(1)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,3 +75,9 @@ func (f *FakeController) Delete(ctx context.Context, id int64) error {
|
|||||||
args := f.Called()
|
args := f.Called()
|
||||||
return args.Error(0)
|
return args.Error(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update ...
|
||||||
|
func (f *FakeController) Update(ctx context.Context, repository *models.RepoRecord, properties ...string) error {
|
||||||
|
args := f.Called()
|
||||||
|
return args.Error(0)
|
||||||
|
}
|
||||||
|
@ -27,14 +27,20 @@ type FakeManager struct {
|
|||||||
mock.Mock
|
mock.Mock
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Count ...
|
||||||
|
func (f *FakeManager) Count(ctx context.Context, query *q.Query) (int64, error) {
|
||||||
|
args := f.Called()
|
||||||
|
return int64(args.Int(0)), args.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
// List ...
|
// List ...
|
||||||
func (f *FakeManager) List(ctx context.Context, query *q.Query) (int64, []*artifact.Artifact, error) {
|
func (f *FakeManager) List(ctx context.Context, query *q.Query) ([]*artifact.Artifact, error) {
|
||||||
args := f.Called()
|
args := f.Called()
|
||||||
var artifacts []*artifact.Artifact
|
var artifacts []*artifact.Artifact
|
||||||
if args.Get(1) != nil {
|
if args.Get(0) != nil {
|
||||||
artifacts = args.Get(1).([]*artifact.Artifact)
|
artifacts = args.Get(0).([]*artifact.Artifact)
|
||||||
}
|
}
|
||||||
return int64(args.Int(0)), artifacts, args.Error(2)
|
return artifacts, args.Error(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get ...
|
// Get ...
|
||||||
|
@ -26,14 +26,20 @@ type FakeManager struct {
|
|||||||
mock.Mock
|
mock.Mock
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Count ...
|
||||||
|
func (f *FakeManager) Count(ctx context.Context, query *q.Query) (int64, error) {
|
||||||
|
args := f.Called()
|
||||||
|
return int64(args.Int(0)), args.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
// List ...
|
// List ...
|
||||||
func (f *FakeManager) List(ctx context.Context, query *q.Query) (int64, []*models.RepoRecord, error) {
|
func (f *FakeManager) List(ctx context.Context, query *q.Query) ([]*models.RepoRecord, error) {
|
||||||
args := f.Called()
|
args := f.Called()
|
||||||
var repositories []*models.RepoRecord
|
var repositories []*models.RepoRecord
|
||||||
if args.Get(1) != nil {
|
if args.Get(0) != nil {
|
||||||
repositories = args.Get(1).([]*models.RepoRecord)
|
repositories = args.Get(0).([]*models.RepoRecord)
|
||||||
}
|
}
|
||||||
return int64(args.Int(0)), repositories, args.Error(2)
|
return repositories, args.Error(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get ...
|
// Get ...
|
||||||
|
@ -26,14 +26,20 @@ type FakeManager struct {
|
|||||||
mock.Mock
|
mock.Mock
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Count ...
|
||||||
|
func (f *FakeManager) Count(ctx context.Context, query *q.Query) (int64, error) {
|
||||||
|
args := f.Called()
|
||||||
|
return int64(args.Int(0)), args.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
// List ...
|
// List ...
|
||||||
func (f *FakeManager) List(ctx context.Context, query *q.Query) (int64, []*tag.Tag, error) {
|
func (f *FakeManager) List(ctx context.Context, query *q.Query) ([]*tag.Tag, error) {
|
||||||
args := f.Called()
|
args := f.Called()
|
||||||
var tags []*tag.Tag
|
var tags []*tag.Tag
|
||||||
if args.Get(1) != nil {
|
if args.Get(0) != nil {
|
||||||
tags = args.Get(1).([]*tag.Tag)
|
tags = args.Get(0).([]*tag.Tag)
|
||||||
}
|
}
|
||||||
return int64(args.Int(0)), tags, args.Error(2)
|
return tags, args.Error(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get ...
|
// Get ...
|
||||||
|
Loading…
Reference in New Issue
Block a user