harbor/api/replication_policy.go

243 lines
6.6 KiB
Go
Raw Normal View History

2016-05-17 12:49:02 +02:00
package api
import (
"fmt"
"net/http"
"strconv"
2016-05-17 12:49:02 +02:00
"github.com/vmware/harbor/dao"
"github.com/vmware/harbor/models"
"github.com/vmware/harbor/utils/log"
)
2016-05-27 12:46:07 +02:00
// RepPolicyAPI handles /api/replicationPolicies /api/replicationPolicies/:id/enablement
2016-05-17 12:49:02 +02:00
type RepPolicyAPI struct {
BaseAPI
}
2016-05-27 12:46:07 +02:00
// Prepare validates whether the user has system admin role
2016-05-17 12:49:02 +02:00
func (pa *RepPolicyAPI) Prepare() {
uid := pa.ValidateUser()
var err error
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 {
pa.CustomAbort(http.StatusForbidden, "")
}
}
2016-06-13 10:49:46 +02:00
// Get ...
2016-05-17 12:49:02 +02:00
func (pa *RepPolicyAPI) Get() {
2016-06-13 10:49:46 +02:00
id := pa.GetIDFromURL()
policy, err := dao.GetRepPolicy(id)
2016-05-17 12:49:02 +02:00
if err != nil {
2016-06-13 10:49:46 +02:00
log.Errorf("failed to get policy %d: %v", id, err)
pa.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
}
if policy == nil {
pa.CustomAbort(http.StatusNotFound, http.StatusText(http.StatusNotFound))
}
pa.Data["json"] = policy
pa.ServeJSON()
}
// List filters policies by name and project_id, if name and project_id
// are nil, List returns all policies
func (pa *RepPolicyAPI) List() {
name := pa.GetString("name")
projectIDStr := pa.GetString("project_id")
var projectID int64
var err error
if len(projectIDStr) != 0 {
projectID, err = strconv.ParseInt(projectIDStr, 10, 64)
if err != nil || projectID <= 0 {
pa.CustomAbort(http.StatusBadRequest, "invalid project ID")
}
2016-05-17 12:49:02 +02:00
}
2016-06-13 10:49:46 +02:00
policies, err := dao.FilterRepPolicies(name, projectID)
2016-05-17 12:49:02 +02:00
if err != nil {
2016-06-13 10:49:46 +02:00
log.Errorf("failed to filter policies %s project ID %d: %v", name, projectID, err)
pa.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
2016-05-17 12:49:02 +02:00
}
pa.Data["json"] = policies
pa.ServeJSON()
}
2016-05-30 09:39:51 +02:00
// Post creates a policy, and if it is enbled, the replication will be triggered right now.
2016-05-17 12:49:02 +02:00
func (pa *RepPolicyAPI) Post() {
policy := &models.RepPolicy{}
2016-06-06 11:46:19 +02:00
pa.DecodeJSONReqAndValidate(policy)
po, err := dao.GetRepPolicyByName(policy.Name)
if err != nil {
log.Errorf("failed to get policy %s: %v", policy.Name, err)
pa.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
}
if po != nil {
pa.CustomAbort(http.StatusConflict, "name is already used")
}
project, err := dao.GetProjectByID(policy.ProjectID)
if err != nil {
log.Errorf("failed to get project %d: %v", policy.ProjectID, err)
pa.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
}
if project == nil {
pa.CustomAbort(http.StatusBadRequest, fmt.Sprintf("project %d does not exist", policy.ProjectID))
}
target, err := dao.GetRepTarget(policy.TargetID)
if err != nil {
log.Errorf("failed to get target %d: %v", policy.TargetID, err)
pa.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
}
if target == nil {
pa.CustomAbort(http.StatusBadRequest, fmt.Sprintf("target %d does not exist", policy.TargetID))
}
pid, err := dao.AddRepPolicy(*policy)
2016-05-17 12:49:02 +02:00
if err != nil {
log.Errorf("Failed to add policy to DB, error: %v", err)
pa.RenderError(http.StatusInternalServerError, "Internal Error")
return
}
2016-05-27 09:04:20 +02:00
if policy.Enabled == 1 {
go func() {
if err := TriggerReplication(pid, "", nil, models.RepOpTransfer); err != nil {
log.Errorf("failed to trigger replication of %d: %v", pid, err)
} else {
log.Infof("replication of %d triggered", pid)
}
}()
}
2016-05-17 12:49:02 +02:00
pa.Redirect(http.StatusCreated, strconv.FormatInt(pid, 10))
}
2016-06-13 11:32:22 +02:00
// Put modifies name and description of policy
func (pa *RepPolicyAPI) Put() {
id := pa.GetIDFromURL()
originalPolicy, err := dao.GetRepPolicy(id)
if err != nil {
log.Errorf("failed to get policy %d: %v", id, err)
pa.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
}
if originalPolicy == nil {
pa.CustomAbort(http.StatusNotFound, http.StatusText(http.StatusNotFound))
}
2016-06-14 11:33:37 +02:00
policy := &models.RepPolicy{}
2016-06-13 11:32:22 +02:00
pa.DecodeJSONReq(policy)
policy.ProjectID = originalPolicy.ProjectID
policy.TargetID = originalPolicy.TargetID
pa.Validate(policy)
if policy.Name != originalPolicy.Name {
po, err := dao.GetRepPolicyByName(policy.Name)
if err != nil {
log.Errorf("failed to get policy %s: %v", policy.Name, err)
pa.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
}
if po != nil {
pa.CustomAbort(http.StatusConflict, "name is already used")
}
}
policy.ID = id
if err = dao.UpdateRepPolicy(policy); err != nil {
log.Errorf("failed to update policy %d: %v", id, err)
pa.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
}
if policy.Enabled == originalPolicy.Enabled {
return
}
//enablement has been modified
if policy.Enabled == 1 {
go func() {
if err := TriggerReplication(id, "", nil, models.RepOpTransfer); err != nil {
log.Errorf("failed to trigger replication of %d: %v", id, err)
} else {
log.Infof("replication of %d triggered", id)
}
}()
} else {
go func() {
if err := postReplicationAction(id, "stop"); err != nil {
log.Errorf("failed to stop replication of %d: %v", id, err)
} else {
log.Infof("try to stop replication of %d", id)
}
}()
}
}
2016-05-17 12:49:02 +02:00
type enablementReq struct {
Enabled int `json:"enabled"`
}
2016-05-30 09:39:51 +02:00
// UpdateEnablement changes the enablement of the policy
2016-05-17 12:49:02 +02:00
func (pa *RepPolicyAPI) UpdateEnablement() {
2016-06-13 11:32:22 +02:00
id := pa.GetIDFromURL()
policy, err := dao.GetRepPolicy(id)
if err != nil {
log.Errorf("failed to get policy %d: %v", id, err)
pa.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
}
if policy == nil {
pa.CustomAbort(http.StatusNotFound, http.StatusText(http.StatusNotFound))
}
2016-05-17 12:49:02 +02:00
e := enablementReq{}
pa.DecodeJSONReq(&e)
2016-05-27 09:04:20 +02:00
if e.Enabled != 0 && e.Enabled != 1 {
2016-05-17 12:49:02 +02:00
pa.RenderError(http.StatusBadRequest, "invalid enabled value")
return
}
2016-05-27 09:04:20 +02:00
2016-06-14 05:14:48 +02:00
if policy.Enabled == e.Enabled {
2016-05-27 09:04:20 +02:00
return
}
2016-06-14 05:14:48 +02:00
if err := dao.UpdateRepPolicyEnablement(id, e.Enabled); err != nil {
2016-05-17 12:49:02 +02:00
log.Errorf("Failed to update policy enablement in DB, error: %v", err)
pa.RenderError(http.StatusInternalServerError, "Internal Error")
return
}
if e.Enabled == 1 {
go func() {
2016-06-14 05:14:48 +02:00
if err := TriggerReplication(id, "", nil, models.RepOpTransfer); err != nil {
log.Errorf("failed to trigger replication of %d: %v", id, err)
} else {
2016-06-14 05:14:48 +02:00
log.Infof("replication of %d triggered", id)
}
}()
} else {
go func() {
2016-06-14 05:14:48 +02:00
if err := postReplicationAction(id, "stop"); err != nil {
log.Errorf("failed to stop replication of %d: %v", id, err)
} else {
2016-06-14 05:14:48 +02:00
log.Infof("try to stop replication of %d", id)
}
}()
}
2016-05-17 12:49:02 +02:00
}