Skip to content

Commit

Permalink
add list artifacts of project
Browse files Browse the repository at this point in the history
Signed-off-by: wang yan <wangyan@vmware.com>

fix

fix
  • Loading branch information
wy65701436 committed Jul 31, 2024
1 parent 14f98c0 commit 16196b0
Show file tree
Hide file tree
Showing 9 changed files with 268 additions and 10 deletions.
88 changes: 88 additions & 0 deletions api/v2.0/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1548,6 +1548,88 @@ paths:
$ref: '#/responses/409'
'500':
$ref: '#/responses/500'
/projects/{project_name_or_id}/artifacts:
get:
summary: List artifacts
description: List artifacts of the specified project
tags:
- project
operationId: listArtifactsOfProject
parameters:
- $ref: '#/parameters/requestId'
- $ref: '#/parameters/isResourceName'
- $ref: '#/parameters/projectNameOrId'
- $ref: '#/parameters/query'
- $ref: '#/parameters/sort'
- $ref: '#/parameters/page'
- $ref: '#/parameters/pageSize'
- $ref: '#/parameters/acceptVulnerabilities'
- name: with_tag
in: query
description: Specify whether the tags are included inside the returning artifacts
type: boolean
required: false
default: true
- name: with_label
in: query
description: Specify whether the labels are included inside the returning artifacts
type: boolean
required: false
default: false
- name: with_scan_overview
in: query
description: Specify whether the scan overview is included inside the returning artifacts
type: boolean
required: false
default: false
- name: with_sbom_overview
in: query
description: Specify whether the SBOM overview is included in returning artifacts, when this option is true, the SBOM overview will be included in the response
type: boolean
required: false
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_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
- name: latest_in_repository
in: query
description: Specify whether only the latest are included inside the returning artifacts
type: boolean
required: false
default: false
responses:
'200':
description: Success
headers:
X-Total-Count:
description: The total count of artifacts
type: integer
Link:
description: Link refers to the previous page and next page
type: string
schema:
type: array
items:
$ref: '#/definitions/Artifact'
'400':
$ref: '#/responses/400'
'401':
$ref: '#/responses/401'
'403':
$ref: '#/responses/403'
'404':
$ref: '#/responses/404'
'500':
$ref: '#/responses/500'
'/projects/{project_name_or_id}/scanner':
get:
summary: Get project level scanner
Expand Down Expand Up @@ -6586,6 +6668,9 @@ definitions:
manifest_media_type:
type: string
description: The manifest media type of the artifact
artifact_type:
type: string
description: The artifact_type in the manifest of the artifact
project_id:
type: integer
format: int64
Expand All @@ -6594,6 +6679,9 @@ definitions:
type: integer
format: int64
description: The ID of the repository that the artifact belongs to
repository_name:
type: string
description: The name of the repository that the artifact belongs to
digest:
type: string
description: The digest of the artifact
Expand Down
15 changes: 15 additions & 0 deletions src/controller/artifact/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ type Controller interface {
Walk(ctx context.Context, root *Artifact, walkFn func(*Artifact) error, option *Option) error
// HasUnscannableLayer check artifact with digest if has unscannable layer
HasUnscannableLayer(ctx context.Context, dgst string) (bool, error)
// ListWithLatest list the artifacts when the latest_in_repository in the query was set
ListWithLatest(ctx context.Context, query *q.Query, option *Option) (artifacts []*Artifact, err error)
}

// NewController creates an instance of the default artifact controller
Expand Down Expand Up @@ -782,3 +784,16 @@ func (c *controller) HasUnscannableLayer(ctx context.Context, dgst string) (bool
}
return false, nil
}

// ListWithLatest ...
func (c *controller) ListWithLatest(ctx context.Context, query *q.Query, option *Option) (artifacts []*Artifact, err error) {
arts, err := c.artMgr.ListWithLatest(ctx, query)
if err != nil {
return nil, err
}
var res []*Artifact
for _, art := range arts {
res = append(res, c.assembleArtifact(ctx, art, option))
}
return res, nil
}
9 changes: 5 additions & 4 deletions src/controller/artifact/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,9 @@ 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
WithAccessory bool
WithTag bool
TagOption *tag.Option // only works when WithTag is set to true
WithLabel bool
WithAccessory bool
LatestInRepository bool
}
49 changes: 49 additions & 0 deletions src/pkg/artifact/dao/dao.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ type DAO interface {
DeleteReference(ctx context.Context, id int64) (err error)
// DeleteReferences deletes the references referenced by the artifact specified by parent ID
DeleteReferences(ctx context.Context, parentID int64) (err error)
// ListWithLatest ...
ListWithLatest(ctx context.Context, query *q.Query) (artifacts []*Artifact, err error)
}

const (
Expand Down Expand Up @@ -282,6 +284,53 @@ func (d *dao) DeleteReferences(ctx context.Context, parentID int64) error {
return err
}

func (d *dao) ListWithLatest(ctx context.Context, query *q.Query) (artifacts []*Artifact, err error) {
ormer, err := orm.FromContext(ctx)
if err != nil {
return nil, err
}

sql := `SELECT a.*
FROM artifact a
JOIN (
SELECT repository_name, MAX(push_time) AS latest_push_time
FROM artifact
WHERE project_id = ? and %s = ?
GROUP BY repository_name
) latest ON a.repository_name = latest.repository_name AND a.push_time = latest.latest_push_time`

queryParam := make([]interface{}, 0)
var ok bool
var pid interface{}
if pid, ok = query.Keywords["ProjectID"]; !ok {
return nil, errors.New(nil).WithCode(errors.BadRequestCode).
WithMessage(`the value of "ProjectID" must be set`)
}
queryParam = append(queryParam, pid)

var attributionValue interface{}
if attributionValue, ok = query.Keywords["media_type"]; ok {
sql = fmt.Sprintf(sql, "media_type")
} else if attributionValue, ok = query.Keywords["artifact_type"]; ok {
sql = fmt.Sprintf(sql, "artifact_type")
}

if attributionValue == "" {
return nil, errors.New(nil).WithCode(errors.BadRequestCode).
WithMessage(`the value of "media_type" or "artifact_type" must be set`)
}
queryParam = append(queryParam, attributionValue)

sql, queryParam = orm.PaginationOnRawSQL(query, sql, queryParam)
arts := []*Artifact{}
_, err = ormer.Raw(sql, queryParam...).QueryRows(&arts)
if err != nil {
return nil, err
}

return arts, nil
}

func querySetter(ctx context.Context, query *q.Query) (beegoorm.QuerySeter, error) {
qs, err := orm.QuerySetter(ctx, &Artifact{}, query)
if err != nil {
Expand Down
18 changes: 18 additions & 0 deletions src/pkg/artifact/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ type Manager interface {
ListReferences(ctx context.Context, query *q.Query) (references []*Reference, err error)
// DeleteReference specified by ID
DeleteReference(ctx context.Context, id int64) (err error)
// ListWithLatest list the artifacts when the latest_in_repository in the query was set
ListWithLatest(ctx context.Context, query *q.Query) (artifacts []*Artifact, err error)
}

// NewManager returns an instance of the default manager
Expand Down Expand Up @@ -147,6 +149,22 @@ func (m *manager) DeleteReference(ctx context.Context, id int64) error {
return m.dao.DeleteReference(ctx, id)
}

func (m *manager) ListWithLatest(ctx context.Context, query *q.Query) ([]*Artifact, error) {
arts, err := m.dao.ListWithLatest(ctx, query)
if err != nil {
return nil, err
}
var artifacts []*Artifact
for _, art := range arts {
artifact, err := m.assemble(ctx, art)
if err != nil {
return nil, err
}
artifacts = append(artifacts, artifact)
}
return artifacts, nil
}

// assemble the artifact with references populated
func (m *manager) assemble(ctx context.Context, art *dao.Artifact) (*Artifact, error) {
artifact := &Artifact{}
Expand Down
4 changes: 4 additions & 0 deletions src/pkg/cached/artifact/redis/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ func (m *Manager) List(ctx context.Context, query *q.Query) ([]*artifact.Artifac
return m.delegator.List(ctx, query)
}

func (m *Manager) ListWithLatest(ctx context.Context, query *q.Query) ([]*artifact.Artifact, error) {
return m.delegator.ListWithLatest(ctx, query)
}

func (m *Manager) Create(ctx context.Context, artifact *artifact.Artifact) (int64, error) {
return m.delegator.Create(ctx, artifact)
}
Expand Down
13 changes: 7 additions & 6 deletions src/server/v2.0/handler/artifact.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ func (a *artifactAPI) ListArtifacts(ctx context.Context, params operation.ListAr

// set option
option := option(params.WithTag, params.WithImmutableStatus,
params.WithLabel, params.WithAccessory)
params.WithLabel, params.WithAccessory, nil)

// get the total count of artifacts
total, err := a.artCtl.Count(ctx, query)
Expand Down Expand Up @@ -129,7 +129,7 @@ func (a *artifactAPI) GetArtifact(ctx context.Context, params operation.GetArtif
}
// set option
option := option(params.WithTag, params.WithImmutableStatus,
params.WithLabel, params.WithAccessory)
params.WithLabel, params.WithAccessory, nil)

// get the artifact
artifact, err := a.artCtl.GetByReference(ctx, fmt.Sprintf("%s/%s", params.ProjectName, params.RepositoryName), params.Reference, option)
Expand Down Expand Up @@ -501,11 +501,12 @@ func (a *artifactAPI) RequireLabelInProject(ctx context.Context, projectID, labe
return nil
}

func option(withTag, withImmutableStatus, withLabel, withAccessory *bool) *artifact.Option {
func option(withTag, withImmutableStatus, withLabel, withAccessory, latestInRepository *bool) *artifact.Option {
option := &artifact.Option{
WithTag: true, // return the tag by default
WithLabel: lib.BoolValue(withLabel),
WithAccessory: true, // return the accessory by default
WithTag: true, // return the tag by default
WithLabel: lib.BoolValue(withLabel),
WithAccessory: true, // return the accessory by default
LatestInRepository: lib.BoolValue(latestInRepository),
}

if withTag != nil {
Expand Down
2 changes: 2 additions & 0 deletions src/server/v2.0/handler/model/artifact.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ func (a *Artifact) ToSwagger() *models.Artifact {
PushTime: strfmt.DateTime(a.PushTime),
ExtraAttrs: a.ExtraAttrs,
Annotations: a.Annotations,
ArtifactType: a.ArtifactType,
RepositoryName: a.RepositoryName,
}

for _, reference := range a.References {
Expand Down
Loading

0 comments on commit 16196b0

Please sign in to comment.