2016-06-16 08:57:45 +02:00
|
|
|
/*
|
|
|
|
Copyright (c) 2016 VMware, Inc. All Rights Reserved.
|
|
|
|
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.
|
|
|
|
*/
|
|
|
|
|
2016-05-17 12:49:02 +02:00
|
|
|
package api
|
|
|
|
|
|
|
|
import (
|
2016-05-27 12:46:07 +02:00
|
|
|
"fmt"
|
|
|
|
"io"
|
2016-05-25 09:25:16 +02:00
|
|
|
"io/ioutil"
|
|
|
|
"net/http"
|
2016-05-27 09:04:20 +02:00
|
|
|
"strconv"
|
2016-05-25 09:25:16 +02:00
|
|
|
|
2016-05-17 12:49:02 +02:00
|
|
|
"github.com/vmware/harbor/dao"
|
2016-05-27 12:46:07 +02:00
|
|
|
"github.com/vmware/harbor/models"
|
2016-05-17 12:49:02 +02:00
|
|
|
"github.com/vmware/harbor/utils/log"
|
|
|
|
)
|
|
|
|
|
2016-05-27 12:46:07 +02:00
|
|
|
// RepJobAPI handles request to /api/replicationJobs /api/replicationJobs/:id/log
|
2016-05-17 12:49:02 +02:00
|
|
|
type RepJobAPI struct {
|
|
|
|
BaseAPI
|
2016-05-27 12:46:07 +02:00
|
|
|
jobID int64
|
2016-05-17 12:49:02 +02:00
|
|
|
}
|
|
|
|
|
2016-05-27 12:46:07 +02:00
|
|
|
// Prepare validates that whether user has system admin role
|
|
|
|
func (ra *RepJobAPI) Prepare() {
|
|
|
|
uid := ra.ValidateUser()
|
2016-05-17 12:49:02 +02:00
|
|
|
isAdmin, err := dao.IsAdminRole(uid)
|
|
|
|
if err != nil {
|
|
|
|
log.Errorf("Failed to Check if the user is admin, error: %v, uid: %d", err, uid)
|
|
|
|
}
|
|
|
|
if !isAdmin {
|
2016-05-27 12:46:07 +02:00
|
|
|
ra.CustomAbort(http.StatusForbidden, "")
|
|
|
|
}
|
|
|
|
|
|
|
|
idStr := ra.Ctx.Input.Param(":id")
|
|
|
|
if len(idStr) != 0 {
|
|
|
|
id, err := strconv.ParseInt(idStr, 10, 64)
|
|
|
|
if err != nil {
|
|
|
|
ra.CustomAbort(http.StatusBadRequest, "ID is invalid")
|
|
|
|
}
|
|
|
|
ra.jobID = id
|
2016-05-17 12:49:02 +02:00
|
|
|
}
|
2016-05-25 09:25:16 +02:00
|
|
|
|
2016-05-17 12:49:02 +02:00
|
|
|
}
|
|
|
|
|
2016-05-30 09:39:51 +02:00
|
|
|
// Get gets all the jobs according to the policy
|
2016-05-27 12:46:07 +02:00
|
|
|
func (ra *RepJobAPI) Get() {
|
|
|
|
policyID, err := ra.GetInt64("policy_id")
|
2016-05-17 12:49:02 +02:00
|
|
|
if err != nil {
|
|
|
|
log.Errorf("Failed to get policy id, error: %v", err)
|
2016-05-27 12:46:07 +02:00
|
|
|
ra.RenderError(http.StatusBadRequest, "Invalid policy id")
|
2016-05-17 12:49:02 +02:00
|
|
|
return
|
|
|
|
}
|
|
|
|
jobs, err := dao.GetRepJobByPolicy(policyID)
|
|
|
|
if err != nil {
|
|
|
|
log.Errorf("Failed to query job from db, error: %v", err)
|
2016-05-27 12:46:07 +02:00
|
|
|
ra.RenderError(http.StatusInternalServerError, "Failed to query job")
|
2016-05-17 12:49:02 +02:00
|
|
|
return
|
|
|
|
}
|
2016-05-27 12:46:07 +02:00
|
|
|
ra.Data["json"] = jobs
|
|
|
|
ra.ServeJSON()
|
2016-05-17 12:49:02 +02:00
|
|
|
}
|
|
|
|
|
2016-05-27 12:46:07 +02:00
|
|
|
// Delete ...
|
|
|
|
func (ra *RepJobAPI) Delete() {
|
|
|
|
if ra.jobID == 0 {
|
|
|
|
ra.CustomAbort(http.StatusBadRequest, "id is nil")
|
2016-05-25 09:25:16 +02:00
|
|
|
}
|
|
|
|
|
2016-05-27 12:46:07 +02:00
|
|
|
job, err := dao.GetRepJob(ra.jobID)
|
2016-05-25 09:25:16 +02:00
|
|
|
if err != nil {
|
2016-05-27 12:46:07 +02:00
|
|
|
log.Errorf("failed to get job %d: %v", ra.jobID, err)
|
|
|
|
ra.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
|
2016-05-25 09:25:16 +02:00
|
|
|
}
|
|
|
|
|
2016-05-27 12:46:07 +02:00
|
|
|
if job.Status == models.JobPending || job.Status == models.JobRunning {
|
|
|
|
ra.CustomAbort(http.StatusBadRequest, fmt.Sprintf("job is %s, can not be deleted", job.Status))
|
|
|
|
}
|
|
|
|
|
|
|
|
if err = dao.DeleteRepJob(ra.jobID); err != nil {
|
|
|
|
log.Errorf("failed to deleted job %d: %v", ra.jobID, err)
|
|
|
|
ra.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetLog ...
|
|
|
|
func (ra *RepJobAPI) GetLog() {
|
|
|
|
if ra.jobID == 0 {
|
|
|
|
ra.CustomAbort(http.StatusBadRequest, "id is nil")
|
|
|
|
}
|
|
|
|
|
|
|
|
resp, err := http.Get(buildJobLogURL(strconv.FormatInt(ra.jobID, 10)))
|
2016-05-25 09:25:16 +02:00
|
|
|
if err != nil {
|
2016-05-27 12:46:07 +02:00
|
|
|
log.Errorf("failed to get log for job %d: %v", ra.jobID, err)
|
|
|
|
ra.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
|
2016-05-25 09:25:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if resp.StatusCode == http.StatusOK {
|
2016-05-27 12:46:07 +02:00
|
|
|
for key, values := range resp.Header {
|
|
|
|
for _, value := range values {
|
|
|
|
ra.Ctx.ResponseWriter.Header().Set(key, value)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if _, err = io.Copy(ra.Ctx.ResponseWriter, resp.Body); err != nil {
|
2016-05-25 09:25:16 +02:00
|
|
|
log.Errorf("failed to write log to response; %v", err)
|
2016-05-27 12:46:07 +02:00
|
|
|
ra.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
|
2016-05-25 09:25:16 +02:00
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2016-05-27 12:46:07 +02:00
|
|
|
defer resp.Body.Close()
|
|
|
|
b, err := ioutil.ReadAll(resp.Body)
|
|
|
|
if err != nil {
|
|
|
|
log.Errorf("failed to read reponse body: %v", err)
|
|
|
|
ra.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
|
|
|
|
}
|
|
|
|
|
|
|
|
ra.CustomAbort(resp.StatusCode, string(b))
|
2016-05-25 09:25:16 +02:00
|
|
|
}
|
|
|
|
|
2016-05-17 12:49:02 +02:00
|
|
|
//TODO:add Post handler to call job service API to submit jobs by policy
|