mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-21 22:32:15 +08:00
Merge pull request #8876 from ioito/feat/qx-rds-create-by-backup
feat: rds recovery new instance from backup supported
This commit is contained in:
@@ -135,6 +135,9 @@ type DBInstanceCreateInput struct {
|
||||
// required: true
|
||||
DiskSizeGB int `json:"disk_size_gb"`
|
||||
|
||||
// 指定连接端口
|
||||
Port int `json:"port"`
|
||||
|
||||
// rds初始化密码
|
||||
// 阿里云不需要此参数
|
||||
// 华为云会默认创建一个用户,若不传此参数, 则为随机密码
|
||||
@@ -154,6 +157,9 @@ type DBInstanceCreateInput struct {
|
||||
// rds实例内存大小
|
||||
// 若指定实例套餐,此参数将根据套餐设置
|
||||
VmemSizeMb int `json:"vmem_size_mb"`
|
||||
|
||||
// 从备份中创建新实例
|
||||
DBInstancebackupId string `json:"dbinstancebackup_id"`
|
||||
}
|
||||
|
||||
type SDBInstanceChangeConfigInput struct {
|
||||
|
||||
@@ -16,6 +16,14 @@ package cloudprovider
|
||||
|
||||
import "yunion.io/x/onecloud/pkg/util/billing"
|
||||
|
||||
type TBackupMethod string
|
||||
|
||||
const (
|
||||
BackupMethodLogical = TBackupMethod("Logical")
|
||||
BackupMethodPhysical = TBackupMethod("Physical")
|
||||
BackupMethodUnknown = TBackupMethod("")
|
||||
)
|
||||
|
||||
type SDBInstanceNetwork struct {
|
||||
IP string
|
||||
NetworkId string
|
||||
@@ -61,6 +69,9 @@ type SManagedDBInstanceCreateConfig struct {
|
||||
|
||||
BillingCycle *billing.SBillingCycle
|
||||
Tags map[string]string
|
||||
|
||||
// 仅从备份恢复到新实例用到
|
||||
RdsId string
|
||||
}
|
||||
|
||||
type SManagedDBInstanceChangeConfig struct {
|
||||
|
||||
@@ -848,6 +848,9 @@ type ICloudDBInstanceBackup interface {
|
||||
GetBackupSizeMb() int
|
||||
GetDBNames() string
|
||||
GetBackupMode() string
|
||||
GetBackupMethod() TBackupMethod
|
||||
|
||||
CreateICloudDBInstance(opts *SManagedDBInstanceCreateConfig) (ICloudDBInstance, error)
|
||||
|
||||
Delete() error
|
||||
}
|
||||
|
||||
@@ -866,6 +866,10 @@ func syncDBInstanceResource(ctx context.Context, userCred mcclient.TokenCredenti
|
||||
if err != nil {
|
||||
log.Errorf("syncDBInstanceAccounts: %v", err)
|
||||
}
|
||||
err = syncDBInstanceBackups(ctx, userCred, syncResults, localInstance, remoteInstance)
|
||||
if err != nil {
|
||||
log.Errorf("syncDBInstanceBackups: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func syncDBInstanceNetwork(ctx context.Context, userCred mcclient.TokenCredential, syncResults SSyncResultSet, localInstance *SDBInstance, remoteInstance cloudprovider.ICloudDBInstance) error {
|
||||
@@ -901,6 +905,26 @@ func syncDBInstanceSecgroups(ctx context.Context, userCred mcclient.TokenCredent
|
||||
return nil
|
||||
}
|
||||
|
||||
func syncDBInstanceBackups(ctx context.Context, userCred mcclient.TokenCredential, syncResults SSyncResultSet, localInstance *SDBInstance, remoteInstance cloudprovider.ICloudDBInstance) error {
|
||||
backups, err := remoteInstance.GetIDBInstanceBackups()
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "GetIDBInstanceBackups")
|
||||
}
|
||||
|
||||
region := localInstance.GetRegion()
|
||||
provider := localInstance.GetCloudprovider()
|
||||
|
||||
result := DBInstanceBackupManager.SyncDBInstanceBackups(ctx, userCred, provider, localInstance, region, backups)
|
||||
syncResults.Add(DBInstanceBackupManager, result)
|
||||
|
||||
msg := result.Result()
|
||||
log.Infof("SyncDBInstanceBackups for dbinstance %s result: %s", localInstance.Name, msg)
|
||||
if result.IsError() {
|
||||
return result.AllError()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func syncDBInstanceParameters(ctx context.Context, userCred mcclient.TokenCredential, syncResults SSyncResultSet, localInstance *SDBInstance, remoteInstance cloudprovider.ICloudDBInstance) error {
|
||||
parameters, err := remoteInstance.GetIDBInstanceParameters()
|
||||
if err != nil {
|
||||
|
||||
@@ -85,9 +85,8 @@ type SDBInstanceBackup struct {
|
||||
// example: 32
|
||||
BackupSizeMb int `nullable:"false" list:"user" json:"backup_size_mb"`
|
||||
|
||||
// RDS实例Id
|
||||
// example: 239b9663-6d06-4ef4-8cfc-320a7fb6660d
|
||||
// DBInstanceId string `width:"36" charset:"ascii" name:"dbinstance_id" nullable:"false" list:"user" create:"required" index:"true"`
|
||||
// 备份方式 Logical|Physical
|
||||
BackupMethod string `width:"32" charset:"ascii" nullable:"true" list:"user" create:"optional" json:"backup_method"`
|
||||
}
|
||||
|
||||
func (manager *SDBInstanceBackupManager) GetContextManagers() [][]db.IModelManager {
|
||||
@@ -381,6 +380,22 @@ func (backup *SDBInstanceBackup) GetIDBInstanceBackup() (cloudprovider.ICloudDBI
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "GetIDBInstance")
|
||||
}
|
||||
err = cloudprovider.Wait(time.Second*3, time.Second*15, func() (bool, error) {
|
||||
backups, err := iRds.GetIDBInstanceBackups()
|
||||
if err != nil {
|
||||
return false, errors.Wrapf(err, "GetIDBInstanceBackups")
|
||||
}
|
||||
for i := range backups {
|
||||
if backups[i].GetGlobalId() == backup.ExternalId {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
log.Warningf("failed to found backup %s", backup.ExternalId)
|
||||
return false, nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "timeout for search backup %s", backup.ExternalId)
|
||||
}
|
||||
backups, err := iRds.GetIDBInstanceBackups()
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "GetIDBInstanceBackups")
|
||||
@@ -390,7 +405,7 @@ func (backup *SDBInstanceBackup) GetIDBInstanceBackup() (cloudprovider.ICloudDBI
|
||||
return backups[i], nil
|
||||
}
|
||||
}
|
||||
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "externalId: %s", backup.ExternalId)
|
||||
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "search backup %s", backup.ExternalId)
|
||||
}
|
||||
|
||||
iRegion, err := backup.GetIRegion()
|
||||
@@ -464,6 +479,7 @@ func (self *SDBInstanceBackup) SyncWithCloudDBInstanceBackup(
|
||||
self.Engine = extBackup.GetEngine()
|
||||
self.EngineVersion = extBackup.GetEngineVersion()
|
||||
self.DBNames = extBackup.GetDBNames()
|
||||
self.BackupMethod = string(extBackup.GetBackupMethod())
|
||||
|
||||
if dbinstanceId := extBackup.GetDBInstanceId(); len(dbinstanceId) > 0 {
|
||||
//有可能云上删除了实例,未删除备份
|
||||
@@ -522,6 +538,7 @@ func (manager *SDBInstanceBackupManager) newFromCloudDBInstanceBackup(
|
||||
backup.BackupSizeMb = extBackup.GetBackupSizeMb()
|
||||
backup.DBNames = extBackup.GetDBNames()
|
||||
backup.BackupMode = extBackup.GetBackupMode()
|
||||
backup.BackupMethod = string(extBackup.GetBackupMethod())
|
||||
backup.ExternalId = extBackup.GetGlobalId()
|
||||
|
||||
if dbinstanceId := extBackup.GetDBInstanceId(); len(dbinstanceId) > 0 {
|
||||
@@ -616,3 +633,70 @@ func (manager *SDBInstanceBackupManager) ListItemExportKeys(ctx context.Context,
|
||||
func (self *SDBInstanceBackup) GetChangeOwnerCandidateDomainIds() []string {
|
||||
return self.SManagedResourceBase.GetChangeOwnerCandidateDomainIds()
|
||||
}
|
||||
|
||||
func (self *SDBInstanceBackup) fillRdsConfig(output *api.DBInstanceCreateInput) error {
|
||||
if self.Status != api.DBINSTANCE_BACKUP_READY {
|
||||
return fmt.Errorf("backup %s status is %s require %s", self.Name, self.Status, api.DBINSTANCE_BACKUP_READY)
|
||||
}
|
||||
if len(self.DBInstanceId) == 0 {
|
||||
if len(self.Engine) == 0 {
|
||||
return fmt.Errorf("backup engine %s is unknown", self.Name)
|
||||
}
|
||||
output.Engine = self.Engine
|
||||
if len(self.EngineVersion) == 0 {
|
||||
return fmt.Errorf("backup engine version %s is unknown", self.Name)
|
||||
}
|
||||
output.EngineVersion = self.EngineVersion
|
||||
return nil
|
||||
}
|
||||
rds, err := self.GetDBInstance()
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "backup.GetDBInstance")
|
||||
}
|
||||
if len(output.NetworkId) == 0 {
|
||||
networks, err := rds.GetDBNetworks()
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "GetDBNetworks")
|
||||
}
|
||||
if len(networks) > 0 {
|
||||
output.NetworkId = networks[0].NetworkId
|
||||
}
|
||||
}
|
||||
|
||||
if output.VcpuCount == 0 {
|
||||
output.VcpuCount = rds.VcpuCount
|
||||
}
|
||||
if output.VmemSizeMb == 0 {
|
||||
output.VmemSizeMb = rds.VmemSizeMb
|
||||
}
|
||||
if output.DiskSizeGB == 0 {
|
||||
output.DiskSizeGB = rds.DiskSizeGB
|
||||
}
|
||||
if output.Port == 0 {
|
||||
output.Port = rds.Port
|
||||
}
|
||||
if len(output.Category) == 0 {
|
||||
output.Category = rds.Category
|
||||
}
|
||||
if len(output.StorageType) == 0 {
|
||||
output.StorageType = rds.StorageType
|
||||
}
|
||||
output.Engine = rds.Engine
|
||||
output.EngineVersion = rds.EngineVersion
|
||||
if len(output.InstanceType) == 0 {
|
||||
output.InstanceType = rds.InstanceType
|
||||
}
|
||||
if len(output.VpcId) == 0 {
|
||||
output.VpcId = rds.VpcId
|
||||
}
|
||||
if len(output.Zone1) == 0 {
|
||||
output.Zone1 = rds.Zone1
|
||||
}
|
||||
if len(output.Zone2) == 0 {
|
||||
output.Zone2 = rds.Zone2
|
||||
}
|
||||
if len(output.Zone3) == 0 {
|
||||
output.Zone3 = rds.Zone3
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -132,6 +132,9 @@ type SDBInstance struct {
|
||||
Zone2 string `width:"36" charset:"ascii" nullable:"false" create:"optional" list:"user"`
|
||||
// 可用区3
|
||||
Zone3 string `width:"36" charset:"ascii" nullable:"false" create:"optional" list:"user"`
|
||||
|
||||
// 从备份创建新实例
|
||||
DBInstancebackupId string `width:"36" name:"dbinstancebackup_id" charset:"ascii" nullable:"false" create:"optional"`
|
||||
}
|
||||
|
||||
func (manager *SDBInstanceManager) GetContextManagers() [][]db.IModelManager {
|
||||
@@ -284,6 +287,17 @@ func (manager *SDBInstanceManager) BatchCreateValidateCreateData(ctx context.Con
|
||||
}
|
||||
|
||||
func (man *SDBInstanceManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, input api.DBInstanceCreateInput) (api.DBInstanceCreateInput, error) {
|
||||
if len(input.DBInstancebackupId) > 0 {
|
||||
_backup, err := validators.ValidateModel(userCred, DBInstanceBackupManager, &input.DBInstancebackupId)
|
||||
if err != nil {
|
||||
return input, err
|
||||
}
|
||||
backup := _backup.(*SDBInstanceBackup)
|
||||
err = backup.fillRdsConfig(&input)
|
||||
if err != nil {
|
||||
return input, err
|
||||
}
|
||||
}
|
||||
for _, v := range map[string]*string{"zone1": &input.Zone1, "zone2": &input.Zone2, "zone3": &input.Zone3} {
|
||||
if len(*v) > 0 {
|
||||
_, err := validators.ValidateModel(userCred, ZoneManager, v)
|
||||
@@ -298,28 +312,35 @@ func (man *SDBInstanceManager) ValidateCreateData(ctx context.Context, userCred
|
||||
return input, httperrors.NewWeakPasswordError()
|
||||
}
|
||||
}
|
||||
if len(input.NetworkId) == 0 {
|
||||
return input, httperrors.NewMissingParameterError("network_id")
|
||||
}
|
||||
_network, err := validators.ValidateModel(userCred, NetworkManager, &input.NetworkId)
|
||||
if err != nil {
|
||||
return input, err
|
||||
}
|
||||
|
||||
network := _network.(*SNetwork)
|
||||
|
||||
if len(input.Address) > 0 {
|
||||
ip := net.ParseIP(input.Address).To4()
|
||||
if ip == nil {
|
||||
return input, httperrors.NewInputParameterError("invalid address: %s", input.Address)
|
||||
var vpc *SVpc
|
||||
var network *SNetwork
|
||||
if len(input.NetworkId) > 0 {
|
||||
_network, err := validators.ValidateModel(userCred, NetworkManager, &input.NetworkId)
|
||||
if err != nil {
|
||||
return input, err
|
||||
}
|
||||
addr, _ := netutils.NewIPV4Addr(input.Address)
|
||||
if !network.IsAddressInRange(addr) {
|
||||
return input, httperrors.NewInputParameterError("Ip %s not in network %s(%s) range", input.Address, network.Name, network.Id)
|
||||
network = _network.(*SNetwork)
|
||||
if len(input.Address) > 0 {
|
||||
ip := net.ParseIP(input.Address).To4()
|
||||
if ip == nil {
|
||||
return input, httperrors.NewInputParameterError("invalid address: %s", input.Address)
|
||||
}
|
||||
addr, _ := netutils.NewIPV4Addr(input.Address)
|
||||
if !network.IsAddressInRange(addr) {
|
||||
return input, httperrors.NewInputParameterError("Ip %s not in network %s(%s) range", input.Address, network.Name, network.Id)
|
||||
}
|
||||
}
|
||||
vpc = network.GetVpc()
|
||||
} else if len(input.VpcId) > 0 {
|
||||
_vpc, err := validators.ValidateModel(userCred, VpcManager, &input.VpcId)
|
||||
if err != nil {
|
||||
return input, err
|
||||
}
|
||||
vpc = _vpc.(*SVpc)
|
||||
} else {
|
||||
return input, httperrors.NewMissingParameterError("vpc_id")
|
||||
}
|
||||
|
||||
vpc := network.GetVpc()
|
||||
input.VpcId = vpc.Id
|
||||
input.ManagerId = vpc.ManagerId
|
||||
cloudprovider := vpc.GetCloudprovider()
|
||||
|
||||
@@ -161,6 +161,7 @@ type IDBInstanceDriver interface {
|
||||
ValidateResetDBInstancePassword(ctx context.Context, userCred mcclient.TokenCredential, instance *SDBInstance, account string) error
|
||||
|
||||
RequestCreateDBInstance(ctx context.Context, userCred mcclient.TokenCredential, dbinstance *SDBInstance, task taskman.ITask) error
|
||||
RequestCreateDBInstanceFromBackup(ctx context.Context, userCred mcclient.TokenCredential, dbinstance *SDBInstance, task taskman.ITask) error
|
||||
RequestCreateDBInstanceBackup(ctx context.Context, userCred mcclient.TokenCredential, instance *SDBInstance, backup *SDBInstanceBackup, task taskman.ITask) error
|
||||
RequestChangeDBInstanceConfig(ctx context.Context, userCred mcclient.TokenCredential, instance *SDBInstance, task taskman.ITask) error
|
||||
|
||||
|
||||
@@ -1000,25 +1000,26 @@ func (self *SAliyunRegionDriver) ValidateCreateDBInstanceData(ctx context.Contex
|
||||
return input, httperrors.NewInputParameterError("slave dbinstance not support prepaid billing type")
|
||||
}
|
||||
|
||||
wire := network.GetWire()
|
||||
if wire == nil {
|
||||
return input, httperrors.NewGeneralError(fmt.Errorf("failed to found wire for network %s(%s)", network.Name, network.Id))
|
||||
}
|
||||
zone := wire.GetZone()
|
||||
if zone == nil {
|
||||
return input, httperrors.NewGeneralError(fmt.Errorf("failed to found zone for wire %s(%s)", wire.Name, wire.Id))
|
||||
}
|
||||
|
||||
match := false
|
||||
for _, sku := range skus {
|
||||
if utils.IsInStringArray(zone.Id, []string{sku.Zone1, sku.Zone2, sku.Zone3}) {
|
||||
match = true
|
||||
break
|
||||
if network != nil {
|
||||
wire := network.GetWire()
|
||||
if wire == nil {
|
||||
return input, httperrors.NewGeneralError(fmt.Errorf("failed to found wire for network %s(%s)", network.Name, network.Id))
|
||||
}
|
||||
zone := wire.GetZone()
|
||||
if zone == nil {
|
||||
return input, httperrors.NewGeneralError(fmt.Errorf("failed to found zone for wire %s(%s)", wire.Name, wire.Id))
|
||||
}
|
||||
}
|
||||
|
||||
if !match {
|
||||
return input, httperrors.NewInputParameterError("failed to match any skus in the network %s(%s) zone %s(%s)", network.Name, network.Id, zone.Name, zone.Id)
|
||||
match := false
|
||||
for _, sku := range skus {
|
||||
if utils.IsInStringArray(zone.Id, []string{sku.Zone1, sku.Zone2, sku.Zone3}) {
|
||||
match = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !match {
|
||||
return input, httperrors.NewInputParameterError("failed to match any skus in the network %s(%s) zone %s(%s)", network.Name, network.Id, zone.Name, zone.Id)
|
||||
}
|
||||
}
|
||||
|
||||
var master *models.SDBInstance
|
||||
|
||||
@@ -295,6 +295,10 @@ func (self *SBaseRegionDriver) RequestCreateDBInstance(ctx context.Context, user
|
||||
return fmt.Errorf("Not Implement RequestCreateDBInstance")
|
||||
}
|
||||
|
||||
func (self *SBaseRegionDriver) RequestCreateDBInstanceFromBackup(ctx context.Context, userCred mcclient.TokenCredential, dbinstance *models.SDBInstance, task taskman.ITask) error {
|
||||
return fmt.Errorf("Not Implement RequestCreateDBInstanceFromBackup")
|
||||
}
|
||||
|
||||
func (self *SBaseRegionDriver) RequestCreateDBInstanceBackup(ctx context.Context, userCred mcclient.TokenCredential, dbinstance *models.SDBInstance, backup *models.SDBInstanceBackup, task taskman.ITask) error {
|
||||
return fmt.Errorf("Not Implement RequestCreateDBInstanceBackup")
|
||||
}
|
||||
|
||||
@@ -1801,6 +1801,85 @@ func (self *SManagedVirtualizationRegionDriver) RequestCreateDBInstance(ctx cont
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SManagedVirtualizationRegionDriver) RequestCreateDBInstanceFromBackup(ctx context.Context, userCred mcclient.TokenCredential, rds *models.SDBInstance, task taskman.ITask) error {
|
||||
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
|
||||
_backup, err := models.DBInstanceBackupManager.FetchById(rds.DBInstancebackupId)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "DBInstanceBackupManager.FetchById(%s)", rds.DBInstancebackupId)
|
||||
}
|
||||
backup := _backup.(*models.SDBInstanceBackup)
|
||||
iBackup, err := backup.GetIDBInstanceBackup()
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "backup.GetIDBInstanceBackup")
|
||||
}
|
||||
vpc, err := rds.GetVpc()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "rds.GetVpc()")
|
||||
}
|
||||
desc := cloudprovider.SManagedDBInstanceCreateConfig{
|
||||
Name: rds.Name,
|
||||
Description: rds.Description,
|
||||
StorageType: rds.StorageType,
|
||||
DiskSizeGB: rds.DiskSizeGB,
|
||||
VcpuCount: rds.VcpuCount,
|
||||
VmemSizeMb: rds.VmemSizeMb,
|
||||
VpcId: vpc.ExternalId,
|
||||
Engine: rds.Engine,
|
||||
EngineVersion: rds.EngineVersion,
|
||||
Category: rds.Category,
|
||||
Port: rds.Port,
|
||||
}
|
||||
if len(backup.DBInstanceId) > 0 {
|
||||
parentRds, err := backup.GetDBInstance()
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "backup.GetDBInstance")
|
||||
}
|
||||
desc.RdsId = parentRds.ExternalId
|
||||
}
|
||||
|
||||
log.Debugf("create from backup params: %s", jsonutils.Marshal(desc).String())
|
||||
|
||||
networks, err := rds.GetDBNetworks()
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "dbinstance.GetDBNetworks")
|
||||
}
|
||||
|
||||
if len(networks) > 0 {
|
||||
net, err := networks[0].GetNetwork()
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "GetNetwork")
|
||||
}
|
||||
desc.NetworkId, desc.Address = net.ExternalId, networks[0].IpAddr
|
||||
}
|
||||
if rds.BillingType == billing_api.BILLING_TYPE_PREPAID {
|
||||
bc, err := billing.ParseBillingCycle(rds.BillingCycle)
|
||||
if err != nil {
|
||||
log.Errorf("failed to parse billing cycle %s: %v", rds.BillingCycle, err)
|
||||
} else if bc.IsValid() {
|
||||
desc.BillingCycle = &bc
|
||||
desc.BillingCycle.AutoRenew = rds.AutoRenew
|
||||
}
|
||||
}
|
||||
|
||||
iRds, err := iBackup.CreateICloudDBInstance(&desc)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "iBackup.CreateICloudDBInstance")
|
||||
}
|
||||
|
||||
err = db.SetExternalId(rds, userCred, iRds.GetGlobalId())
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "db.SetExternalId")
|
||||
}
|
||||
|
||||
err = cloudprovider.WaitStatus(iRds, api.DBINSTANCE_RUNNING, time.Second*5, time.Hour*1)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "cloudprovider.WaitStatus runing")
|
||||
}
|
||||
return nil, nil
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SManagedVirtualizationRegionDriver) RequestCreateElasticcache(ctx context.Context, userCred mcclient.TokenCredential, elasticcache *models.SElasticcache, task taskman.ITask, data *jsonutils.JSONDict) error {
|
||||
task.ScheduleRun(nil)
|
||||
return nil
|
||||
@@ -2433,14 +2512,9 @@ func (self *SManagedVirtualizationRegionDriver) RequestCreateDBInstanceBackup(ct
|
||||
return nil, errors.Wrapf(err, "backup.GetIDBInstanceBackup")
|
||||
}
|
||||
|
||||
_, err = db.Update(backup, func() error {
|
||||
backup.StartTime = iBackup.GetStartTime()
|
||||
backup.EndTime = iBackup.GetEndTime()
|
||||
backup.BackupSizeMb = iBackup.GetBackupSizeMb()
|
||||
return nil
|
||||
})
|
||||
err = backup.SyncWithCloudDBInstanceBackup(ctx, userCred, iBackup, instance.GetCloudprovider())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "db.Update")
|
||||
log.Warningf("sync backup info error: %v", err)
|
||||
}
|
||||
|
||||
instance.SetStatus(userCred, api.DBINSTANCE_RUNNING, "")
|
||||
|
||||
@@ -48,12 +48,17 @@ func (self *DBInstanceCreateTask) OnInit(ctx context.Context, obj db.IStandalone
|
||||
self.CreateDBInstance(ctx, dbinstance)
|
||||
}
|
||||
|
||||
func (self *DBInstanceCreateTask) CreateDBInstance(ctx context.Context, dbinstance *models.SDBInstance) {
|
||||
region := dbinstance.GetRegion()
|
||||
func (self *DBInstanceCreateTask) CreateDBInstance(ctx context.Context, rds *models.SDBInstance) {
|
||||
region := rds.GetRegion()
|
||||
self.SetStage("OnCreateDBInstanceComplete", nil)
|
||||
err := region.GetDriver().RequestCreateDBInstance(ctx, self.UserCred, dbinstance, self)
|
||||
var err error
|
||||
if len(rds.DBInstancebackupId) > 0 {
|
||||
err = region.GetDriver().RequestCreateDBInstanceFromBackup(ctx, self.UserCred, rds, self)
|
||||
} else {
|
||||
err = region.GetDriver().RequestCreateDBInstance(ctx, self.UserCred, rds, self)
|
||||
}
|
||||
if err != nil {
|
||||
self.taskFailed(ctx, dbinstance, err)
|
||||
self.taskFailed(ctx, rds, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,23 +22,24 @@ import (
|
||||
)
|
||||
|
||||
type DBInstanceCreateOptions struct {
|
||||
NAME string `help:"DBInstance Name"`
|
||||
InstanceType string `help:"InstanceType for DBInstance"`
|
||||
VcpuCount int `help:"Core of cpu for DBInstance"`
|
||||
VmemSizeMb int `help:"Memory size of DBInstance"`
|
||||
Port int `help:"Port of DBInstance"`
|
||||
Category string `help:"Category of DBInstance"`
|
||||
Network string `help:"Network of DBInstance"`
|
||||
Address string `help:"Address of DBInstance"`
|
||||
Engine string `help:"Engine of DBInstance"`
|
||||
EngineVersion string `help:"EngineVersion of DBInstance Engine"`
|
||||
StorageType string `help:"StorageTyep of DBInstance"`
|
||||
Secgroup string `help:"Secgroup name or Id for DBInstance"`
|
||||
Zone string `help:"ZoneId or name for DBInstance"`
|
||||
DiskSizeGB int `help:"Storage size for DBInstance"`
|
||||
Duration string `help:"Duration for DBInstance"`
|
||||
AllowDelete *bool `help:"not lock dbinstance" `
|
||||
Tags []string `help:"Tags info,prefix with 'user:', eg: user:project=default" json:"-"`
|
||||
NAME string `help:"DBInstance Name"`
|
||||
InstanceType string `help:"InstanceType for DBInstance"`
|
||||
VcpuCount int `help:"Core of cpu for DBInstance"`
|
||||
VmemSizeMb int `help:"Memory size of DBInstance"`
|
||||
Port int `help:"Port of DBInstance"`
|
||||
Category string `help:"Category of DBInstance"`
|
||||
Network string `help:"Network of DBInstance"`
|
||||
Address string `help:"Address of DBInstance"`
|
||||
Engine string `help:"Engine of DBInstance"`
|
||||
EngineVersion string `help:"EngineVersion of DBInstance Engine"`
|
||||
StorageType string `help:"StorageTyep of DBInstance"`
|
||||
Secgroup string `help:"Secgroup name or Id for DBInstance"`
|
||||
Zone string `help:"ZoneId or name for DBInstance"`
|
||||
DiskSizeGB int `help:"Storage size for DBInstance"`
|
||||
Duration string `help:"Duration for DBInstance"`
|
||||
AllowDelete *bool `help:"not lock dbinstance" `
|
||||
Tags []string `help:"Tags info,prefix with 'user:', eg: user:project=default" json:"-"`
|
||||
DBInstancebackupId string `help:"create dbinstance from backup" json:"dbinstancebackup_id"`
|
||||
}
|
||||
|
||||
func (opts *DBInstanceCreateOptions) Params() (*jsonutils.JSONDict, error) {
|
||||
|
||||
@@ -19,8 +19,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/coredns/coredns/plugin/pkg/log"
|
||||
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/utils"
|
||||
|
||||
@@ -325,3 +324,33 @@ func (region *SRegion) waitBackupCreateComplete(instanceId, jobId string) (strin
|
||||
}
|
||||
return "", fmt.Errorf("failed to found backup job %s backupid", jobId)
|
||||
}
|
||||
|
||||
func (self *SDBInstanceBackup) GetBackupMethod() cloudprovider.TBackupMethod {
|
||||
return cloudprovider.TBackupMethod(self.BackupMethod)
|
||||
}
|
||||
|
||||
func (self *SDBInstanceBackup) CreateICloudDBInstance(opts *cloudprovider.SManagedDBInstanceCreateConfig) (cloudprovider.ICloudDBInstance, error) {
|
||||
rdsId, err := self.region.CreateDBInstanceByBackup(self.BackupId, opts)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "CreateDBInstanceByBackup")
|
||||
}
|
||||
return self.region.GetDBInstanceDetail(rdsId)
|
||||
}
|
||||
|
||||
func (self *SRegion) CreateDBInstanceByBackup(backupId string, opts *cloudprovider.SManagedDBInstanceCreateConfig) (string, error) {
|
||||
params := map[string]string{
|
||||
"DBInstanceId": opts.RdsId,
|
||||
"DBInstanceStorageType": opts.StorageType,
|
||||
"PayType": "Postpaid",
|
||||
"BackupId": backupId,
|
||||
}
|
||||
resp, err := self.rdsRequest("CloneDBInstance", params)
|
||||
if err != nil {
|
||||
return "", errors.Wrapf(err, "rdsRequest")
|
||||
}
|
||||
rdsId, err := resp.GetString("DBInstanceId")
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("missing DBInstanceId after CloneDBInstance")
|
||||
}
|
||||
return rdsId, nil
|
||||
}
|
||||
|
||||
@@ -36,3 +36,11 @@ func (backup *SDBInstanceBackupBase) Delete() error {
|
||||
func (backup *SDBInstanceBackupBase) GetProjectId() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (backup *SDBInstanceBackupBase) CreateICloudDBInstance(opts *cloudprovider.SManagedDBInstanceCreateConfig) (cloudprovider.ICloudDBInstance, error) {
|
||||
return nil, errors.Wrap(cloudprovider.ErrNotImplemented, "CreateICloudDBInstance")
|
||||
}
|
||||
|
||||
func (backup *SDBInstanceBackupBase) GetBackupMethod() cloudprovider.TBackupMethod {
|
||||
return cloudprovider.BackupMethodUnknown
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/multicloud"
|
||||
)
|
||||
|
||||
type OperationError struct {
|
||||
@@ -32,6 +33,7 @@ type OperationError struct {
|
||||
}
|
||||
|
||||
type SDBInstanceBackup struct {
|
||||
multicloud.SDBInstanceBackupBase
|
||||
rds *SDBInstance
|
||||
|
||||
Kind string
|
||||
|
||||
Reference in New Issue
Block a user