Unify retention schedule/task retrieve and update (#17083)

Add not-found handling for non exist items in retention operation.

Signed-off-by: Wang Yan <wangyan@vmware.com>
This commit is contained in:
Wang Yan 2022-07-01 01:58:14 +08:00 committed by GitHub
parent 90e9b997bf
commit b4ef1dbfd5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 68 additions and 7 deletions

View File

@ -306,6 +306,7 @@ func convertExecution(exec *task.Execution) *retention.Execution {
Status: exec.Status, Status: exec.Status,
Trigger: exec.Trigger, Trigger: exec.Trigger,
DryRun: exec.ExtraAttrs["dry_run"].(bool), DryRun: exec.ExtraAttrs["dry_run"].(bool),
Type: exec.VendorType,
} }
} }

View File

@ -39,6 +39,7 @@ type Execution struct {
Status string `json:"status"` Status string `json:"status"`
Trigger string `json:"trigger"` Trigger string `json:"trigger"`
DryRun bool `json:"dry_run"` DryRun bool `json:"dry_run"`
Type string `json:"-"`
} }
// Task of retention // Task of retention

View File

@ -11,6 +11,7 @@ import (
"github.com/goharbor/harbor/src/common/rbac" "github.com/goharbor/harbor/src/common/rbac"
projectCtl "github.com/goharbor/harbor/src/controller/project" projectCtl "github.com/goharbor/harbor/src/controller/project"
retentionCtl "github.com/goharbor/harbor/src/controller/retention" retentionCtl "github.com/goharbor/harbor/src/controller/retention"
"github.com/goharbor/harbor/src/jobservice/job"
"github.com/goharbor/harbor/src/lib/errors" "github.com/goharbor/harbor/src/lib/errors"
"github.com/goharbor/harbor/src/pkg" "github.com/goharbor/harbor/src/pkg"
"github.com/goharbor/harbor/src/pkg/project/metadata" "github.com/goharbor/harbor/src/pkg/project/metadata"
@ -274,11 +275,19 @@ func (r *retentionAPI) OperateRetentionExecution(ctx context.Context, params ope
if err != nil { if err != nil {
return r.SendError(ctx, errors.BadRequestError(err)) return r.SendError(ctx, errors.BadRequestError(err))
} }
err = r.requireAccess(ctx, p, rbac.ActionUpdate) if p == nil {
if err != nil { return r.SendError(ctx, errors.New("retention policy is not found").WithCode(errors.NotFoundCode))
}
if err := r.requireAccess(ctx, p, rbac.ActionUpdate); err != nil {
return r.SendError(ctx, err) return r.SendError(ctx, err)
} }
if err = r.retentionCtl.OperateRetentionExec(ctx, params.Eid, params.Body.Action); err != nil { if err := r.requirePolicyAccess(ctx, p); err != nil {
return r.SendError(ctx, err)
}
if err := r.requireExecutionInProject(ctx, p, params.Eid); err != nil {
return r.SendError(ctx, err)
}
if err := r.retentionCtl.OperateRetentionExec(ctx, params.Eid, params.Body.Action); err != nil {
return r.SendError(ctx, err) return r.SendError(ctx, err)
} }
return operation.NewOperateRetentionExecutionOK() return operation.NewOperateRetentionExecutionOK()
@ -323,8 +332,16 @@ func (r *retentionAPI) ListRetentionTasks(ctx context.Context, params operation.
if err != nil { if err != nil {
return r.SendError(ctx, errors.BadRequestError(err)) return r.SendError(ctx, errors.BadRequestError(err))
} }
err = r.requireAccess(ctx, p, rbac.ActionList) if p == nil {
if err != nil { return r.SendError(ctx, errors.New("retention policy is not found").WithCode(errors.NotFoundCode))
}
if err := r.requireAccess(ctx, p, rbac.ActionList); err != nil {
return r.SendError(ctx, err)
}
if err := r.requirePolicyAccess(ctx, p); err != nil {
return r.SendError(ctx, err)
}
if err := r.requireExecutionInProject(ctx, p, params.Eid); err != nil {
return r.SendError(ctx, err) return r.SendError(ctx, err)
} }
tasks, err := r.retentionCtl.ListRetentionExecTasks(ctx, params.Eid, query) tasks, err := r.retentionCtl.ListRetentionExecTasks(ctx, params.Eid, query)
@ -349,8 +366,16 @@ func (r *retentionAPI) GetRetentionTaskLog(ctx context.Context, params operation
if err != nil { if err != nil {
return r.SendError(ctx, errors.BadRequestError(err)) return r.SendError(ctx, errors.BadRequestError(err))
} }
err = r.requireAccess(ctx, p, rbac.ActionRead) if p == nil {
if err != nil { return r.SendError(ctx, errors.New("retention policy is not found").WithCode(errors.NotFoundCode))
}
if err := r.requireAccess(ctx, p, rbac.ActionRead); err != nil {
return r.SendError(ctx, err)
}
if err := r.requirePolicyAccess(ctx, p); err != nil {
return r.SendError(ctx, err)
}
if err := r.requireTaskInProject(ctx, p, params.Eid, params.Tid); err != nil {
return r.SendError(ctx, err) return r.SendError(ctx, err)
} }
@ -391,3 +416,37 @@ func (r *retentionAPI) requirePolicyAccess(ctx context.Context, p *policy.Metada
return errors.NotFoundError(errors.Errorf("the retention policy id %d does not match", p.ID)) return errors.NotFoundError(errors.Errorf("the retention policy id %d does not match", p.ID))
} }
func (r *retentionAPI) requireExecutionInProject(ctx context.Context, p *policy.Metadata, executionID int64) error {
exec, err := r.retentionCtl.GetRetentionExec(ctx, executionID)
if err != nil {
return err
}
if exec == nil {
return errors.New(nil).WithMessage("project: %d, execution id %d not found", p.Scope.Reference, executionID).WithCode(errors.NotFoundCode)
}
if exec.PolicyID != p.ID {
return errors.New(nil).WithMessage("project: %d, execution id %d not found", p.Scope.Reference, executionID).WithCode(errors.NotFoundCode)
}
if exec.Type != job.Retention {
return errors.New(nil).WithMessage("project: %d, execution id %d not found", p.Scope.Reference, executionID).WithCode(errors.NotFoundCode)
}
return nil
}
func (r *retentionAPI) requireTaskInProject(ctx context.Context, p *policy.Metadata, executionID, taskID int64) error {
if err := r.requireExecutionInProject(ctx, p, executionID); err != nil {
return err
}
task, err := r.retentionCtl.GetRetentionExecTask(ctx, taskID)
if err != nil {
return err
}
if task == nil {
return errors.New(nil).WithMessage("project: %d, execution id %d not found", p.Scope.Reference, executionID).WithCode(errors.NotFoundCode)
}
if task.ExecutionID != executionID {
return errors.New(nil).WithMessage("project: %d, execution id %d not found", p.Scope.Reference, executionID).WithCode(errors.NotFoundCode)
}
return nil
}