Skip to content

Commit

Permalink
Merge branch 'oic-ui-1' of https://github.com/goharbor/harbor into oi…
Browse files Browse the repository at this point in the history
…c-ui-1
  • Loading branch information
Yogi_Wang committed Feb 10, 2020
2 parents 41e38e3 + e00a4bc commit 4a9aea3
Show file tree
Hide file tree
Showing 12 changed files with 152 additions and 158 deletions.
22 changes: 22 additions & 0 deletions api/v2.0/swagger.yaml
Expand Up @@ -227,6 +227,28 @@ paths:
$ref: '#/responses/404'
'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:
requestId:
name: X-Request-Id
Expand Down
1 change: 1 addition & 0 deletions src/api/artifact/controller.go
Expand Up @@ -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) {
// TODO fire event
return c.tagMgr.Create(ctx, &(tag.Tag))
}
func (c *controller) ListTags(ctx context.Context, query *q.Query, option *TagOption) (int64, []*Tag, error) {
Expand Down
27 changes: 27 additions & 0 deletions src/api/repository/controller.go
Expand Up @@ -16,6 +16,7 @@ package repository

import (
"context"
"github.com/goharbor/harbor/src/api/artifact"
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/common/utils"
ierror "github.com/goharbor/harbor/src/internal/error"
Expand All @@ -41,19 +42,23 @@ type Controller interface {
Get(ctx context.Context, id int64) (repository *models.RepoRecord, err error)
// GetByName gets the repository specified by name
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
func NewController() Controller {
return &controller{
proMgr: project.Mgr,
repoMgr: repository.Mgr,
artCtl: artifact.Ctl,
}
}

type controller struct {
proMgr project.Manager
repoMgr repository.Manager
artCtl artifact.Controller
}

func (c *controller) Ensure(ctx context.Context, name string) (bool, int64, error) {
Expand Down Expand Up @@ -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) {
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 changes: 15 additions & 0 deletions src/api/repository/controller_test.go
Expand Up @@ -15,7 +15,9 @@
package repository

import (
"github.com/goharbor/harbor/src/api/artifact"
"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/repository"
"github.com/stretchr/testify/suite"
Expand All @@ -27,14 +29,17 @@ type controllerTestSuite struct {
ctl *controller
proMgr *project.FakeManager
repoMgr *repository.FakeManager
artCtl *artifacttesting.FakeController
}

func (c *controllerTestSuite) SetupTest() {
c.proMgr = &project.FakeManager{}
c.repoMgr = &repository.FakeManager{}
c.artCtl = &artifacttesting.FakeController{}
c.ctl = &controller{
proMgr: c.proMgr,
repoMgr: c.repoMgr,
artCtl: c.artCtl,
}
}

Expand Down Expand Up @@ -104,6 +109,16 @@ func (c *controllerTestSuite) TestGetByName() {
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) {
suite.Run(t, &controllerTestSuite{})
}
Expand Up @@ -22,6 +22,7 @@ import { UserPermissionService } from "../../services/permission.service";
import { of } from "rxjs";
import { HarborLibraryModule } from "../../harbor-library.module";
import { delay } from 'rxjs/operators';
import { RepositoryService as NewRepositoryService } from "../../../../ng-swagger-gen/services/repository.service";
describe('RepositoryComponentGridview (inline template)', () => {

let compRepo: RepositoryGridviewComponent;
Expand Down Expand Up @@ -117,6 +118,7 @@ describe('RepositoryComponentGridview (inline template)', () => {
{ provide: ErrorHandler, useValue: fakedErrorHandler },
{ provide: SERVICE_CONFIG, useValue: config },
{ provide: RepositoryService, useValue: fakedRepositoryService },
{ provide: NewRepositoryService, useValue: fakedRepositoryService },
{ provide: TagService, useClass: TagDefaultService },
{ provide: ProjectService, useClass: ProjectDefaultService },
{ provide: RetagService, useClass: RetagDefaultService },
Expand Down
Expand Up @@ -42,6 +42,7 @@ import { Observable, throwError as observableThrowError } from "rxjs";
import { errorHandler as errorHandFn } from "../../utils/shared/shared.utils";
import { ClrDatagridStateInterface } from "@clr/angular";
import { FilterComponent } from "../filter/filter.component";
import { RepositoryService as NewRepositoryService} from "../../../../ng-swagger-gen/services/repository.service";
@Component({
selector: "hbr-repository-gridview",
templateUrl: "./repository-gridview.component.html",
Expand Down Expand Up @@ -89,6 +90,7 @@ export class RepositoryGridviewComponent implements OnChanges, OnInit, OnDestroy
private errorHandler: ErrorHandler,
private translateService: TranslateService,
private repositoryService: RepositoryService,
private newRepoService: NewRepositoryService,
private systemInfoService: SystemInfoService,
private tagService: TagService,
private operationService: OperationService,
Expand Down Expand Up @@ -220,8 +222,10 @@ export class RepositoryGridviewComponent implements OnChanges, OnInit, OnDestroy
operateChanges(operMessage, OperationState.failure, res[1]);
}));
} else {
return this.repositoryService
.deleteRepository(repo.name)
return this.newRepoService
.deleteRepository({
repositoryName: repo.name,
projectName: this.projectName})
.pipe(map(
response => {
this.translateService.get('BATCH.DELETED_SUCCESS').subscribe(res => {
Expand Down
61 changes: 10 additions & 51 deletions src/server/middleware/immutable/deletemf.go
Expand Up @@ -3,14 +3,9 @@ package immutable
import (
"errors"
"fmt"
"github.com/goharbor/harbor/src/api/artifact"
common_util "github.com/goharbor/harbor/src/common/utils"
internal_errors "github.com/goharbor/harbor/src/internal/error"
"github.com/goharbor/harbor/src/pkg/art"
"github.com/goharbor/harbor/src/pkg/artifact"
"github.com/goharbor/harbor/src/pkg/immutabletag/match/rule"
"github.com/goharbor/harbor/src/pkg/q"
"github.com/goharbor/harbor/src/pkg/repository"
"github.com/goharbor/harbor/src/pkg/tag"
"github.com/goharbor/harbor/src/server/middleware"
"net/http"
)
Expand Down Expand Up @@ -43,56 +38,20 @@ func handleDelete(req *http.Request) error {
return errors.New("cannot get the manifest information from request context")
}

_, repoName := common_util.ParseRepository(mf.Repository)
total, repos, err := repository.Mgr.List(req.Context(), &q.Query{
Keywords: map[string]interface{}{
"Name": mf.Repository,
},
})
if err != nil {
return err
}
if total == 0 {
return nil
}

total, afs, err := artifact.Mgr.List(req.Context(), &q.Query{
Keywords: map[string]interface{}{
"ProjectID": mf.ProjectID,
"RepositoryID": repos[0].RepositoryID,
"Digest": mf.Digest,
},
})
if err != nil {
return err
}
if total == 0 {
return nil
}

total, tags, err := tag.Mgr.List(req.Context(), &q.Query{
Keywords: map[string]interface{}{
"ArtifactID": afs[0].ID,
},
af, err := artifact.Ctl.GetByReference(req.Context(), mf.Repository, mf.Digest, &artifact.Option{
WithTag: true,
TagOption: &artifact.TagOption{WithImmutableStatus: true},
})
if err != nil {
if internal_errors.IsErr(err, internal_errors.NotFoundCode) {
return nil
}
return err
}
if total == 0 {
return nil
}

for _, tag := range tags {
var matched bool
matched, err = rule.NewRuleMatcher().Match(mf.ProjectID, art.Candidate{
Repository: repoName,
Tag: tag.Name,
NamespaceID: mf.ProjectID,
})
if err != nil {
return err
}
if matched {
_, repoName := common_util.ParseRepository(mf.Repository)
for _, tag := range af.Tags {
if tag.Immutable {
return NewErrImmutable(repoName, tag.Name)
}
}
Expand Down
72 changes: 12 additions & 60 deletions src/server/middleware/immutable/pushmf.go
Expand Up @@ -3,14 +3,9 @@ package immutable
import (
"errors"
"fmt"
"github.com/goharbor/harbor/src/api/artifact"
common_util "github.com/goharbor/harbor/src/common/utils"
internal_errors "github.com/goharbor/harbor/src/internal/error"
"github.com/goharbor/harbor/src/pkg/art"
"github.com/goharbor/harbor/src/pkg/artifact"
"github.com/goharbor/harbor/src/pkg/immutabletag/match/rule"
"github.com/goharbor/harbor/src/pkg/q"
"github.com/goharbor/harbor/src/pkg/repository"
"github.com/goharbor/harbor/src/pkg/tag"
"github.com/goharbor/harbor/src/server/middleware"
"net/http"
)
Expand Down Expand Up @@ -45,65 +40,22 @@ func handlePush(req *http.Request) error {
return errors.New("cannot get the manifest information from request context")
}

_, repoName := common_util.ParseRepository(mf.Repository)
var matched bool
matched, err := rule.NewRuleMatcher().Match(mf.ProjectID, art.Candidate{
Repository: repoName,
Tag: mf.Tag,
NamespaceID: mf.ProjectID,
})
if err != nil {
return err
}
if !matched {
return nil
}

// match repository ...
total, repos, err := repository.Mgr.List(req.Context(), &q.Query{
Keywords: map[string]interface{}{
"Name": mf.Repository,
},
})
if err != nil {
return err
}
if total == 0 {
return nil
}

// match artifacts ...
total, afs, err := artifact.Mgr.List(req.Context(), &q.Query{
Keywords: map[string]interface{}{
"ProjectID": mf.ProjectID,
"RepositoryID": repos[0].RepositoryID,
},
af, err := artifact.Ctl.GetByReference(req.Context(), mf.Repository, mf.Tag, &artifact.Option{
WithTag: true,
TagOption: &artifact.TagOption{WithImmutableStatus: true},
})
if err != nil {
if internal_errors.IsErr(err, internal_errors.NotFoundCode) {
return nil
}
return err
}
if total == 0 {
return nil
}

// match tags ...
for _, af := range afs {
total, tags, err := tag.Mgr.List(req.Context(), &q.Query{
Keywords: map[string]interface{}{
"ArtifactID": af.ID,
},
})
if err != nil {
return err
}
if total == 0 {
continue
}
for _, tag := range tags {
// push a existing immutable tag, reject the request
if tag.Name == mf.Tag {
return NewErrImmutable(repoName, mf.Tag)
}
_, repoName := common_util.ParseRepository(mf.Repository)
for _, tag := range af.Tags {
// push a existing immutable tag, reject th e request
if tag.Name == mf.Tag && tag.Immutable {
return NewErrImmutable(repoName, mf.Tag)
}
}

Expand Down

0 comments on commit 4a9aea3

Please sign in to comment.