mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-22 18:25:56 +01:00
Unify the process of job schedule/task retrieve and update (#17012)
Unify the process of jobservice execution/task retrieve and update Change regular expression in robot account Signed-off-by: stonezdj <stonezdj@gmail.com>
This commit is contained in:
parent
0cf036e73a
commit
e6eb7821d0
@ -1,3 +1,17 @@
|
||||
// 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 (
|
||||
@ -40,6 +54,21 @@ func (n *notificationPolicyAPI) Prepare(ctx context.Context, operation string, p
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *notificationPolicyAPI) requirePolicyInProject(ctx context.Context, projectIDOrName interface{}, policyID int64) error {
|
||||
projectID, err := getProjectID(ctx, projectIDOrName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
l, err := n.webhookPolicyMgr.Get(ctx, policyID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if projectID != l.ProjectID {
|
||||
return errors.NotFoundError(fmt.Errorf("project id:%d, webhook policy id: %d not found", projectID, policyID))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *notificationPolicyAPI) ListWebhookPoliciesOfProject(ctx context.Context, params webhook.ListWebhookPoliciesOfProjectParams) middleware.Responder {
|
||||
projectNameOrID := parseProjectNameOrID(params.ProjectNameOrID, params.XIsResourceName)
|
||||
if err := n.RequireProjectAccess(ctx, projectNameOrID, rbac.ActionList, rbac.ResourceNotificationPolicy); err != nil {
|
||||
@ -114,7 +143,14 @@ func (n *notificationPolicyAPI) UpdateWebhookPolicyOfProject(ctx context.Context
|
||||
if err := n.RequireProjectAccess(ctx, projectNameOrID, rbac.ActionUpdate, rbac.ResourceNotificationPolicy); err != nil {
|
||||
return n.SendError(ctx, err)
|
||||
}
|
||||
|
||||
projectID, err := getProjectID(ctx, projectNameOrID)
|
||||
if err != nil {
|
||||
return n.SendError(ctx, err)
|
||||
}
|
||||
policyID := params.WebhookPolicyID
|
||||
if err := n.requirePolicyInProject(ctx, projectID, policyID); err != nil {
|
||||
return n.SendError(ctx, err)
|
||||
}
|
||||
policy := &policy_model.Policy{}
|
||||
if err := lib.JSONCopy(policy, params.Policy); err != nil {
|
||||
log.Warningf("failed to call JSONCopy on notification policy when UpdateWebhookPolicyOfProject, error: %v", err)
|
||||
@ -127,10 +163,7 @@ func (n *notificationPolicyAPI) UpdateWebhookPolicyOfProject(ctx context.Context
|
||||
return n.SendError(ctx, err)
|
||||
}
|
||||
|
||||
projectID, err := getProjectID(ctx, projectNameOrID)
|
||||
if err != nil {
|
||||
return n.SendError(ctx, err)
|
||||
}
|
||||
policy.ID = policyID
|
||||
policy.ProjectID = projectID
|
||||
if err := n.webhookPolicyMgr.Update(ctx, policy); err != nil {
|
||||
return n.SendError(ctx, err)
|
||||
@ -144,7 +177,9 @@ func (n *notificationPolicyAPI) DeleteWebhookPolicyOfProject(ctx context.Context
|
||||
if err := n.RequireProjectAccess(ctx, projectNameOrID, rbac.ActionDelete, rbac.ResourceNotificationPolicy); err != nil {
|
||||
return n.SendError(ctx, err)
|
||||
}
|
||||
|
||||
if err := n.requirePolicyInProject(ctx, projectNameOrID, params.WebhookPolicyID); err != nil {
|
||||
return n.SendError(ctx, err)
|
||||
}
|
||||
if err := n.webhookPolicyMgr.Delete(ctx, params.WebhookPolicyID); err != nil {
|
||||
return n.SendError(ctx, err)
|
||||
}
|
||||
@ -153,7 +188,14 @@ func (n *notificationPolicyAPI) DeleteWebhookPolicyOfProject(ctx context.Context
|
||||
|
||||
func (n *notificationPolicyAPI) GetWebhookPolicyOfProject(ctx context.Context, params webhook.GetWebhookPolicyOfProjectParams) middleware.Responder {
|
||||
projectNameOrID := parseProjectNameOrID(params.ProjectNameOrID, params.XIsResourceName)
|
||||
if err := n.RequireProjectAccess(ctx, projectNameOrID, rbac.ActionRead, rbac.ResourceNotificationPolicy); err != nil {
|
||||
projectID, err := getProjectID(ctx, projectNameOrID)
|
||||
if err != nil {
|
||||
return n.SendError(ctx, err)
|
||||
}
|
||||
if err := n.RequireProjectAccess(ctx, projectID, rbac.ActionRead, rbac.ResourceNotificationPolicy); err != nil {
|
||||
return n.SendError(ctx, err)
|
||||
}
|
||||
if err := n.requirePolicyInProject(ctx, projectID, params.WebhookPolicyID); err != nil {
|
||||
return n.SendError(ctx, err)
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,17 @@
|
||||
// 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 (
|
||||
@ -578,6 +592,10 @@ func (api *preheatAPI) GetExecution(ctx context.Context, params operation.GetExe
|
||||
return api.SendError(ctx, err)
|
||||
}
|
||||
|
||||
if err := api.requireExecutionInProject(ctx, params.ProjectName, params.PreheatPolicyName, params.ExecutionID); err != nil {
|
||||
return api.SendError(ctx, err)
|
||||
}
|
||||
|
||||
execution, err := api.executionCtl.Get(ctx, params.ExecutionID)
|
||||
if err != nil {
|
||||
return api.SendError(ctx, err)
|
||||
@ -646,6 +664,10 @@ func (api *preheatAPI) StopExecution(ctx context.Context, params operation.StopE
|
||||
return api.SendError(ctx, err)
|
||||
}
|
||||
|
||||
if err := api.requireExecutionInProject(ctx, params.ProjectName, params.PreheatPolicyName, params.ExecutionID); err != nil {
|
||||
return api.SendError(ctx, err)
|
||||
}
|
||||
|
||||
if params.Execution.Status == "Stopped" {
|
||||
err := api.executionCtl.Stop(ctx, params.ExecutionID)
|
||||
if err != nil {
|
||||
@ -683,7 +705,6 @@ func (api *preheatAPI) ListTasks(ctx context.Context, params operation.ListTasks
|
||||
if err := api.RequireProjectAccess(ctx, params.ProjectName, rbac.ActionList, rbac.ResourcePreatPolicy); err != nil {
|
||||
return api.SendError(ctx, err)
|
||||
}
|
||||
|
||||
query, err := api.BuildQuery(ctx, params.Q, params.Sort, params.Page, params.PageSize)
|
||||
if err != nil {
|
||||
return api.SendError(ctx, err)
|
||||
@ -722,6 +743,10 @@ func (api *preheatAPI) GetPreheatLog(ctx context.Context, params operation.GetPr
|
||||
return api.SendError(ctx, err)
|
||||
}
|
||||
|
||||
if err := api.requireTaskInProject(ctx, params.ProjectName, params.PreheatPolicyName, params.TaskID); err != nil {
|
||||
return api.SendError(ctx, err)
|
||||
}
|
||||
|
||||
l, err := api.taskCtl.GetLog(ctx, params.TaskID)
|
||||
if err != nil {
|
||||
return api.SendError(ctx, err)
|
||||
@ -730,6 +755,64 @@ func (api *preheatAPI) GetPreheatLog(ctx context.Context, params operation.GetPr
|
||||
return operation.NewGetPreheatLogOK().WithPayload(string(l))
|
||||
}
|
||||
|
||||
func (api *preheatAPI) requireTaskInProject(ctx context.Context, projectNameOrID interface{}, policyName string, taskID int64) error {
|
||||
projectID, err := getProjectID(ctx, projectNameOrID)
|
||||
notFoundErr := fmt.Errorf("project id %d, task id %d not found", projectID, taskID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
plc, err := api.preheatCtl.GetPolicyByName(ctx, projectID, policyName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
execs, err := api.executionCtl.List(ctx, q.New(q.KeyWords{"VendorType": job.P2PPreheat, "VendorID": plc.ID}))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(execs) == 0 {
|
||||
return errors.NotFoundError(notFoundErr)
|
||||
}
|
||||
var execIds []interface{}
|
||||
for _, item := range execs {
|
||||
execIds = append(execIds, item.ID)
|
||||
}
|
||||
tasks, err := api.taskCtl.List(ctx, q.New(q.KeyWords{"ExecutionID": q.NewOrList(execIds)}))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(tasks) == 0 {
|
||||
return errors.NotFoundError(notFoundErr)
|
||||
}
|
||||
for _, t := range tasks {
|
||||
if t.ID == taskID {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return errors.NotFoundError(notFoundErr)
|
||||
}
|
||||
|
||||
func (api *preheatAPI) requireExecutionInProject(ctx context.Context, projectNameOrID interface{}, policyName string, executionID int64) error {
|
||||
projectID, err := getProjectID(ctx, projectNameOrID)
|
||||
notFoundErr := fmt.Errorf("project id %d, execution id %d not found", projectID, executionID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
plc, err := api.preheatCtl.GetPolicyByName(ctx, projectID, policyName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
execs, err := api.executionCtl.List(ctx, q.New(q.KeyWords{"VendorType": job.P2PPreheat, "VendorID": plc.ID}))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, e := range execs {
|
||||
if e.ID == executionID {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return errors.NotFoundError(notFoundErr)
|
||||
}
|
||||
|
||||
// ListProvidersUnderProject is Get all providers at project level
|
||||
func (api *preheatAPI) ListProvidersUnderProject(ctx context.Context, params operation.ListProvidersUnderProjectParams) middleware.Responder {
|
||||
if err := api.RequireProjectAccess(ctx, params.ProjectName, rbac.ActionList, rbac.ResourcePreatPolicy); err != nil {
|
||||
|
@ -185,6 +185,9 @@ func (p *purgeAPI) GetPurgeJob(ctx context.Context, params purge.GetPurgeJobPara
|
||||
}
|
||||
|
||||
exec, err := p.executionCtl.Get(ctx, params.PurgeID)
|
||||
if exec.VendorType != pg.VendorType {
|
||||
return p.SendError(ctx, fmt.Errorf("purge job with id %d not found", params.PurgeID))
|
||||
}
|
||||
if err != nil {
|
||||
return p.SendError(ctx, err)
|
||||
}
|
||||
|
@ -1,3 +1,17 @@
|
||||
// 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 (
|
||||
@ -95,7 +109,7 @@ func (rAPI *robotAPI) DeleteRobot(ctx context.Context, params operation.DeleteRo
|
||||
}
|
||||
|
||||
if err := rAPI.robotCtl.Delete(ctx, params.RobotID); err != nil {
|
||||
// for the version 1 robot account, has to ignore the no permissions error.
|
||||
// for the version 1 robot account, has to ignore the no permission error.
|
||||
if !r.Editable && errors.IsNotFoundErr(err) {
|
||||
return operation.NewDeleteRobotOK()
|
||||
}
|
||||
@ -177,7 +191,6 @@ func (rAPI *robotAPI) GetRobotByID(ctx context.Context, params operation.GetRobo
|
||||
if err != nil {
|
||||
return rAPI.SendError(ctx, err)
|
||||
}
|
||||
|
||||
if err := rAPI.requireAccess(ctx, r.Level, r.ProjectID, rbac.ActionRead); err != nil {
|
||||
return rAPI.SendError(ctx, err)
|
||||
}
|
||||
@ -285,11 +298,16 @@ func (rAPI *robotAPI) updateV2Robot(ctx context.Context, params operation.Update
|
||||
if err := rAPI.validate(params.Robot.Duration, params.Robot.Level, params.Robot.Permissions); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := rAPI.requireAccess(ctx, params.Robot.Level, params.Robot.Permissions[0].Namespace, rbac.ActionUpdate); err != nil {
|
||||
projectID, err := getProjectID(ctx, params.Robot.Permissions[0].Namespace)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if r.Level != robot.LEVELSYSTEM && r.ProjectID != projectID {
|
||||
return errors.BadRequestError(nil).WithMessage("cannot update the project id of robot")
|
||||
}
|
||||
if err := rAPI.requireAccess(ctx, params.Robot.Level, projectID, rbac.ActionUpdate); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if params.Robot.Level != r.Level || params.Robot.Name != r.Name {
|
||||
return errors.BadRequestError(nil).WithMessage("cannot update the level or name of robot")
|
||||
}
|
||||
@ -333,7 +351,7 @@ func isValidDuration(d int64) bool {
|
||||
func isValidSec(sec string) bool {
|
||||
hasLower := regexp.MustCompile(`[a-z]`)
|
||||
hasUpper := regexp.MustCompile(`[A-Z]`)
|
||||
hasNumber := regexp.MustCompile(`[0-9]`)
|
||||
hasNumber := regexp.MustCompile(`\d`)
|
||||
if len(sec) >= 8 && hasLower.MatchString(sec) && hasUpper.MatchString(sec) && hasNumber.MatchString(sec) {
|
||||
return true
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user