Add API to list tags under the specific repository (#11336)

Add API to list tags under the specific repository

Signed-off-by: Wenkai Yin <yinw@vmware.com>
This commit is contained in:
Wenkai Yin(尹文开) 2020-03-29 12:19:54 +08:00 committed by GitHub
parent d82dfaf11e
commit 98759642b7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 175 additions and 126 deletions

View File

@ -529,6 +529,56 @@ paths:
$ref: '#/responses/409'
'500':
$ref: '#/responses/500'
/projects/{project_name}/repositories/{repository_name}/tags:
get:
summary: List tags
description: List tags under the specific project and repository.
tags:
- tag
operationId: listTags
parameters:
- $ref: '#/parameters/requestId'
- $ref: '#/parameters/projectName'
- $ref: '#/parameters/repositoryName'
- $ref: '#/parameters/query'
- $ref: '#/parameters/page'
- $ref: '#/parameters/pageSize'
- name: with_signature
in: query
description: Specify whether the signature is included inside the returning tags
type: boolean
required: false
default: false
- name: with_immutable_status
in: query
description: Specify whether the immutable status is included inside the returning tags
type: boolean
required: false
default: false
responses:
'200':
description: Success
headers:
X-Total-Count:
description: The total count of tags
type: integer
Link:
description: Link refers to the previous page and next page
type: string
schema:
type: array
items:
$ref: '#/definitions/Tag'
'400':
$ref: '#/responses/400'
'401':
$ref: '#/responses/401'
'403':
$ref: '#/responses/403'
'404':
$ref: '#/responses/404'
'500':
$ref: '#/responses/500'
/audit-logs:
get:
summary: Get recent logs of the projects which the user is a member of

View File

@ -34,37 +34,26 @@ const (
// const resource variables
const (
ResourceAll = Resource("*") // resource match any other resources
ResourceConfiguration = Resource("configuration") // project configuration compatible for portal only
ResourceHelmChart = Resource("helm-chart")
ResourceHelmChartVersion = Resource("helm-chart-version")
ResourceHelmChartVersionLabel = Resource("helm-chart-version-label")
ResourceLabel = Resource("label")
ResourceLabelResource = Resource("label-resource")
ResourceLog = Resource("log")
ResourceMember = Resource("member")
ResourceMetadata = Resource("metadata")
ResourceQuota = Resource("quota")
ResourceReplication = Resource("replication") // TODO remove
ResourceReplicationJob = Resource("replication-job") // TODO remove
ResourceReplicationExecution = Resource("replication-execution")
ResourceReplicationTask = Resource("replication-task")
ResourceRepository = Resource("repository")
ResourceTagRetention = Resource("tag-retention")
ResourceImmutableTag = Resource("immutable-tag")
ResourceRepositoryLabel = Resource("repository-label") // TODO remove
ResourceRepositoryTag = Resource("repository-tag") // TODO remove
ResourceRepositoryTagLabel = Resource("repository-tag-label") // TODO remove
ResourceRepositoryTagManifest = Resource("repository-tag-manifest")
ResourceRepositoryTagScanJob = Resource("repository-tag-scan-job") // TODO: remove
ResourceRepositoryTagVulnerability = Resource("repository-tag-vulnerability") // TODO: remove
ResourceRobot = Resource("robot")
ResourceNotificationPolicy = Resource("notification-policy")
ResourceScan = Resource("scan")
ResourceScanner = Resource("scanner")
ResourceArtifact = Resource("artifact")
ResourceTag = Resource("tag")
ResourceArtifactAddition = Resource("artifact-addition")
ResourceArtifactLabel = Resource("artifact-label")
ResourceSelf = Resource("") // subresource for self
ResourceAll = Resource("*") // resource match any other resources
ResourceConfiguration = Resource("configuration") // project configuration compatible for portal only
ResourceHelmChart = Resource("helm-chart")
ResourceHelmChartVersion = Resource("helm-chart-version")
ResourceHelmChartVersionLabel = Resource("helm-chart-version-label")
ResourceLabel = Resource("label")
ResourceLog = Resource("log")
ResourceMember = Resource("member")
ResourceMetadata = Resource("metadata")
ResourceQuota = Resource("quota")
ResourceRepository = Resource("repository")
ResourceTagRetention = Resource("tag-retention")
ResourceImmutableTag = Resource("immutable-tag")
ResourceRobot = Resource("robot")
ResourceNotificationPolicy = Resource("notification-policy")
ResourceScan = Resource("scan")
ResourceScanner = Resource("scanner")
ResourceArtifact = Resource("artifact")
ResourceTag = Resource("tag")
ResourceArtifactAddition = Resource("artifact-addition")
ResourceArtifactLabel = Resource("artifact-label")
ResourceSelf = Resource("") // subresource for self
)

View File

@ -39,20 +39,12 @@ var (
{Resource: ResourceLog, Action: ActionList},
{Resource: ResourceReplication, Action: ActionRead},
{Resource: ResourceReplication, Action: ActionList},
{Resource: ResourceReplicationJob, Action: ActionRead},
{Resource: ResourceReplicationJob, Action: ActionList},
{Resource: ResourceLabel, Action: ActionCreate},
{Resource: ResourceLabel, Action: ActionRead},
{Resource: ResourceLabel, Action: ActionUpdate},
{Resource: ResourceLabel, Action: ActionDelete},
{Resource: ResourceLabel, Action: ActionList},
{Resource: ResourceLabelResource, Action: ActionList},
{Resource: ResourceQuota, Action: ActionRead},
{Resource: ResourceRepository, Action: ActionCreate},
@ -75,25 +67,6 @@ var (
{Resource: ResourceImmutableTag, Action: ActionDelete},
{Resource: ResourceImmutableTag, Action: ActionList},
{Resource: ResourceRepositoryLabel, Action: ActionCreate},
{Resource: ResourceRepositoryLabel, Action: ActionDelete},
{Resource: ResourceRepositoryLabel, Action: ActionList},
{Resource: ResourceRepositoryTag, Action: ActionRead},
{Resource: ResourceRepositoryTag, Action: ActionDelete},
{Resource: ResourceRepositoryTag, Action: ActionList},
{Resource: ResourceRepositoryTagScanJob, Action: ActionCreate},
{Resource: ResourceRepositoryTagScanJob, Action: ActionRead},
{Resource: ResourceRepositoryTagVulnerability, Action: ActionList},
{Resource: ResourceRepositoryTagManifest, Action: ActionRead},
{Resource: ResourceRepositoryTagLabel, Action: ActionCreate},
{Resource: ResourceRepositoryTagLabel, Action: ActionDelete},
{Resource: ResourceRepositoryTagLabel, Action: ActionList},
{Resource: ResourceHelmChart, Action: ActionCreate}, // upload helm chart
{Resource: ResourceHelmChart, Action: ActionRead}, // download helm chart
{Resource: ResourceHelmChart, Action: ActionDelete},
@ -134,6 +107,7 @@ var (
{Resource: ResourceArtifact, Action: ActionList},
{Resource: ResourceArtifactAddition, Action: ActionRead},
{Resource: ResourceTag, Action: ActionList},
{Resource: ResourceTag, Action: ActionCreate},
{Resource: ResourceTag, Action: ActionDelete},
@ -156,9 +130,6 @@ var (
{Resource: ResourceQuota, Action: ActionRead},
{Resource: ResourceReplication, Action: ActionRead},
{Resource: ResourceReplication, Action: ActionList},
{Resource: ResourceLabel, Action: ActionCreate},
{Resource: ResourceLabel, Action: ActionRead},
{Resource: ResourceLabel, Action: ActionUpdate},
@ -185,25 +156,6 @@ var (
{Resource: ResourceImmutableTag, Action: ActionDelete},
{Resource: ResourceImmutableTag, Action: ActionList},
{Resource: ResourceRepositoryLabel, Action: ActionCreate},
{Resource: ResourceRepositoryLabel, Action: ActionDelete},
{Resource: ResourceRepositoryLabel, Action: ActionList},
{Resource: ResourceRepositoryTag, Action: ActionRead},
{Resource: ResourceRepositoryTag, Action: ActionDelete},
{Resource: ResourceRepositoryTag, Action: ActionList},
{Resource: ResourceRepositoryTagScanJob, Action: ActionCreate},
{Resource: ResourceRepositoryTagScanJob, Action: ActionRead},
{Resource: ResourceRepositoryTagVulnerability, Action: ActionList},
{Resource: ResourceRepositoryTagManifest, Action: ActionRead},
{Resource: ResourceRepositoryTagLabel, Action: ActionCreate},
{Resource: ResourceRepositoryTagLabel, Action: ActionDelete},
{Resource: ResourceRepositoryTagLabel, Action: ActionList},
{Resource: ResourceHelmChart, Action: ActionCreate},
{Resource: ResourceHelmChart, Action: ActionRead},
{Resource: ResourceHelmChart, Action: ActionDelete},
@ -235,6 +187,7 @@ var (
{Resource: ResourceArtifact, Action: ActionList},
{Resource: ResourceArtifactAddition, Action: ActionRead},
{Resource: ResourceTag, Action: ActionList},
{Resource: ResourceTag, Action: ActionCreate},
{Resource: ResourceTag, Action: ActionDelete},
@ -262,21 +215,6 @@ var (
{Resource: ResourceRepository, Action: ActionPush},
{Resource: ResourceRepository, Action: ActionPull},
{Resource: ResourceRepositoryLabel, Action: ActionCreate},
{Resource: ResourceRepositoryLabel, Action: ActionDelete},
{Resource: ResourceRepositoryLabel, Action: ActionList},
{Resource: ResourceRepositoryTag, Action: ActionRead},
{Resource: ResourceRepositoryTag, Action: ActionList},
{Resource: ResourceRepositoryTagVulnerability, Action: ActionList},
{Resource: ResourceRepositoryTagManifest, Action: ActionRead},
{Resource: ResourceRepositoryTagLabel, Action: ActionCreate},
{Resource: ResourceRepositoryTagLabel, Action: ActionDelete},
{Resource: ResourceRepositoryTagLabel, Action: ActionList},
{Resource: ResourceHelmChart, Action: ActionCreate},
{Resource: ResourceHelmChart, Action: ActionRead},
{Resource: ResourceHelmChart, Action: ActionList},
@ -302,6 +240,7 @@ var (
{Resource: ResourceArtifact, Action: ActionList},
{Resource: ResourceArtifactAddition, Action: ActionRead},
{Resource: ResourceTag, Action: ActionList},
{Resource: ResourceTag, Action: ActionCreate},
{Resource: ResourceArtifactLabel, Action: ActionCreate},
@ -325,17 +264,6 @@ var (
{Resource: ResourceRepository, Action: ActionList},
{Resource: ResourceRepository, Action: ActionPull},
{Resource: ResourceRepositoryLabel, Action: ActionList},
{Resource: ResourceRepositoryTag, Action: ActionRead},
{Resource: ResourceRepositoryTag, Action: ActionList},
{Resource: ResourceRepositoryTagLabel, Action: ActionList},
{Resource: ResourceRepositoryTagVulnerability, Action: ActionList},
{Resource: ResourceRepositoryTagManifest, Action: ActionRead},
{Resource: ResourceHelmChart, Action: ActionRead},
{Resource: ResourceHelmChart, Action: ActionList},
@ -351,6 +279,8 @@ var (
{Resource: ResourceScanner, Action: ActionRead},
{Resource: ResourceTag, Action: ActionList},
{Resource: ResourceArtifact, Action: ActionRead},
{Resource: ResourceArtifact, Action: ActionList},
{Resource: ResourceArtifactAddition, Action: ActionRead},
@ -364,13 +294,6 @@ var (
{Resource: ResourceRepository, Action: ActionList},
{Resource: ResourceRepository, Action: ActionPull},
{Resource: ResourceRepositoryTag, Action: ActionRead},
{Resource: ResourceRepositoryTag, Action: ActionList},
{Resource: ResourceRepositoryTagVulnerability, Action: ActionList},
{Resource: ResourceRepositoryTagManifest, Action: ActionRead},
{Resource: ResourceHelmChart, Action: ActionRead},
{Resource: ResourceHelmChart, Action: ActionList},
@ -383,6 +306,8 @@ var (
{Resource: ResourceScanner, Action: ActionRead},
{Resource: ResourceTag, Action: ActionList},
{Resource: ResourceArtifact, Action: ActionRead},
{Resource: ResourceArtifact, Action: ActionList},
{Resource: ResourceArtifactAddition, Action: ActionRead},

View File

@ -29,17 +29,6 @@ var (
{Resource: ResourceRepository, Action: ActionList},
{Resource: ResourceRepository, Action: ActionPull},
{Resource: ResourceRepositoryLabel, Action: ActionList},
{Resource: ResourceRepositoryTag, Action: ActionRead},
{Resource: ResourceRepositoryTag, Action: ActionList},
{Resource: ResourceRepositoryTagLabel, Action: ActionList},
{Resource: ResourceRepositoryTagVulnerability, Action: ActionList},
{Resource: ResourceRepositoryTagManifest, Action: ActionRead},
{Resource: ResourceHelmChart, Action: ActionRead},
{Resource: ResourceHelmChart, Action: ActionList},
@ -49,6 +38,8 @@ var (
{Resource: ResourceScan, Action: ActionRead},
{Resource: ResourceScanner, Action: ActionRead},
{Resource: ResourceTag, Action: ActionList},
{Resource: ResourceArtifact, Action: ActionRead},
{Resource: ResourceArtifact, Action: ActionList},
{Resource: ResourceArtifactAddition, Action: ActionRead},

View File

@ -34,6 +34,7 @@ func New() http.Handler {
AuditlogAPI: newAuditLogAPI(),
ScanAPI: newScanAPI(),
ProjectAPI: newProjectAPI(),
TagAPI: newTagAPI(),
})
if err != nil {
log.Fatal(err)

View File

@ -0,0 +1,93 @@
// 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/common/rbac"
"github.com/goharbor/harbor/src/controller/repository"
"github.com/goharbor/harbor/src/controller/tag"
"github.com/goharbor/harbor/src/server/v2.0/models"
operation "github.com/goharbor/harbor/src/server/v2.0/restapi/operations/tag"
)
func newTagAPI() *tagAPI {
return &tagAPI{
repoCtl: repository.Ctl,
tagCtl: tag.Ctl,
}
}
type tagAPI struct {
BaseAPI
repoCtl repository.Controller
tagCtl tag.Controller
}
func (t *tagAPI) Prepare(ctx context.Context, operation string, params interface{}) middleware.Responder {
if err := unescapePathParams(params, "RepositoryName"); err != nil {
t.SendError(ctx, err)
}
return nil
}
func (t *tagAPI) ListTags(ctx context.Context, params operation.ListTagsParams) middleware.Responder {
if err := t.RequireProjectAccess(ctx, params.ProjectName, rbac.ActionList, rbac.ResourceTag); err != nil {
return t.SendError(ctx, err)
}
// set query
query, err := t.BuildQuery(ctx, params.Q, params.Page, params.PageSize)
if err != nil {
return t.SendError(ctx, err)
}
repository, err := t.repoCtl.GetByName(ctx, fmt.Sprintf("%s/%s", params.ProjectName, params.RepositoryName))
if err != nil {
return t.SendError(ctx, err)
}
query.Keywords["RepositoryID"] = repository.RepositoryID
// get the total count of tags
total, err := t.tagCtl.Count(ctx, query)
if err != nil {
return t.SendError(ctx, err)
}
// set option
option := &tag.Option{}
if params.WithSignature != nil {
option.WithSignature = *params.WithSignature
}
if params.WithImmutableStatus != nil {
option.WithImmutableStatus = *params.WithImmutableStatus
}
// list tags according to the query and option
tags, err := t.tagCtl.List(ctx, query, option)
if err != nil {
return t.SendError(ctx, err)
}
var ts []*models.Tag
for _, tag := range tags {
ts = append(ts, tag.ToSwagger())
}
return operation.NewListTagsOK().
WithXTotalCount(total).
WithLink(t.Links(ctx, params.HTTPRequest.URL, total, query.PageNumber, query.PageSize).String()).
WithPayload(ts)
}