From d7dd5facb41c4ef093d03b833d8452490a3cf32b Mon Sep 17 00:00:00 2001 From: ioito Date: Fri, 2 Aug 2019 15:07:41 +0800 Subject: [PATCH] feature: add huawei rds sync --- pkg/apis/compute/dbinstance_const.go | 23 +- pkg/compute/models/cloudregions.go | 2 +- pkg/multicloud/huawei/client/client.go | 4 + .../huawei/client/modules/manager_resource.go | 1 + .../huawei/client/modules/mod_dbinstance.go | 80 +++++ .../client/modules/mod_dbinstance_backup.go | 37 +++ pkg/multicloud/huawei/dbinstance.go | 301 ++++++++++++++++++ pkg/multicloud/huawei/dbinstance_account.go | 68 ++++ pkg/multicloud/huawei/dbinstance_backup.go | 133 ++++++++ pkg/multicloud/huawei/dbinstance_database.go | 46 +++ pkg/multicloud/huawei/dbinstance_parameter.go | 41 +++ pkg/multicloud/huawei/dbinstance_privilege.go | 29 ++ pkg/multicloud/huawei/shell/dbinstance.go | 83 +++++ pkg/multicloud/huawei/utils.go | 20 +- 14 files changed, 856 insertions(+), 12 deletions(-) create mode 100644 pkg/multicloud/huawei/client/modules/mod_dbinstance.go create mode 100644 pkg/multicloud/huawei/client/modules/mod_dbinstance_backup.go create mode 100644 pkg/multicloud/huawei/dbinstance.go create mode 100644 pkg/multicloud/huawei/dbinstance_account.go create mode 100644 pkg/multicloud/huawei/dbinstance_backup.go create mode 100644 pkg/multicloud/huawei/dbinstance_database.go create mode 100644 pkg/multicloud/huawei/dbinstance_parameter.go create mode 100644 pkg/multicloud/huawei/dbinstance_privilege.go create mode 100644 pkg/multicloud/huawei/shell/dbinstance.go diff --git a/pkg/apis/compute/dbinstance_const.go b/pkg/apis/compute/dbinstance_const.go index 122dbd4642..0b4498be91 100644 --- a/pkg/apis/compute/dbinstance_const.go +++ b/pkg/apis/compute/dbinstance_const.go @@ -15,15 +15,16 @@ package compute const ( - DBINSTANCE_DEPLOYING = "deploying" //部署中 - DBINSTANCE_RUNNING = "running" //使用中 - DBINSTANCE_REBOOTING = "rebooting" //重启中 - DBINSTANCE_MIGRATING = "migrating" //迁移中 - DBINSTANCE_RESTORING = "restoring" //备份恢复中 - DBINSTANCE_IMPORTING = "importing" //数据导入中 - DBINSTANCE_CLONING = "cloning" //克隆中 - DBINSTANCE_DELETING = "deleting" //删除中 - DBINSTANCE_UNKNOWN = "unknown" + DBINSTANCE_DEPLOYING = "deploying" //部署中 + DBINSTANCE_RUNNING = "running" //使用中 + DBINSTANCE_REBOOTING = "rebooting" //重启中 + DBINSTANCE_MIGRATING = "migrating" //迁移中 + DBINSTANCE_BACKING_UP = "backing_up" //备份中 + DBINSTANCE_RESTORING = "restoring" //备份恢复中 + DBINSTANCE_IMPORTING = "importing" //数据导入中 + DBINSTANCE_CLONING = "cloning" //克隆中 + DBINSTANCE_DELETING = "deleting" //删除中 + DBINSTANCE_UNKNOWN = "unknown" DBINSTANCE_BACKUP_READY = "ready" DBINSTANCE_BACKUP_CREATING = "creating" @@ -56,7 +57,9 @@ const ( DBINSTANCE_TYPE_PPAS = "PPAS" DBINSTANCE_CATEGORY_BASIC = "basic" //基础版 - DBINSTANCE_CATEGORY_HA = "high_availability" //高可用 + DBINSTANCE_CATEGORY_HA = "high_availability" //高可用或主备 DBINSTANCE_CATEGORY_ALWAYSON = "always_on" //集群版 DBINSTANCE_CATEGORY_FINANCE = "finance" + DBINSTANCE_CATEGORY_SINGLE = "single" //单机 + DBINSTANCE_CATEGORY_Replica = "replica" //只读 ) diff --git a/pkg/compute/models/cloudregions.go b/pkg/compute/models/cloudregions.go index 8e8e0afaa3..2dc68037c0 100644 --- a/pkg/compute/models/cloudregions.go +++ b/pkg/compute/models/cloudregions.go @@ -158,7 +158,7 @@ func (self *SCloudregion) GetDBInstances(provider *SCloudprovider) ([]SDBInstanc if provider != nil { q = q.Equals("manager_id", provider.Id) } - err := db.FetchModelObjects(DBInstanceBackupManager, q, &instances) + err := db.FetchModelObjects(DBInstanceManager, q, &instances) if err != nil { return nil, errors.Wrapf(err, "FetchModelObjects for region %s", self.Id) } diff --git a/pkg/multicloud/huawei/client/client.go b/pkg/multicloud/huawei/client/client.go index 51f088d93d..ff7310bae2 100644 --- a/pkg/multicloud/huawei/client/client.go +++ b/pkg/multicloud/huawei/client/client.go @@ -72,6 +72,8 @@ type Client struct { SNatRules *modules.SNatSRuleManager DNatRules *modules.SNatDRuleManager NatGateways *modules.SNatGatewayManager + DBInstance *modules.SDBInstanceManager + DBInstanceBackup *modules.SDBInstanceBackupManager } func (self *Client) Init() error { @@ -148,6 +150,8 @@ func (self *Client) initManagers() { self.SNatRules = modules.NewNatSManager(self.regionId, self.projectId, self.signer, self.debug) self.DNatRules = modules.NewNatDManager(self.regionId, self.projectId, self.signer, self.debug) self.NatGateways = modules.NewNatGatewayManager(self.regionId, self.projectId, self.signer, self.debug) + self.DBInstance = modules.NewDBInstanceManager(self.regionId, self.projectId, self.signer, self.debug) + self.DBInstanceBackup = modules.NewDBInstanceBackupManager(self.regionId, self.projectId, self.signer, self.debug) } self.init = true diff --git a/pkg/multicloud/huawei/client/modules/manager_resource.go b/pkg/multicloud/huawei/client/modules/manager_resource.go index 37bb6f7ff7..13713ebee0 100644 --- a/pkg/multicloud/huawei/client/modules/manager_resource.go +++ b/pkg/multicloud/huawei/client/modules/manager_resource.go @@ -47,6 +47,7 @@ const ( ServiceNameBSS ServiceNameType = "bss" // 合作伙伴运营能力 ServiceNameNAT ServiceNameType = "nat" // Nat网关 NAT ServiceNameDCS ServiceNameType = "dcs" // 分布式缓存服务 + ServiceNameRDS ServiceNameType = "rds" // 关系型数据库 RDS ) type SManagerContext struct { diff --git a/pkg/multicloud/huawei/client/modules/mod_dbinstance.go b/pkg/multicloud/huawei/client/modules/mod_dbinstance.go new file mode 100644 index 0000000000..feaf2ceb6f --- /dev/null +++ b/pkg/multicloud/huawei/client/modules/mod_dbinstance.go @@ -0,0 +1,80 @@ +// 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 modules + +import ( + "fmt" + + "yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth" + "yunion.io/x/onecloud/pkg/multicloud/huawei/client/responses" +) + +type SDBInstanceManager struct { + SResourceManager +} + +func NewDBInstanceManager(regionId string, projectId string, signer auth.Signer, debug bool) *SDBInstanceManager { + return &SDBInstanceManager{SResourceManager: SResourceManager{ + SBaseManager: NewBaseManager(signer, debug), + ServiceName: ServiceNameRDS, + Region: regionId, + ProjectId: projectId, + version: "v3", + Keyword: "instance", + KeywordPlural: "instances", + + ResourceKeyword: "instances", + }} +} + +func (self *SDBInstanceManager) ListParameters(queries map[string]string) (*responses.ListResult, error) { + id, _ := queries["instance_id"] + if len(id) == 0 { + return nil, fmt.Errorf("SDBInstanceManager.ListParameters missing parameter instance_id") + } + + delete(queries, "instance_id") + return self.ListInContextWithSpec(nil, fmt.Sprintf("%s/configurations", id), queries, "configuration_parameters") +} + +func (self *SDBInstanceManager) ListDatabases(queries map[string]string) (*responses.ListResult, error) { + id, _ := queries["instance_id"] + if len(id) == 0 { + return nil, fmt.Errorf("SDBInstanceManager.ListDatabases missing parameter instance_id") + } + + delete(queries, "instance_id") + return self.ListInContextWithSpec(nil, fmt.Sprintf("%s/database/detail", id), queries, "databases") +} + +func (self *SDBInstanceManager) ListAccounts(queries map[string]string) (*responses.ListResult, error) { + id, _ := queries["instance_id"] + if len(id) == 0 { + return nil, fmt.Errorf("SDBInstanceManager.ListAccounts missing parameter instance_id") + } + + delete(queries, "instance_id") + return self.ListInContextWithSpec(nil, fmt.Sprintf("%s/db_user/detail", id), queries, "users") +} + +func (self *SDBInstanceManager) ListPrivileges(queries map[string]string) (*responses.ListResult, error) { + id, _ := queries["instance_id"] + if len(id) == 0 { + return nil, fmt.Errorf("SDBInstanceManager.ListPrivileges missing parameter instance_id") + } + + delete(queries, "instance_id") + return self.ListInContextWithSpec(nil, fmt.Sprintf("%s/db_user/database", id), queries, "databases") +} diff --git a/pkg/multicloud/huawei/client/modules/mod_dbinstance_backup.go b/pkg/multicloud/huawei/client/modules/mod_dbinstance_backup.go new file mode 100644 index 0000000000..eeefa7804b --- /dev/null +++ b/pkg/multicloud/huawei/client/modules/mod_dbinstance_backup.go @@ -0,0 +1,37 @@ +// 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 modules + +import ( + "yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth" +) + +type SDBInstanceBackupManager struct { + SResourceManager +} + +func NewDBInstanceBackupManager(regionId string, projectId string, signer auth.Signer, debug bool) *SDBInstanceBackupManager { + return &SDBInstanceBackupManager{SResourceManager: SResourceManager{ + SBaseManager: NewBaseManager(signer, debug), + ServiceName: ServiceNameRDS, + Region: regionId, + ProjectId: projectId, + version: "v3", + Keyword: "backups", + KeywordPlural: "backups", + + ResourceKeyword: "backups", + }} +} diff --git a/pkg/multicloud/huawei/dbinstance.go b/pkg/multicloud/huawei/dbinstance.go new file mode 100644 index 0000000000..4728a086d4 --- /dev/null +++ b/pkg/multicloud/huawei/dbinstance.go @@ -0,0 +1,301 @@ +package huawei + +import ( + "fmt" + "time" + + "yunion.io/x/jsonutils" + billing "yunion.io/x/onecloud/pkg/apis/billing" + api "yunion.io/x/onecloud/pkg/apis/compute" + "yunion.io/x/onecloud/pkg/cloudprovider" + "yunion.io/x/onecloud/pkg/multicloud" + "yunion.io/x/pkg/errors" +) + +type SBackupStrategy struct { + KeepDays int + StartTime string +} + +type SDatastore struct { + Type string + Version string +} + +type SHa struct { + ReplicationMode string +} + +type SNonde struct { + AvailabilityZone string + Id string + Name string + Role string + Staus string +} + +type SVolume struct { + Size int + Type string +} + +type SRelatedInstance struct { + Id string + Type string +} + +type SDBInstance struct { + multicloud.SDBInstanceBase + region *SRegion + + BackupStrategy SBackupStrategy + Created string //time.Time + Datastore SDatastore + DbUserName string + DIskEncryptionId string + FlavorRef string + Ha SHa + Id string + MaintenanceWindow string + Name string + Nodes []SNonde + Port int + PrivateIps []string + PublicIps []string + Region string + RelatedInstance []SRelatedInstance + SecurityGroupId string + Status string + SubnetId string + SwitchStrategy string + TimeZone string + Type string + Updated string //time.Time + Volume SVolume + VpcId string +} + +func (region *SRegion) GetDBInstances() ([]SDBInstance, error) { + params := map[string]string{} + dbinstances := []SDBInstance{} + err := doListAllWithOffset(region.ecsClient.DBInstance.List, params, &dbinstances) + return dbinstances, err +} + +func (region *SRegion) GetDBInstance(instanceId string) (*SDBInstance, error) { + instance := SDBInstance{} + err := DoGet(region.ecsClient.DBInstance.Get, instanceId, nil, &instance) + return &instance, err +} + +func (rds *SDBInstance) GetName() string { + return rds.Name +} + +func (rds *SDBInstance) GetId() string { + return rds.Id +} + +func (rds *SDBInstance) GetGlobalId() string { + return rds.GetId() +} + +// 值为“BUILD”,表示实例正在创建。 +// 值为“ACTIVE”,表示实例正常。 +// 值为“FAILED”,表示实例异常。 +// 值为“FROZEN”,表示实例冻结。 +// 值为“MODIFYING”,表示实例正在扩容。 +// 值为“REBOOTING”,表示实例正在重启。 +// 值为“RESTORING”,表示实例正在恢复。 +// 值为“MODIFYING INSTANCE TYPE”,表示实例正在转主备。 +// 值为“SWITCHOVER”,表示实例正在主备切换。 +// 值为“MIGRATING”,表示实例正在迁移。 +// 值为“BACKING UP”,表示实例正在进行备份。 +// 值为“MODIFYING DATABASE PORT”,表示实例正在修改数据库端口。 +// 值为“STORAGE FULL”,表示实例磁盘空间满。 + +func (rds *SDBInstance) GetStatus() string { + switch rds.Status { + case "BUILD", "MODIFYING", "MODIFYING INSTANCE TYPE", "SWITCHOVER", "MODIFYING DATABASE PORT": + return api.DBINSTANCE_DEPLOYING + case "ACTIVE": + return api.DBINSTANCE_RUNNING + case "FAILED", "FROZEN", "STORAGE FULL": + return api.DBINSTANCE_UNKNOWN + case "REBOOTING": + return api.DBINSTANCE_REBOOTING + case "RESTORING": + return api.DBINSTANCE_RESTORING + case "MIGRATING": + return api.DBINSTANCE_MIGRATING + case "BACKING UP": + return api.DBINSTANCE_BACKING_UP + } + return rds.Status +} + +func (rds *SDBInstance) GetBillingType() string { + return billing.BILLING_TYPE_POSTPAID +} + +func (rds *SDBInstance) GetExpiredAt() time.Time { + return time.Time{} +} + +func (rds *SDBInstance) GetCreatedAt() time.Time { + t, err := time.Parse("2006-01-02T15:04:05Z0700", rds.Created) + if err != nil { + return time.Time{} + } + return t +} + +func (rds *SDBInstance) GetEngine() string { + return rds.Datastore.Type +} + +func (rds *SDBInstance) GetEngineVersion() string { + return rds.Datastore.Version +} + +func (rds *SDBInstance) GetInstanceType() string { + return rds.FlavorRef +} + +func (rds *SDBInstance) GetCategory() string { + switch rds.Type { + case "Single": + return api.DBINSTANCE_CATEGORY_BASIC + case "Ha": + return api.DBINSTANCE_CATEGORY_HA + case "Replica": + return api.DBINSTANCE_CATEGORY_Replica + } + return rds.Type +} + +func (rds *SDBInstance) GetVcpuCount() int { + return 0 +} + +func (rds *SDBInstance) GetVmemSizeMB() int { + return 0 +} + +func (rds *SDBInstance) GetDiskSizeGB() int { + return rds.Volume.Size +} + +func (rds *SDBInstance) GetPort() int { + return rds.Port +} + +func (rds *SDBInstance) GetMaintainTime() string { + return rds.MaintenanceWindow +} + +func (rds *SDBInstance) GetIVpcId() string { + return rds.VpcId +} + +func (rds *SDBInstance) Refresh() error { + instance, err := rds.region.GetDBInstance(rds.Id) + if err != nil { + return err + } + return jsonutils.Update(rds, instance) +} + +func (rds *SDBInstance) GetIZoneId() string { + if len(rds.Nodes) == 1 { + zone, err := rds.region.getZoneById(rds.Nodes[0].AvailabilityZone) + if err == nil { + return zone.GetGlobalId() + } + } + return "" +} + +type SRdsNetwork struct { + SubnetId string + IP string +} + +func (rds *SDBInstance) GetDBNetwork() (*cloudprovider.SDBInstanceNetwork, error) { + for _, ip := range rds.PrivateIps { + inetwork := &cloudprovider.SDBInstanceNetwork{ + IP: ip, + NetworkId: rds.SubnetId, + } + return inetwork, nil + } + + return nil, fmt.Errorf("failed to found network for huawei rds %s", rds.Name) +} + +func (rds *SDBInstance) GetInternalConnectionStr() string { + for _, ip := range rds.PrivateIps { + return ip + } + return "" +} + +func (rds *SDBInstance) GetConnectionStr() string { + for _, ip := range rds.PublicIps { + return ip + } + return "" +} + +func (region *SRegion) GetIDBInstances() ([]cloudprovider.ICloudDBInstance, error) { + instances, err := region.GetDBInstances() + if err != nil { + return nil, errors.Wrapf(err, "region.GetDBInstances()") + } + idbinstances := []cloudprovider.ICloudDBInstance{} + for i := 0; i < len(instances); i++ { + instances[i].region = region + idbinstances = append(idbinstances, &instances[i]) + } + return idbinstances, nil +} + +func (rds *SDBInstance) GetIDBInstanceParameters() ([]cloudprovider.ICloudDBInstanceParameter, error) { + parameters, err := rds.region.GetDBInstanceParameters(rds.Id) + if err != nil { + return nil, err + } + iparameters := []cloudprovider.ICloudDBInstanceParameter{} + for i := 0; i < len(parameters); i++ { + iparameters = append(iparameters, ¶meters[i]) + } + return iparameters, nil +} + +func (rds *SDBInstance) GetIDBInstanceDatabases() ([]cloudprovider.ICloudDBInstanceDatabase, error) { + databases, err := rds.region.GetDBInstanceDatabases(rds.Id) + if err != nil { + return nil, errors.Wrap(err, "rds.region.GetDBInstanceDatabases(rds.Id)") + } + + idatabase := []cloudprovider.ICloudDBInstanceDatabase{} + for i := 0; i < len(databases); i++ { + databases[i].instance = rds + idatabase = append(idatabase, &databases[i]) + } + return idatabase, nil +} + +func (rds *SDBInstance) GetIDBInstanceAccounts() ([]cloudprovider.ICloudDBInstanceAccount, error) { + accounts, err := rds.region.GetDBInstanceAccounts(rds.Id) + if err != nil { + return nil, errors.Wrap(err, "rds.region.GetDBInstanceAccounts(rds.Id)") + } + + iaccounts := []cloudprovider.ICloudDBInstanceAccount{} + for i := 0; i < len(accounts); i++ { + accounts[i].instance = rds + iaccounts = append(iaccounts, &accounts[i]) + } + return iaccounts, nil +} diff --git a/pkg/multicloud/huawei/dbinstance_account.go b/pkg/multicloud/huawei/dbinstance_account.go new file mode 100644 index 0000000000..e3be9b2ccc --- /dev/null +++ b/pkg/multicloud/huawei/dbinstance_account.go @@ -0,0 +1,68 @@ +package huawei + +import ( + api "yunion.io/x/onecloud/pkg/apis/compute" + "yunion.io/x/onecloud/pkg/cloudprovider" + "yunion.io/x/onecloud/pkg/multicloud" +) + +type SDBInstanceAccount struct { + multicloud.SDBInstanceAccountBase + instance *SDBInstance + Name string +} + +func (account *SDBInstanceAccount) GetId() string { + return account.Name + +} + +func (account *SDBInstanceAccount) GetGlobalId() string { + return account.Name +} + +func (account *SDBInstanceAccount) GetName() string { + return account.Name +} + +func (account *SDBInstanceAccount) GetStatus() string { + return api.DBINSTANCE_USER_AVAILABLE +} + +func (account *SDBInstanceAccount) GetIDBInstanceAccountPrivileges() ([]cloudprovider.ICloudDBInstanceAccountPrivilege, error) { + privileges, err := account.instance.region.GetDBInstancePrivvileges(account.instance.Id, account.Name) + if err != nil { + return nil, err + } + iprivileves := []cloudprovider.ICloudDBInstanceAccountPrivilege{} + for i := 0; i < len(privileges); i++ { + privileges[i].account = account + iprivileves = append(iprivileves, &privileges[i]) + } + return iprivileves, nil +} + +func (region *SRegion) GetDBInstanceAccounts(instanceId string) ([]SDBInstanceAccount, error) { + params := map[string]string{ + "instance_id": instanceId, + } + accounts := []SDBInstanceAccount{} + err := doListAllWithPage(region.ecsClient.DBInstance.ListAccounts, params, &accounts) + if err != nil { + return nil, err + } + return accounts, nil +} + +func (region *SRegion) GetDBInstancePrivvileges(instanceId string, username string) ([]SDatabasePrivilege, error) { + params := map[string]string{ + "instance_id": instanceId, + "user-name": username, + } + privileges := []SDatabasePrivilege{} + err := doListAllWithPage(region.ecsClient.DBInstance.ListPrivileges, params, &privileges) + if err != nil { + return nil, err + } + return privileges, nil +} diff --git a/pkg/multicloud/huawei/dbinstance_backup.go b/pkg/multicloud/huawei/dbinstance_backup.go new file mode 100644 index 0000000000..c04619288a --- /dev/null +++ b/pkg/multicloud/huawei/dbinstance_backup.go @@ -0,0 +1,133 @@ +package huawei + +import ( + "time" + + api "yunion.io/x/onecloud/pkg/apis/compute" + "yunion.io/x/onecloud/pkg/cloudprovider" + "yunion.io/x/onecloud/pkg/multicloud" + "yunion.io/x/pkg/errors" +) + +type SDBInstanceBackup struct { + multicloud.SDBInstanceBackupBase + region *SRegion + + BeginTime string + Datastore SDatastore + EndTime string + Id string + InstanceId string + Name string + Size int + Status string + Type string +} + +func (backup *SDBInstanceBackup) GetId() string { + return backup.Id +} + +func (backup *SDBInstanceBackup) GetGlobalId() string { + return backup.Id +} + +func (backup *SDBInstanceBackup) GetName() string { + return backup.Name +} + +func (backup *SDBInstanceBackup) GetStartTime() time.Time { + //2019-08-05T08:00:02+0000 + t, err := time.Parse("2006-01-02T15:04:05Z0700", backup.BeginTime) + if err != nil { + return time.Time{} + } + return t +} + +func (backup *SDBInstanceBackup) GetEndTime() time.Time { + t, err := time.Parse("2006-01-02T15:04:05Z0700", backup.EndTime) + if err != nil { + return time.Time{} + } + return t +} + +func (backup *SDBInstanceBackup) GetBackupMode() string { + switch backup.Type { + case "manual": + return api.BACKUP_MODE_MANUAL + default: + return api.BACKUP_MODE_AUTOMATED + } +} + +func (backup *SDBInstanceBackup) GetStatus() string { + switch backup.Status { + case "COMPLETED": + return api.DBINSTANCE_BACKUP_READY + case "FAILED": + return api.DBINSTANCE_BACKUP_FAILED + case "BUILDING": + return api.DBINSTANCE_BACKUP_CREATING + case "DELETING": + return api.DBINSTANCE_BACKUP_DELETING + default: + return api.DBINSTANCE_BACKUP_UNKNOWN + } +} + +func (backup *SDBInstanceBackup) GetBackupSizeMb() int { + return backup.Size / 1024 +} + +func (backup *SDBInstanceBackup) GetDBNames() string { + return "" +} + +func (backup *SDBInstanceBackup) GetDBInstanceId() string { + return backup.InstanceId +} + +func (region *SRegion) GetDBInstanceBackups(instanceId string) ([]SDBInstanceBackup, error) { + params := map[string]string{ + "instance_id": instanceId, + } + backups := []SDBInstanceBackup{} + err := doListAllWithOffset(region.ecsClient.DBInstanceBackup.List, params, &backups) + if err != nil { + return nil, err + } + return backups, nil +} + +func (region *SRegion) GetIDBInstanceBackups() ([]cloudprovider.ICloudDBInstanceBackup, error) { + dbinstnaces, err := region.GetIDBInstances() + if err != nil { + return nil, err + } + ibackups := []cloudprovider.ICloudDBInstanceBackup{} + for i := 0; i < len(dbinstnaces); i++ { + _dbinstance := dbinstnaces[i].(*SDBInstance) + _ibackup, err := _dbinstance.GetIDBInstanceBackups() + if err != nil { + return nil, errors.Wrapf(err, "_dbinstance(%v).GetIDBInstanceBackups", _dbinstance) + } + ibackups = append(ibackups, _ibackup...) + } + return ibackups, nil +} + +func (rds *SDBInstance) GetIDBInstanceBackups() ([]cloudprovider.ICloudDBInstanceBackup, error) { + backups, err := rds.region.GetDBInstanceBackups(rds.Id) + if err != nil { + return nil, err + } + + ibackups := []cloudprovider.ICloudDBInstanceBackup{} + for i := 0; i < len(backups); i++ { + backups[i].region = rds.region + ibackups = append(ibackups, &backups[i]) + } + return ibackups, nil +} diff --git a/pkg/multicloud/huawei/dbinstance_database.go b/pkg/multicloud/huawei/dbinstance_database.go new file mode 100644 index 0000000000..ff15aef4da --- /dev/null +++ b/pkg/multicloud/huawei/dbinstance_database.go @@ -0,0 +1,46 @@ +package huawei + +import ( + api "yunion.io/x/onecloud/pkg/apis/compute" + "yunion.io/x/onecloud/pkg/multicloud" +) + +type SDBInstanceDatabase struct { + instance *SDBInstance + multicloud.SDBInstanceDatabaseBase + + Name string + CharacterSet string +} + +func (database *SDBInstanceDatabase) GetId() string { + return database.Name +} + +func (database *SDBInstanceDatabase) GetGlobalId() string { + return database.Name +} + +func (database *SDBInstanceDatabase) GetName() string { + return database.Name +} + +func (database *SDBInstanceDatabase) GetStatus() string { + return api.DBINSTANCE_DATABASE_RUNNING +} + +func (database *SDBInstanceDatabase) GetCharacterSet() string { + return database.CharacterSet +} + +func (region *SRegion) GetDBInstanceDatabases(instanceId string) ([]SDBInstanceDatabase, error) { + params := map[string]string{ + "instance_id": instanceId, + } + databases := []SDBInstanceDatabase{} + err := doListAllWithPage(region.ecsClient.DBInstance.ListDatabases, params, &databases) + if err != nil { + return nil, err + } + return databases, nil +} diff --git a/pkg/multicloud/huawei/dbinstance_parameter.go b/pkg/multicloud/huawei/dbinstance_parameter.go new file mode 100644 index 0000000000..81e8e68bf5 --- /dev/null +++ b/pkg/multicloud/huawei/dbinstance_parameter.go @@ -0,0 +1,41 @@ +package huawei + +type SDBInstanceParameter struct { + instance *SDBInstance + + Name string + Value string + RestartRequired bool + Readonly bool + ValueRange string + Type string + Description string +} + +func (region *SRegion) GetDBInstanceParameters(dbinstanceId string) ([]SDBInstanceParameter, error) { + params := map[string]string{ + "instance_id": dbinstanceId, + } + paramters := []SDBInstanceParameter{} + err := doListAll(region.ecsClient.DBInstance.ListParameters, params, ¶mters) + if err != nil { + return nil, err + } + return paramters, nil +} + +func (param *SDBInstanceParameter) GetGlobalId() string { + return param.Name +} + +func (param *SDBInstanceParameter) GetKey() string { + return param.Name +} + +func (param *SDBInstanceParameter) GetValue() string { + return param.Value +} + +func (param *SDBInstanceParameter) GetDescription() string { + return param.Description +} diff --git a/pkg/multicloud/huawei/dbinstance_privilege.go b/pkg/multicloud/huawei/dbinstance_privilege.go new file mode 100644 index 0000000000..7d2b7b002d --- /dev/null +++ b/pkg/multicloud/huawei/dbinstance_privilege.go @@ -0,0 +1,29 @@ +package huawei + +import ( + "fmt" + + api "yunion.io/x/onecloud/pkg/apis/compute" +) + +type SDatabasePrivilege struct { + account *SDBInstanceAccount + + Name string + Readonly bool +} + +func (privilege *SDatabasePrivilege) GetGlobalId() string { + return fmt.Sprintf("%s/%s", privilege.account.GetGlobalId(), privilege.Name) +} + +func (privilege *SDatabasePrivilege) GetPrivilege() string { + if privilege.Readonly { + return api.DATABASE_PRIVILEGE_R + } + return api.DATABASE_PRIVILEGE_RW +} + +func (privilege *SDatabasePrivilege) GetDBName() string { + return privilege.Name +} diff --git a/pkg/multicloud/huawei/shell/dbinstance.go b/pkg/multicloud/huawei/shell/dbinstance.go new file mode 100644 index 0000000000..a5e1ba9744 --- /dev/null +++ b/pkg/multicloud/huawei/shell/dbinstance.go @@ -0,0 +1,83 @@ +// 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 shell + +import ( + "yunion.io/x/onecloud/pkg/multicloud/huawei" + "yunion.io/x/onecloud/pkg/util/shellutils" +) + +func init() { + type DBInstanceListOptions struct { + } + shellutils.R(&DBInstanceListOptions{}, "dbinstance-list", "List dbinstances", func(cli *huawei.SRegion, args *DBInstanceListOptions) error { + dbinstances, err := cli.GetDBInstances() + if err != nil { + return err + } + printList(dbinstances, 0, 0, 0, nil) + return nil + }) + + type DBInstanceIdOptions struct { + ID string `help:"DBInstance ID"` + } + + shellutils.R(&DBInstanceIdOptions{}, "dbinstance-show", "Show dbinstance", func(cli *huawei.SRegion, args *DBInstanceIdOptions) error { + dbinstance, err := cli.GetDBInstance(args.ID) + if err != nil { + return err + } + printObject(dbinstance) + return nil + }) + + shellutils.R(&DBInstanceIdOptions{}, "dbinstance-parameter-list", "Show dbinstance parameters", func(cli *huawei.SRegion, args *DBInstanceIdOptions) error { + parameters, err := cli.GetDBInstanceParameters(args.ID) + if err != nil { + return err + } + printList(parameters, 0, 0, 0, nil) + return nil + }) + + shellutils.R(&DBInstanceIdOptions{}, "dbinstance-database-list", "Show dbinstance databases", func(cli *huawei.SRegion, args *DBInstanceIdOptions) error { + databases, err := cli.GetDBInstanceDatabases(args.ID) + if err != nil { + return err + } + printList(databases, 0, 0, 0, nil) + return nil + }) + + shellutils.R(&DBInstanceIdOptions{}, "dbinstance-account-list", "Show dbinstance accounts", func(cli *huawei.SRegion, args *DBInstanceIdOptions) error { + accounts, err := cli.GetDBInstanceAccounts(args.ID) + if err != nil { + return err + } + printList(accounts, 0, 0, 0, nil) + return nil + }) + + shellutils.R(&DBInstanceIdOptions{}, "dbinstance-backup-list", "Show dbinstance backups", func(cli *huawei.SRegion, args *DBInstanceIdOptions) error { + backups, err := cli.GetDBInstanceBackups(args.ID) + if err != nil { + return err + } + printList(backups, 0, 0, 0, nil) + return nil + }) + +} diff --git a/pkg/multicloud/huawei/utils.go b/pkg/multicloud/huawei/utils.go index bc086a0276..fc47eba559 100644 --- a/pkg/multicloud/huawei/utils.go +++ b/pkg/multicloud/huawei/utils.go @@ -65,7 +65,7 @@ func unmarshalResult(resp jsonutils.JSONObject, respErr error, result interface{ return err } -var pageLimit = 1000 +var pageLimit = 100 func doListAllWithOffset(doList listFunc, queries map[string]string, result interface{}) error { startIndex := 0 @@ -85,6 +85,24 @@ func doListAllWithOffset(doList listFunc, queries map[string]string, result inte return nil } +func doListAllWithPage(doList listFunc, queries map[string]string, result interface{}) error { + startIndex := 1 + resultValue := reflect.Indirect(reflect.ValueOf(result)) + queries["limit"] = fmt.Sprintf("%d", pageLimit) + queries["page"] = fmt.Sprintf("%d", startIndex) + for { + total, part, err := doListPart(doList, queries, result) + if err != nil { + return err + } + if (total > 0 && resultValue.Len() >= total) || (total == 0 && pageLimit > part) { + break + } + queries["page"] = fmt.Sprintf("%d", startIndex+resultValue.Len()) + } + return nil +} + func doListAllWithMarker(doList listFunc, queries map[string]string, result interface{}) error { resultValue := reflect.Indirect(reflect.ValueOf(result)) queries["limit"] = fmt.Sprintf("%d", pageLimit)