Merge pull request #8713 from ioito/hotfix/qx-rds-auto-renew

fix: support rds set auto renew
This commit is contained in:
Zexi Li
2020-11-10 12:55:19 +08:00
committed by GitHub
10 changed files with 190 additions and 18 deletions
+5
View File
@@ -357,3 +357,8 @@ type DBInstanceNetworkListInput struct {
NetworkFilterListInput
}
type DBInstanceAutoRenewInput struct {
// 是否自动续费
AutoRenew bool `json:"auto_renew"`
}
+20 -18
View File
@@ -16,24 +16,26 @@ package compute
const (
//实例状态
DBINSTANCE_INIT = "init" //初始化
DBINSTANCE_DEPLOYING = "deploying" //部署中
DBINSTANCE_RUNNING = "running" //运行中
DBINSTANCE_REBOOTING = "rebooting" //重启中
DBINSTANCE_MIGRATING = "migrating" //迁移中
DBINSTANCE_BACKING_UP = "backing_up" //备份中
DBINSTANCE_BACKING_UP_FAILED = "backing_up_failed" //备份失败
DBINSTANCE_RESTORING = "restoring" //备份恢复中
DBINSTANCE_RESTORE_FAILED = "restore_failed"
DBINSTANCE_IMPORTING = "importing" //数据导入中
DBINSTANCE_CLONING = "cloning" //克隆中
DBINSTANCE_DELETING = "deleting" //删除中
DBINSTANCE_DELETE_FAILED = "delete_failed" //删除失败
DBINSTANCE_MAINTENANCE = "maintenance" //维护中
DBINSTANCE_ISOLATING = "isolating" //隔离中
DBINSTANCE_ISOLATE = "isolate" //已隔离
DBINSTANCE_UPGRADING = "upgrading" //升级中
DBINSTANCE_UNKNOWN = "unknown"
DBINSTANCE_INIT = "init" //初始化
DBINSTANCE_DEPLOYING = "deploying" //部署中
DBINSTANCE_RUNNING = "running" //运行中
DBINSTANCE_REBOOTING = "rebooting" //重启中
DBINSTANCE_MIGRATING = "migrating" //迁移中
DBINSTANCE_BACKING_UP = "backing_up" //备份中
DBINSTANCE_BACKING_UP_FAILED = "backing_up_failed" //备份失败
DBINSTANCE_RESTORING = "restoring" //备份恢复中
DBINSTANCE_RESTORE_FAILED = "restore_failed"
DBINSTANCE_IMPORTING = "importing" //数据导入中
DBINSTANCE_CLONING = "cloning" //克隆中
DBINSTANCE_DELETING = "deleting" //删除中
DBINSTANCE_DELETE_FAILED = "delete_failed" //删除失败
DBINSTANCE_MAINTENANCE = "maintenance" //维护中
DBINSTANCE_ISOLATING = "isolating" //隔离中
DBINSTANCE_ISOLATE = "isolate" //已隔离
DBINSTANCE_UPGRADING = "upgrading" //升级中
DBINSTANCE_SET_AUTO_RENEW = "set_auto_renew" //设置自动续费中
DBINSTANCE_SET_AUTO_RENEW_FAILED = "set_auto_renew_failed" //设置自动续费失败
DBINSTANCE_UNKNOWN = "unknown"
DBINSTANCE_CHANGE_CONFIG = "change_config" //调整配置
DBINSTANCE_CHANGE_CONFIG_FAILED = "change_config_failed" //调整配置失败
+58
View File
@@ -901,6 +901,64 @@ func (self *SDBInstance) PerformRenew(ctx context.Context, userCred mcclient.Tok
return nil, self.StartDBInstanceRenewTask(ctx, userCred, durationStr, "")
}
func (self *SDBInstance) AllowPerformSetAutoRenew(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return db.IsAdminAllowPerform(userCred, self, "set-auto-renew")
}
func (self *SDBInstance) SetAutoRenew(autoRenew bool) error {
_, err := db.Update(self, func() error {
self.AutoRenew = autoRenew
return nil
})
return err
}
// 设置自动续费
// 要求RDS状态为running
// 要求RDS计费类型为包年包月(预付费)
func (self *SDBInstance) PerformSetAutoRenew(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.DBInstanceAutoRenewInput) (jsonutils.JSONObject, error) {
if !utils.IsInStringArray(self.Status, []string{api.DBINSTANCE_RUNNING}) {
return nil, httperrors.NewUnsupportOperationError("The dbinstance status need be %s, current is %s", api.DBINSTANCE_RUNNING, self.Status)
}
if self.BillingType != billing_api.BILLING_TYPE_PREPAID {
return nil, httperrors.NewUnsupportOperationError("Only %s dbinstance support this operation", billing_api.BILLING_TYPE_PREPAID)
}
if self.AutoRenew == input.AutoRenew {
return nil, nil
}
driver, err := self.GetRegionDriver()
if err != nil {
return nil, errors.Wrapf(err, "GetRegionDriver")
}
if !driver.IsSupportedDBInstanceAutoRenew() {
err := self.SetAutoRenew(input.AutoRenew)
if err != nil {
return nil, httperrors.NewGeneralError(err)
}
logclient.AddSimpleActionLog(self, logclient.ACT_SET_AUTO_RENEW, jsonutils.Marshal(input), userCred, true)
return nil, nil
}
return nil, self.StartSetAutoRenewTask(ctx, userCred, input.AutoRenew, "")
}
func (self *SDBInstance) StartSetAutoRenewTask(ctx context.Context, userCred mcclient.TokenCredential, autoRenew bool, parentTaskId string) error {
data := jsonutils.NewDict()
data.Set("auto_renew", jsonutils.NewBool(autoRenew))
task, err := taskman.TaskManager.NewTask(ctx, "DBInstanceSetAutoRenewTask", self, userCred, data, parentTaskId, "", nil)
if err != nil {
return errors.Wrap(err, "NewTask")
}
self.SetStatus(userCred, api.DBINSTANCE_SET_AUTO_RENEW, "")
task.ScheduleRun(nil)
return nil
}
func (self *SDBInstance) AllowPerformPublicConnection(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return self.IsOwner(userCred) || db.IsAdminAllowPerform(userCred, self, "public-connection")
}
+1
View File
@@ -162,6 +162,7 @@ type IDBInstanceDriver interface {
RequestChangeDBInstanceConfig(ctx context.Context, userCred mcclient.TokenCredential, instance *SDBInstance, task taskman.ITask) error
IsSupportedDBInstance() bool
IsSupportedDBInstanceAutoRenew() bool
IsSupportDBInstancePublicConnection() bool
IsSupportKeepDBInstanceManualBackup() bool
+4
View File
@@ -1573,6 +1573,10 @@ func (self *SAliyunRegionDriver) IsSupportedDBInstance() bool {
return true
}
func (self *SAliyunRegionDriver) IsSupportedDBInstanceAutoRenew() bool {
return true
}
func (self *SAliyunRegionDriver) IsSupportedElasticcache() bool {
return true
}
+4
View File
@@ -364,6 +364,10 @@ func (self *SBaseRegionDriver) IsSupportedDBInstance() bool {
return false
}
func (self *SBaseRegionDriver) IsSupportedDBInstanceAutoRenew() bool {
return false
}
func (self *SBaseRegionDriver) IsSupportedElasticcache() bool {
return false
}
@@ -1720,6 +1720,7 @@ func (self *SManagedVirtualizationRegionDriver) RequestCreateDBInstance(ctx cont
log.Errorf("failed to parse billing cycle %s: %v", dbinstance.BillingCycle, err)
} else if bc.IsValid() {
desc.BillingCycle = &bc
desc.BillingCycle.AutoRenew = dbinstance.AutoRenew
}
}
+4
View File
@@ -1392,6 +1392,10 @@ func (self *SQcloudRegionDriver) IsSupportedDBInstance() bool {
return true
}
func (self *SQcloudRegionDriver) IsSupportedDBInstanceAutoRenew() bool {
return true
}
func (self *SQcloudRegionDriver) GetRdsSupportSecgroupCount() int {
return 5
}
@@ -0,0 +1,68 @@
// Copyright 2019 Yunion
//
// 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 tasks
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type DBInstanceSetAutoRenewTask struct {
taskman.ITask
}
func init() {
taskman.RegisterTask(DBInstanceSetAutoRenewTask{})
}
func (self *DBInstanceSetAutoRenewTask) taskFailed(ctx context.Context, rds *models.SDBInstance, err error) {
db.OpsLog.LogEvent(rds, db.ACT_SET_AUTO_RENEW_FAIL, err, self.GetUserCred())
logclient.AddActionLogWithStartable(self, rds, logclient.ACT_SET_AUTO_RENEW, err, self.GetUserCred(), false)
rds.SetStatus(self.GetUserCred(), api.DBINSTANCE_SET_AUTO_RENEW_FAILED, err.Error())
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *DBInstanceSetAutoRenewTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
rds := obj.(*models.SDBInstance)
autoRenew, _ := self.GetParams().Bool("auto_renew")
iRds, err := rds.GetIDBInstance()
if err != nil {
self.taskFailed(ctx, rds, errors.Wrapf(err, "GetIDBInstance"))
return
}
err = iRds.SetAutoRenew(autoRenew)
if err != nil {
self.taskFailed(ctx, rds, errors.Wrapf(err, "iRds.SetAutoRenew"))
return
}
self.SetStage("OnDBInstanceSyncComplete", nil)
rds.StartDBInstanceSyncTask(ctx, self.GetUserCred(), nil, "")
}
func (self *DBInstanceSetAutoRenewTask) OnDBInstanceSyncComplete(ctx context.Context, rds *models.SDBInstance, data jsonutils.JSONObject) {
self.SetStageComplete(ctx, nil)
}
func (self *DBInstanceSetAutoRenewTask) OnDBInstanceSyncCompleteFailed(ctx context.Context, rds *models.SDBInstance, data jsonutils.JSONObject) {
self.SetStageFailed(ctx, data)
}
+25
View File
@@ -645,6 +645,9 @@ func (region *SRegion) CreateIDBInstance(desc *cloudprovider.SManagedDBInstanceC
params["UsedTime"] = fmt.Sprintf("%d", desc.BillingCycle.GetYears())
}
params["AutoRenew"] = "False"
if desc.BillingCycle.AutoRenew {
params["AutoRenew"] = "True"
}
}
action := "CreateDBInstance"
@@ -768,6 +771,28 @@ func (rds *SDBInstance) Renew(bc billing.SBillingCycle) error {
return rds.region.RenewInstance(rds.DBInstanceId, bc)
}
func (rds *SDBInstance) SetAutoRenew(autoRenew bool) error {
return rds.region.ModifyInstanceAutoRenewalAttribute(rds.DBInstanceId, 1, autoRenew)
}
func (region *SRegion) ModifyInstanceAutoRenewalAttribute(rdsId string, month int, autoRenew bool) error {
params := map[string]string{
"RegionId": region.RegionId,
"DBInstanceId": rdsId,
"AutoRenew": "False",
"ClientToken": utils.GenRequestId(20),
}
if autoRenew {
params["AutoRenew"] = "True"
params["Duration"] = fmt.Sprintf("%d", month)
}
_, err := region.rdsRequest("ModifyInstanceAutoRenewalAttribute", params)
if err != nil {
return errors.Wrap(err, "ModifyInstanceAutoRenewalAttribute")
}
return nil
}
func (region *SRegion) RenewDBInstance(instanceId string, bc billing.SBillingCycle) error {
params := map[string]string{
"DBInstanceId": instanceId,