mirror of
https://github.com/goharbor/harbor.git
synced 2024-12-19 23:28:20 +01:00
Merge pull request #9859 from ywk253100/191113_subresource_1.10
Refine the implementation of replication execution API
This commit is contained in:
commit
10850a06d8
@ -30,6 +30,8 @@ import (
|
|||||||
// ReplicationOperationAPI handles the replication operation requests
|
// ReplicationOperationAPI handles the replication operation requests
|
||||||
type ReplicationOperationAPI struct {
|
type ReplicationOperationAPI struct {
|
||||||
BaseController
|
BaseController
|
||||||
|
execution *models.Execution
|
||||||
|
task *models.Task
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepare ...
|
// Prepare ...
|
||||||
@ -45,6 +47,46 @@ func (r *ReplicationOperationAPI) Prepare() {
|
|||||||
r.SendForbiddenError(errors.New(r.SecurityCtx.GetUsername()))
|
r.SendForbiddenError(errors.New(r.SecurityCtx.GetUsername()))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check the existence of execution if execution ID is provided in the request path
|
||||||
|
executionIDStr := r.GetStringFromPath(":id")
|
||||||
|
if len(executionIDStr) > 0 {
|
||||||
|
executionID, err := strconv.ParseInt(executionIDStr, 10, 64)
|
||||||
|
if err != nil || executionID <= 0 {
|
||||||
|
r.SendBadRequestError(fmt.Errorf("invalid execution ID: %s", executionIDStr))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
execution, err := replication.OperationCtl.GetExecution(executionID)
|
||||||
|
if err != nil {
|
||||||
|
r.SendInternalServerError(fmt.Errorf("failed to get execution %d: %v", executionID, err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if execution == nil {
|
||||||
|
r.SendNotFoundError(fmt.Errorf("execution %d not found", executionID))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
r.execution = execution
|
||||||
|
|
||||||
|
// check the existence of task if task ID is provided in the request path
|
||||||
|
taskIDStr := r.GetStringFromPath(":tid")
|
||||||
|
if len(taskIDStr) > 0 {
|
||||||
|
taskID, err := strconv.ParseInt(taskIDStr, 10, 64)
|
||||||
|
if err != nil || taskID <= 0 {
|
||||||
|
r.SendBadRequestError(fmt.Errorf("invalid task ID: %s", taskIDStr))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
task, err := replication.OperationCtl.GetTask(taskID)
|
||||||
|
if err != nil {
|
||||||
|
r.SendInternalServerError(fmt.Errorf("failed to get task %d: %v", taskID, err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if task == nil || task.ExecutionID != executionID {
|
||||||
|
r.SendNotFoundError(fmt.Errorf("task %d not found", taskID))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
r.task = task
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The API is open only for system admin currently, we can use
|
// The API is open only for system admin currently, we can use
|
||||||
@ -146,68 +188,21 @@ func (r *ReplicationOperationAPI) CreateExecution() {
|
|||||||
|
|
||||||
// GetExecution gets one execution of the replication
|
// GetExecution gets one execution of the replication
|
||||||
func (r *ReplicationOperationAPI) GetExecution() {
|
func (r *ReplicationOperationAPI) GetExecution() {
|
||||||
executionID, err := r.GetInt64FromPath(":id")
|
r.WriteJSONData(r.execution)
|
||||||
if err != nil || executionID <= 0 {
|
|
||||||
r.SendBadRequestError(errors.New("invalid execution ID"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
execution, err := replication.OperationCtl.GetExecution(executionID)
|
|
||||||
if err != nil {
|
|
||||||
r.SendInternalServerError(fmt.Errorf("failed to get execution %d: %v", executionID, err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if execution == nil {
|
|
||||||
r.SendNotFoundError(fmt.Errorf("execution %d not found", executionID))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
r.WriteJSONData(execution)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// StopExecution stops one execution of the replication
|
// StopExecution stops one execution of the replication
|
||||||
func (r *ReplicationOperationAPI) StopExecution() {
|
func (r *ReplicationOperationAPI) StopExecution() {
|
||||||
executionID, err := r.GetInt64FromPath(":id")
|
if err := replication.OperationCtl.StopReplication(r.execution.ID); err != nil {
|
||||||
if err != nil || executionID <= 0 {
|
r.SendInternalServerError(fmt.Errorf("failed to stop execution %d: %v", r.execution.ID, err))
|
||||||
r.SendBadRequestError(errors.New("invalid execution ID"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
execution, err := replication.OperationCtl.GetExecution(executionID)
|
|
||||||
if err != nil {
|
|
||||||
r.SendInternalServerError(fmt.Errorf("failed to get execution %d: %v", executionID, err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if execution == nil {
|
|
||||||
r.SendNotFoundError(fmt.Errorf("execution %d not found", executionID))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := replication.OperationCtl.StopReplication(executionID); err != nil {
|
|
||||||
r.SendInternalServerError(fmt.Errorf("failed to stop execution %d: %v", executionID, err))
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListTasks ...
|
// ListTasks ...
|
||||||
func (r *ReplicationOperationAPI) ListTasks() {
|
func (r *ReplicationOperationAPI) ListTasks() {
|
||||||
executionID, err := r.GetInt64FromPath(":id")
|
|
||||||
if err != nil || executionID <= 0 {
|
|
||||||
r.SendBadRequestError(errors.New("invalid execution ID"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
execution, err := replication.OperationCtl.GetExecution(executionID)
|
|
||||||
if err != nil {
|
|
||||||
r.SendInternalServerError(fmt.Errorf("failed to get execution %d: %v", executionID, err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if execution == nil {
|
|
||||||
r.SendNotFoundError(fmt.Errorf("execution %d not found", executionID))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
query := &models.TaskQuery{
|
query := &models.TaskQuery{
|
||||||
ExecutionID: executionID,
|
ExecutionID: r.execution.ID,
|
||||||
ResourceType: r.GetString("resource_type"),
|
ResourceType: r.GetString("resource_type"),
|
||||||
}
|
}
|
||||||
status := r.GetString("status")
|
status := r.GetString("status")
|
||||||
@ -232,53 +227,22 @@ func (r *ReplicationOperationAPI) ListTasks() {
|
|||||||
|
|
||||||
// GetTaskLog ...
|
// GetTaskLog ...
|
||||||
func (r *ReplicationOperationAPI) GetTaskLog() {
|
func (r *ReplicationOperationAPI) GetTaskLog() {
|
||||||
executionID, err := r.GetInt64FromPath(":id")
|
logBytes, err := replication.OperationCtl.GetTaskLog(r.task.ID)
|
||||||
if err != nil || executionID <= 0 {
|
|
||||||
r.SendBadRequestError(errors.New("invalid execution ID"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
execution, err := replication.OperationCtl.GetExecution(executionID)
|
|
||||||
if err != nil {
|
|
||||||
r.SendInternalServerError(fmt.Errorf("failed to get execution %d: %v", executionID, err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if execution == nil {
|
|
||||||
r.SendNotFoundError(fmt.Errorf("execution %d not found", executionID))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
taskID, err := r.GetInt64FromPath(":tid")
|
|
||||||
if err != nil || taskID <= 0 {
|
|
||||||
r.SendBadRequestError(errors.New("invalid task ID"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
task, err := replication.OperationCtl.GetTask(taskID)
|
|
||||||
if err != nil {
|
|
||||||
r.SendInternalServerError(fmt.Errorf("failed to get task %d: %v", taskID, err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if task == nil {
|
|
||||||
r.SendNotFoundError(fmt.Errorf("task %d not found", taskID))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
logBytes, err := replication.OperationCtl.GetTaskLog(taskID)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if httpErr, ok := err.(*common_http.Error); ok {
|
if httpErr, ok := err.(*common_http.Error); ok {
|
||||||
if ok && httpErr.Code == http.StatusNotFound {
|
if ok && httpErr.Code == http.StatusNotFound {
|
||||||
r.SendNotFoundError(fmt.Errorf("the log of task %d not found", taskID))
|
r.SendNotFoundError(fmt.Errorf("the log of task %d not found", r.task.ID))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
r.SendInternalServerError(fmt.Errorf("failed to get log of task %d: %v", taskID, err))
|
r.SendInternalServerError(fmt.Errorf("failed to get log of task %d: %v", r.task.ID, err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r.Ctx.ResponseWriter.Header().Set(http.CanonicalHeaderKey("Content-Length"), strconv.Itoa(len(logBytes)))
|
r.Ctx.ResponseWriter.Header().Set(http.CanonicalHeaderKey("Content-Length"), strconv.Itoa(len(logBytes)))
|
||||||
r.Ctx.ResponseWriter.Header().Set(http.CanonicalHeaderKey("Content-Type"), "text/plain")
|
r.Ctx.ResponseWriter.Header().Set(http.CanonicalHeaderKey("Content-Type"), "text/plain")
|
||||||
_, err = r.Ctx.ResponseWriter.Write(logBytes)
|
_, err = r.Ctx.ResponseWriter.Write(logBytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
r.SendInternalServerError(fmt.Errorf("failed to write log of task %d: %v", taskID, err))
|
r.SendInternalServerError(fmt.Errorf("failed to write log of task %d: %v", r.task.ID, err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,6 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/goharbor/harbor/src/replication"
|
"github.com/goharbor/harbor/src/replication"
|
||||||
|
|
||||||
"github.com/goharbor/harbor/src/replication/dao/models"
|
"github.com/goharbor/harbor/src/replication/dao/models"
|
||||||
"github.com/goharbor/harbor/src/replication/model"
|
"github.com/goharbor/harbor/src/replication/model"
|
||||||
)
|
)
|
||||||
@ -50,7 +49,7 @@ func (f *fakedOperationController) GetExecution(id int64) (*models.Execution, er
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
func (f *fakedOperationController) ListTasks(...*models.TaskQuery) (int64, []*models.Task, error) {
|
func (f *fakedOperationController) ListTasks(...*models.TaskQuery) (int64, []*models.Task, error) {
|
||||||
return 1, []*models.Task{
|
return 2, []*models.Task{
|
||||||
{
|
{
|
||||||
ID: 1,
|
ID: 1,
|
||||||
ExecutionID: 1,
|
ExecutionID: 1,
|
||||||
@ -64,6 +63,12 @@ func (f *fakedOperationController) GetTask(id int64) (*models.Task, error) {
|
|||||||
ExecutionID: 1,
|
ExecutionID: 1,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
if id == 3 {
|
||||||
|
return &models.Task{
|
||||||
|
ID: 3,
|
||||||
|
ExecutionID: 2,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
func (f *fakedOperationController) UpdateTaskStatus(id int64, status string, statusRevision int64, statusCondition ...string) error {
|
func (f *fakedOperationController) UpdateTaskStatus(id int64, status string, statusRevision int64, statusCondition ...string) error {
|
||||||
@ -414,6 +419,15 @@ func TestGetTaskLog(t *testing.T) {
|
|||||||
},
|
},
|
||||||
code: http.StatusNotFound,
|
code: http.StatusNotFound,
|
||||||
},
|
},
|
||||||
|
// 404, task not found
|
||||||
|
{
|
||||||
|
request: &testingRequest{
|
||||||
|
method: http.MethodGet,
|
||||||
|
url: "/api/replication/executions/1/tasks/3/log",
|
||||||
|
credential: sysAdmin,
|
||||||
|
},
|
||||||
|
code: http.StatusNotFound,
|
||||||
|
},
|
||||||
// 200
|
// 200
|
||||||
{
|
{
|
||||||
request: &testingRequest{
|
request: &testingRequest{
|
||||||
|
Loading…
Reference in New Issue
Block a user