mirror of
https://github.com/goharbor/harbor.git
synced 2025-01-22 23:51:27 +01:00
Cosign artifact api
1,update artifact list & delete api to support accessory 2, add list accesories api Signed-off-by: Wang Yan <wangyan@vmware.com>
This commit is contained in:
parent
3c0a5a936f
commit
2111703d8d
@ -1000,7 +1000,13 @@ paths:
|
||||
default: false
|
||||
- name: with_immutable_status
|
||||
in: query
|
||||
description: Specify whether the immutable status is included inside the tags of the returning artifacts. Only works when setting "with_tag=true"
|
||||
description: Specify whether the immutable status is included inside the tags of the returning artifacts. Only works when setting "with_immutable_status=true"
|
||||
type: boolean
|
||||
required: false
|
||||
default: false
|
||||
- name: with_accessory
|
||||
in: query
|
||||
description: Specify whether the accessories are included of the returning artifacts. Only works when setting "with_accessory=true"
|
||||
type: boolean
|
||||
required: false
|
||||
default: false
|
||||
@ -1091,6 +1097,12 @@ paths:
|
||||
type: boolean
|
||||
required: false
|
||||
default: false
|
||||
- name: with_accessory
|
||||
in: query
|
||||
description: Specify whether the accessories are included of the returning artifacts.
|
||||
type: boolean
|
||||
required: false
|
||||
default: false
|
||||
# should be in tag level
|
||||
- name: with_signature
|
||||
in: query
|
||||
@ -1100,7 +1112,7 @@ paths:
|
||||
default: false
|
||||
- name: with_immutable_status
|
||||
in: query
|
||||
description: Specify whether the immutable status is inclued inside the tags of the returning artifacts. Only works when setting "with_tag=true"
|
||||
description: Specify whether the immutable status is inclued inside the tags of the returning artifacts.
|
||||
type: boolean
|
||||
required: false
|
||||
default: false
|
||||
@ -1333,6 +1345,46 @@ paths:
|
||||
$ref: '#/responses/404'
|
||||
'500':
|
||||
$ref: '#/responses/500'
|
||||
/projects/{project_name}/repositories/{repository_name}/artifacts/{reference}/accessories:
|
||||
get:
|
||||
summary: List accessories
|
||||
description: List accessories of the specific artifact
|
||||
tags:
|
||||
- artifact
|
||||
operationId: listAccessories
|
||||
parameters:
|
||||
- $ref: '#/parameters/requestId'
|
||||
- $ref: '#/parameters/projectName'
|
||||
- $ref: '#/parameters/repositoryName'
|
||||
- $ref: '#/parameters/reference'
|
||||
- $ref: '#/parameters/query'
|
||||
- $ref: '#/parameters/sort'
|
||||
- $ref: '#/parameters/page'
|
||||
- $ref: '#/parameters/pageSize'
|
||||
responses:
|
||||
'200':
|
||||
description: Success
|
||||
headers:
|
||||
X-Total-Count:
|
||||
description: The total count of accessories
|
||||
type: integer
|
||||
Link:
|
||||
description: Link refers to the previous page and next page
|
||||
type: string
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/Accessory'
|
||||
'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/{reference}/additions/vulnerabilities:
|
||||
get:
|
||||
summary: Get the vulnerabilities addition of the specific artifact
|
||||
@ -5487,6 +5539,13 @@ parameters:
|
||||
required: true
|
||||
type: integer
|
||||
format: int64
|
||||
accessoryId:
|
||||
name: accessory_id
|
||||
in: path
|
||||
description: The ID of the accessory
|
||||
required: true
|
||||
type: integer
|
||||
format: int64
|
||||
|
||||
responses:
|
||||
'200':
|
||||
@ -5827,6 +5886,11 @@ definitions:
|
||||
scan_overview:
|
||||
$ref: '#/definitions/ScanOverview'
|
||||
description: The overview of the scan result.
|
||||
accessories:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/Accessory'
|
||||
description: The accessory of the artifact.
|
||||
Tag:
|
||||
type: object
|
||||
properties:
|
||||
@ -8657,3 +8721,42 @@ definitions:
|
||||
format: int64
|
||||
description: The total storage consumption of blobs, only be seen by the system admin
|
||||
x-omitempty: false
|
||||
Accessory:
|
||||
type: object
|
||||
description: 'The accessory of the artifact'
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
description: The ID of the accessory
|
||||
artifact_id:
|
||||
type: integer
|
||||
format: int64
|
||||
description: The artifact id of the accessory
|
||||
x-omitempty: false
|
||||
subject_artifact_id:
|
||||
type: integer
|
||||
format: int64
|
||||
description: The subject artifact id of the accessory
|
||||
x-omitempty: false
|
||||
size:
|
||||
type: integer
|
||||
format: int64
|
||||
description: The artifact size of the accessory
|
||||
x-omitempty: false
|
||||
digest:
|
||||
type: string
|
||||
description: The artifact digest of the accessory
|
||||
x-omitempty: false
|
||||
type:
|
||||
type: string
|
||||
description: The artifact size of the accessory
|
||||
x-omitempty: false
|
||||
icon:
|
||||
type: string
|
||||
description: The icon of the accessory
|
||||
x-omitempty: false
|
||||
creation_time:
|
||||
type: string
|
||||
format: date-time
|
||||
description: The creation time of the accessory
|
||||
|
@ -55,6 +55,7 @@ const (
|
||||
ResourceScanner = Resource("scanner")
|
||||
ResourceArtifact = Resource("artifact")
|
||||
ResourceTag = Resource("tag")
|
||||
ResourceAccessory = Resource("accessory")
|
||||
ResourceArtifactAddition = Resource("artifact-addition")
|
||||
ResourceArtifactLabel = Resource("artifact-label")
|
||||
ResourcePreatPolicy = Resource("preheat-policy")
|
||||
|
@ -113,6 +113,8 @@ var (
|
||||
{Resource: rbac.ResourceTag, Action: rbac.ActionCreate},
|
||||
{Resource: rbac.ResourceTag, Action: rbac.ActionDelete},
|
||||
|
||||
{Resource: rbac.ResourceAccessory, Action: rbac.ActionList},
|
||||
|
||||
{Resource: rbac.ResourceArtifactLabel, Action: rbac.ActionCreate},
|
||||
{Resource: rbac.ResourceArtifactLabel, Action: rbac.ActionDelete},
|
||||
|
||||
@ -159,6 +161,8 @@ var (
|
||||
{Resource: rbac.ResourceTagRetention, Action: rbac.ActionList},
|
||||
{Resource: rbac.ResourceTagRetention, Action: rbac.ActionOperate},
|
||||
|
||||
{Resource: rbac.ResourceAccessory, Action: rbac.ActionList},
|
||||
|
||||
{Resource: rbac.ResourceImmutableTag, Action: rbac.ActionCreate},
|
||||
{Resource: rbac.ResourceImmutableTag, Action: rbac.ActionUpdate},
|
||||
{Resource: rbac.ResourceImmutableTag, Action: rbac.ActionDelete},
|
||||
@ -252,6 +256,8 @@ var (
|
||||
{Resource: rbac.ResourceTag, Action: rbac.ActionList},
|
||||
{Resource: rbac.ResourceTag, Action: rbac.ActionCreate},
|
||||
|
||||
{Resource: rbac.ResourceAccessory, Action: rbac.ActionList},
|
||||
|
||||
{Resource: rbac.ResourceArtifactLabel, Action: rbac.ActionCreate},
|
||||
{Resource: rbac.ResourceArtifactLabel, Action: rbac.ActionDelete},
|
||||
},
|
||||
@ -289,6 +295,7 @@ var (
|
||||
{Resource: rbac.ResourceScanner, Action: rbac.ActionRead},
|
||||
|
||||
{Resource: rbac.ResourceTag, Action: rbac.ActionList},
|
||||
{Resource: rbac.ResourceAccessory, Action: rbac.ActionList},
|
||||
|
||||
{Resource: rbac.ResourceArtifact, Action: rbac.ActionRead},
|
||||
{Resource: rbac.ResourceArtifact, Action: rbac.ActionList},
|
||||
@ -316,6 +323,7 @@ var (
|
||||
{Resource: rbac.ResourceScanner, Action: rbac.ActionRead},
|
||||
|
||||
{Resource: rbac.ResourceTag, Action: rbac.ActionList},
|
||||
{Resource: rbac.ResourceAccessory, Action: rbac.ActionList},
|
||||
|
||||
{Resource: rbac.ResourceArtifact, Action: rbac.ActionRead},
|
||||
{Resource: rbac.ResourceArtifact, Action: rbac.ActionList},
|
||||
|
@ -35,6 +35,7 @@ import (
|
||||
"github.com/goharbor/harbor/src/lib/log"
|
||||
"github.com/goharbor/harbor/src/lib/orm"
|
||||
"github.com/goharbor/harbor/src/lib/q"
|
||||
"github.com/goharbor/harbor/src/pkg/accessory"
|
||||
"github.com/goharbor/harbor/src/pkg/artifact"
|
||||
"github.com/goharbor/harbor/src/pkg/artifactrash"
|
||||
"github.com/goharbor/harbor/src/pkg/artifactrash/model"
|
||||
@ -121,6 +122,7 @@ func NewController() Controller {
|
||||
immutableMtr: rule.NewRuleMatcher(),
|
||||
regCli: registry.Cli,
|
||||
abstractor: NewAbstractor(),
|
||||
accessoryMgr: accessory.Mgr,
|
||||
}
|
||||
}
|
||||
|
||||
@ -135,6 +137,7 @@ type controller struct {
|
||||
immutableMtr match.ImmutableTagMatcher
|
||||
regCli registry.Client
|
||||
abstractor Abstractor
|
||||
accessoryMgr accessory.Manager
|
||||
}
|
||||
|
||||
func (c *controller) Ensure(ctx context.Context, repository, digest string, tags ...string) (bool, int64, error) {
|
||||
@ -229,11 +232,18 @@ func (c *controller) List(ctx context.Context, query *q.Query, option *Option) (
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var artifacts []*Artifact
|
||||
var res []*Artifact
|
||||
// Only the displayed accessory will in the artifact list
|
||||
for _, art := range arts {
|
||||
artifacts = append(artifacts, c.assembleArtifact(ctx, art, option))
|
||||
accs, err := c.accessoryMgr.List(ctx, q.New(q.KeyWords{"ArtifactID": art.ID, "digest": art.Digest}))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(accs) == 0 || (len(accs) > 0 && accs[0].Display()) {
|
||||
res = append(res, c.assembleArtifact(ctx, art, option))
|
||||
}
|
||||
}
|
||||
return artifacts, nil
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (c *controller) Get(ctx context.Context, id int64, option *Option) (*Artifact, error) {
|
||||
@ -283,13 +293,18 @@ func (c *controller) getByTag(ctx context.Context, repository, tag string, optio
|
||||
}
|
||||
|
||||
func (c *controller) Delete(ctx context.Context, id int64) error {
|
||||
return c.deleteDeeply(ctx, id, true)
|
||||
accs, err := c.accessoryMgr.List(ctx, q.New(q.KeyWords{"ArtifactID": id}))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return c.deleteDeeply(ctx, id, true, len(accs) > 0)
|
||||
}
|
||||
|
||||
// "isRoot" is used to specify whether the artifact is the root parent artifact
|
||||
// the error handling logic for the root parent artifact and others is different
|
||||
func (c *controller) deleteDeeply(ctx context.Context, id int64, isRoot bool) error {
|
||||
art, err := c.Get(ctx, id, &Option{WithTag: true})
|
||||
// "isAccessory" is used to specify whether the artifact is an accessory.
|
||||
func (c *controller) deleteDeeply(ctx context.Context, id int64, isRoot, isAccessory bool) error {
|
||||
art, err := c.Get(ctx, id, &Option{WithTag: true, WithAccessory: true})
|
||||
if err != nil {
|
||||
// return nil if the nonexistent artifact isn't the root parent
|
||||
if !isRoot && errors.IsErr(err, errors.NotFoundCode) {
|
||||
@ -298,6 +313,12 @@ func (c *controller) deleteDeeply(ctx context.Context, id int64, isRoot bool) er
|
||||
return err
|
||||
}
|
||||
|
||||
if isAccessory {
|
||||
if err := c.accessoryMgr.DeleteAccessories(ctx, q.New(q.KeyWords{"ArtifactID": art.ID, "Digest": art.Digest})); err != nil && !errors.IsErr(err, errors.NotFoundCode) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// the child artifact is referenced by some tags, skip
|
||||
if !isRoot && len(art.Tags) > 0 {
|
||||
return nil
|
||||
@ -319,6 +340,17 @@ func (c *controller) deleteDeeply(ctx context.Context, id int64, isRoot bool) er
|
||||
// the child artifact is referenced by other artifacts, skip
|
||||
return nil
|
||||
}
|
||||
|
||||
// delete accessories if contains any
|
||||
for _, acc := range art.Accessories {
|
||||
// only hard ref accessory should be removed
|
||||
if acc.IsHard() {
|
||||
if err = c.deleteDeeply(ctx, acc.GetData().ArtifactID, true, true); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// delete child artifacts if contains any
|
||||
for _, reference := range art.References {
|
||||
// delete reference
|
||||
@ -326,7 +358,7 @@ func (c *controller) deleteDeeply(ctx context.Context, id int64, isRoot bool) er
|
||||
!errors.IsErr(err, errors.NotFoundCode) {
|
||||
return err
|
||||
}
|
||||
if err = c.deleteDeeply(ctx, reference.ChildID, false); err != nil {
|
||||
if err = c.deleteDeeply(ctx, reference.ChildID, false, false); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -582,6 +614,9 @@ func (c *controller) assembleArtifact(ctx context.Context, art *artifact.Artifac
|
||||
if option.WithLabel {
|
||||
c.populateLabels(ctx, artifact)
|
||||
}
|
||||
if option.WithAccessory {
|
||||
c.populateAccessories(ctx, artifact)
|
||||
}
|
||||
return artifact
|
||||
}
|
||||
|
||||
@ -626,3 +661,12 @@ func (c *controller) populateAdditionLinks(ctx context.Context, artifact *Artifa
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *controller) populateAccessories(ctx context.Context, art *Artifact) {
|
||||
accs, err := c.accessoryMgr.List(ctx, q.New(q.KeyWords{"SubjectArtifactID": art.ID}))
|
||||
if err != nil {
|
||||
log.Errorf("failed to list accessories of artifact %d: %v", art.ID, err)
|
||||
return
|
||||
}
|
||||
art.Accessories = accs
|
||||
}
|
||||
|
@ -28,12 +28,16 @@ import (
|
||||
"github.com/goharbor/harbor/src/lib/icon"
|
||||
"github.com/goharbor/harbor/src/lib/orm"
|
||||
"github.com/goharbor/harbor/src/lib/q"
|
||||
accessorymodel "github.com/goharbor/harbor/src/pkg/accessory/model"
|
||||
basemodel "github.com/goharbor/harbor/src/pkg/accessory/model/base"
|
||||
"github.com/goharbor/harbor/src/pkg/artifact"
|
||||
"github.com/goharbor/harbor/src/pkg/label/model"
|
||||
repomodel "github.com/goharbor/harbor/src/pkg/repository/model"
|
||||
model_tag "github.com/goharbor/harbor/src/pkg/tag/model/tag"
|
||||
tagtesting "github.com/goharbor/harbor/src/testing/controller/tag"
|
||||
ormtesting "github.com/goharbor/harbor/src/testing/lib/orm"
|
||||
"github.com/goharbor/harbor/src/testing/pkg/accessory"
|
||||
accessorytesting "github.com/goharbor/harbor/src/testing/pkg/accessory"
|
||||
arttesting "github.com/goharbor/harbor/src/testing/pkg/artifact"
|
||||
artrashtesting "github.com/goharbor/harbor/src/testing/pkg/artifactrash"
|
||||
"github.com/goharbor/harbor/src/testing/pkg/blob"
|
||||
@ -69,6 +73,7 @@ type controllerTestSuite struct {
|
||||
abstractor *fakeAbstractor
|
||||
immutableMtr *immutable.FakeMatcher
|
||||
regCli *registry.FakeClient
|
||||
accMgr *accessory.Manager
|
||||
}
|
||||
|
||||
func (c *controllerTestSuite) SetupTest() {
|
||||
@ -80,6 +85,7 @@ func (c *controllerTestSuite) SetupTest() {
|
||||
c.labelMgr = &label.Manager{}
|
||||
c.abstractor = &fakeAbstractor{}
|
||||
c.immutableMtr = &immutable.FakeMatcher{}
|
||||
c.accMgr = &accessorytesting.Manager{}
|
||||
c.regCli = ®istry.FakeClient{}
|
||||
c.ctl = &controller{
|
||||
repoMgr: c.repoMgr,
|
||||
@ -91,6 +97,7 @@ func (c *controllerTestSuite) SetupTest() {
|
||||
abstractor: c.abstractor,
|
||||
immutableMtr: c.immutableMtr,
|
||||
regCli: c.regCli,
|
||||
accessoryMgr: c.accMgr,
|
||||
}
|
||||
}
|
||||
|
||||
@ -105,7 +112,8 @@ func (c *controllerTestSuite) TestAssembleArtifact() {
|
||||
TagOption: &tag.Option{
|
||||
WithImmutableStatus: false,
|
||||
},
|
||||
WithLabel: true,
|
||||
WithLabel: true,
|
||||
WithAccessory: true,
|
||||
}
|
||||
tg := &tag.Tag{
|
||||
Tag: model_tag.Tag{
|
||||
@ -126,12 +134,24 @@ func (c *controllerTestSuite) TestAssembleArtifact() {
|
||||
c.labelMgr.On("ListByArtifact", mock.Anything, mock.Anything).Return([]*model.Label{
|
||||
lb,
|
||||
}, nil)
|
||||
acc := &basemodel.Default{
|
||||
Data: accessorymodel.AccessoryData{
|
||||
ID: 1,
|
||||
ArtifactID: 2,
|
||||
SubArtifactID: 1,
|
||||
Type: accessorymodel.TypeCosignSignature,
|
||||
},
|
||||
}
|
||||
c.accMgr.On("List", mock.Anything, mock.Anything).Return([]accessorymodel.Accessory{
|
||||
acc,
|
||||
}, nil)
|
||||
artifact := c.ctl.assembleArtifact(ctx, art, option)
|
||||
c.Require().NotNil(artifact)
|
||||
c.Equal(art.ID, artifact.ID)
|
||||
c.Equal(icon.DigestOfIconDefault, artifact.Icon)
|
||||
c.Contains(artifact.Tags, tg)
|
||||
c.Contains(artifact.Labels, lb)
|
||||
c.Contains(artifact.Accessories, acc)
|
||||
// TODO check other fields of option
|
||||
}
|
||||
|
||||
@ -249,7 +269,8 @@ func (c *controllerTestSuite) TestCount() {
|
||||
func (c *controllerTestSuite) TestList() {
|
||||
query := &q.Query{}
|
||||
option := &Option{
|
||||
WithTag: true,
|
||||
WithTag: true,
|
||||
WithAccessory: true,
|
||||
}
|
||||
c.artMgr.On("List", mock.Anything, mock.Anything).Return([]*artifact.Artifact{
|
||||
{
|
||||
@ -273,12 +294,14 @@ func (c *controllerTestSuite) TestList() {
|
||||
c.repoMgr.On("List", mock.Anything, mock.Anything).Return([]*repomodel.RepoRecord{
|
||||
{RepositoryID: 1, Name: "library/hello-world"},
|
||||
}, nil)
|
||||
c.accMgr.On("List", mock.Anything, mock.Anything).Return([]accessorymodel.Accessory{}, nil)
|
||||
artifacts, err := c.ctl.List(nil, query, option)
|
||||
c.Require().Nil(err)
|
||||
c.Require().Len(artifacts, 1)
|
||||
c.Equal(int64(1), artifacts[0].ID)
|
||||
c.Require().Len(artifacts[0].Tags, 1)
|
||||
c.Equal(int64(1), artifacts[0].Tags[0].ID)
|
||||
c.Equal(0, len(artifacts[0].Accessories))
|
||||
}
|
||||
|
||||
func (c *controllerTestSuite) TestGet() {
|
||||
@ -406,7 +429,8 @@ func (c *controllerTestSuite) TestGetByReference() {
|
||||
func (c *controllerTestSuite) TestDeleteDeeply() {
|
||||
// root artifact and doesn't exist
|
||||
c.artMgr.On("Get", mock.Anything, mock.Anything).Return(nil, errors.NotFoundError(nil))
|
||||
err := c.ctl.deleteDeeply(orm.NewContext(nil, &ormtesting.FakeOrmer{}), 1, true)
|
||||
c.accMgr.On("List", mock.Anything, mock.Anything).Return([]accessorymodel.Accessory{}, nil)
|
||||
err := c.ctl.deleteDeeply(orm.NewContext(nil, &ormtesting.FakeOrmer{}), 1, true, false)
|
||||
c.Require().NotNil(err)
|
||||
c.Assert().True(errors.IsErr(err, errors.NotFoundCode))
|
||||
|
||||
@ -415,7 +439,8 @@ func (c *controllerTestSuite) TestDeleteDeeply() {
|
||||
|
||||
// child artifact and doesn't exist
|
||||
c.artMgr.On("Get", mock.Anything, mock.Anything).Return(nil, errors.NotFoundError(nil))
|
||||
err = c.ctl.deleteDeeply(orm.NewContext(nil, &ormtesting.FakeOrmer{}), 1, false)
|
||||
c.accMgr.On("List", mock.Anything, mock.Anything).Return([]accessorymodel.Accessory{}, nil)
|
||||
err = c.ctl.deleteDeeply(orm.NewContext(nil, &ormtesting.FakeOrmer{}), 1, false, false)
|
||||
c.Require().Nil(err)
|
||||
|
||||
// reset the mock
|
||||
@ -433,7 +458,8 @@ func (c *controllerTestSuite) TestDeleteDeeply() {
|
||||
}, nil)
|
||||
c.repoMgr.On("Get", mock.Anything, mock.Anything).Return(&repomodel.RepoRecord{}, nil)
|
||||
c.artrashMgr.On("Create").Return(0, nil)
|
||||
err = c.ctl.deleteDeeply(orm.NewContext(nil, &ormtesting.FakeOrmer{}), 1, false)
|
||||
c.accMgr.On("List", mock.Anything, mock.Anything).Return([]accessorymodel.Accessory{}, nil)
|
||||
err = c.ctl.deleteDeeply(orm.NewContext(nil, &ormtesting.FakeOrmer{}), 1, false, false)
|
||||
c.Require().Nil(err)
|
||||
|
||||
// reset the mock
|
||||
@ -448,7 +474,8 @@ func (c *controllerTestSuite) TestDeleteDeeply() {
|
||||
ID: 1,
|
||||
},
|
||||
}, nil)
|
||||
err = c.ctl.deleteDeeply(orm.NewContext(nil, &ormtesting.FakeOrmer{}), 1, true)
|
||||
c.accMgr.On("List", mock.Anything, mock.Anything).Return([]accessorymodel.Accessory{}, nil)
|
||||
err = c.ctl.deleteDeeply(orm.NewContext(nil, &ormtesting.FakeOrmer{}), 1, true, false)
|
||||
c.Require().NotNil(err)
|
||||
|
||||
// reset the mock
|
||||
@ -463,8 +490,35 @@ func (c *controllerTestSuite) TestDeleteDeeply() {
|
||||
ID: 1,
|
||||
},
|
||||
}, nil)
|
||||
err = c.ctl.deleteDeeply(nil, 1, false)
|
||||
c.accMgr.On("List", mock.Anything, mock.Anything).Return([]accessorymodel.Accessory{}, nil)
|
||||
err = c.ctl.deleteDeeply(nil, 1, false, false)
|
||||
c.Require().Nil(err)
|
||||
|
||||
// reset the mock
|
||||
c.SetupTest()
|
||||
|
||||
// accessory contains tag
|
||||
c.artMgr.On("Get", mock.Anything, mock.Anything).Return(&artifact.Artifact{ID: 1}, nil)
|
||||
c.artMgr.On("Delete", mock.Anything, mock.Anything).Return(nil)
|
||||
c.tagCtl.On("List").Return([]*tag.Tag{
|
||||
{
|
||||
Tag: model_tag.Tag{
|
||||
ID: 1,
|
||||
},
|
||||
},
|
||||
}, nil)
|
||||
c.tagCtl.On("DeleteTags", mock.Anything, mock.Anything).Return(nil)
|
||||
c.labelMgr.On("RemoveAllFrom", mock.Anything, mock.Anything).Return(nil)
|
||||
c.artMgr.On("ListReferences", mock.Anything, mock.Anything).Return([]*artifact.Reference{}, nil)
|
||||
c.accMgr.On("List", mock.Anything, mock.Anything).Return([]accessorymodel.Accessory{}, nil)
|
||||
c.accMgr.On("DeleteAccessories", mock.Anything, mock.Anything).Return(nil)
|
||||
c.blobMgr.On("List", mock.Anything, mock.Anything).Return(nil, nil)
|
||||
c.blobMgr.On("CleanupAssociationsForProject", mock.Anything, mock.Anything, mock.Anything).Return(nil)
|
||||
c.repoMgr.On("Get", mock.Anything, mock.Anything).Return(&repomodel.RepoRecord{}, nil)
|
||||
c.artrashMgr.On("Create").Return(0, nil)
|
||||
err = c.ctl.deleteDeeply(orm.NewContext(nil, &ormtesting.FakeOrmer{}), 1, true, true)
|
||||
c.Require().Nil(err)
|
||||
|
||||
}
|
||||
|
||||
func (c *controllerTestSuite) TestCopy() {
|
||||
@ -554,6 +608,7 @@ func (c *controllerTestSuite) TestWalk() {
|
||||
{Digest: "d1", ManifestMediaType: v1.MediaTypeImageManifest},
|
||||
{Digest: "d2", ManifestMediaType: v1.MediaTypeImageManifest},
|
||||
}, nil)
|
||||
c.accMgr.On("List", mock.Anything, mock.Anything).Return([]accessorymodel.Accessory{}, nil)
|
||||
|
||||
{
|
||||
root := &Artifact{}
|
||||
|
@ -16,10 +16,13 @@ package artifact
|
||||
|
||||
import (
|
||||
"context"
|
||||
accessorymodel "github.com/goharbor/harbor/src/pkg/accessory/model"
|
||||
"testing"
|
||||
|
||||
"github.com/goharbor/harbor/src/lib/q"
|
||||
"github.com/goharbor/harbor/src/pkg/artifact"
|
||||
"github.com/goharbor/harbor/src/testing/pkg/accessory"
|
||||
accessorytesting "github.com/goharbor/harbor/src/testing/pkg/accessory"
|
||||
artifacttesting "github.com/goharbor/harbor/src/testing/pkg/artifact"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/suite"
|
||||
@ -29,6 +32,7 @@ type IteratorTestSuite struct {
|
||||
suite.Suite
|
||||
|
||||
artMgr *artifacttesting.Manager
|
||||
accMgr *accessory.Manager
|
||||
|
||||
ctl *controller
|
||||
originalCtl Controller
|
||||
@ -36,9 +40,13 @@ type IteratorTestSuite struct {
|
||||
|
||||
func (suite *IteratorTestSuite) SetupSuite() {
|
||||
suite.artMgr = &artifacttesting.Manager{}
|
||||
suite.accMgr = &accessorytesting.Manager{}
|
||||
|
||||
suite.originalCtl = Ctl
|
||||
suite.ctl = &controller{artMgr: suite.artMgr}
|
||||
suite.ctl = &controller{
|
||||
artMgr: suite.artMgr,
|
||||
accessoryMgr: suite.accMgr,
|
||||
}
|
||||
Ctl = suite.ctl
|
||||
}
|
||||
|
||||
@ -47,6 +55,7 @@ func (suite *IteratorTestSuite) TeardownSuite() {
|
||||
}
|
||||
|
||||
func (suite *IteratorTestSuite) TestIterator() {
|
||||
suite.accMgr.On("List", mock.Anything, mock.Anything).Return([]accessorymodel.Accessory{}, nil)
|
||||
q1 := &q.Query{PageNumber: 1, PageSize: 5, Keywords: map[string]interface{}{}}
|
||||
suite.artMgr.On("List", mock.Anything, q1).Return([]*artifact.Artifact{
|
||||
{ID: 1},
|
||||
|
@ -19,6 +19,7 @@ import (
|
||||
"github.com/goharbor/harbor/src/common/utils"
|
||||
"github.com/goharbor/harbor/src/controller/tag"
|
||||
"github.com/goharbor/harbor/src/lib/encode/repository"
|
||||
accessoryModel "github.com/goharbor/harbor/src/pkg/accessory/model"
|
||||
"github.com/goharbor/harbor/src/pkg/artifact"
|
||||
"github.com/goharbor/harbor/src/pkg/label/model"
|
||||
)
|
||||
@ -26,9 +27,10 @@ import (
|
||||
// Artifact is the overall view of artifact
|
||||
type Artifact struct {
|
||||
artifact.Artifact
|
||||
Tags []*tag.Tag `json:"tags"` // the list of tags that attached to the artifact
|
||||
AdditionLinks map[string]*AdditionLink `json:"addition_links"` // the resource link for build history(image), values.yaml(chart), dependency(chart), etc
|
||||
Labels []*model.Label `json:"labels"`
|
||||
Tags []*tag.Tag `json:"tags"` // the list of tags that attached to the artifact
|
||||
AdditionLinks map[string]*AdditionLink `json:"addition_links"` // the resource link for build history(image), values.yaml(chart), dependency(chart), etc
|
||||
Labels []*model.Label `json:"labels"`
|
||||
Accessories []accessoryModel.Accessory `json:"accessories"`
|
||||
}
|
||||
|
||||
// SetAdditionLink set a addition link
|
||||
@ -53,7 +55,8 @@ type AdditionLink struct {
|
||||
|
||||
// Option is used to specify the properties returned when listing/getting artifacts
|
||||
type Option struct {
|
||||
WithTag bool
|
||||
TagOption *tag.Option // only works when WithTag is set to true
|
||||
WithLabel bool
|
||||
WithTag bool
|
||||
TagOption *tag.Option // only works when WithTag is set to true
|
||||
WithLabel bool
|
||||
WithAccessory bool
|
||||
}
|
||||
|
@ -33,8 +33,8 @@ type DAO interface {
|
||||
Create(ctx context.Context, accessory *Accessory) (id int64, err error)
|
||||
// Delete the accessory specified by ID
|
||||
Delete(ctx context.Context, id int64) (err error)
|
||||
// DeleteOfArtifact deletes all accessory attached to the artifact
|
||||
DeleteOfArtifact(ctx context.Context, subArtifactID int64) (err error)
|
||||
// DeleteAccessories deletes accessories by query
|
||||
DeleteAccessories(ctx context.Context, query *q.Query) (int64, error)
|
||||
}
|
||||
|
||||
// New returns an instance of the default DAO
|
||||
@ -116,15 +116,10 @@ func (d *dao) Delete(ctx context.Context, id int64) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *dao) DeleteOfArtifact(ctx context.Context, subArtifactID int64) error {
|
||||
qs, err := orm.QuerySetter(ctx, &Accessory{}, &q.Query{
|
||||
Keywords: map[string]interface{}{
|
||||
"SubjectArtifactID": subArtifactID,
|
||||
},
|
||||
})
|
||||
func (d *dao) DeleteAccessories(ctx context.Context, query *q.Query) (int64, error) {
|
||||
qs, err := orm.QuerySetter(ctx, &Accessory{}, query)
|
||||
if err != nil {
|
||||
return err
|
||||
return 0, err
|
||||
}
|
||||
_, err = qs.Delete()
|
||||
return err
|
||||
return qs.Delete()
|
||||
}
|
||||
|
@ -246,7 +246,11 @@ func (d *daoTestSuite) TestDeleteOfArtifact() {
|
||||
d.Require().Nil(err)
|
||||
d.Require().Len(accs, 2)
|
||||
|
||||
err = d.dao.DeleteOfArtifact(d.ctx, subArtID)
|
||||
_, err = d.dao.DeleteAccessories(d.ctx, &q.Query{
|
||||
Keywords: map[string]interface{}{
|
||||
"SubjectArtifactID": subArtID,
|
||||
},
|
||||
})
|
||||
d.Require().Nil(err)
|
||||
|
||||
accs, err = d.dao.List(d.ctx, &q.Query{
|
||||
|
@ -42,8 +42,8 @@ type Manager interface {
|
||||
Create(ctx context.Context, accessory model.AccessoryData) (id int64, err error)
|
||||
// Delete the tag specified by ID
|
||||
Delete(ctx context.Context, id int64) (err error)
|
||||
// DeleteOfArtifact deletes all tags attached to the artifact
|
||||
DeleteOfArtifact(ctx context.Context, artifactID int64) (err error)
|
||||
// DeleteAccessories deletes accessories according to the query
|
||||
DeleteAccessories(ctx context.Context, q *q.Query) (err error)
|
||||
}
|
||||
|
||||
// NewManager returns an instance of the default manager
|
||||
@ -116,6 +116,7 @@ func (m *manager) Delete(ctx context.Context, id int64) error {
|
||||
return m.dao.Delete(ctx, id)
|
||||
}
|
||||
|
||||
func (m *manager) DeleteOfArtifact(ctx context.Context, artifactID int64) error {
|
||||
return m.dao.DeleteOfArtifact(ctx, artifactID)
|
||||
func (m *manager) DeleteAccessories(ctx context.Context, q *q.Query) error {
|
||||
_, err := m.dao.DeleteAccessories(ctx, q)
|
||||
return err
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
package accessory
|
||||
|
||||
import (
|
||||
"github.com/goharbor/harbor/src/lib/q"
|
||||
"github.com/goharbor/harbor/src/pkg/accessory/dao"
|
||||
"github.com/goharbor/harbor/src/pkg/accessory/model"
|
||||
"github.com/goharbor/harbor/src/testing/mock"
|
||||
@ -90,8 +91,8 @@ func (m *managerTestSuite) TestCount() {
|
||||
}
|
||||
|
||||
func (m *managerTestSuite) TestDeleteOfArtifact() {
|
||||
mock.OnAnything(m.dao, "DeleteOfArtifact").Return(nil)
|
||||
err := m.mgr.DeleteOfArtifact(nil, 1)
|
||||
mock.OnAnything(m.dao, "DeleteAccessories").Return(int64(1), nil)
|
||||
err := m.mgr.DeleteAccessories(nil, q.New(q.KeyWords{"ArtifactID": 1}))
|
||||
m.Require().Nil(err)
|
||||
m.dao.AssertExpectations(m.T())
|
||||
}
|
||||
|
@ -76,6 +76,8 @@ type AccessoryData struct {
|
||||
type Accessory interface {
|
||||
RefProvider
|
||||
RefIdentifier
|
||||
// Define whether shows in the artifact list response.
|
||||
Display() bool
|
||||
GetData() AccessoryData
|
||||
}
|
||||
|
||||
|
@ -40,6 +40,11 @@ func (a *Default) IsHard() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Display ...
|
||||
func (a *Default) Display() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// GetData ...
|
||||
func (a *Default) GetData() model.AccessoryData {
|
||||
return a.Data
|
||||
|
@ -11,10 +11,12 @@ type BaseTestSuite struct {
|
||||
htesting.Suite
|
||||
accessory model.Accessory
|
||||
digest string
|
||||
subDigest string
|
||||
}
|
||||
|
||||
func (suite *BaseTestSuite) SetupSuite() {
|
||||
suite.digest = suite.DigestString()
|
||||
suite.subDigest = suite.DigestString()
|
||||
suite.accessory, _ = model.New(model.TypeNone,
|
||||
model.AccessoryData{
|
||||
ArtifactID: 1,
|
||||
@ -60,6 +62,10 @@ func (suite *BaseTestSuite) TestIsHard() {
|
||||
suite.False(suite.accessory.IsHard())
|
||||
}
|
||||
|
||||
func (suite *BaseTestSuite) TestDisplay() {
|
||||
suite.False(suite.accessory.Display())
|
||||
}
|
||||
|
||||
func TestCacheTestSuite(t *testing.T) {
|
||||
suite.Run(t, new(BaseTestSuite))
|
||||
}
|
||||
|
@ -60,6 +60,10 @@ func (suite *CosignTestSuite) TestIsHard() {
|
||||
suite.True(suite.accessory.IsHard())
|
||||
}
|
||||
|
||||
func (suite *CosignTestSuite) TestDisplay() {
|
||||
suite.False(suite.accessory.Display())
|
||||
}
|
||||
|
||||
func TestCacheTestSuite(t *testing.T) {
|
||||
suite.Run(t, new(CosignTestSuite))
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ import (
|
||||
"github.com/goharbor/harbor/src/controller/tag"
|
||||
"github.com/goharbor/harbor/src/lib"
|
||||
"github.com/goharbor/harbor/src/lib/errors"
|
||||
"github.com/goharbor/harbor/src/pkg/accessory"
|
||||
"github.com/goharbor/harbor/src/pkg/notification"
|
||||
"github.com/goharbor/harbor/src/pkg/scan/report"
|
||||
"github.com/goharbor/harbor/src/server/v2.0/handler/assembler"
|
||||
@ -46,6 +47,7 @@ import (
|
||||
|
||||
func newArtifactAPI() *artifactAPI {
|
||||
return &artifactAPI{
|
||||
accMgr: accessory.Mgr,
|
||||
artCtl: artifact.Ctl,
|
||||
proCtl: project.Ctl,
|
||||
repoCtl: repository.Ctl,
|
||||
@ -56,6 +58,7 @@ func newArtifactAPI() *artifactAPI {
|
||||
|
||||
type artifactAPI struct {
|
||||
BaseAPI
|
||||
accMgr accessory.Manager
|
||||
artCtl artifact.Controller
|
||||
proCtl project.Controller
|
||||
repoCtl repository.Controller
|
||||
@ -85,7 +88,7 @@ func (a *artifactAPI) ListArtifacts(ctx context.Context, params operation.ListAr
|
||||
|
||||
// set option
|
||||
option := option(params.WithTag, params.WithImmutableStatus,
|
||||
params.WithLabel, params.WithSignature)
|
||||
params.WithLabel, params.WithSignature, params.WithAccessory)
|
||||
|
||||
// get the total count of artifacts
|
||||
total, err := a.artCtl.Count(ctx, query)
|
||||
@ -119,7 +122,7 @@ func (a *artifactAPI) GetArtifact(ctx context.Context, params operation.GetArtif
|
||||
}
|
||||
// set option
|
||||
option := option(params.WithTag, params.WithImmutableStatus,
|
||||
params.WithLabel, params.WithSignature)
|
||||
params.WithLabel, params.WithSignature, params.WithAccessory)
|
||||
|
||||
// get the artifact
|
||||
artifact, err := a.artCtl.GetByReference(ctx, fmt.Sprintf("%s/%s", params.ProjectName, params.RepositoryName), params.Reference, option)
|
||||
@ -333,6 +336,39 @@ func (a *artifactAPI) ListTags(ctx context.Context, params operation.ListTagsPar
|
||||
WithPayload(ts)
|
||||
}
|
||||
|
||||
func (a *artifactAPI) ListAccessories(ctx context.Context, params operation.ListAccessoriesParams) middleware.Responder {
|
||||
if err := a.RequireProjectAccess(ctx, params.ProjectName, rbac.ActionList, rbac.ResourceAccessory); err != nil {
|
||||
return a.SendError(ctx, err)
|
||||
}
|
||||
// set query
|
||||
query, err := a.BuildQuery(ctx, params.Q, params.Sort, params.Page, params.PageSize)
|
||||
if err != nil {
|
||||
return a.SendError(ctx, err)
|
||||
}
|
||||
|
||||
artifact, err := a.artCtl.GetByReference(ctx, fmt.Sprintf("%s/%s", params.ProjectName, params.RepositoryName), params.Reference, nil)
|
||||
if err != nil {
|
||||
return a.SendError(ctx, err)
|
||||
}
|
||||
query.Keywords["SubjectArtifactID"] = artifact.ID
|
||||
|
||||
// list accessories according to the query
|
||||
accs, err := a.accMgr.List(ctx, query)
|
||||
if err != nil {
|
||||
return a.SendError(ctx, err)
|
||||
}
|
||||
total := len(accs)
|
||||
|
||||
var res []*models.Accessory
|
||||
for _, acc := range accs {
|
||||
res = append(res, model.NewAccessory(acc.GetData()).ToSwagger())
|
||||
}
|
||||
return operation.NewListAccessoriesOK().
|
||||
WithXTotalCount(int64(total)).
|
||||
WithLink(a.Links(ctx, params.HTTPRequest.URL, int64(total), query.PageNumber, query.PageSize).String()).
|
||||
WithPayload(res)
|
||||
}
|
||||
|
||||
func (a *artifactAPI) GetVulnerabilitiesAddition(ctx context.Context, params operation.GetVulnerabilitiesAdditionParams) middleware.Responder {
|
||||
if err := a.RequireProjectAccess(ctx, params.ProjectName, rbac.ActionRead, rbac.ResourceArtifactAddition); err != nil {
|
||||
return a.SendError(ctx, err)
|
||||
@ -424,16 +460,21 @@ func (a *artifactAPI) RemoveLabel(ctx context.Context, params operation.RemoveLa
|
||||
return operation.NewRemoveLabelOK()
|
||||
}
|
||||
|
||||
func option(withTag, withImmutableStatus, withLabel, withSignature *bool) *artifact.Option {
|
||||
func option(withTag, withImmutableStatus, withLabel, withSignature, withAccessory *bool) *artifact.Option {
|
||||
option := &artifact.Option{
|
||||
WithTag: true, // return the tag by default
|
||||
WithLabel: lib.BoolValue(withLabel),
|
||||
WithTag: true, // return the tag by default
|
||||
WithLabel: lib.BoolValue(withLabel),
|
||||
WithAccessory: true, // return the accessory by default
|
||||
}
|
||||
|
||||
if withTag != nil {
|
||||
option.WithTag = *(withTag)
|
||||
}
|
||||
|
||||
if withAccessory != nil {
|
||||
option.WithAccessory = *(withAccessory)
|
||||
}
|
||||
|
||||
if option.WithTag {
|
||||
option.TagOption = &tag.Option{
|
||||
WithImmutableStatus: lib.BoolValue(withImmutableStatus),
|
||||
|
31
src/server/v2.0/handler/model/accessory.go
Normal file
31
src/server/v2.0/handler/model/accessory.go
Normal file
@ -0,0 +1,31 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/goharbor/harbor/src/pkg/accessory/model"
|
||||
"github.com/goharbor/harbor/src/server/v2.0/models"
|
||||
)
|
||||
|
||||
// Accessory model
|
||||
type Accessory struct {
|
||||
model.AccessoryData
|
||||
}
|
||||
|
||||
// ToSwagger converts the label to the swagger model
|
||||
func (a *Accessory) ToSwagger() *models.Accessory {
|
||||
return &models.Accessory{
|
||||
ID: a.ID,
|
||||
ArtifactID: a.ArtifactID,
|
||||
SubjectArtifactID: a.SubArtifactID,
|
||||
Size: a.Size,
|
||||
Digest: a.Digest,
|
||||
Type: a.Type,
|
||||
Icon: "",
|
||||
CreationTime: strfmt.DateTime(a.CreatTime),
|
||||
}
|
||||
}
|
||||
|
||||
// NewAccessory ...
|
||||
func NewAccessory(a model.AccessoryData) *Accessory {
|
||||
return &Accessory{AccessoryData: a}
|
||||
}
|
@ -51,6 +51,9 @@ func (a *Artifact) ToSwagger() *models.Artifact {
|
||||
for _, reference := range a.References {
|
||||
art.References = append(art.References, NewReference(reference).ToSwagger())
|
||||
}
|
||||
for _, acc := range a.Accessories {
|
||||
art.Accessories = append(art.Accessories, NewAccessory(acc.GetData()).ToSwagger())
|
||||
}
|
||||
for _, tag := range a.Tags {
|
||||
art.Tags = append(art.Tags, NewTag(tag).ToSwagger())
|
||||
}
|
||||
|
@ -72,18 +72,25 @@ func (_m *DAO) Delete(ctx context.Context, id int64) error {
|
||||
return r0
|
||||
}
|
||||
|
||||
// DeleteOfArtifact provides a mock function with given fields: ctx, subArtifactID
|
||||
func (_m *DAO) DeleteOfArtifact(ctx context.Context, subArtifactID int64) error {
|
||||
ret := _m.Called(ctx, subArtifactID)
|
||||
// DeleteAccessories provides a mock function with given fields: ctx, query
|
||||
func (_m *DAO) DeleteAccessories(ctx context.Context, query *q.Query) (int64, error) {
|
||||
ret := _m.Called(ctx, query)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, int64) error); ok {
|
||||
r0 = rf(ctx, subArtifactID)
|
||||
var r0 int64
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *q.Query) int64); ok {
|
||||
r0 = rf(ctx, query)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
r0 = ret.Get(0).(int64)
|
||||
}
|
||||
|
||||
return r0
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *q.Query) error); ok {
|
||||
r1 = rf(ctx, query)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Get provides a mock function with given fields: ctx, id
|
||||
|
133
src/testing/pkg/accessory/manager.go
Normal file
133
src/testing/pkg/accessory/manager.go
Normal file
@ -0,0 +1,133 @@
|
||||
// Code generated by mockery v2.1.0. DO NOT EDIT.
|
||||
|
||||
package accessory
|
||||
|
||||
import (
|
||||
context "context"
|
||||
|
||||
model "github.com/goharbor/harbor/src/pkg/accessory/model"
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
|
||||
q "github.com/goharbor/harbor/src/lib/q"
|
||||
)
|
||||
|
||||
// Manager is an autogenerated mock type for the Manager type
|
||||
type Manager struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// Count provides a mock function with given fields: ctx, query
|
||||
func (_m *Manager) Count(ctx context.Context, query *q.Query) (int64, error) {
|
||||
ret := _m.Called(ctx, query)
|
||||
|
||||
var r0 int64
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *q.Query) int64); ok {
|
||||
r0 = rf(ctx, query)
|
||||
} else {
|
||||
r0 = ret.Get(0).(int64)
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *q.Query) error); ok {
|
||||
r1 = rf(ctx, query)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Create provides a mock function with given fields: ctx, _a1
|
||||
func (_m *Manager) Create(ctx context.Context, _a1 model.AccessoryData) (int64, error) {
|
||||
ret := _m.Called(ctx, _a1)
|
||||
|
||||
var r0 int64
|
||||
if rf, ok := ret.Get(0).(func(context.Context, model.AccessoryData) int64); ok {
|
||||
r0 = rf(ctx, _a1)
|
||||
} else {
|
||||
r0 = ret.Get(0).(int64)
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, model.AccessoryData) error); ok {
|
||||
r1 = rf(ctx, _a1)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Delete provides a mock function with given fields: ctx, id
|
||||
func (_m *Manager) Delete(ctx context.Context, id int64) error {
|
||||
ret := _m.Called(ctx, id)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, int64) error); ok {
|
||||
r0 = rf(ctx, id)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// DeleteAccessories provides a mock function with given fields: ctx, _a1
|
||||
func (_m *Manager) DeleteAccessories(ctx context.Context, _a1 *q.Query) error {
|
||||
ret := _m.Called(ctx, _a1)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *q.Query) error); ok {
|
||||
r0 = rf(ctx, _a1)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// Get provides a mock function with given fields: ctx, id
|
||||
func (_m *Manager) Get(ctx context.Context, id int64) (model.Accessory, error) {
|
||||
ret := _m.Called(ctx, id)
|
||||
|
||||
var r0 model.Accessory
|
||||
if rf, ok := ret.Get(0).(func(context.Context, int64) model.Accessory); ok {
|
||||
r0 = rf(ctx, id)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(model.Accessory)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, int64) error); ok {
|
||||
r1 = rf(ctx, id)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// List provides a mock function with given fields: ctx, query
|
||||
func (_m *Manager) List(ctx context.Context, query *q.Query) ([]model.Accessory, error) {
|
||||
ret := _m.Called(ctx, query)
|
||||
|
||||
var r0 []model.Accessory
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *q.Query) []model.Accessory); ok {
|
||||
r0 = rf(ctx, query)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]model.Accessory)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *q.Query) error); ok {
|
||||
r1 = rf(ctx, query)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
@ -12,6 +12,20 @@ type Accessory struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// Display provides a mock function with given fields:
|
||||
func (_m *Accessory) Display() bool {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 bool
|
||||
if rf, ok := ret.Get(0).(func() bool); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
r0 = ret.Get(0).(bool)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// GetData provides a mock function with given fields:
|
||||
func (_m *Accessory) GetData() model.AccessoryData {
|
||||
ret := _m.Called()
|
||||
|
@ -55,3 +55,4 @@ package pkg
|
||||
//go:generate mockery --case snake --dir ../../pkg/joblog/dao --name DAO --output ./joblog/dao --outpkg dao
|
||||
//go:generate mockery --case snake --dir ../../pkg/accessory/model --name Accessory --output ./accessory/model --outpkg model
|
||||
//go:generate mockery --case snake --dir ../../pkg/accessory/dao --name DAO --output ./accessory/dao --outpkg dao
|
||||
//go:generate mockery --case snake --dir ../../pkg/accessory --name Manager --output ./accessory --outpkg accessory
|
||||
|
Loading…
Reference in New Issue
Block a user