mirror of
https://github.com/goharbor/harbor.git
synced 2025-01-20 06:31:55 +01:00
Merge pull request #12462 from chlins/feat/preheat-execution-api
Feat/preheat execution api
This commit is contained in:
commit
3b43162b6d
@ -1013,6 +1013,151 @@ paths:
|
||||
$ref: '#/responses/403'
|
||||
'500':
|
||||
$ref: '#/responses/500'
|
||||
/projects/{project_name}/preheat/policies/{preheat_policy_name}/executions:
|
||||
get:
|
||||
summary: List executions for the given policy
|
||||
description: List executions for the given policy
|
||||
tags:
|
||||
- preheat
|
||||
operationId: ListExecutions
|
||||
parameters:
|
||||
- $ref: '#/parameters/requestId'
|
||||
- $ref: '#/parameters/projectName'
|
||||
- $ref: '#/parameters/preheatPolicyName'
|
||||
- $ref: '#/parameters/page'
|
||||
- $ref: '#/parameters/pageSize'
|
||||
- $ref: '#/parameters/query'
|
||||
responses:
|
||||
'200':
|
||||
description: List executions success
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/Execution'
|
||||
'400':
|
||||
$ref: '#/responses/400'
|
||||
'401':
|
||||
$ref: '#/responses/401'
|
||||
'404':
|
||||
$ref: '#/responses/404'
|
||||
'403':
|
||||
$ref: '#/responses/403'
|
||||
'500':
|
||||
$ref: '#/responses/500'
|
||||
/projects/{project_name}/preheat/policies/{preheat_policy_name}/executions/{execution_id}:
|
||||
get:
|
||||
summary: Get a execution detail by id
|
||||
description: Get a execution detail by id
|
||||
tags:
|
||||
- preheat
|
||||
operationId: GetExecution
|
||||
parameters:
|
||||
- $ref: '#/parameters/requestId'
|
||||
- $ref: '#/parameters/projectName'
|
||||
- $ref: '#/parameters/preheatPolicyName'
|
||||
- $ref: '#/parameters/executionId'
|
||||
responses:
|
||||
'200':
|
||||
description: Get execution success
|
||||
schema:
|
||||
$ref: '#/definitions/Execution'
|
||||
'400':
|
||||
$ref: '#/responses/400'
|
||||
'401':
|
||||
$ref: '#/responses/401'
|
||||
'404':
|
||||
$ref: '#/responses/404'
|
||||
'403':
|
||||
$ref: '#/responses/403'
|
||||
'500':
|
||||
$ref: '#/responses/500'
|
||||
patch:
|
||||
summary: Stop a execution
|
||||
description: Stop a execution
|
||||
tags:
|
||||
- preheat
|
||||
operationId: StopExecution
|
||||
parameters:
|
||||
- $ref: '#/parameters/requestId'
|
||||
- $ref: '#/parameters/projectName'
|
||||
- $ref: '#/parameters/preheatPolicyName'
|
||||
- $ref: '#/parameters/executionId'
|
||||
- name: execution
|
||||
description: The data of execution
|
||||
in: body
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/Execution'
|
||||
responses:
|
||||
'200':
|
||||
$ref: '#/responses/200'
|
||||
'400':
|
||||
$ref: '#/responses/400'
|
||||
'401':
|
||||
$ref: '#/responses/401'
|
||||
'404':
|
||||
$ref: '#/responses/404'
|
||||
'403':
|
||||
$ref: '#/responses/403'
|
||||
'500':
|
||||
$ref: '#/responses/500'
|
||||
/projects/{project_name}/preheat/policies/{preheat_policy_name}/executions/{execution_id}/tasks:
|
||||
get:
|
||||
summary: List all the related tasks for the given execution
|
||||
description: List all the related tasks for the given execution
|
||||
tags:
|
||||
- preheat
|
||||
operationId: ListTasks
|
||||
parameters:
|
||||
- $ref: '#/parameters/requestId'
|
||||
- $ref: '#/parameters/projectName'
|
||||
- $ref: '#/parameters/preheatPolicyName'
|
||||
- $ref: '#/parameters/executionId'
|
||||
responses:
|
||||
'200':
|
||||
description: List tasks success
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/Task'
|
||||
'400':
|
||||
$ref: '#/responses/400'
|
||||
'401':
|
||||
$ref: '#/responses/401'
|
||||
'404':
|
||||
$ref: '#/responses/404'
|
||||
'403':
|
||||
$ref: '#/responses/403'
|
||||
'500':
|
||||
$ref: '#/responses/500'
|
||||
/projects/{project_name}/preheat/policies/{preheat_policy_name}/executions/{execution_id}/tasks/{task_id}/logs:
|
||||
get:
|
||||
summary: Get the log text stream of the specified task for the given execution
|
||||
description: Get the log text stream of the specified task for the given execution
|
||||
tags:
|
||||
- preheat
|
||||
operationId: GetLog
|
||||
parameters:
|
||||
- $ref: '#/parameters/requestId'
|
||||
- $ref: '#/parameters/projectName'
|
||||
- $ref: '#/parameters/preheatPolicyName'
|
||||
- $ref: '#/parameters/executionId'
|
||||
- $ref: '#/parameters/taskId'
|
||||
responses:
|
||||
'200':
|
||||
description: Get log success
|
||||
schema:
|
||||
type: string
|
||||
'400':
|
||||
$ref: '#/responses/400'
|
||||
'401':
|
||||
$ref: '#/responses/401'
|
||||
'404':
|
||||
$ref: '#/responses/404'
|
||||
'403':
|
||||
$ref: '#/responses/403'
|
||||
'500':
|
||||
$ref: '#/responses/500'
|
||||
parameters:
|
||||
query:
|
||||
name: q
|
||||
@ -1085,7 +1230,18 @@ parameters:
|
||||
description: Preheat Policy Name
|
||||
required: true
|
||||
type: string
|
||||
|
||||
executionId:
|
||||
name: execution_id
|
||||
in: path
|
||||
description: Execution ID
|
||||
required: true
|
||||
type: integer
|
||||
taskId:
|
||||
name: task_id
|
||||
in: path
|
||||
description: Task ID
|
||||
required: true
|
||||
type: integer
|
||||
responses:
|
||||
'200':
|
||||
description: Success
|
||||
@ -1601,3 +1757,90 @@ definitions:
|
||||
type: string
|
||||
format: date-time
|
||||
description: The Update Time of preheat policy
|
||||
Metrics:
|
||||
type: object
|
||||
properties:
|
||||
task_count:
|
||||
type: integer
|
||||
description: The count of task
|
||||
success_task_count:
|
||||
type: integer
|
||||
description: The count of success task
|
||||
error_task_count:
|
||||
type: integer
|
||||
description: The count of error task
|
||||
pending_task_count:
|
||||
type: integer
|
||||
description: The count of pending task
|
||||
running_task_count:
|
||||
type: integer
|
||||
description: The count of running task
|
||||
scheduled_task_count:
|
||||
type: integer
|
||||
description: The count of scheduled task
|
||||
stopped_task_count:
|
||||
type: integer
|
||||
description: The count of stopped task
|
||||
Execution:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
description: The ID of execution
|
||||
vendor_type:
|
||||
type: string
|
||||
description: The vendor type of execution
|
||||
vendor_id:
|
||||
type: integer
|
||||
description: The vendor id of execution
|
||||
status:
|
||||
type: string
|
||||
description: The status of execution
|
||||
status_message:
|
||||
type: string
|
||||
description: The status message of execution
|
||||
metrics:
|
||||
$ref: '#/definitions/Metrics'
|
||||
trigger:
|
||||
type: string
|
||||
description: The trigger of execution
|
||||
extra_attrs:
|
||||
$ref: '#/definitions/ExtraAttrs'
|
||||
start_time:
|
||||
type: string
|
||||
description: The start time of execution
|
||||
end_time:
|
||||
type: string
|
||||
description: The end time of execution
|
||||
Task:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
description: The ID of task
|
||||
execution_id:
|
||||
type: integer
|
||||
description: The ID of task execution
|
||||
status:
|
||||
type: string
|
||||
description: The status of task
|
||||
status_message:
|
||||
type: string
|
||||
description: The status message of task
|
||||
run_count:
|
||||
type: integer
|
||||
description: The count of task run
|
||||
extra_attrs:
|
||||
$ref: '#/definitions/ExtraAttrs'
|
||||
creation_time:
|
||||
type: string
|
||||
description: The creation time of task
|
||||
update_time:
|
||||
type: string
|
||||
description: The update time of task
|
||||
start_time:
|
||||
type: string
|
||||
description: The start time of task
|
||||
end_time:
|
||||
type: string
|
||||
description: The end time of task
|
||||
|
71
src/controller/task/controller.go
Normal file
71
src/controller/task/controller.go
Normal file
@ -0,0 +1,71 @@
|
||||
// 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 task
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/goharbor/harbor/src/lib/q"
|
||||
"github.com/goharbor/harbor/src/pkg/task"
|
||||
)
|
||||
|
||||
var (
|
||||
// Ctl is a global task controller instance
|
||||
Ctl = NewController()
|
||||
)
|
||||
|
||||
// Controller manages the task
|
||||
type Controller interface {
|
||||
// Stop the specified task.
|
||||
Stop(ctx context.Context, id int64) (err error)
|
||||
// Get the specified task.
|
||||
Get(ctx context.Context, id int64) (task *task.Task, err error)
|
||||
// List the tasks according to the query.
|
||||
List(ctx context.Context, query *q.Query) (tasks []*task.Task, err error)
|
||||
// Get the log of the specified task.
|
||||
GetLog(ctx context.Context, id int64) (log []byte, err error)
|
||||
}
|
||||
|
||||
// NewController creates an instance of the default task controller.
|
||||
func NewController() Controller {
|
||||
return &controller{
|
||||
mgr: task.Mgr,
|
||||
}
|
||||
}
|
||||
|
||||
// controller defines the default task controller.
|
||||
type controller struct {
|
||||
mgr task.Manager
|
||||
}
|
||||
|
||||
// Stop the specified task.
|
||||
func (c *controller) Stop(ctx context.Context, id int64) (err error) {
|
||||
return c.mgr.Stop(ctx, id)
|
||||
}
|
||||
|
||||
// Get the specified task.
|
||||
func (c *controller) Get(ctx context.Context, id int64) (task *task.Task, err error) {
|
||||
return c.mgr.Get(ctx, id)
|
||||
}
|
||||
|
||||
// List the tasks according to the query.
|
||||
func (c *controller) List(ctx context.Context, query *q.Query) (tasks []*task.Task, err error) {
|
||||
return c.mgr.List(ctx, query)
|
||||
}
|
||||
|
||||
// Get the log of the specified task.
|
||||
func (c *controller) GetLog(ctx context.Context, id int64) (log []byte, err error) {
|
||||
return c.mgr.GetLog(ctx, id)
|
||||
}
|
74
src/controller/task/controller_test.go
Normal file
74
src/controller/task/controller_test.go
Normal file
@ -0,0 +1,74 @@
|
||||
// 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 task
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
model "github.com/goharbor/harbor/src/pkg/task"
|
||||
"github.com/goharbor/harbor/src/testing/mock"
|
||||
"github.com/goharbor/harbor/src/testing/pkg/task"
|
||||
"github.com/stretchr/testify/suite"
|
||||
)
|
||||
|
||||
type controllerTestSuite struct {
|
||||
suite.Suite
|
||||
ctl *controller
|
||||
mgr *task.FakeManager
|
||||
}
|
||||
|
||||
// TestControllerTestSuite tests controller.
|
||||
func TestControllerTestSuite(t *testing.T) {
|
||||
suite.Run(t, &controllerTestSuite{})
|
||||
}
|
||||
|
||||
// SetupTest setups the testing env.
|
||||
func (c *controllerTestSuite) SetupTest() {
|
||||
c.mgr = &task.FakeManager{}
|
||||
c.ctl = &controller{mgr: c.mgr}
|
||||
}
|
||||
|
||||
// TestStop tests stop.
|
||||
func (c *controllerTestSuite) TestStop() {
|
||||
c.mgr.On("Stop", mock.Anything, mock.Anything).Return(nil)
|
||||
err := c.ctl.Stop(nil, 1)
|
||||
c.NoError(err)
|
||||
}
|
||||
|
||||
// TestGet tests get.
|
||||
func (c *controllerTestSuite) TestGet() {
|
||||
c.mgr.On("Get", mock.Anything, int64(1)).Return(&model.Task{ID: 1}, nil)
|
||||
t, err := c.ctl.Get(nil, 1)
|
||||
c.NoError(err)
|
||||
c.Equal(int64(1), t.ID)
|
||||
}
|
||||
|
||||
// TestList tests list.
|
||||
func (c *controllerTestSuite) TestList() {
|
||||
c.mgr.On("List", mock.Anything, mock.Anything).Return([]*model.Task{
|
||||
{ID: 1}, {ID: 2},
|
||||
}, nil)
|
||||
ts, err := c.ctl.List(nil, nil)
|
||||
c.NoError(err)
|
||||
c.Len(ts, 2)
|
||||
}
|
||||
|
||||
// TestGetLog tests get log.
|
||||
func (c *controllerTestSuite) TestGetLog() {
|
||||
c.mgr.On("GetLog", mock.Anything, mock.Anything).Return([]byte("logs"), nil)
|
||||
l, err := c.ctl.GetLog(nil, 1)
|
||||
c.NoError(err)
|
||||
c.Equal([]byte("logs"), l)
|
||||
}
|
71
src/controller/task/execution_controller.go
Normal file
71
src/controller/task/execution_controller.go
Normal file
@ -0,0 +1,71 @@
|
||||
// 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 task
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/goharbor/harbor/src/lib/q"
|
||||
"github.com/goharbor/harbor/src/pkg/task"
|
||||
)
|
||||
|
||||
var (
|
||||
// ExecutionCtl is a global execution controller.
|
||||
ExecutionCtl = NewExecutionController()
|
||||
)
|
||||
|
||||
// ExecutionController manages the execution.
|
||||
type ExecutionController interface {
|
||||
// Stop all linked tasks of the specified execution.
|
||||
Stop(ctx context.Context, id int64) (err error)
|
||||
// Delete the specified execution and its tasks.
|
||||
Delete(ctx context.Context, id int64) (err error)
|
||||
// Get the specified execution.
|
||||
Get(ctx context.Context, id int64) (execution *task.Execution, err error)
|
||||
// List executions according to the query.
|
||||
List(ctx context.Context, query *q.Query) (executions []*task.Execution, err error)
|
||||
}
|
||||
|
||||
// executionController defines the execution controller.
|
||||
type executionController struct {
|
||||
mgr task.ExecutionManager
|
||||
}
|
||||
|
||||
// NewExecutionController creates an instance of the default execution controller.
|
||||
func NewExecutionController() ExecutionController {
|
||||
return &executionController{
|
||||
mgr: task.ExecMgr,
|
||||
}
|
||||
}
|
||||
|
||||
// Stop all linked tasks of the specified execution.
|
||||
func (ec *executionController) Stop(ctx context.Context, id int64) (err error) {
|
||||
return ec.mgr.Stop(ctx, id)
|
||||
}
|
||||
|
||||
// Delete the specified execution and its tasks.
|
||||
func (ec *executionController) Delete(ctx context.Context, id int64) (err error) {
|
||||
return ec.mgr.Delete(ctx, id)
|
||||
}
|
||||
|
||||
// Get the specified execution.
|
||||
func (ec *executionController) Get(ctx context.Context, id int64) (execution *task.Execution, err error) {
|
||||
return ec.mgr.Get(ctx, id)
|
||||
}
|
||||
|
||||
// List executions according to the query.
|
||||
func (ec *executionController) List(ctx context.Context, query *q.Query) (executions []*task.Execution, err error) {
|
||||
return ec.mgr.List(ctx, query)
|
||||
}
|
76
src/controller/task/execution_controller_test.go
Normal file
76
src/controller/task/execution_controller_test.go
Normal file
@ -0,0 +1,76 @@
|
||||
// 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 task
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
model "github.com/goharbor/harbor/src/pkg/task"
|
||||
"github.com/goharbor/harbor/src/testing/mock"
|
||||
"github.com/goharbor/harbor/src/testing/pkg/task"
|
||||
"github.com/stretchr/testify/suite"
|
||||
)
|
||||
|
||||
type executionControllerTestSuite struct {
|
||||
suite.Suite
|
||||
ctl *executionController
|
||||
mgr *task.FakeExecutionManager
|
||||
}
|
||||
|
||||
// TestExecutionControllerTestSuite tests controller.
|
||||
func TestExecutionControllerTestSuite(t *testing.T) {
|
||||
suite.Run(t, &executionControllerTestSuite{})
|
||||
}
|
||||
|
||||
// SetupTest setups the testing env.
|
||||
func (ec *executionControllerTestSuite) SetupTest() {
|
||||
ec.mgr = &task.FakeExecutionManager{}
|
||||
ec.ctl = &executionController{
|
||||
mgr: ec.mgr,
|
||||
}
|
||||
}
|
||||
|
||||
// TestStop tests stop.
|
||||
func (ec *executionControllerTestSuite) TestStop() {
|
||||
ec.mgr.On("Stop", mock.Anything, mock.Anything).Return(nil)
|
||||
err := ec.ctl.Stop(nil, 1)
|
||||
ec.NoError(err)
|
||||
}
|
||||
|
||||
// TestDelete tests delete.
|
||||
func (ec *executionControllerTestSuite) TestDelete() {
|
||||
ec.mgr.On("Delete", mock.Anything, mock.Anything).Return(nil)
|
||||
err := ec.ctl.Delete(nil, 1)
|
||||
ec.NoError(err)
|
||||
}
|
||||
|
||||
// TestGet tests get.
|
||||
func (ec *executionControllerTestSuite) TestGet() {
|
||||
ec.mgr.On("Get", mock.Anything, mock.Anything).Return(&model.Execution{ID: 1}, nil)
|
||||
e, err := ec.ctl.Get(nil, 1)
|
||||
ec.NoError(err)
|
||||
ec.Equal(int64(1), e.ID)
|
||||
}
|
||||
|
||||
// TestList tests list.
|
||||
func (ec *executionControllerTestSuite) TestList() {
|
||||
ec.mgr.On("List", mock.Anything, mock.Anything).Return([]*model.Execution{
|
||||
{ID: 1},
|
||||
{ID: 2},
|
||||
}, nil)
|
||||
es, err := ec.ctl.List(nil, nil)
|
||||
ec.NoError(err)
|
||||
ec.Len(es, 2)
|
||||
}
|
@ -8,11 +8,18 @@ import (
|
||||
"regexp"
|
||||
"time"
|
||||
|
||||
"github.com/goharbor/harbor/src/lib/q"
|
||||
|
||||
"github.com/goharbor/harbor/src/jobservice/job"
|
||||
|
||||
"github.com/goharbor/harbor/src/pkg/task"
|
||||
|
||||
"github.com/go-openapi/runtime/middleware"
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/goharbor/harbor/src/common/rbac"
|
||||
preheatCtl "github.com/goharbor/harbor/src/controller/p2p/preheat"
|
||||
projectCtl "github.com/goharbor/harbor/src/controller/project"
|
||||
taskCtl "github.com/goharbor/harbor/src/controller/task"
|
||||
liberrors "github.com/goharbor/harbor/src/lib/errors"
|
||||
"github.com/goharbor/harbor/src/pkg/p2p/preheat/models/policy"
|
||||
instanceModel "github.com/goharbor/harbor/src/pkg/p2p/preheat/models/provider"
|
||||
@ -24,9 +31,11 @@ import (
|
||||
|
||||
func newPreheatAPI() *preheatAPI {
|
||||
return &preheatAPI{
|
||||
preheatCtl: preheatCtl.Ctl,
|
||||
projectCtl: projectCtl.Ctl,
|
||||
enforcer: preheatCtl.Enf,
|
||||
preheatCtl: preheatCtl.Ctl,
|
||||
projectCtl: projectCtl.Ctl,
|
||||
enforcer: preheatCtl.Enf,
|
||||
executionCtl: taskCtl.ExecutionCtl,
|
||||
taskCtl: taskCtl.Ctl,
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,9 +46,11 @@ const nameRegex = "^[A-Za-z0-9]+(?:[._-][A-Za-z0-9]+)*$"
|
||||
|
||||
type preheatAPI struct {
|
||||
BaseAPI
|
||||
preheatCtl preheatCtl.Controller
|
||||
projectCtl projectCtl.Controller
|
||||
enforcer preheatCtl.Enforcer
|
||||
preheatCtl preheatCtl.Controller
|
||||
projectCtl projectCtl.Controller
|
||||
enforcer preheatCtl.Enforcer
|
||||
executionCtl taskCtl.ExecutionController
|
||||
taskCtl taskCtl.Controller
|
||||
}
|
||||
|
||||
func (api *preheatAPI) Prepare(ctx context.Context, operation string, params interface{}) middleware.Responder {
|
||||
@ -473,3 +484,178 @@ func convertParamInstanceToModelInstance(model *models.Instance) (*instanceModel
|
||||
Vendor: model.Vendor,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// convertExecutionToPayload converts model execution to swagger model.
|
||||
func convertExecutionToPayload(model *task.Execution) (*models.Execution, error) {
|
||||
if model == nil {
|
||||
return nil, errors.New("execution can not be nil")
|
||||
}
|
||||
|
||||
execution := &models.Execution{
|
||||
EndTime: model.EndTime.String(),
|
||||
ExtraAttrs: model.ExtraAttrs,
|
||||
ID: model.ID,
|
||||
StartTime: model.StartTime.String(),
|
||||
Status: model.Status,
|
||||
StatusMessage: model.StatusMessage,
|
||||
Trigger: model.Trigger,
|
||||
VendorID: model.VendorID,
|
||||
VendorType: model.VendorType,
|
||||
}
|
||||
if model.Metrics != nil {
|
||||
execution.Metrics = &models.Metrics{
|
||||
ErrorTaskCount: model.Metrics.ErrorTaskCount,
|
||||
PendingTaskCount: model.Metrics.PendingTaskCount,
|
||||
RunningTaskCount: model.Metrics.RunningTaskCount,
|
||||
ScheduledTaskCount: model.Metrics.ScheduledTaskCount,
|
||||
StoppedTaskCount: model.Metrics.StoppedTaskCount,
|
||||
SuccessTaskCount: model.Metrics.SuccessTaskCount,
|
||||
TaskCount: model.Metrics.TaskCount,
|
||||
}
|
||||
}
|
||||
|
||||
return execution, nil
|
||||
}
|
||||
|
||||
// GetExecution gets an execution.
|
||||
func (api *preheatAPI) GetExecution(ctx context.Context, params operation.GetExecutionParams) middleware.Responder {
|
||||
if err := api.RequireProjectAccess(ctx, params.ProjectName, rbac.ActionRead, rbac.ResourcePreatPolicy); err != nil {
|
||||
return api.SendError(ctx, err)
|
||||
}
|
||||
|
||||
execution, err := api.executionCtl.Get(ctx, params.ExecutionID)
|
||||
if err != nil {
|
||||
return api.SendError(ctx, err)
|
||||
}
|
||||
|
||||
payload, err := convertExecutionToPayload(execution)
|
||||
if err != nil {
|
||||
return api.SendError(ctx, err)
|
||||
}
|
||||
|
||||
return operation.NewGetExecutionOK().WithPayload(payload)
|
||||
}
|
||||
|
||||
// ListExecutions lists executions.
|
||||
func (api *preheatAPI) ListExecutions(ctx context.Context, params operation.ListExecutionsParams) middleware.Responder {
|
||||
if err := api.RequireProjectAccess(ctx, params.ProjectName, rbac.ActionList, rbac.ResourcePreatPolicy); err != nil {
|
||||
return api.SendError(ctx, err)
|
||||
}
|
||||
|
||||
project, err := api.projectCtl.GetByName(ctx, params.ProjectName)
|
||||
if err != nil {
|
||||
return api.SendError(ctx, err)
|
||||
}
|
||||
|
||||
policy, err := api.preheatCtl.GetPolicyByName(ctx, project.ProjectID, params.PreheatPolicyName)
|
||||
if err != nil {
|
||||
return api.SendError(ctx, err)
|
||||
}
|
||||
|
||||
query, err := api.BuildQuery(ctx, params.Q, params.Page, params.PageSize)
|
||||
if err != nil {
|
||||
return api.SendError(ctx, err)
|
||||
}
|
||||
|
||||
if query != nil {
|
||||
query.Keywords["vendor_type"] = job.P2PPreheat
|
||||
query.Keywords["vendor_id"] = policy.ID
|
||||
}
|
||||
|
||||
executions, err := api.executionCtl.List(ctx, query)
|
||||
if err != nil {
|
||||
return api.SendError(ctx, err)
|
||||
}
|
||||
|
||||
var payloads []*models.Execution
|
||||
for _, exec := range executions {
|
||||
p, err := convertExecutionToPayload(exec)
|
||||
if err != nil {
|
||||
return api.SendError(ctx, err)
|
||||
}
|
||||
payloads = append(payloads, p)
|
||||
}
|
||||
|
||||
return operation.NewListExecutionsOK().WithPayload(payloads)
|
||||
}
|
||||
|
||||
// StopExecution stops execution.
|
||||
func (api *preheatAPI) StopExecution(ctx context.Context, params operation.StopExecutionParams) middleware.Responder {
|
||||
if err := api.RequireProjectAccess(ctx, params.ProjectName, rbac.ActionUpdate, rbac.ResourcePreatPolicy); err != nil {
|
||||
return api.SendError(ctx, err)
|
||||
}
|
||||
|
||||
if params.Execution.Status == "Stopped" {
|
||||
err := api.executionCtl.Stop(ctx, params.ExecutionID)
|
||||
if err != nil {
|
||||
return api.SendError(ctx, err)
|
||||
}
|
||||
|
||||
return operation.NewStopExecutionOK()
|
||||
}
|
||||
|
||||
return api.SendError(ctx, fmt.Errorf("param status invalid: %#v", params.Execution))
|
||||
}
|
||||
|
||||
// convertTaskToPayload converts task to swagger model.
|
||||
func convertTaskToPayload(model *task.Task) (*models.Task, error) {
|
||||
if model == nil {
|
||||
return nil, errors.New("task model can not be nil")
|
||||
}
|
||||
|
||||
return &models.Task{
|
||||
CreationTime: model.CreationTime.String(),
|
||||
EndTime: model.EndTime.String(),
|
||||
ExecutionID: model.ExecutionID,
|
||||
ExtraAttrs: model.ExtraAttrs,
|
||||
ID: model.ID,
|
||||
RunCount: int64(model.RunCount),
|
||||
StartTime: model.StartTime.String(),
|
||||
Status: model.Status,
|
||||
StatusMessage: model.StatusMessage,
|
||||
UpdateTime: model.UpdateTime.String(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ListTasks lists tasks.
|
||||
func (api *preheatAPI) ListTasks(ctx context.Context, params operation.ListTasksParams) middleware.Responder {
|
||||
if err := api.RequireProjectAccess(ctx, params.ProjectName, rbac.ActionList, rbac.ResourcePreatPolicy); err != nil {
|
||||
return api.SendError(ctx, err)
|
||||
}
|
||||
|
||||
query := &q.Query{
|
||||
Keywords: map[string]interface{}{
|
||||
"execution_id": params.ExecutionID,
|
||||
},
|
||||
}
|
||||
|
||||
tasks, err := api.taskCtl.List(ctx, query)
|
||||
if err != nil {
|
||||
return api.SendError(ctx, err)
|
||||
}
|
||||
|
||||
var payloads []*models.Task
|
||||
for _, task := range tasks {
|
||||
p, err := convertTaskToPayload(task)
|
||||
if err != nil {
|
||||
return api.SendError(ctx, err)
|
||||
}
|
||||
payloads = append(payloads, p)
|
||||
}
|
||||
|
||||
return operation.NewListTasksOK().WithPayload(payloads)
|
||||
}
|
||||
|
||||
// GetLog gets log.
|
||||
func (api *preheatAPI) GetLog(ctx context.Context, params operation.GetLogParams) middleware.Responder {
|
||||
if err := api.RequireProjectAccess(ctx, params.ProjectName, rbac.ActionRead, rbac.ResourcePreatPolicy); err != nil {
|
||||
return api.SendError(ctx, err)
|
||||
}
|
||||
|
||||
l, err := api.taskCtl.GetLog(ctx, params.TaskID)
|
||||
if err != nil {
|
||||
return api.SendError(ctx, err)
|
||||
}
|
||||
|
||||
return operation.NewGetLogOK().WithPayload(string(l))
|
||||
}
|
||||
|
@ -5,6 +5,8 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/goharbor/harbor/src/pkg/task"
|
||||
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/goharbor/harbor/src/pkg/p2p/preheat/models/policy"
|
||||
instanceModel "github.com/goharbor/harbor/src/pkg/p2p/preheat/models/provider"
|
||||
@ -289,3 +291,113 @@ func Test_convertParamInstanceToModelInstance(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_convertExecutionToPayload(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
input *task.Execution
|
||||
expect *models.Execution
|
||||
shouldErr bool
|
||||
}{
|
||||
{
|
||||
name: "nil model",
|
||||
input: nil,
|
||||
expect: nil,
|
||||
shouldErr: true,
|
||||
},
|
||||
{
|
||||
name: "should ok",
|
||||
input: &task.Execution{
|
||||
ID: 1,
|
||||
VendorType: "p2p",
|
||||
VendorID: 1,
|
||||
Status: "",
|
||||
StatusMessage: "",
|
||||
Metrics: nil,
|
||||
Trigger: "",
|
||||
ExtraAttrs: nil,
|
||||
StartTime: time.Time{},
|
||||
EndTime: time.Time{},
|
||||
},
|
||||
expect: &models.Execution{
|
||||
EndTime: "0001-01-01 00:00:00 +0000 UTC",
|
||||
ExtraAttrs: nil,
|
||||
ID: 1,
|
||||
Metrics: nil,
|
||||
StartTime: "0001-01-01 00:00:00 +0000 UTC",
|
||||
Status: "",
|
||||
StatusMessage: "",
|
||||
Trigger: "",
|
||||
VendorID: 1,
|
||||
VendorType: "p2p",
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := convertExecutionToPayload(tt.input)
|
||||
if (err != nil) != tt.shouldErr {
|
||||
t.Errorf("convertExecutionToPayload() error = %v, wantErr %v", err, tt.shouldErr)
|
||||
return
|
||||
}
|
||||
if !reflect.DeepEqual(got, tt.expect) {
|
||||
t.Errorf("convertExecutionToPayload() = %v, want %v", got, tt.expect)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_convertTaskToPayload(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
input *task.Task
|
||||
expect *models.Task
|
||||
shouldErr bool
|
||||
}{
|
||||
{
|
||||
name: "nil model",
|
||||
input: nil,
|
||||
expect: nil,
|
||||
shouldErr: true,
|
||||
},
|
||||
{
|
||||
name: "should ok",
|
||||
input: &task.Task{
|
||||
ID: 0,
|
||||
ExecutionID: 0,
|
||||
Status: "",
|
||||
StatusMessage: "",
|
||||
RunCount: 0,
|
||||
ExtraAttrs: nil,
|
||||
CreationTime: time.Time{},
|
||||
StartTime: time.Time{},
|
||||
UpdateTime: time.Time{},
|
||||
EndTime: time.Time{},
|
||||
},
|
||||
expect: &models.Task{
|
||||
CreationTime: "0001-01-01 00:00:00 +0000 UTC",
|
||||
EndTime: "0001-01-01 00:00:00 +0000 UTC",
|
||||
ExecutionID: 0,
|
||||
ExtraAttrs: nil,
|
||||
ID: 0,
|
||||
RunCount: 0,
|
||||
StartTime: "0001-01-01 00:00:00 +0000 UTC",
|
||||
Status: "",
|
||||
StatusMessage: "",
|
||||
UpdateTime: "0001-01-01 00:00:00 +0000 UTC",
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := convertTaskToPayload(tt.input)
|
||||
if (err != nil) != tt.shouldErr {
|
||||
t.Errorf("convertTaskToPayload() error = %v, wantErr %v", err, tt.shouldErr)
|
||||
return
|
||||
}
|
||||
if !reflect.DeepEqual(got, tt.expect) {
|
||||
t.Errorf("convertTaskToPayload() = %v, want %v", got, tt.expect)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user