1. support updating the target of policy 2. can not delete a target if it is being used

This commit is contained in:
Wenkai Yin 2016-06-16 14:18:23 +08:00
parent 836598f5c9
commit 8939b54448
4 changed files with 105 additions and 17 deletions

View File

@ -126,7 +126,7 @@ func (pa *RepPolicyAPI) Post() {
pa.Redirect(http.StatusCreated, strconv.FormatInt(pid, 10)) pa.Redirect(http.StatusCreated, strconv.FormatInt(pid, 10))
} }
// Put modifies name and description of policy // Put modifies name, description, target and enablement of policy
func (pa *RepPolicyAPI) Put() { func (pa *RepPolicyAPI) Put() {
id := pa.GetIDFromURL() id := pa.GetIDFromURL()
originalPolicy, err := dao.GetRepPolicy(id) originalPolicy, err := dao.GetRepPolicy(id)
@ -142,7 +142,6 @@ func (pa *RepPolicyAPI) Put() {
policy := &models.RepPolicy{} policy := &models.RepPolicy{}
pa.DecodeJSONReq(policy) pa.DecodeJSONReq(policy)
policy.ProjectID = originalPolicy.ProjectID policy.ProjectID = originalPolicy.ProjectID
policy.TargetID = originalPolicy.TargetID
pa.Validate(policy) pa.Validate(policy)
if policy.Name != originalPolicy.Name { if policy.Name != originalPolicy.Name {
@ -157,19 +156,77 @@ func (pa *RepPolicyAPI) Put() {
} }
} }
if policy.TargetID != originalPolicy.TargetID {
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))
}
}
policy.ID = id policy.ID = id
isTargetChanged := !(policy.TargetID == originalPolicy.TargetID)
isEnablementChanged := !(policy.Enabled == policy.Enabled)
var shouldStop, shouldTrigger bool
// if target and enablement are not changed, do nothing
if !isTargetChanged && !isEnablementChanged {
shouldStop = false
shouldTrigger = false
} else if !isTargetChanged && isEnablementChanged {
// target is not changed, but enablement is changed
if policy.Enabled == 0 {
shouldStop = true
shouldTrigger = false
} else {
shouldStop = false
shouldTrigger = true
}
} else if isTargetChanged && !isEnablementChanged {
// target is changed, but enablement is not changed
if policy.Enabled == 0 {
// enablement is 0, do nothing
shouldStop = false
shouldTrigger = false
} else {
// enablement is 1, so stop original target's jobs
// and trigger new target's jobs
shouldStop = true
shouldTrigger = true
}
} else {
// both target and enablement are changed
// enablement: 1 -> 0
if policy.Enabled == 0 {
shouldStop = true
shouldTrigger = false
} else {
shouldStop = false
shouldTrigger = true
}
}
if shouldStop {
if err := postReplicationAction(id, "stop"); err != nil {
log.Errorf("failed to stop replication of %d: %v", id, err)
pa.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
}
log.Infof("replication of %d has been stopped", id)
}
if err = dao.UpdateRepPolicy(policy); err != nil { if err = dao.UpdateRepPolicy(policy); err != nil {
log.Errorf("failed to update policy %d: %v", id, err) log.Errorf("failed to update policy %d: %v", id, err)
pa.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) pa.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
} }
if policy.Enabled == originalPolicy.Enabled { if shouldTrigger {
return
}
//enablement has been modified
if policy.Enabled == 1 {
go func() { go func() {
if err := TriggerReplication(id, "", nil, models.RepOpTransfer); err != nil { if err := TriggerReplication(id, "", nil, models.RepOpTransfer); err != nil {
log.Errorf("failed to trigger replication of %d: %v", id, err) log.Errorf("failed to trigger replication of %d: %v", id, err)
@ -177,14 +234,6 @@ func (pa *RepPolicyAPI) Put() {
log.Infof("replication of %d triggered", id) 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)
}
}()
} }
} }

View File

@ -258,6 +258,16 @@ func (t *TargetAPI) Delete() {
t.CustomAbort(http.StatusNotFound, http.StatusText(http.StatusNotFound)) t.CustomAbort(http.StatusNotFound, http.StatusText(http.StatusNotFound))
} }
policies, err := dao.GetRepPolicyByTarget(id)
if err != nil {
log.Errorf("failed to get policies according target %d: %v", id, err)
t.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
}
if len(policies) > 0 {
t.CustomAbort(http.StatusBadRequest, "the target is used by policies, can not be deleted")
}
if err = dao.DeleteRepTarget(id); err != nil { if err = dao.DeleteRepTarget(id); err != nil {
log.Errorf("failed to delete target %d: %v", id, err) log.Errorf("failed to delete target %d: %v", id, err)
t.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) t.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))

View File

@ -911,6 +911,21 @@ func TestAddRepPolicy(t *testing.T) {
} }
func TestGetRepPolicyByTarget(t *testing.T) {
policies, err := GetRepPolicyByTarget(targetID)
if err != nil {
t.Fatalf("failed to get policy according target %d: %v", targetID, err)
}
if len(policies) == 0 {
t.Fatal("unexpected length of policies 0, expected is >0")
}
if policies[0].ID != policyID {
t.Fatal("unexpected policy: %d, expected: %d", policies[0].ID, policyID)
}
}
func TestGetRepPolicyByName(t *testing.T) { func TestGetRepPolicyByName(t *testing.T) {
policy, err := GetRepPolicy(policyID) policy, err := GetRepPolicy(policyID)
if err != nil { if err != nil {

View File

@ -177,10 +177,24 @@ func GetRepPolicyByProject(projectID int64) ([]*models.RepPolicy, error) {
return policies, nil return policies, nil
} }
// GetRepPolicyByTarget ...
func GetRepPolicyByTarget(targetID int64) ([]*models.RepPolicy, error) {
o := GetOrmer()
sql := `select * from replication_policy where target_id = ?`
var policies []*models.RepPolicy
if _, err := o.Raw(sql, targetID).QueryRows(&policies); err != nil {
return nil, err
}
return policies, nil
}
// UpdateRepPolicy ... // UpdateRepPolicy ...
func UpdateRepPolicy(policy *models.RepPolicy) error { func UpdateRepPolicy(policy *models.RepPolicy) error {
o := GetOrmer() o := GetOrmer()
_, err := o.Update(policy, "Name", "Enabled", "Description", "CronStr") _, err := o.Update(policy, "TargetID", "Name", "Enabled", "Description", "CronStr")
return err return err
} }