mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-23 02:35:17 +01:00
Merge pull request #10662 from ywk253100/200206_delete_repo
Implement repository deletion API
This commit is contained in:
commit
6bad9f62ba
@ -227,6 +227,28 @@ 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'
|
||||||
parameters:
|
parameters:
|
||||||
requestId:
|
requestId:
|
||||||
name: X-Request-Id
|
name: X-Request-Id
|
||||||
|
@ -295,6 +295,7 @@ func (c *controller) Delete(ctx context.Context, id int64) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *controller) CreateTag(ctx context.Context, tag *Tag) (int64, error) {
|
func (c *controller) CreateTag(ctx context.Context, tag *Tag) (int64, error) {
|
||||||
|
// 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) (int64, []*Tag, error) {
|
||||||
|
@ -16,6 +16,7 @@ package repository
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"github.com/goharbor/harbor/src/api/artifact"
|
||||||
"github.com/goharbor/harbor/src/common/models"
|
"github.com/goharbor/harbor/src/common/models"
|
||||||
"github.com/goharbor/harbor/src/common/utils"
|
"github.com/goharbor/harbor/src/common/utils"
|
||||||
ierror "github.com/goharbor/harbor/src/internal/error"
|
ierror "github.com/goharbor/harbor/src/internal/error"
|
||||||
@ -41,6 +42,8 @@ type Controller interface {
|
|||||||
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(ctx context.Context, id int64) (err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewController creates an instance of the default repository controller
|
// NewController creates an instance of the default repository controller
|
||||||
@ -48,12 +51,14 @@ func NewController() Controller {
|
|||||||
return &controller{
|
return &controller{
|
||||||
proMgr: project.Mgr,
|
proMgr: project.Mgr,
|
||||||
repoMgr: repository.Mgr,
|
repoMgr: repository.Mgr,
|
||||||
|
artCtl: artifact.Ctl,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type controller struct {
|
type controller struct {
|
||||||
proMgr project.Manager
|
proMgr project.Manager
|
||||||
repoMgr repository.Manager
|
repoMgr repository.Manager
|
||||||
|
artCtl artifact.Controller
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *controller) Ensure(ctx context.Context, name string) (bool, int64, error) {
|
func (c *controller) Ensure(ctx context.Context, name string) (bool, int64, error) {
|
||||||
@ -108,3 +113,25 @@ func (c *controller) Get(ctx context.Context, id int64) (*models.RepoRecord, err
|
|||||||
func (c *controller) GetByName(ctx context.Context, name string) (*models.RepoRecord, error) {
|
func (c *controller) GetByName(ctx context.Context, name string) (*models.RepoRecord, error) {
|
||||||
return c.repoMgr.GetByName(ctx, name)
|
return c.repoMgr.GetByName(ctx, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *controller) Delete(ctx context.Context, id int64) error {
|
||||||
|
// TODO auth
|
||||||
|
// TODO how to make sure the logic included by middlewares(immutable, readonly, quota, etc)
|
||||||
|
// TODO is covered when deleting the artifacts of the repository
|
||||||
|
_, artifacts, err := c.artCtl.List(ctx, &q.Query{
|
||||||
|
Keywords: map[string]interface{}{
|
||||||
|
"RepositoryID": id,
|
||||||
|
},
|
||||||
|
}, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, artifact := range artifacts {
|
||||||
|
if err = c.artCtl.Delete(ctx, artifact.ID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return c.repoMgr.Delete(ctx, id)
|
||||||
|
|
||||||
|
// TODO fire event
|
||||||
|
}
|
||||||
|
@ -15,7 +15,9 @@
|
|||||||
package repository
|
package repository
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/goharbor/harbor/src/api/artifact"
|
||||||
"github.com/goharbor/harbor/src/common/models"
|
"github.com/goharbor/harbor/src/common/models"
|
||||||
|
artifacttesting "github.com/goharbor/harbor/src/testing/api/artifact"
|
||||||
"github.com/goharbor/harbor/src/testing/pkg/project"
|
"github.com/goharbor/harbor/src/testing/pkg/project"
|
||||||
"github.com/goharbor/harbor/src/testing/pkg/repository"
|
"github.com/goharbor/harbor/src/testing/pkg/repository"
|
||||||
"github.com/stretchr/testify/suite"
|
"github.com/stretchr/testify/suite"
|
||||||
@ -27,14 +29,17 @@ type controllerTestSuite struct {
|
|||||||
ctl *controller
|
ctl *controller
|
||||||
proMgr *project.FakeManager
|
proMgr *project.FakeManager
|
||||||
repoMgr *repository.FakeManager
|
repoMgr *repository.FakeManager
|
||||||
|
artCtl *artifacttesting.FakeController
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *controllerTestSuite) SetupTest() {
|
func (c *controllerTestSuite) SetupTest() {
|
||||||
c.proMgr = &project.FakeManager{}
|
c.proMgr = &project.FakeManager{}
|
||||||
c.repoMgr = &repository.FakeManager{}
|
c.repoMgr = &repository.FakeManager{}
|
||||||
|
c.artCtl = &artifacttesting.FakeController{}
|
||||||
c.ctl = &controller{
|
c.ctl = &controller{
|
||||||
proMgr: c.proMgr,
|
proMgr: c.proMgr,
|
||||||
repoMgr: c.repoMgr,
|
repoMgr: c.repoMgr,
|
||||||
|
artCtl: c.artCtl,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,6 +109,16 @@ func (c *controllerTestSuite) TestGetByName() {
|
|||||||
c.Equal(int64(1), repository.RepositoryID)
|
c.Equal(int64(1), repository.RepositoryID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *controllerTestSuite) TestDelete() {
|
||||||
|
art := &artifact.Artifact{}
|
||||||
|
art.ID = 1
|
||||||
|
c.artCtl.On("List").Return(1, []*artifact.Artifact{art}, nil)
|
||||||
|
c.artCtl.On("Delete").Return(nil)
|
||||||
|
c.repoMgr.On("Delete").Return(nil)
|
||||||
|
err := c.ctl.Delete(nil, 1)
|
||||||
|
c.Require().Nil(err)
|
||||||
|
}
|
||||||
|
|
||||||
func TestControllerTestSuite(t *testing.T) {
|
func TestControllerTestSuite(t *testing.T) {
|
||||||
suite.Run(t, &controllerTestSuite{})
|
suite.Run(t, &controllerTestSuite{})
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,7 @@ import (
|
|||||||
func New() http.Handler {
|
func New() http.Handler {
|
||||||
h, api, err := restapi.HandlerAPI(restapi.Config{
|
h, api, err := restapi.HandlerAPI(restapi.Config{
|
||||||
ArtifactAPI: newArtifactAPI(),
|
ArtifactAPI: newArtifactAPI(),
|
||||||
|
RepositoryAPI: newRepositoryAPI(),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
|
45
src/server/v2.0/handler/repository.go
Normal file
45
src/server/v2.0/handler/repository.go
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
// Copyright Project Harbor Authors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"github.com/go-openapi/runtime/middleware"
|
||||||
|
"github.com/goharbor/harbor/src/api/repository"
|
||||||
|
operation "github.com/goharbor/harbor/src/server/v2.0/restapi/operations/repository"
|
||||||
|
)
|
||||||
|
|
||||||
|
func newRepositoryAPI() *repositoryAPI {
|
||||||
|
return &repositoryAPI{
|
||||||
|
repoCtl: repository.Ctl,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type repositoryAPI struct {
|
||||||
|
BaseAPI
|
||||||
|
repoCtl repository.Controller
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *repositoryAPI) DeleteRepository(ctx context.Context, params operation.DeleteRepositoryParams) middleware.Responder {
|
||||||
|
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.Delete(ctx, repository.RepositoryID); err != nil {
|
||||||
|
return r.SendError(ctx, err)
|
||||||
|
}
|
||||||
|
return operation.NewDeleteRepositoryOK()
|
||||||
|
}
|
@ -62,3 +62,9 @@ func (f *FakeController) GetByName(ctx context.Context, name string) (*models.Re
|
|||||||
}
|
}
|
||||||
return repository, args.Error(1)
|
return repository, args.Error(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Delete ...
|
||||||
|
func (f *FakeController) Delete(ctx context.Context, id int64) error {
|
||||||
|
args := f.Called()
|
||||||
|
return args.Error(0)
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user