mirror of
https://github.com/goharbor/harbor.git
synced 2025-02-01 12:31:23 +01:00
It was deprecated in 2.4.0. Signed-off-by: Samuel Gaist <samuel.gaist@idiap.ch> Co-authored-by: Wang Yan <wangyan@vmware.com>
This commit is contained in:
parent
12382fa8ae
commit
15d17a3338
@ -2438,160 +2438,6 @@ paths:
|
||||
$ref: '#/responses/404'
|
||||
'500':
|
||||
$ref: '#/responses/500'
|
||||
/projects/{project_name_or_id}/robots:
|
||||
get:
|
||||
summary: Get all robot accounts of specified project
|
||||
description: Get all robot accounts of specified project
|
||||
parameters:
|
||||
- $ref: '#/parameters/requestId'
|
||||
- $ref: '#/parameters/isResourceName'
|
||||
- $ref: '#/parameters/projectNameOrId'
|
||||
- $ref: '#/parameters/page'
|
||||
- $ref: '#/parameters/pageSize'
|
||||
- $ref: '#/parameters/query'
|
||||
- $ref: '#/parameters/sort'
|
||||
tags:
|
||||
- robotv1
|
||||
operationId: ListRobotV1
|
||||
responses:
|
||||
'200':
|
||||
description: Success
|
||||
headers:
|
||||
X-Total-Count:
|
||||
description: The total count of robot accounts
|
||||
type: integer
|
||||
Link:
|
||||
description: Link refers to the previous page and next page
|
||||
type: string
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/Robot'
|
||||
'400':
|
||||
$ref: '#/responses/400'
|
||||
'404':
|
||||
$ref: '#/responses/404'
|
||||
'500':
|
||||
$ref: '#/responses/500'
|
||||
post:
|
||||
summary: Create a robot account
|
||||
description: Create a robot account
|
||||
tags:
|
||||
- robotv1
|
||||
operationId: CreateRobotV1
|
||||
parameters:
|
||||
- $ref: '#/parameters/requestId'
|
||||
- $ref: '#/parameters/isResourceName'
|
||||
- $ref: '#/parameters/projectNameOrId'
|
||||
- name: robot
|
||||
in: body
|
||||
description: The JSON object of a robot account.
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/RobotCreateV1'
|
||||
responses:
|
||||
'201':
|
||||
description: Created
|
||||
headers:
|
||||
X-Request-Id:
|
||||
description: The ID of the corresponding request for the response
|
||||
type: string
|
||||
Location:
|
||||
description: The location of the resource
|
||||
type: string
|
||||
schema:
|
||||
$ref: '#/definitions/RobotCreated'
|
||||
'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}/robots/{robot_id}:
|
||||
get:
|
||||
summary: Get a robot account
|
||||
description: This endpoint returns specific robot account information by robot ID.
|
||||
tags:
|
||||
- robotv1
|
||||
operationId: GetRobotByIDV1
|
||||
parameters:
|
||||
- $ref: '#/parameters/requestId'
|
||||
- $ref: '#/parameters/isResourceName'
|
||||
- $ref: '#/parameters/projectNameOrId'
|
||||
- $ref: '#/parameters/robotId'
|
||||
responses:
|
||||
'200':
|
||||
description: Return matched robot information.
|
||||
schema:
|
||||
$ref: '#/definitions/Robot'
|
||||
'401':
|
||||
$ref: '#/responses/401'
|
||||
'403':
|
||||
$ref: '#/responses/403'
|
||||
'404':
|
||||
$ref: '#/responses/404'
|
||||
'500':
|
||||
$ref: '#/responses/500'
|
||||
put:
|
||||
summary: Update status of robot account.
|
||||
description: Used to disable/enable a specified robot account.
|
||||
tags:
|
||||
- robotv1
|
||||
operationId: UpdateRobotV1
|
||||
parameters:
|
||||
- $ref: '#/parameters/requestId'
|
||||
- $ref: '#/parameters/isResourceName'
|
||||
- $ref: '#/parameters/projectNameOrId'
|
||||
- $ref: '#/parameters/robotId'
|
||||
- name: robot
|
||||
in: body
|
||||
description: The JSON object of a robot account.
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/Robot'
|
||||
responses:
|
||||
'200':
|
||||
$ref: '#/responses/200'
|
||||
'400':
|
||||
$ref: '#/responses/400'
|
||||
'401':
|
||||
$ref: '#/responses/401'
|
||||
'403':
|
||||
$ref: '#/responses/403'
|
||||
'404':
|
||||
$ref: '#/responses/404'
|
||||
'409':
|
||||
$ref: '#/responses/409'
|
||||
'500':
|
||||
$ref: '#/responses/500'
|
||||
delete:
|
||||
summary: Delete a robot account
|
||||
description: This endpoint deletes specific robot account information by robot ID.
|
||||
tags:
|
||||
- robotv1
|
||||
operationId: DeleteRobotV1
|
||||
parameters:
|
||||
- $ref: '#/parameters/requestId'
|
||||
- $ref: '#/parameters/isResourceName'
|
||||
- $ref: '#/parameters/projectNameOrId'
|
||||
- $ref: '#/parameters/robotId'
|
||||
responses:
|
||||
'200':
|
||||
$ref: '#/responses/200'
|
||||
'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}/immutabletagrules':
|
||||
get:
|
||||
summary: List all immutable tag rules of current project
|
||||
|
@ -44,7 +44,6 @@ func New() http.Handler {
|
||||
PreheatAPI: newPreheatAPI(),
|
||||
IconAPI: newIconAPI(),
|
||||
RobotAPI: newRobotAPI(),
|
||||
Robotv1API: newRobotV1API(),
|
||||
ReplicationAPI: newReplicationAPI(),
|
||||
RegistryAPI: newRegistryAPI(),
|
||||
SysteminfoAPI: newSystemInfoAPI(),
|
||||
|
@ -1,292 +0,0 @@
|
||||
// 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"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/go-openapi/runtime/middleware"
|
||||
"github.com/go-openapi/strfmt"
|
||||
|
||||
"github.com/goharbor/harbor/src/common/rbac"
|
||||
rbac_project "github.com/goharbor/harbor/src/common/rbac/project"
|
||||
"github.com/goharbor/harbor/src/controller/project"
|
||||
"github.com/goharbor/harbor/src/controller/robot"
|
||||
"github.com/goharbor/harbor/src/lib"
|
||||
"github.com/goharbor/harbor/src/lib/errors"
|
||||
"github.com/goharbor/harbor/src/lib/log"
|
||||
"github.com/goharbor/harbor/src/lib/q"
|
||||
"github.com/goharbor/harbor/src/pkg/permission/types"
|
||||
pkg_robot "github.com/goharbor/harbor/src/pkg/robot"
|
||||
pkg "github.com/goharbor/harbor/src/pkg/robot/model"
|
||||
handler_model "github.com/goharbor/harbor/src/server/v2.0/handler/model"
|
||||
"github.com/goharbor/harbor/src/server/v2.0/models"
|
||||
operation "github.com/goharbor/harbor/src/server/v2.0/restapi/operations/robotv1"
|
||||
)
|
||||
|
||||
func newRobotV1API() *robotV1API {
|
||||
return &robotV1API{
|
||||
robotCtl: robot.Ctl,
|
||||
robotMgr: pkg_robot.Mgr,
|
||||
projectCtr: project.Ctl,
|
||||
}
|
||||
}
|
||||
|
||||
type robotV1API struct {
|
||||
BaseAPI
|
||||
robotCtl robot.Controller
|
||||
robotMgr pkg_robot.Manager
|
||||
projectCtr project.Controller
|
||||
}
|
||||
|
||||
func (rAPI *robotV1API) CreateRobotV1(ctx context.Context, params operation.CreateRobotV1Params) middleware.Responder {
|
||||
projectNameOrID := parseProjectNameOrID(params.ProjectNameOrID, params.XIsResourceName)
|
||||
if err := rAPI.RequireProjectAccess(ctx, projectNameOrID, rbac.ActionCreate, rbac.ResourceRobot); err != nil {
|
||||
return rAPI.SendError(ctx, err)
|
||||
}
|
||||
|
||||
if err := rAPI.validate(ctx, params); err != nil {
|
||||
return rAPI.SendError(ctx, err)
|
||||
}
|
||||
|
||||
r := &robot.Robot{
|
||||
Robot: pkg.Robot{
|
||||
Name: params.Robot.Name,
|
||||
Description: params.Robot.Description,
|
||||
ExpiresAt: params.Robot.ExpiresAt,
|
||||
Visible: true,
|
||||
},
|
||||
Level: robot.LEVELPROJECT,
|
||||
}
|
||||
|
||||
projectName, ok := projectNameOrID.(string)
|
||||
if !ok {
|
||||
p, err := rAPI.projectCtr.Get(ctx, projectNameOrID, project.Metadata(false))
|
||||
if err != nil {
|
||||
log.Errorf("failed to get project %s: %v", projectNameOrID, err)
|
||||
return rAPI.SendError(ctx, err)
|
||||
}
|
||||
projectName = p.Name
|
||||
}
|
||||
|
||||
permission := &robot.Permission{
|
||||
Kind: "project",
|
||||
Namespace: projectName,
|
||||
}
|
||||
|
||||
var policies []*types.Policy
|
||||
for _, acc := range params.Robot.Access {
|
||||
policy := &types.Policy{
|
||||
Action: types.Action(acc.Action),
|
||||
Effect: types.Effect(acc.Effect),
|
||||
}
|
||||
res, err := getRawResource(acc.Resource)
|
||||
if err != nil {
|
||||
return rAPI.SendError(ctx, err)
|
||||
}
|
||||
policy.Resource = types.Resource(res)
|
||||
policies = append(policies, policy)
|
||||
}
|
||||
permission.Access = policies
|
||||
r.Permissions = append(r.Permissions, permission)
|
||||
|
||||
rid, pwd, err := rAPI.robotCtl.Create(ctx, r)
|
||||
if err != nil {
|
||||
return rAPI.SendError(ctx, err)
|
||||
}
|
||||
|
||||
created, err := rAPI.robotCtl.Get(ctx, rid, nil)
|
||||
if err != nil {
|
||||
return rAPI.SendError(ctx, err)
|
||||
}
|
||||
|
||||
location := fmt.Sprintf("%s/%d", strings.TrimSuffix(params.HTTPRequest.URL.Path, "/"), created.ID)
|
||||
return operation.NewCreateRobotV1Created().WithLocation(location).WithPayload(&models.RobotCreated{
|
||||
ID: created.ID,
|
||||
Name: created.Name,
|
||||
Secret: pwd,
|
||||
CreationTime: strfmt.DateTime(created.CreationTime),
|
||||
})
|
||||
}
|
||||
|
||||
func (rAPI *robotV1API) DeleteRobotV1(ctx context.Context, params operation.DeleteRobotV1Params) middleware.Responder {
|
||||
projectNameOrID := parseProjectNameOrID(params.ProjectNameOrID, params.XIsResourceName)
|
||||
if err := rAPI.RequireProjectAccess(ctx, projectNameOrID, rbac.ActionDelete, rbac.ResourceRobot); err != nil {
|
||||
return rAPI.SendError(ctx, err)
|
||||
}
|
||||
|
||||
pro, err := rAPI.projectCtr.Get(ctx, projectNameOrID)
|
||||
if err != nil {
|
||||
return rAPI.SendError(ctx, err)
|
||||
}
|
||||
r, err := rAPI.robotCtl.List(ctx, q.New(q.KeyWords{"ProjectID": pro.ProjectID, "ID": params.RobotID}), &robot.Option{
|
||||
WithPermission: true,
|
||||
})
|
||||
if err != nil {
|
||||
return rAPI.SendError(ctx, err)
|
||||
}
|
||||
if len(r) == 0 {
|
||||
return rAPI.SendError(ctx, errors.NotFoundError(fmt.Errorf("cannot find robot with project id: %d and id: %d", pro.ProjectID, params.RobotID)))
|
||||
}
|
||||
|
||||
// ignore the not permissions error.
|
||||
if err := rAPI.robotCtl.Delete(ctx, params.RobotID); err != nil && !errors.IsNotFoundErr(err) {
|
||||
return rAPI.SendError(ctx, err)
|
||||
}
|
||||
return operation.NewDeleteRobotV1OK()
|
||||
}
|
||||
|
||||
func (rAPI *robotV1API) ListRobotV1(ctx context.Context, params operation.ListRobotV1Params) middleware.Responder {
|
||||
projectNameOrID := parseProjectNameOrID(params.ProjectNameOrID, params.XIsResourceName)
|
||||
if err := rAPI.RequireProjectAccess(ctx, projectNameOrID, rbac.ActionList, rbac.ResourceRobot); err != nil {
|
||||
return rAPI.SendError(ctx, err)
|
||||
}
|
||||
|
||||
query, err := rAPI.BuildQuery(ctx, params.Q, params.Sort, params.Page, params.PageSize)
|
||||
if err != nil {
|
||||
return rAPI.SendError(ctx, err)
|
||||
}
|
||||
query.Keywords["Visible"] = true
|
||||
|
||||
pro, err := rAPI.projectCtr.Get(ctx, projectNameOrID)
|
||||
if err != nil {
|
||||
return rAPI.SendError(ctx, err)
|
||||
}
|
||||
|
||||
query.Keywords["ProjectID"] = pro.ProjectID
|
||||
|
||||
total, err := rAPI.robotCtl.Count(ctx, query)
|
||||
if err != nil {
|
||||
return rAPI.SendError(ctx, err)
|
||||
}
|
||||
|
||||
robots, err := rAPI.robotCtl.List(ctx, query, &robot.Option{
|
||||
WithPermission: true,
|
||||
})
|
||||
if err != nil {
|
||||
return rAPI.SendError(ctx, err)
|
||||
}
|
||||
|
||||
var results []*models.Robot
|
||||
for _, r := range robots {
|
||||
results = append(results, handler_model.NewRobot(r).ToSwagger())
|
||||
}
|
||||
|
||||
return operation.NewListRobotV1OK().
|
||||
WithXTotalCount(total).
|
||||
WithLink(rAPI.Links(ctx, params.HTTPRequest.URL, total, query.PageNumber, query.PageSize).String()).
|
||||
WithPayload(results)
|
||||
}
|
||||
|
||||
func (rAPI *robotV1API) GetRobotByIDV1(ctx context.Context, params operation.GetRobotByIDV1Params) middleware.Responder {
|
||||
projectNameOrID := parseProjectNameOrID(params.ProjectNameOrID, params.XIsResourceName)
|
||||
if err := rAPI.RequireProjectAccess(ctx, projectNameOrID, rbac.ActionRead, rbac.ResourceRobot); err != nil {
|
||||
return rAPI.SendError(ctx, err)
|
||||
}
|
||||
|
||||
pro, err := rAPI.projectCtr.Get(ctx, projectNameOrID)
|
||||
if err != nil {
|
||||
return rAPI.SendError(ctx, err)
|
||||
}
|
||||
|
||||
r, err := rAPI.robotCtl.List(ctx, q.New(q.KeyWords{"ProjectID": pro.ProjectID, "ID": params.RobotID}), &robot.Option{
|
||||
WithPermission: true,
|
||||
})
|
||||
if err != nil {
|
||||
return rAPI.SendError(ctx, err)
|
||||
}
|
||||
if len(r) == 0 {
|
||||
return rAPI.SendError(ctx, errors.NotFoundError(fmt.Errorf("cannot find robot with project id: %d and id: %d", pro.ProjectID, params.RobotID)))
|
||||
}
|
||||
|
||||
return operation.NewGetRobotByIDV1OK().WithPayload(handler_model.NewRobot(r[0]).ToSwagger())
|
||||
}
|
||||
|
||||
func (rAPI *robotV1API) UpdateRobotV1(ctx context.Context, params operation.UpdateRobotV1Params) middleware.Responder {
|
||||
projectNameOrID := parseProjectNameOrID(params.ProjectNameOrID, params.XIsResourceName)
|
||||
if err := rAPI.RequireProjectAccess(ctx, projectNameOrID, rbac.ActionUpdate, rbac.ResourceRobot); err != nil {
|
||||
return rAPI.SendError(ctx, err)
|
||||
}
|
||||
|
||||
pro, err := rAPI.projectCtr.Get(ctx, projectNameOrID)
|
||||
if err != nil {
|
||||
return rAPI.SendError(ctx, err)
|
||||
}
|
||||
r, err := rAPI.robotCtl.List(ctx, q.New(q.KeyWords{"ProjectID": pro.ProjectID, "ID": params.RobotID}), &robot.Option{
|
||||
WithPermission: true,
|
||||
})
|
||||
if err != nil {
|
||||
return rAPI.SendError(ctx, err)
|
||||
}
|
||||
if len(r) == 0 {
|
||||
return rAPI.SendError(ctx, errors.NotFoundError(fmt.Errorf("cannot find robot with project id: %d and id: %d", pro.ProjectID, params.RobotID)))
|
||||
}
|
||||
robot := r[0]
|
||||
|
||||
// for v1 API, only update the disable.
|
||||
robot.Disabled = params.Robot.Disable
|
||||
if err := rAPI.robotCtl.Update(ctx, robot, nil); err != nil {
|
||||
return rAPI.SendError(ctx, err)
|
||||
}
|
||||
|
||||
return operation.NewUpdateRobotV1OK()
|
||||
}
|
||||
|
||||
func (rAPI *robotV1API) validate(ctx context.Context, params operation.CreateRobotV1Params) error {
|
||||
if params.Robot == nil {
|
||||
return errors.New(nil).WithMessage("bad request no robot").WithCode(errors.BadRequestCode)
|
||||
}
|
||||
if len(params.Robot.Access) == 0 {
|
||||
return errors.New(nil).WithMessage("bad request no access").WithCode(errors.BadRequestCode)
|
||||
}
|
||||
|
||||
projectNameOrID := parseProjectNameOrID(params.ProjectNameOrID, params.XIsResourceName)
|
||||
pro, err := rAPI.projectCtr.Get(ctx, projectNameOrID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
policies := rbac_project.GetPoliciesOfProject(pro.ProjectID)
|
||||
|
||||
mp := map[string]bool{}
|
||||
for _, policy := range policies {
|
||||
mp[policy.String()] = true
|
||||
}
|
||||
|
||||
for _, policy := range params.Robot.Access {
|
||||
p := &types.Policy{}
|
||||
if err := lib.JSONCopy(p, policy); err != nil {
|
||||
log.Warningf("failed to call JSONCopy on robot access policy when validate, error: %v", err)
|
||||
}
|
||||
if !mp[p.String()] {
|
||||
return errors.New(nil).WithMessagef("%s action of %s resource not exist in project %s", policy.Action, policy.Resource, projectNameOrID).WithCode(errors.BadRequestCode)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// /project/1/repository => repository
|
||||
func getRawResource(resource string) (string, error) {
|
||||
resourceReg := regexp.MustCompile("^/project/[0-9]+/(?P<repository>[a-z-]+)$")
|
||||
matches := resourceReg.FindStringSubmatch(resource)
|
||||
if len(matches) <= 1 {
|
||||
return "", errors.New(nil).WithMessagef("bad resource %s", resource).WithCode(errors.BadRequestCode)
|
||||
}
|
||||
return matches[1], nil
|
||||
}
|
Loading…
Reference in New Issue
Block a user