fix: 避免因backup删除失败导致删除rds无限失败

This commit is contained in:
Qu Xuan
2019-11-07 15:01:42 +08:00
parent e7491733d7
commit cf7e876e03
7 changed files with 76 additions and 56 deletions

View File

@@ -231,8 +231,17 @@ func init() {
return nil
})
R(&DBInstanceIdOptions{}, "dbinstance-delete", "Delete DB instance", func(s *mcclient.ClientSession, opts *DBInstanceIdOptions) error {
result, err := modules.DBInstance.Delete(s, opts.ID, nil)
type DBInstanceDeleteOptions struct {
ID string `help:"DBInstance Id or name"`
KeepBackup bool `help:"Keep dbinstance manual backup after delete dbinstance"`
}
R(&DBInstanceDeleteOptions{}, "dbinstance-delete", "Delete DB instance", func(s *mcclient.ClientSession, opts *DBInstanceDeleteOptions) error {
params := jsonutils.NewDict()
if opts.KeepBackup {
params.Add(jsonutils.JSONTrue, "keep_backup")
}
result, err := modules.DBInstance.Delete(s, opts.ID, params)
if err != nil {
return err
}

View File

@@ -14,10 +14,11 @@ delete:
summary: 删除指定RDS实例
parameters:
- $ref: '../parameters/dbinstance.yaml#/dbinstanceId'
- $ref: '../parameters/dbinstance.yaml#/keep_backup'
responses:
200:
description: 被删除RDS实例的信息
schema:
$ref: '../schemas/dbinstance.yaml#/DBInstanceResponse'
tags:
- dbinstance
- dbinstance

View File

@@ -39,4 +39,11 @@ dbinstance:
name: dbinstance
in: query
type: string
description: 根据RDS实例名称或ID过滤资源
description: 根据RDS实例名称或ID过滤资源
keep_backup:
name: keep_backup
in: body
type: boolean
default: false
description: 删除RDS实例时保留手动备份

View File

@@ -773,7 +773,9 @@ func (manager *SDBInstanceManager) getDBInstancesByProviderId(providerId string)
}
func (self *SDBInstance) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
return self.StartDBInstanceDeleteTask(ctx, userCred, nil, "")
params := jsonutils.NewDict()
params.Set("keep_backup", jsonutils.NewBool(jsonutils.QueryBoolean(data, "keep_backup", false)))
return self.StartDBInstanceDeleteTask(ctx, userCred, params, "")
}
func (self *SDBInstance) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
@@ -923,14 +925,23 @@ func (self *SDBInstance) GetDBInstancePrivilege(account, database string) (*SDBI
return privilege, nil
}
func (self *SDBInstance) GetDBInstanceBackups() ([]SDBInstanceBackup, error) {
func (self *SDBInstance) GetDBInstanceBackupByMode(mode string) ([]SDBInstanceBackup, error) {
backups := []SDBInstanceBackup{}
q := DBInstanceBackupManager.Query().Equals("dbinstance_id", self.Id)
switch mode {
case api.BACKUP_MODE_MANUAL, api.BACKUP_MODE_AUTOMATED:
q = q.Equals("backup_mode", mode)
}
err := db.FetchModelObjects(DBInstanceBackupManager, q, &backups)
if err != nil {
return nil, errors.Wrap(err, "GetDBInstanceBackups.FetchModelObjects")
}
return backups, nil
}
func (self *SDBInstance) GetDBInstanceBackups() ([]SDBInstanceBackup, error) {
return self.GetDBInstanceBackupByMode("")
}
func (self *SDBInstance) GetDBDatabases() ([]SDBInstanceDatabase, error) {

View File

@@ -1354,17 +1354,15 @@ func (instance *SDBInstance) purgeNetwork(ctx context.Context, userCred mcclient
return nil
}
func (instance *SDBInstance) purgeBackups(ctx context.Context, userCred mcclient.TokenCredential) error {
backups, err := instance.GetDBInstanceBackups()
func (instance *SDBInstance) PurgeBackups(ctx context.Context, userCred mcclient.TokenCredential, mode string) error {
backups, err := instance.GetDBInstanceBackupByMode(mode)
if err != nil {
return errors.Wrap(err, "instance.GetDBInstanceBackups")
}
for _, backup := range backups {
if backup.BackupMode == api.BACKUP_MODE_AUTOMATED {
err = backup.purge(ctx, userCred)
if err != nil {
return errors.Wrapf(err, "backup.purge %s(%s)", backup.Name, backup.Id)
}
err = backup.purge(ctx, userCred)
if err != nil {
return errors.Wrapf(err, "backup.purge %s(%s)", backup.Name, backup.Id)
}
}
return nil
@@ -1394,7 +1392,7 @@ func (instance *SDBInstance) Purge(ctx context.Context, userCred mcclient.TokenC
return err
}
err = instance.purgeBackups(ctx, userCred)
err = instance.PurgeBackups(ctx, userCred, api.BACKUP_MODE_AUTOMATED)
if err != nil {
return errors.Wrap(err, "instance.purgeBackups")
}

View File

@@ -2225,7 +2225,7 @@ func (self *SHuaWeiRegionDriver) ValidateDBInstanceAccountPrivilege(ctx context.
if account == "root" {
return httperrors.NewInputParameterError("No need to grant or revoke privilege for admin account")
}
if utils.IsInStringArray(privilege, []string{api.DATABASE_PRIVILEGE_RW, api.DATABASE_PRIVILEGE_R}) {
if !utils.IsInStringArray(privilege, []string{api.DATABASE_PRIVILEGE_RW, api.DATABASE_PRIVILEGE_R}) {
return httperrors.NewInputParameterError("Unknown privilege %s", privilege)
}
return nil

View File

@@ -45,47 +45,7 @@ func (self *DBInstanceDeleteTask) taskFailed(ctx context.Context, dbinstance *mo
func (self *DBInstanceDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
dbinstance := obj.(*models.SDBInstance)
keepBackup := false
if !dbinstance.GetRegion().GetDriver().IsSupportKeepDBInstanceManualBackup() {
keepBackup = jsonutils.QueryBoolean(self.Params, "keep_backup", false)
}
if !keepBackup {
self.SetStage("OnBackupDeleteComplete", nil)
self.OnBackupDeleteComplete(ctx, dbinstance, nil)
} else {
self.DeleteDBInstance(ctx, dbinstance)
}
}
func (self *DBInstanceDeleteTask) OnBackupDeleteComplete(ctx context.Context, instance *models.SDBInstance, data jsonutils.JSONObject) {
_backups, err := instance.GetDBInstanceBackups()
if err != nil {
self.taskFailed(ctx, instance, errors.Wrap(err, "instance.GetDBInstanceBackups"))
return
}
backups := []models.SDBInstanceBackup{}
for _, backup := range _backups {
if backup.BackupMode == api.BACKUP_MODE_MANUAL {
backups = append(backups, backup)
}
}
if len(backups) == 0 {
self.DeleteDBInstance(ctx, instance)
return
}
backups[0].StartDBInstanceBackupDeleteTask(ctx, self.UserCred, self.GetTaskId())
}
func (self *DBInstanceDeleteTask) DeleteDBInstanceComplete(ctx context.Context, dbinstance *models.SDBInstance) {
err := dbinstance.Purge(ctx, self.UserCred)
if err != nil {
self.taskFailed(ctx, dbinstance, errors.Wrap(err, "dbinstance.Purge"))
return
}
self.SetStageComplete(ctx, nil)
self.DeleteDBInstance(ctx, dbinstance)
}
func (self *DBInstanceDeleteTask) DeleteDBInstance(ctx context.Context, dbinstance *models.SDBInstance) {
@@ -109,3 +69,37 @@ func (self *DBInstanceDeleteTask) DeleteDBInstance(ctx context.Context, dbinstan
self.DeleteDBInstanceComplete(ctx, dbinstance)
}
func (self *DBInstanceDeleteTask) DeleteDBInstanceComplete(ctx context.Context, dbinstance *models.SDBInstance) {
if !dbinstance.GetRegion().GetDriver().IsSupportKeepDBInstanceManualBackup() || jsonutils.QueryBoolean(self.Params, "purge", false) {
err := dbinstance.PurgeBackups(ctx, self.UserCred, api.BACKUP_MODE_MANUAL)
if err != nil {
self.taskFailed(ctx, dbinstance, errors.Wrap(err, "dbinstance.PurgeManualBackups"))
return
}
err = dbinstance.Purge(ctx, self.UserCred)
if err != nil {
self.taskFailed(ctx, dbinstance, errors.Wrap(err, "dbinstance.Purge"))
return
}
self.SetStageComplete(ctx, nil)
return
}
self.DeleteBackups(ctx, dbinstance, nil)
}
func (self *DBInstanceDeleteTask) DeleteBackups(ctx context.Context, instance *models.SDBInstance, data jsonutils.JSONObject) {
if !jsonutils.QueryBoolean(self.Params, "keep_backup", false) {
backups, _ := instance.GetDBInstanceBackupByMode(api.BACKUP_MODE_MANUAL)
for i := range backups {
backups[i].StartDBInstanceBackupDeleteTask(ctx, self.UserCred, "")
}
}
err := instance.Purge(ctx, self.UserCred)
if err != nil {
self.taskFailed(ctx, instance, errors.Wrap(err, "instance.Purge"))
return
}
self.SetStageComplete(ctx, nil)
}