Merge pull request #11548 from ioito/hotfix/qx-mongodb

feat(region): add mongodb
This commit is contained in:
Zexi Li
2021-07-08 11:26:55 +08:00
committed by GitHub
29 changed files with 2483 additions and 14 deletions
+32
View File
@@ -0,0 +1,32 @@
// 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 compute
import (
"yunion.io/x/onecloud/cmd/climc/shell"
"yunion.io/x/onecloud/pkg/mcclient/modules"
"yunion.io/x/onecloud/pkg/mcclient/options"
"yunion.io/x/onecloud/pkg/mcclient/options/compute"
)
func init() {
cmd := shell.NewResourceCmd(&modules.MongoDB)
cmd.List(&compute.MongoDBListOptions{})
cmd.Update(&compute.MongoDBUpdateOptions{})
cmd.Show(&options.BaseIdOptions{})
cmd.Delete(&options.BaseIdOptions{})
cmd.Get("backups", &options.BaseIdOptions{})
cmd.Perform("syncstatus", &options.BaseIdOptions{})
}
+126
View File
@@ -0,0 +1,126 @@
// 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 compute
import (
"yunion.io/x/onecloud/pkg/apis"
)
type MongoDBCreateInput struct {
apis.VirtualResourceCreateInput
DeletePreventableCreateInput
}
type SMongoDBChangeConfigInput struct {
apis.Meta
InstanceType string
DiskSizeGB int
}
type MongoDBListInput struct {
apis.VirtualResourceListInput
apis.ExternalizedResourceBaseListInput
apis.DeletePreventableResourceBaseListInput
VpcFilterListInput
ZoneResourceInput
VcpuCount int `json:"vcpu_count"`
VmemSizeMb int `json:"vmem_size_mb"`
Category string `json:"category"`
Engine string `json:"engine"`
EngineVersion string `json:"engine_version"`
InstanceType string `json:"instance_type"`
}
type MongoDBDetails struct {
apis.VirtualResourceDetails
CloudregionResourceInfo
ManagedResourceInfo
VpcResourceInfoBase
// IP子网名称
// example: test-network
Network string `json:"network"`
}
type MongoDBResourceInfoBase struct {
// MongoDB实例名称
MongoDB string `json:"mongodb"`
}
type MongoDBResourceInfo struct {
MongoDBResourceInfoBase
// 归属VPC ID
VpcId string `json:"vpc_id"`
VpcResourceInfo
}
type MongoDBResourceInput struct {
// MongoDB实例(ID or Name)
MongoDBId string `json:"mongodb_id"`
// swagger:ignore
// Deprecated
MongoDB string `json:"mongodb" yunion-deprecated-by:"mongodb_id"`
}
type MongoDBFilterListInputBase struct {
MongoDBResourceInput
// 以MongoDB实例名字排序
OrderByMongoDB string `json:"order_by_mongodb"`
}
type MongoDBFilterListInput struct {
MongoDBFilterListInputBase
VpcFilterListInput
}
type MongoDBJoinListInput struct {
apis.VirtualJointResourceBaseListInput
MongoDBFilterListInput
}
type MongoDBRemoteUpdateInput struct {
// 是否覆盖替换所有标签
ReplaceTags *bool `json:"replace_tags" help:"replace all remote tags"`
}
type MongoDBNetworkListInput struct {
MongoDBJoinListInput
NetworkFilterListInput
}
type MongoDBAutoRenewInput struct {
// 是否自动续费
AutoRenew bool `json:"auto_renew"`
}
type MongoDBSetSecgroupInput struct {
SecgroupIds []string `json:"secgroup_ids"`
}
+38
View File
@@ -0,0 +1,38 @@
// 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 compute
const (
MONGO_DB_STATUS_CREATING = "creating"
MONGO_DB_STATUS_RUNNING = "running"
MONGO_DB_STATUS_DEPLOY = "deploy"
MONGO_DB_STATUS_CHANGE_CONFIG = "change_config"
MONGO_DB_STATUS_DELETING = "deleting"
MONGO_DB_STATUS_DELETE_FAILED = "delete_failed"
MONGO_DB_STATUS_REBOOTING = "rebooting"
MONGO_DB_STATUS_UNKNOWN = "unknown"
MONGO_DB_ENGINE_WIRED_TIGER = "WiredTiger"
MONGO_DB_ENGINE_ROCKS = "Rocks"
MONGO_DB_ENGINE_VERSION_40 = "4.0"
MONGO_DB_ENGINE_VERSION_36 = "3.6"
MONGO_DB_ENGINE_VERSION_32 = "3.2"
// 分片
MONGO_DB_CATEGORY_SHARDING = "sharding"
// 副本集
MONGO_DB_CATEGORY_REPLICATE = "replicate"
)
+1
View File
@@ -57,6 +57,7 @@ const (
CLOUD_CAPABILITY_NAT = "nat" // NAT网关
CLOUD_CAPABILITY_NAS = "nas" // NAS
CLOUD_CAPABILITY_WAF = "waf" // WAF
CLOUD_CAPABILITY_MONGO_DB = "mongodb" // MongoDB
)
const (
+55
View File
@@ -0,0 +1,55 @@
// 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 cloudprovider
import "time"
// 备份状态
type TMongoDBBackupStatus string
// 备份方法
type TMongoDBBackupMethod string
// 备份方式
type TMongoDBBackupType string
const (
MongoDBBackupStatusCreating = TMongoDBBackupStatus("creating")
MongoDBBackupStatusAvailable = TMongoDBBackupStatus("available")
MongoDBBackupStatusFailed = TMongoDBBackupStatus("failed")
MongoDBBackupStatusUnknown = TMongoDBBackupStatus("unknown")
MongoDBBackupMethodPhysical = TMongoDBBackupMethod("physical")
MongoDBBackupMethodLogical = TMongoDBBackupMethod("logical")
MongoDBBackupTypeAuto = TMongoDBBackupType("auto")
MongoDBBackupTypeManual = TMongoDBBackupType("manual")
)
type SMongoDBBackup struct {
Name string
Description string
StartTime time.Time
EndTime time.Time
Status TMongoDBBackupStatus
BackupMethod TMongoDBBackupMethod
BackupType TMongoDBBackupType
BackupSizeKb int
}
type SMongoDBBackups struct {
Data []SMongoDBBackup
Total int
}
+27
View File
@@ -174,6 +174,9 @@ type ICloudRegion interface {
GetICloudWafInstanceById(id string) (ICloudWafInstance, error)
CreateICloudWafInstance(opts *WafCreateOptions) (ICloudWafInstance, error)
GetICloudWafRuleGroups() ([]ICloudWafRuleGroup, error)
GetICloudMongoDBs() ([]ICloudMongoDB, error)
GetICloudMongoDBById(id string) (ICloudMongoDB, error)
}
type ICloudZone interface {
@@ -1365,3 +1368,27 @@ type ICloudWafRule interface {
Update(opts *SWafRule) error
Delete() error
}
type ICloudMongoDB interface {
IVirtualResource
IBillingResource
GetVpcId() string
GetNetworkId() string
GetIpAddr() string
GetVcpuCount() int
GetVmemSizeMb() int
GetDiskSizeMb() int
GetZoneId() string
GetReplicationNum() int
GetCategory() string
GetEngine() string
GetEngineVersion() string
GetInstanceType() string
GetMaintainTime() string
GetPort() int
GetIBackups() ([]SMongoDBBackup, error)
Delete() error
}
+1
View File
@@ -1482,6 +1482,7 @@ func (self *SCloudprovider) RealDelete(ctx context.Context, userCred mcclient.To
WafInstanceManager,
VpcManager,
ElasticipManager,
MongoDBManager,
NetworkInterfaceManager,
CloudproviderRegionManager,
CloudregionManager,
+23
View File
@@ -1115,6 +1115,25 @@ func syncWafRegexSets(ctx context.Context, userCred mcclient.TokenCredential, sy
return nil
}
func syncMongoDBs(ctx context.Context, userCred mcclient.TokenCredential, syncResults SSyncResultSet, provider *SCloudprovider, localRegion *SCloudregion, remoteRegion cloudprovider.ICloudRegion) error {
dbs, err := remoteRegion.GetICloudMongoDBs()
if err != nil {
msg := fmt.Sprintf("GetICloudMongoDBs for region %s failed %s", remoteRegion.GetName(), err)
log.Errorf(msg)
return err
}
_, _, result := localRegion.SyncMongoDBs(ctx, userCred, provider, dbs)
syncResults.Add(MongoDBManager, result)
msg := result.Result()
log.Infof("SyncMongoDBs for region %s result: %s", localRegion.Name, msg)
if result.IsError() {
return result.AllError()
}
return nil
}
func syncWafInstances(ctx context.Context, userCred mcclient.TokenCredential, syncResults SSyncResultSet, provider *SCloudprovider, localRegion *SCloudregion, remoteRegion cloudprovider.ICloudRegion) error {
wafIns, err := remoteRegion.GetICloudWafInstances()
if err != nil {
@@ -1349,6 +1368,10 @@ func syncPublicCloudProviderInfo(
syncWafInstances(ctx, userCred, syncResults, provider, localRegion, remoteRegion)
}
if utils.IsInStringArray(cloudprovider.CLOUD_CAPABILITY_MONGO_DB, driver.GetCapabilities()) {
syncMongoDBs(ctx, userCred, syncResults, provider, localRegion, remoteRegion)
}
if cloudprovider.IsSupportCompute(driver) {
log.Debugf("storageCachePairs count %d", len(storageCachePairs))
for i := range storageCachePairs {
+782
View File
@@ -0,0 +1,782 @@
// 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 models
import (
"context"
"fmt"
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/compare"
"yunion.io/x/sqlchemy"
"yunion.io/x/onecloud/pkg/apis"
billing_api "yunion.io/x/onecloud/pkg/apis/billing"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudcommon/db/quotas"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/billing"
"yunion.io/x/onecloud/pkg/util/rbacutils"
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
type SMongoDBManager struct {
db.SVirtualResourceBaseManager
db.SExternalizedResourceBaseManager
SDeletePreventableResourceBaseManager
SCloudregionResourceBaseManager
SZoneResourceBaseManager
SManagedResourceBaseManager
SVpcResourceBaseManager
}
var MongoDBManager *SMongoDBManager
func init() {
MongoDBManager = &SMongoDBManager{
SVirtualResourceBaseManager: db.NewVirtualResourceBaseManager(
SMongoDB{},
"mongodbs_tbl",
"mongodb",
"mongodbs",
),
}
MongoDBManager.SetVirtualObject(MongoDBManager)
}
type SMongoDB struct {
db.SVirtualResourceBase
db.SExternalizedResourceBase
SManagedResourceBase
SBillingResourceBase
SCloudregionResourceBase
SZoneResourceBase
SDeletePreventableResourceBase
// CPU数量
// example: 1
VcpuCount int `nullable:"false" default:"1" list:"user" create:"optional"`
// 内存大小
// example: 1024
VmemSizeMb int `nullable:"false" list:"user" create:"required"`
// 存储大小, 单位Mb
// example: 10240
DiskSizeMb int `nullable:"false" list:"user" create:"required"`
// 端口
// example: 3306
Port int `nullable:"false" list:"user" create:"optional"`
// 实例类型
// example: ha
Category string `nullable:"false" list:"user" create:"optional"`
// 分片数量
// example: 3
ReplicationNum int `nullable:"false" default:"0" list:"user" create:"optional"`
// 实例IP地址
IpAddr string `nullable:"false" list:"user"`
// 引擎
// example: MySQL
Engine string `width:"16" charset:"ascii" nullable:"false" list:"user" create:"required"`
// 引擎版本
// example: 5.7
EngineVersion string `width:"16" charset:"ascii" nullable:"false" list:"user" create:"required"`
// 套餐名称
// example: mysql.x4.large.2c
InstanceType string `width:"64" charset:"utf8" nullable:"true" list:"user" create:"optional"`
// 维护时间
MaintainTime string `width:"64" charset:"ascii" nullable:"true" list:"user" create:"optional"`
// 虚拟私有网络Id
// example: ed20d84e-3158-41b1-870c-1725e412e8b6
VpcId string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"optional"`
// 所属网络ID
NetworkId string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"optional" json:"network_id"`
}
func (manager *SMongoDBManager) GetContextManagers() [][]db.IModelManager {
return [][]db.IModelManager{
{CloudregionManager},
}
}
// MongoDB实例列表
func (man *SMongoDBManager) ListItemFilter(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.MongoDBListInput,
) (*sqlchemy.SQuery, error) {
var err error
q, err = man.SVirtualResourceBaseManager.ListItemFilter(ctx, q, userCred, query.VirtualResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SVirtualResourceBaseManager.ListItemFilter")
}
q, err = man.SExternalizedResourceBaseManager.ListItemFilter(ctx, q, userCred, query.ExternalizedResourceBaseListInput)
if err != nil {
return nil, errors.Wrap(err, "SExternalizedResourceBaseManager.ListItemFilter")
}
q, err = man.SDeletePreventableResourceBaseManager.ListItemFilter(ctx, q, userCred, query.DeletePreventableResourceBaseListInput)
if err != nil {
return nil, errors.Wrap(err, "SDeletePreventableResourceBaseManager.ListItemFilter")
}
q, err = man.SManagedResourceBaseManager.ListItemFilter(ctx, q, userCred, query.ManagedResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SManagedResourceBaseManager.ListItemFilter")
}
q, err = man.SCloudregionResourceBaseManager.ListItemFilter(ctx, q, userCred, query.RegionalFilterListInput)
if err != nil {
return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.ListItemFilter")
}
q, err = man.SVpcResourceBaseManager.ListItemFilter(ctx, q, userCred, query.VpcFilterListInput)
if err != nil {
return nil, errors.Wrap(err, "SVpcResourceBaseManager.ListItemFilter")
}
if query.VcpuCount > 0 {
q = q.Equals("vcpu_count", query.VcpuCount)
}
if query.VmemSizeMb > 0 {
q = q.Equals("vmem_size_mb", query.VmemSizeMb)
}
if len(query.Category) > 0 {
q = q.Equals("category", query.Category)
}
if len(query.Engine) > 0 {
q = q.Equals("engine", query.Engine)
}
if len(query.EngineVersion) > 0 {
q = q.Equals("engine_version", query.EngineVersion)
}
if len(query.InstanceType) > 0 {
q = q.Equals("instance_type", query.InstanceType)
}
return q, nil
}
func (man *SMongoDBManager) OrderByExtraFields(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.MongoDBListInput,
) (*sqlchemy.SQuery, error) {
q, err := man.SVirtualResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.VirtualResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SVirtualResourceBaseManager.OrderByExtraFields")
}
q, err = man.SCloudregionResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.RegionalFilterListInput)
if err != nil {
return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.OrderByExtraFields")
}
q, err = man.SManagedResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.ManagedResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SManagedResourceBaseManager.OrderByExtraFields")
}
q, err = man.SVpcResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.VpcFilterListInput)
if err != nil {
return nil, errors.Wrap(err, "SVpcResourceBaseManager.OrderByExtraFields")
}
return q, nil
}
func (man *SMongoDBManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
q, err := man.SVirtualResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
q, err = man.SCloudregionResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
q, err = man.SManagedResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
q, err = man.SVpcResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
return q, httperrors.ErrNotFound
}
func (manager *SMongoDBManager) BatchCreateValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, input *api.MongoDBCreateInput) (*api.MongoDBCreateInput, error) {
return input, httperrors.NewNotImplementedError("Not Implemented")
}
func (man *SMongoDBManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, input api.MongoDBCreateInput) (api.MongoDBCreateInput, error) {
return input, httperrors.NewNotImplementedError("Not Implemented")
}
func (manager *SMongoDBManager) FetchCustomizeColumns(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
objs []interface{},
fields stringutils2.SSortedStrings,
isList bool,
) []api.MongoDBDetails {
rows := make([]api.MongoDBDetails, len(objs))
virtRows := manager.SVirtualResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
manRows := manager.SManagedResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
regRows := manager.SCloudregionResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
rdsIds := make([]string, len(rows))
vpcIds := make([]string, len(rows))
for i := range rows {
rows[i] = api.MongoDBDetails{
VirtualResourceDetails: virtRows[i],
ManagedResourceInfo: manRows[i],
CloudregionResourceInfo: regRows[i],
}
instance := objs[i].(*SMongoDB)
rdsIds[i] = instance.Id
vpcIds[i] = instance.VpcId
}
vpcs := make(map[string]SVpc)
err := db.FetchStandaloneObjectsByIds(VpcManager, vpcIds, &vpcs)
if err != nil {
log.Errorf("db.FetchStandaloneObjectsByIds fail %s", err)
return rows
}
for i := range rows {
if vpc, ok := vpcs[vpcIds[i]]; ok {
rows[i].Vpc = vpc.Name
rows[i].VpcExtId = vpc.ExternalId
}
}
return rows
}
func (self *SMongoDB) GetIMongoDB() (cloudprovider.ICloudMongoDB, error) {
if len(self.ExternalId) == 0 {
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "empty external id")
}
iregion, err := self.GetIRegion()
if err != nil {
return nil, errors.Wrap(err, "self.GetIRegion")
}
iMongoDB, err := iregion.GetICloudMongoDBById(self.ExternalId)
if err != nil {
return nil, errors.Wrapf(err, "GetICloudMongoDBById(%s)", self.ExternalId)
}
return iMongoDB, nil
}
// 同步MongoDB实例状态
func (self *SMongoDB) AllowPerformSyncstatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return self.IsOwner(userCred) || db.IsAdminAllowPerform(userCred, self, "syncstatus")
}
func (self *SMongoDB) PerformSyncstatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
var openTask = true
count, err := taskman.TaskManager.QueryTasksOfObject(self, time.Now().Add(-3*time.Minute), &openTask).CountWithError()
if err != nil {
return nil, err
}
if count > 0 {
return nil, httperrors.NewBadRequestError("MongoDB has %d task active, can't sync status", count)
}
return nil, StartResourceSyncStatusTask(ctx, userCred, self, "MongoDBSyncstatusTask", "")
}
func (self *SMongoDB) SetAutoRenew(autoRenew bool) error {
_, err := db.Update(self, func() error {
self.AutoRenew = autoRenew
return nil
})
return err
}
func (self *SMongoDB) SaveRenewInfo(
ctx context.Context, userCred mcclient.TokenCredential,
bc *billing.SBillingCycle, expireAt *time.Time, billingType string,
) error {
_, err := db.Update(self, func() error {
if billingType == "" {
billingType = billing_api.BILLING_TYPE_PREPAID
}
if self.BillingType == "" {
self.BillingType = billingType
}
if expireAt != nil && !expireAt.IsZero() {
self.ExpiredAt = *expireAt
} else {
self.BillingCycle = bc.String()
self.ExpiredAt = bc.EndAt(self.ExpiredAt)
}
return nil
})
if err != nil {
return errors.Wrapf(err, "db.Update")
}
db.OpsLog.LogEvent(self, db.ACT_RENEW, self.GetShortDesc(ctx), userCred)
return nil
}
func (self *SMongoDB) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
log.Infof("mongodb delete do nothing")
return nil
}
func (self *SMongoDB) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
return self.SVirtualResourceBase.Delete(ctx, userCred)
}
func (self *SMongoDB) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
return self.StartDeleteTask(ctx, userCred, "")
}
func (self *SMongoDB) StartDeleteTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
var err = func() error {
task, err := taskman.TaskManager.NewTask(ctx, "MongoDBDeleteTask", self, userCred, nil, parentTaskId, "", nil)
if err != nil {
return errors.Wrapf(err, "NewTask")
}
return task.ScheduleRun(nil)
}()
if err != nil {
self.SetStatus(userCred, api.MONGO_DB_STATUS_DELETE_FAILED, err.Error())
return err
}
return self.SetStatus(userCred, api.MONGO_DB_STATUS_DELETING, "")
}
func (self *SCloudregion) GetMongoDBs(managerId string) ([]SMongoDB, error) {
q := MongoDBManager.Query().Equals("cloudregion_id", self.Id)
if len(managerId) > 0 {
q = q.Equals("manager_id", managerId)
}
dbs := []SMongoDB{}
err := db.FetchModelObjects(MongoDBManager, q, &dbs)
if err != nil {
return nil, errors.Wrapf(err, "db.FetchModelObjects")
}
return dbs, nil
}
func (self *SCloudregion) SyncMongoDBs(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, cloudMongoDBs []cloudprovider.ICloudMongoDB) ([]SMongoDB, []cloudprovider.ICloudMongoDB, compare.SyncResult) {
lockman.LockRawObject(ctx, "mongodbs", fmt.Sprintf("%s-%s", provider.Id, self.Id))
defer lockman.ReleaseRawObject(ctx, "mongodbs", fmt.Sprintf("%s-%s", provider.Id, self.Id))
localMongoDBs := []SMongoDB{}
remoteMongoDBs := []cloudprovider.ICloudMongoDB{}
result := compare.SyncResult{}
dbInstances, err := self.GetMongoDBs(provider.Id)
if err != nil {
result.Error(err)
return nil, nil, result
}
removed := make([]SMongoDB, 0)
commondb := make([]SMongoDB, 0)
commonext := make([]cloudprovider.ICloudMongoDB, 0)
added := make([]cloudprovider.ICloudMongoDB, 0)
err = compare.CompareSets(dbInstances, cloudMongoDBs, &removed, &commondb, &commonext, &added)
if err != nil {
result.Error(err)
return nil, nil, result
}
for i := 0; i < len(removed); i++ {
err := removed[i].syncRemoveCloudMongoDB(ctx, userCred)
if err != nil {
result.DeleteError(err)
continue
}
result.Delete()
}
for i := 0; i < len(commondb); i++ {
err := commondb[i].SyncWithCloudMongoDB(ctx, userCred, commonext[i])
if err != nil {
result.UpdateError(err)
continue
}
localMongoDBs = append(localMongoDBs, commondb[i])
remoteMongoDBs = append(remoteMongoDBs, commonext[i])
result.Update()
}
for i := 0; i < len(added); i++ {
instance, err := self.newFromCloudMongoDB(ctx, userCred, provider, added[i])
if err != nil {
result.AddError(err)
continue
}
localMongoDBs = append(localMongoDBs, *instance)
remoteMongoDBs = append(remoteMongoDBs, added[i])
result.Add()
}
return localMongoDBs, remoteMongoDBs, result
}
func (self *SMongoDB) syncRemoveCloudMongoDB(ctx context.Context, userCred mcclient.TokenCredential) error {
return self.RealDelete(ctx, userCred)
}
func (self *SMongoDB) ValidateDeleteCondition(ctx context.Context) error {
if self.DisableDelete.IsTrue() {
return httperrors.NewInvalidStatusError("MongoDB is locked, cannot delete")
}
return self.SStatusStandaloneResourceBase.ValidateDeleteCondition(ctx)
}
func (self *SMongoDB) SyncAllWithCloudMongoDB(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, ext cloudprovider.ICloudMongoDB) error {
err := self.SyncWithCloudMongoDB(ctx, userCred, ext)
if err != nil {
return errors.Wrapf(err, "SyncWithCloudMongoDB")
}
return nil
}
func (self *SMongoDB) SyncWithCloudMongoDB(ctx context.Context, userCred mcclient.TokenCredential, ext cloudprovider.ICloudMongoDB) error {
diff, err := db.UpdateWithLock(ctx, self, func() error {
self.ExternalId = ext.GetGlobalId()
self.IpAddr = ext.GetIpAddr()
self.VcpuCount = ext.GetVcpuCount()
self.VmemSizeMb = ext.GetVmemSizeMb()
self.DiskSizeMb = ext.GetDiskSizeMb()
self.ReplicationNum = ext.GetReplicationNum()
self.Engine = ext.GetEngine()
self.EngineVersion = ext.GetEngineVersion()
self.Category = ext.GetCategory()
self.InstanceType = ext.GetInstanceType()
self.MaintainTime = ext.GetMaintainTime()
self.Status = ext.GetStatus()
self.Port = ext.GetPort()
return nil
})
if err != nil {
return errors.Wrapf(err, "db.Update")
}
syncVirtualResourceMetadata(ctx, userCred, self, ext)
if provider := self.GetCloudprovider(); provider != nil {
SyncCloudProject(userCred, self, provider.GetOwnerId(), ext, provider.Id)
}
db.OpsLog.LogSyncUpdate(self, diff, userCred)
return nil
}
func (self *SCloudregion) newFromCloudMongoDB(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, ext cloudprovider.ICloudMongoDB) (*SMongoDB, error) {
ins := SMongoDB{}
ins.SetModelManager(MongoDBManager, &ins)
ins.ExternalId = ext.GetGlobalId()
ins.CloudregionId = self.Id
ins.ManagerId = provider.Id
ins.Status = ext.GetStatus()
ins.IpAddr = ext.GetIpAddr()
ins.VcpuCount = ext.GetVcpuCount()
ins.VmemSizeMb = ext.GetVmemSizeMb()
ins.DiskSizeMb = ext.GetDiskSizeMb()
ins.Engine = ext.GetEngine()
ins.EngineVersion = ext.GetEngineVersion()
ins.Category = ext.GetCategory()
ins.InstanceType = ext.GetInstanceType()
ins.MaintainTime = ext.GetMaintainTime()
ins.Port = ext.GetPort()
ins.ReplicationNum = ext.GetReplicationNum()
if zoneId := ext.GetZoneId(); len(zoneId) > 0 {
_zone, err := db.FetchByExternalId(ZoneManager, zoneId)
if err != nil {
return nil, errors.Wrapf(err, "")
}
ins.ZoneId = _zone.GetId()
}
createdAt := ext.GetCreatedAt()
if !createdAt.IsZero() {
ins.CreatedAt = createdAt
}
ins.BillingType = ext.GetBillingType()
if ins.BillingType == billing_api.BILLING_TYPE_PREPAID {
expiredAt := ext.GetExpiredAt()
if !expiredAt.IsZero() {
ins.ExpiredAt = expiredAt
}
ins.AutoRenew = ext.IsAutoRenew()
}
if vpcId := ext.GetVpcId(); len(vpcId) > 0 {
vpc, err := db.FetchByExternalIdAndManagerId(VpcManager, vpcId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
return q.Equals("manager_id", provider.Id)
})
if err != nil {
log.Errorf("FetchVpcId(%s) error: %v", vpcId, err)
} else {
ins.VpcId = vpc.GetId()
}
}
if networkId := ext.GetNetworkId(); len(networkId) > 0 {
network, err := db.FetchByExternalIdAndManagerId(NetworkManager, networkId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
wire := WireManager.Query().SubQuery()
vpc := VpcManager.Query().SubQuery()
return q.Join(wire, sqlchemy.Equals(wire.Field("id"), q.Field("wire_id"))).
Join(vpc, sqlchemy.Equals(vpc.Field("id"), wire.Field("vpc_id"))).
Filter(sqlchemy.Equals(vpc.Field("manager_id"), provider.Id))
})
if err != nil {
return nil, errors.Wrapf(err, "ext.FetchNetworkId")
}
ins.NetworkId = network.GetId()
}
var err error
err = func() error {
lockman.LockRawObject(ctx, MongoDBManager.Keyword(), "name")
defer lockman.ReleaseRawObject(ctx, MongoDBManager.Keyword(), "name")
ins.Name, err = db.GenerateName(ctx, MongoDBManager, provider.GetOwnerId(), ext.GetName())
if err != nil {
return errors.Wrapf(err, "db.GenerateName")
}
return MongoDBManager.TableSpec().Insert(ctx, &ins)
}()
if err != nil {
return nil, errors.Wrapf(err, "newFromCloudMongoDB.Insert")
}
syncVirtualResourceMetadata(ctx, userCred, &ins, ext)
SyncCloudProject(userCred, &ins, provider.GetOwnerId(), ext, provider.Id)
db.OpsLog.LogEvent(&ins, db.ACT_CREATE, ins.GetShortDesc(ctx), userCred)
return &ins, nil
}
type SMongoDBCountStat struct {
TotalMongodbCount int
TotalCpuCount int
TotalMemSizeMb int
}
func (man *SMongoDBManager) TotalCount(
scope rbacutils.TRbacScope,
ownerId mcclient.IIdentityProvider,
rangeObjs []db.IStandaloneModel,
providers []string, brands []string, cloudEnv string,
) (SMongoDBCountStat, error) {
sq := man.Query().SubQuery()
q := sq.Query(sqlchemy.COUNT("total_mongodb_count"),
sqlchemy.SUM("total_cpu_count", sq.Field("vcpu_count")),
sqlchemy.SUM("total_mem_size_mb", sq.Field("vmem_size_mb")))
q = scopeOwnerIdFilter(q, scope, ownerId)
q = CloudProviderFilter(q, q.Field("manager_id"), providers, brands, cloudEnv)
q = RangeObjectsFilter(q, rangeObjs, q.Field("cloudregion_id"), nil, q.Field("manager_id"), nil, nil)
stat := SMongoDBCountStat{}
row := q.Row()
err := q.Row2Struct(row, &stat)
return stat, err
}
func (self *SMongoDB) GetQuotaKeys() quotas.IQuotaKeys {
return fetchRegionalQuotaKeys(
rbacutils.ScopeProject,
self.GetOwnerId(),
self.GetRegion(),
self.GetCloudprovider(),
)
}
func (self *SMongoDB) GetUsages() []db.IUsage {
if self.PendingDeleted || self.Deleted {
return nil
}
usage := SRegionQuota{Rds: 1}
keys := self.GetQuotaKeys()
usage.SetKeys(keys)
return []db.IUsage{
&usage,
}
}
func (self *SMongoDB) GetIRegion() (cloudprovider.ICloudRegion, error) {
region := self.GetRegion()
if region == nil {
return nil, errors.Wrap(httperrors.ErrInvalidStatus, "no valid cloudregion")
}
provider, err := self.GetDriver()
if err != nil {
return nil, errors.Wrap(err, "self.GetDriver")
}
return provider.GetIRegionById(region.GetExternalId())
}
func (manager *SMongoDBManager) ListItemExportKeys(ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
keys stringutils2.SSortedStrings,
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SVirtualResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SVirtualResourceBaseManager.ListItemExportKeys")
}
if keys.ContainsAny(manager.SManagedResourceBaseManager.GetExportKeys()...) {
q, err = manager.SManagedResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SManagedResourceBaseManager.ListItemExportKeys")
}
}
if keys.ContainsAny(manager.SCloudregionResourceBaseManager.GetExportKeys()...) {
q, err = manager.SCloudregionResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.ListItemExportKeys")
}
}
if keys.Contains("vpc") {
q, err = manager.SVpcResourceBaseManager.ListItemExportKeys(ctx, q, userCred, stringutils2.NewSortedStrings([]string{"vpc"}))
if err != nil {
return nil, errors.Wrap(err, "SVpcResourceBaseManager.ListItemExportKeys")
}
}
return q, nil
}
func (self *SMongoDB) AllowPerformPostpaidExpire(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return self.IsOwner(userCred) || db.IsAdminAllowPerform(userCred, self, "postpaid-expire")
}
func (self *SMongoDB) PerformPostpaidExpire(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input apis.PostpaidExpireInput) (jsonutils.JSONObject, error) {
if self.BillingType != billing_api.BILLING_TYPE_POSTPAID {
return nil, httperrors.NewBadRequestError("self billing type is %s", self.BillingType)
}
bc, err := ParseBillingCycleInput(&self.SBillingResourceBase, input)
if err != nil {
return nil, err
}
err = self.SaveRenewInfo(ctx, userCred, bc, nil, billing_api.BILLING_TYPE_POSTPAID)
return nil, err
}
func (self *SMongoDB) AllowPerformCancelExpire(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return self.IsOwner(userCred) || db.IsAdminAllowPerform(userCred, self, "cancel-expire")
}
func (self *SMongoDB) PerformCancelExpire(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
if err := self.CancelExpireTime(ctx, userCred); err != nil {
return nil, err
}
return nil, nil
}
func (self *SMongoDB) CancelExpireTime(ctx context.Context, userCred mcclient.TokenCredential) error {
if self.BillingType != billing_api.BILLING_TYPE_POSTPAID {
return httperrors.NewBadRequestError("self billing type %s not support cancel expire", self.BillingType)
}
_, err := sqlchemy.GetDB().Exec(
fmt.Sprintf(
"update %s set expired_at = NULL and billing_cycle = NULL where id = ?",
MongoDBManager.TableSpec().Name(),
), self.Id,
)
if err != nil {
return errors.Wrap(err, "self cancel expire time")
}
db.OpsLog.LogEvent(self, db.ACT_RENEW, "self cancel expire time", userCred)
return nil
}
func (self *SMongoDB) AllowPerformRemoteUpdate(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return self.IsOwner(userCred) || db.IsAdminAllowPerform(userCred, self, "remote-update")
}
func (self *SMongoDB) PerformRemoteUpdate(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.MongoDBRemoteUpdateInput) (jsonutils.JSONObject, error) {
err := self.StartRemoteUpdateTask(ctx, userCred, (input.ReplaceTags != nil && *input.ReplaceTags), "")
if err != nil {
return nil, errors.Wrap(err, "StartRemoteUpdateTask")
}
return nil, nil
}
func (self *SMongoDB) StartRemoteUpdateTask(ctx context.Context, userCred mcclient.TokenCredential, replaceTags bool, parentTaskId string) error {
data := jsonutils.NewDict()
if replaceTags {
data.Add(jsonutils.JSONTrue, "replace_tags")
}
if task, err := taskman.TaskManager.NewTask(ctx, "MongoDBRemoteUpdateTask", self, userCred, data, parentTaskId, "", nil); err != nil {
log.Errorln(err)
return errors.Wrap(err, "Start ElasticcacheRemoteUpdateTask")
} else {
self.SetStatus(userCred, api.DBINSTANCE_UPDATE_TAGS, "StartRemoteUpdateTask")
task.ScheduleRun(nil)
}
return nil
}
func (self *SMongoDB) OnMetadataUpdated(ctx context.Context, userCred mcclient.TokenCredential) {
if len(self.ExternalId) == 0 {
return
}
err := self.StartRemoteUpdateTask(ctx, userCred, true, "")
if err != nil {
log.Errorf("StartRemoteUpdateTask fail: %s", err)
}
}
func (self *SMongoDB) AllowGetDetailsBackups(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool {
return self.IsOwner(userCred) || db.IsAdminAllowGetSpec(userCred, self, "backups")
}
// 获取备份列表
func (self *SMongoDB) GetDetailsBackups(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*cloudprovider.SMongoDBBackups, error) {
if self.Status != api.MONGO_DB_STATUS_RUNNING {
return nil, httperrors.NewInvalidStatusError("invalid mongodb status %s for query backups", self.Status)
}
ret := &cloudprovider.SMongoDBBackups{}
iMongoDB, err := self.GetIMongoDB()
if err != nil {
return nil, httperrors.NewGeneralError(errors.Wrapf(err, "GetIMongoDB"))
}
ret.Data, err = iMongoDB.GetIBackups()
if err != nil {
return nil, httperrors.NewGeneralError(errors.Wrapf(err, "GetIBackups"))
}
ret.Total = len(ret.Data)
return ret, nil
}
+15
View File
@@ -1984,3 +1984,18 @@ func (manager *SWafInstanceManager) purgeAll(ctx context.Context, userCred mccli
}
return nil
}
func (manager *SMongoDBManager) purgeAll(ctx context.Context, userCred mcclient.TokenCredential, providerId string) error {
dbs := []SMongoDB{}
err := fetchByManagerId(manager, providerId, &dbs)
if err != nil {
return errors.Wrapf(err, "fetchByManagerId")
}
for i := range dbs {
err := dbs[i].RealDelete(ctx, userCred)
if err != nil {
return errors.Wrapf(err, "cache delete")
}
}
return nil
}
+24 -2
View File
@@ -86,8 +86,9 @@ type SRegionQuota struct {
ObjectGB int `default:"-1" allow_zero:"true" json:"object_gb"`
ObjectCnt int `default:"-1" allow_zero:"true" json:"object_cnt"`
Rds int `default:"-1" allow_zero:"true" json:"rds"`
Cache int `default:"-1" allow_zero:"true" json:"cache"`
Rds int `default:"-1" allow_zero:"true" json:"rds"`
Cache int `default:"-1" allow_zero:"true" json:"cache"`
Mongodb int `default:"-1" allow_zero:"true" json:"mongodb"`
Loadbalancer int `default:"-1" allow_zero:"true" json:"loadbalancer"`
}
@@ -138,6 +139,7 @@ func (self *SRegionQuota) FetchSystemQuota() {
self.ObjectCnt = defaultValue(options.Options.DefaultObjectCntQuota)
self.Rds = defaultValue(options.Options.DefaultRdsQuota)
self.Cache = defaultValue(options.Options.DefaultCacheQuota)
self.Mongodb = defaultValue(options.Options.DefaultMongodbQuota)
self.Loadbalancer = defaultValue(options.Options.DefaultLoadbalancerQuota)
}
@@ -204,6 +206,8 @@ func (self *SRegionQuota) FetchUsage(ctx context.Context) error {
rdsUsage, _ := DBInstanceManager.TotalCount(scope, ownerId, rangeObjs, providers, brands, regionKeys.CloudEnv)
self.Rds = rdsUsage.TotalRdsCount
self.Cache, _ = ElasticcacheManager.TotalCount(scope, ownerId, rangeObjs, providers, brands, regionKeys.CloudEnv)
mongodbUsage, _ := MongoDBManager.TotalCount(scope, ownerId, rangeObjs, providers, brands, regionKeys.CloudEnv)
self.Mongodb = mongodbUsage.TotalMongodbCount
self.Loadbalancer, _ = LoadbalancerManager.TotalCount(scope, ownerId, rangeObjs, providers, brands, regionKeys.CloudEnv)
@@ -247,6 +251,9 @@ func (self *SRegionQuota) ResetNegative() {
if self.Cache < 0 {
self.Cache = 0
}
if self.Mongodb < 0 {
self.Mongodb = 0
}
if self.Loadbalancer < 0 {
self.Loadbalancer = 0
}
@@ -289,6 +296,9 @@ func (self *SRegionQuota) IsEmpty() bool {
if self.Cache > 0 {
return false
}
if self.Mongodb > 0 {
return false
}
if self.Loadbalancer > 0 {
return false
}
@@ -309,6 +319,7 @@ func (self *SRegionQuota) Add(quota quotas.IQuota) {
self.ObjectCnt = self.ObjectCnt + quotas.NonNegative(squota.ObjectCnt)
self.Rds = self.Rds + quotas.NonNegative(squota.Rds)
self.Cache = self.Cache + quotas.NonNegative(squota.Cache)
self.Mongodb = self.Mongodb + quotas.NonNegative(squota.Mongodb)
self.Loadbalancer = self.Loadbalancer + quotas.NonNegative(squota.Loadbalancer)
}
@@ -326,6 +337,7 @@ func (self *SRegionQuota) Sub(quota quotas.IQuota) {
self.ObjectCnt = nonNegative(self.ObjectCnt - squota.ObjectCnt)
self.Rds = nonNegative(self.Rds - squota.Rds)
self.Cache = nonNegative(self.Cache - squota.Cache)
self.Mongodb = nonNegative(self.Mongodb - squota.Mongodb)
self.Loadbalancer = nonNegative(self.Loadbalancer - squota.Loadbalancer)
}
@@ -368,6 +380,9 @@ func (self *SRegionQuota) Allocable(request quotas.IQuota) int {
if self.Cache >= 0 && squota.Cache > 0 && (cnt < 0 || cnt > self.Cache/squota.Cache) {
cnt = self.Cache / squota.Cache
}
if self.Mongodb >= 0 && squota.Mongodb > 0 && (cnt < 0 || cnt > self.Mongodb/squota.Mongodb) {
cnt = self.Mongodb / squota.Mongodb
}
if self.Loadbalancer >= 0 && squota.Loadbalancer > 0 && (cnt < 0 || cnt > self.Loadbalancer/squota.Loadbalancer) {
cnt = self.Loadbalancer / squota.Loadbalancer
}
@@ -412,6 +427,9 @@ func (self *SRegionQuota) Update(quota quotas.IQuota) {
if squota.Cache > 0 {
self.Cache = squota.Cache
}
if squota.Mongodb > 0 {
self.Mongodb = squota.Mongodb
}
if squota.Loadbalancer > 0 {
self.Loadbalancer = squota.Loadbalancer
}
@@ -457,6 +475,9 @@ func (used *SRegionQuota) Exceed(request quotas.IQuota, quota quotas.IQuota) err
if quotas.Exceed(used.Cache, sreq.Cache, squota.Cache) {
err.Add(used, "cache", squota.Cache, used.Cache, sreq.Cache)
}
if quotas.Exceed(used.Mongodb, sreq.Mongodb, squota.Mongodb) {
err.Add(used, "mongodb", squota.Mongodb, used.Mongodb, sreq.Mongodb)
}
if quotas.Exceed(used.Loadbalancer, sreq.Loadbalancer, squota.Loadbalancer) {
err.Add(used, "loadbalancer", squota.Loadbalancer, used.Loadbalancer, sreq.Loadbalancer)
}
@@ -481,6 +502,7 @@ func (self *SRegionQuota) ToJSON(prefix string) jsonutils.JSONObject {
ret.Add(jsonutils.NewInt(int64(self.ObjectCnt)), keyName(prefix, "object_cnt"))
ret.Add(jsonutils.NewInt(int64(self.Rds)), keyName(prefix, "rds"))
ret.Add(jsonutils.NewInt(int64(self.Cache)), keyName(prefix, "cache"))
ret.Add(jsonutils.NewInt(int64(self.Mongodb)), keyName(prefix, "mongodb"))
ret.Add(jsonutils.NewInt(int64(self.Loadbalancer)), keyName(prefix, "loadbalancer"))
return ret
}
+1
View File
@@ -78,6 +78,7 @@ type ComputeOptions struct {
DefaultLoadbalancerQuota int `default:"10" help:"Common loadbalancer quota per tenant, default 10"`
DefaultRdsQuota int `default:"10" help:"Common RDS quota per tenant, default 10"`
DefaultCacheQuota int `default:"10" help:"Common ElasticCache quota per tenant, default 10"`
DefaultMongodbQuota int `default:"10" help:"Common MongoDB quota per tenant, default 10"`
DefaultGlobalvpcQuota int `default:"10" help:"Common global Vpc quota per domain, default 10"`
DefaultCloudaccountQuota int `default:"20" help:"Common cloud account quota per domain, default 20"`
+2
View File
@@ -226,6 +226,8 @@ func InitHandlers(app *appsrv.Application) {
models.WafRegexSetCacheManager,
models.WafInstanceManager,
models.WafRuleManager,
models.MongoDBManager,
} {
db.RegisterModelManager(manager)
handler := db.NewModelHandler(manager)
+70
View File
@@ -0,0 +1,70 @@
// 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 fsreed 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 langufse governing permissions and
// limitations under the License.
package tasks
import (
"context"
"time"
"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/cloudprovider"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type MongoDBDeleteTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(MongoDBDeleteTask{})
}
func (self *MongoDBDeleteTask) taskFailed(ctx context.Context, mongodb *models.SMongoDB, err error) {
mongodb.SetStatus(self.UserCred, api.MONGO_DB_STATUS_DELETE_FAILED, err.Error())
logclient.AddActionLogWithStartable(self, mongodb, logclient.ACT_DELOCATE, err, self.UserCred, false)
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *MongoDBDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
mongodb := obj.(*models.SMongoDB)
iMongoDB, err := mongodb.GetIMongoDB()
if err != nil {
if errors.Cause(err) == cloudprovider.ErrNotFound {
self.taskComplete(ctx, mongodb)
return
}
self.taskFailed(ctx, mongodb, errors.Wrapf(err, "mongodb.GetIMongoDB"))
return
}
err = iMongoDB.Delete()
if err != nil {
self.taskFailed(ctx, mongodb, errors.Wrapf(err, "iMongoDB.Delete"))
return
}
cloudprovider.WaitDeleted(iMongoDB, time.Second*10, time.Minute*5)
self.taskComplete(ctx, mongodb)
}
func (self *MongoDBDeleteTask) taskComplete(ctx context.Context, mongodb *models.SMongoDB) {
mongodb.RealDelete(ctx, self.GetUserCred())
self.SetStageComplete(ctx, nil)
}
@@ -0,0 +1,62 @@
// 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 MongoDBSyncstatusTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(MongoDBSyncstatusTask{})
}
func (self *MongoDBSyncstatusTask) taskFail(ctx context.Context, mongodb *models.SMongoDB, err error) {
mongodb.SetStatus(self.UserCred, api.MONGO_DB_STATUS_UNKNOWN, err.Error())
db.OpsLog.LogEvent(mongodb, db.ACT_SYNC_STATUS, err, self.GetUserCred())
logclient.AddActionLogWithStartable(self, mongodb, logclient.ACT_SYNC_STATUS, err, self.UserCred, false)
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *MongoDBSyncstatusTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
mongodb := obj.(*models.SMongoDB)
ext, err := mongodb.GetIMongoDB()
if err != nil {
self.taskFail(ctx, mongodb, errors.Wrapf(err, "GetIMongoDB"))
return
}
err = mongodb.SyncWithCloudMongoDB(ctx, self.UserCred, ext)
if err != nil {
self.taskFail(ctx, mongodb, errors.Wrapf(err, "SyncWithCloudMongoDB"))
return
}
logclient.AddActionLogWithStartable(self, mongodb, logclient.ACT_SYNC_STATUS, nil, self.UserCred, true)
self.SetStageComplete(ctx, nil)
}
+15
View File
@@ -319,6 +319,8 @@ func getSystemGeneralUsage(userCred mcclient.IIdentityProvider, rangeObjs []db.I
DBInstanceUsage(rbacutils.ScopeSystem, nil, rangeObjs, providers, brands, cloudEnv),
MongoDBUsage(rbacutils.ScopeSystem, nil, rangeObjs, providers, brands, cloudEnv),
ElasticCacheUsage(rbacutils.ScopeSystem, nil, rangeObjs, providers, brands, cloudEnv),
)
@@ -409,6 +411,8 @@ func getDomainGeneralUsage(scope rbacutils.TRbacScope, cred mcclient.IIdentityPr
DBInstanceUsage(scope, cred, rangeObjs, providers, brands, cloudEnv),
MongoDBUsage(scope, cred, rangeObjs, providers, brands, cloudEnv),
ElasticCacheUsage(scope, cred, rangeObjs, providers, brands, cloudEnv),
)
return count, nil
@@ -457,6 +461,8 @@ func getProjectGeneralUsage(scope rbacutils.TRbacScope, cred mcclient.IIdentityP
DBInstanceUsage(scope, cred, rangeObjs, providers, brands, cloudEnv),
MongoDBUsage(scope, cred, rangeObjs, providers, brands, cloudEnv),
ElasticCacheUsage(scope, cred, rangeObjs, providers, brands, cloudEnv),
)
@@ -949,6 +955,15 @@ func DBInstanceUsage(scope rbacutils.TRbacScope, ownerId mcclient.IIdentityProvi
return count
}
func MongoDBUsage(scope rbacutils.TRbacScope, ownerId mcclient.IIdentityProvider, rangeObjs []db.IStandaloneModel, providers []string, brands []string, cloudEnv string) Usage {
cnt, _ := models.MongoDBManager.TotalCount(scope, ownerId, rangeObjs, providers, brands, cloudEnv)
count := make(map[string]interface{})
count[getKey(scope, "mongodb")] = cnt.TotalMongodbCount
count[getKey(scope, "mongodb.cpu")] = cnt.TotalCpuCount
count[getKey(scope, "mongodb.memory")] = cnt.TotalMemSizeMb
return count
}
func ElasticCacheUsage(scope rbacutils.TRbacScope, ownerId mcclient.IIdentityProvider, rangeObjs []db.IStandaloneModel, providers []string, brands []string, cloudEnv string) Usage {
cnt, _ := models.ElasticcacheManager.TotalCount(scope, ownerId, rangeObjs, providers, brands, cloudEnv)
count := make(map[string]interface{})
+33
View File
@@ -0,0 +1,33 @@
// 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/mcclient/modulebase"
type MongoDBManager struct {
modulebase.ResourceManager
}
var (
MongoDB MongoDBManager
)
func init() {
MongoDB = MongoDBManager{NewComputeManager("mongodb", "mongodbs",
[]string{},
[]string{})}
registerCompute(&MongoDB)
}
+59
View File
@@ -0,0 +1,59 @@
// 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 compute
import (
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/mcclient/options"
)
type MongoDBListOptions struct {
options.BaseListOptions
}
func (opts *MongoDBListOptions) Params() (jsonutils.JSONObject, error) {
return options.ListStructToParams(opts)
}
type MongoDBUpdateOptions struct {
options.BaseIdOptions
Name string
Description string
Delete string `help:"Lock or not lock dbinstance" choices:"enable|disable"`
}
func (opts *MongoDBUpdateOptions) Params() (jsonutils.JSONObject, error) {
params, err := options.StructToParams(opts)
if err != nil {
return nil, err
}
if len(opts.Delete) > 0 {
if opts.Delete == "disable" {
params.Add(jsonutils.JSONTrue, "disable_delete")
} else {
params.Add(jsonutils.JSONFalse, "disable_delete")
}
}
return params, nil
}
type MongoDBBackupListOptions struct {
options.BaseIdOptions
}
func (opts *MongoDBBackupListOptions) Property() string {
return "backups"
}
+13 -11
View File
@@ -55,17 +55,18 @@ const (
ALIYUN_BSS_API_VERSION = "2017-12-14"
ALIYUN_RAM_API_VERSION = "2015-05-01"
ALIYUN_API_VERION_RDS = "2014-08-15"
ALIYUN_RM_API_VERSION = "2020-03-31"
ALIYUN_STS_API_VERSION = "2015-04-01"
ALIYUN_PVTZ_API_VERSION = "2018-01-01"
ALIYUN_ALIDNS_API_VERSION = "2015-01-09"
ALIYUN_CBN_API_VERSION = "2017-09-12"
ALIYUN_CDN_API_VERSION = "2018-05-10"
ALIYUN_IMS_API_VERSION = "2019-08-15"
ALIYUN_NAS_API_VERSION = "2017-06-26"
ALIYUN_WAF_API_VERSION = "2019-09-10"
ALIYUN_RAM_API_VERSION = "2015-05-01"
ALIYUN_RDS_API_VERSION = "2014-08-15"
ALIYUN_RM_API_VERSION = "2020-03-31"
ALIYUN_STS_API_VERSION = "2015-04-01"
ALIYUN_PVTZ_API_VERSION = "2018-01-01"
ALIYUN_ALIDNS_API_VERSION = "2015-01-09"
ALIYUN_CBN_API_VERSION = "2017-09-12"
ALIYUN_CDN_API_VERSION = "2018-05-10"
ALIYUN_IMS_API_VERSION = "2019-08-15"
ALIYUN_NAS_API_VERSION = "2017-06-26"
ALIYUN_WAF_API_VERSION = "2019-09-10"
ALIYUN_MONGO_DB_API_VERSION = "2015-12-01"
ALIYUN_SERVICE_ECS = "ecs"
ALIYUN_SERVICE_VPC = "vpc"
@@ -644,6 +645,7 @@ func (region *SAliyunClient) GetCapabilities() []string {
cloudprovider.CLOUD_CAPABILITY_NAT,
cloudprovider.CLOUD_CAPABILITY_NAS,
cloudprovider.CLOUD_CAPABILITY_WAF,
cloudprovider.CLOUD_CAPABILITY_MONGO_DB,
}
return caps
}
+416
View File
@@ -0,0 +1,416 @@
// 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 aliyun
import (
"fmt"
"regexp"
"strconv"
"strings"
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/utils"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/multicloud"
)
type SMongoDB struct {
region *SRegion
multicloud.AliyunTags
multicloud.SBillingBase
multicloud.SResourceBase
ChargeType TChargeType `json:"ChargeType"`
LockMode string `json:"LockMode"`
DBInstanceClass string `json:"DBInstanceClass"`
ResourceGroupId string `json:"ResourceGroupId"`
DBInstanceId string `json:"DBInstanceId"`
ZoneId string `json:"ZoneId"`
MongosList struct {
MongosAttribute []struct {
NodeId string `json:"NodeId"`
NodeClass string `json:"NodeClass"`
} `json:"MongosAttribute"`
} `json:"MongosList"`
DBInstanceDescription string `json:"DBInstanceDescription"`
Engine string `json:"Engine"`
CreationTime time.Time `json:"CreationTime"`
NetworkType string `json:"NetworkType"`
ExpireTime time.Time `json:"ExpireTime"`
DBInstanceType string `json:"DBInstanceType"`
RegionId string `json:"RegionId"`
ShardList struct {
ShardAttribute []struct {
NodeId string `json:"NodeId"`
NodeClass string `json:"NodeClass"`
NodeStorage int `json:"NodeStorage"`
} `json:"ShardAttribute"`
} `json:"ShardList"`
EngineVersion string `json:"EngineVersion"`
DBInstanceStatus string `json:"DBInstanceStatus"`
DBInstanceStorage int `json:"DBInstanceStorage"`
MaintainStartTime string `json:"MaintainStartTime"`
MaintainEndTime string `json:"MaintainEndTime"`
StorageEngine string `json:"StorageEngine"`
VpcId string `json:"VPCId"`
VSwitchId string `json:"VSwitchId"`
VpcAuthMode string `json:"VpcAuthMode"`
ReplicationFactor string `json:"ReplicationFactor"`
}
var mongoSpec = map[string]struct {
VcpuCount int
VmemSizeGb int
}{}
func (self *SMongoDB) GetName() string {
if len(self.DBInstanceDescription) > 0 {
return self.DBInstanceDescription
}
return self.DBInstanceId
}
func (self *SMongoDB) GetId() string {
return self.DBInstanceId
}
func (self *SMongoDB) GetGlobalId() string {
return self.DBInstanceId
}
func (self *SMongoDB) GetStatus() string {
switch self.DBInstanceStatus {
case "Creating":
return api.MONGO_DB_STATUS_CREATING
case "DBInstanceClassChanging":
return api.MONGO_DB_STATUS_CHANGE_CONFIG
case "DBInstanceNetTypeChanging", "EngineVersionUpgrading", "GuardSwitching", "HASwitching", "Importing", "ImportingFromOthers", "LinkSwitching", "MinorVersionUpgrading", "NET_CREATING", "NET_DELETING", "NodeCreating", "NodeDeleting", "Restoring", "SSLModifying", "TempDBInstanceCreating", "Transing", "TransingToOthers":
return api.MONGO_DB_STATUS_DEPLOY
case "Deleting":
return api.MONGO_DB_STATUS_DELETING
case "Rebooting":
return api.MONGO_DB_STATUS_REBOOTING
case "Running":
return api.MONGO_DB_STATUS_RUNNING
default:
return strings.ToLower(self.DBInstanceStatus)
}
}
func (self *SMongoDB) GetProjectId() string {
return self.ResourceGroupId
}
func (self *SMongoDB) Refresh() error {
db, err := self.region.GetMongoDB(self.DBInstanceId)
if err != nil {
return errors.Wrapf(err, "GetMongoDB")
}
return jsonutils.Update(self, db)
}
func (self *SMongoDB) GetCreatedAt() time.Time {
return self.CreationTime
}
func (self *SMongoDB) GetExpiredAt() time.Time {
return self.ExpireTime
}
func (self *SMongoDB) GetIpAddr() string {
return ""
}
func (self *SMongoDB) GetEngine() string {
if len(self.StorageEngine) == 0 {
self.Refresh()
}
return self.StorageEngine
}
func (self *SMongoDB) GetEngineVersion() string {
return self.EngineVersion
}
func (self *SMongoDB) GetVpcId() string {
if self.NetworkType != "VPC" {
return ""
}
if len(self.VpcId) == 0 {
self.Refresh()
}
return self.VpcId
}
func (self *SMongoDB) GetNetworkId() string {
if self.NetworkType != "VPC" {
return ""
}
if len(self.VSwitchId) == 0 {
self.Refresh()
}
return self.VSwitchId
}
func (self *SMongoDB) GetZoneId() string {
if strings.Contains(self.ZoneId, ",") {
return self.ZoneId
}
if info := strings.Split(self.ZoneId, "-"); len(info) == 3 {
return strings.Join([]string{info[0], info[1], string(info[2][strings.Index(info[2], ",")-1])}, "-")
}
return ""
}
func (self *SMongoDB) Delete() error {
return self.region.DeleteMongoDB(self.DBInstanceId)
}
func (self *SMongoDB) GetBillingType() string {
return convertChargeType(self.ChargeType)
}
func (self *SMongoDB) GetCategory() string {
return self.DBInstanceType
}
func (self *SMongoDB) GetDiskSizeMb() int {
if self.DBInstanceStorage == 0 {
self.Refresh()
}
return self.DBInstanceStorage * 1024
}
func (self *SMongoDB) GetInstanceType() string {
return self.DBInstanceClass
}
func (self *SMongoDB) GetMaintainTime() string {
return fmt.Sprintf("%s-%s", self.MaintainStartTime, self.MaintainEndTime)
}
func (self *SMongoDB) GetPort() int {
return 3717
}
func (self *SMongoDB) GetReplicationNum() int {
if len(self.ReplicationFactor) == 0 {
self.Refresh()
}
num, _ := strconv.Atoi(self.ReplicationFactor)
return int(num)
}
func (self *SMongoDB) GetVcpuCount() int {
self.region.GetchMongoSkus()
sku, ok := self.region.mongoSkus[self.DBInstanceClass]
if ok {
return sku.CpuCount
}
return 0
}
func (self *SMongoDB) GetVmemSizeMb() int {
self.region.GetchMongoSkus()
sku, ok := self.region.mongoSkus[self.DBInstanceClass]
if ok {
return sku.MemSizeGb * 1024
}
return 0
}
func (self *SRegion) GetICloudMongoDBs() ([]cloudprovider.ICloudMongoDB, error) {
dbs := []SMongoDB{}
for {
part, total, err := self.GetMongoDBs(100, len(dbs)/100)
if err != nil {
return nil, errors.Wrapf(err, "GetMongoDB")
}
dbs = append(dbs, part...)
if len(dbs) >= total {
break
}
}
ret := []cloudprovider.ICloudMongoDB{}
for i := range dbs {
dbs[i].region = self
ret = append(ret, &dbs[i])
}
return ret, nil
}
func (self *SRegion) GetMongoDBs(pageSize int, pageNum int) ([]SMongoDB, int, error) {
if pageSize < 1 || pageSize > 100 {
pageSize = 100
}
if pageNum < 1 {
pageNum = 1
}
params := map[string]string{
"PageSize": fmt.Sprintf("%d", pageSize),
"PageNumber": fmt.Sprintf("%d", pageNum),
}
resp, err := self.mongodbRequest("DescribeDBInstances", params)
if err != nil {
return nil, 0, errors.Wrapf(err, "DescribeDBInstances")
}
ret := []SMongoDB{}
err = resp.Unmarshal(&ret, "DBInstances", "DBInstance")
if err != nil {
return nil, 0, errors.Wrapf(err, "resp.Unmarshal")
}
totalCount, _ := resp.Int("TotalCount")
return ret, int(totalCount), nil
}
func (self *SRegion) GetMongoDB(id string) (*SMongoDB, error) {
params := map[string]string{
"DBInstanceId": id,
}
resp, err := self.mongodbRequest("DescribeDBInstanceAttribute", params)
if err != nil {
return nil, errors.Wrapf(err, "DescribeDBInstanceAttribute")
}
ret := []SMongoDB{}
err = resp.Unmarshal(&ret, "DBInstances", "DBInstance")
if err != nil {
return nil, errors.Wrapf(err, "resp.Unmarshal")
}
if len(ret) == 1 {
ret[0].region = self
return &ret[0], nil
}
return nil, errors.Wrapf(cloudprovider.ErrNotFound, id)
}
func (self *SRegion) DeleteMongoDB(id string) error {
params := map[string]string{
"DBInstanceId": id,
"ClientToken": utils.GenRequestId(20),
}
_, err := self.mongodbRequest("DeleteDBInstance", params)
return errors.Wrapf(err, "DeleteDBInstance")
}
type SMongoDBAvaibaleResource struct {
SupportedDBTypes struct {
SupportedDBType []struct {
DbType string
AvailableZones struct {
AvailableZone []struct {
ZoneId string
RegionId string
SupportedEngineVersions struct {
SupportedEngineVersion []struct {
Version string
SupportedEngines struct {
SupportedEngine []struct {
SupportedNodeTypes struct {
SupportedNodeType []struct {
NetworkTypes string
NodeType string
AvailableResources struct {
AvailableResource []struct {
InstanceClassRemark string
InstanceClass string
}
}
}
}
}
}
}
}
}
}
}
}
}
func (self *SRegion) GetchMongoSkus() (map[string]struct {
CpuCount int
MemSizeGb int
}, error) {
if len(self.mongoSkus) > 0 {
return self.mongoSkus, nil
}
self.mongoSkus = map[string]struct {
CpuCount int
MemSizeGb int
}{}
res, err := self.GetMongoDBAvailableResource()
if err != nil {
return nil, err
}
for _, dbType := range res.SupportedDBTypes.SupportedDBType {
for _, zone := range dbType.AvailableZones.AvailableZone {
for _, version := range zone.SupportedEngineVersions.SupportedEngineVersion {
for _, engine := range version.SupportedEngines.SupportedEngine {
for _, nodeType := range engine.SupportedNodeTypes.SupportedNodeType {
for _, sku := range nodeType.AvailableResources.AvailableResource {
_, ok := self.mongoSkus[sku.InstanceClass]
if !ok {
self.mongoSkus[sku.InstanceClass] = getMongoDBSkuDetails(sku.InstanceClassRemark)
}
}
}
}
}
}
}
return self.mongoSkus, nil
}
func getMongoDBSkuDetails(remark string) struct {
CpuCount int
MemSizeGb int
} {
ret := struct {
CpuCount int
MemSizeGb int
}{}
r, _ := regexp.Compile(`(\d{1,3})核(\d{1,3})G+`)
result := r.FindSubmatch([]byte(remark))
if len(result) > 2 {
cpu, _ := strconv.Atoi(string(result[1]))
ret.CpuCount = int(cpu)
mem, _ := strconv.Atoi(string(result[2]))
ret.MemSizeGb = int(mem)
} else {
log.Warningf("not match sku remark %s", remark)
}
return ret
}
func (self *SRegion) GetMongoDBAvailableResource() (*SMongoDBAvaibaleResource, error) {
params := map[string]string{}
resp, err := self.mongodbRequest("DescribeAvailableResource", params)
if err != nil {
return nil, errors.Wrapf(err, "DescribeAvailableResource")
}
ret := &SMongoDBAvaibaleResource{}
err = resp.Unmarshal(ret)
if err != nil {
return nil, errors.Wrapf(err, "resp.Unmarshal")
}
return ret, nil
}
+104
View File
@@ -0,0 +1,104 @@
// 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 aliyun
import (
"fmt"
"strings"
"time"
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/cloudprovider"
)
type SMongoDBBackup struct {
BackupDBNames string
BackupDownloadURL string
BackupEndTime time.Time
BackupStartTime time.Time
BackupId string
BackupIntranetDownloadURL string
BackupMethod string
BackupMode string
BackupSize int
BackupStatus string
BackupType string
}
func (self *SRegion) GetMongoDBBackups(id string, start time.Time, end time.Time, pageSize, pageNum int) ([]SMongoDBBackup, int, error) {
if pageSize < 1 || pageSize > 100 {
pageSize = 100
}
if pageNum < 1 {
pageNum = 1
}
params := map[string]string{
"StartTime": start.String(),
"EndTime": end.String(),
"DBInstanceId": id,
"PageSize": fmt.Sprintf("%d", pageSize),
"PageNumber": fmt.Sprintf("%d", pageNum),
}
resp, err := self.mongodbRequest("DescribeBackups", params)
if err != nil {
return nil, 0, errors.Wrapf(err, "DescribeBackups")
}
ret := []SMongoDBBackup{}
err = resp.Unmarshal(&ret, "Backups", "Backup")
if err != nil {
return nil, 0, errors.Wrapf(err, "resp.Unmarshal")
}
totalCount, _ := resp.Int("TotalCount")
return ret, int(totalCount), nil
}
func (self *SMongoDB) GetIBackups() ([]cloudprovider.SMongoDBBackup, error) {
backups := []SMongoDBBackup{}
now := time.Now().Add(time.Minute * -1)
for {
part, total, err := self.region.GetMongoDBBackups(self.DBInstanceId, self.CreationTime, now, 100, len(backups)/100)
if err != nil {
return nil, errors.Wrapf(err, "GetMongoDBBackups")
}
backups = append(backups, part...)
if len(backups) >= total {
break
}
}
ret := []cloudprovider.SMongoDBBackup{}
for _, res := range backups {
backup := cloudprovider.SMongoDBBackup{}
backup.Name = res.BackupId
backup.StartTime = res.BackupStartTime
backup.EndTime = res.BackupEndTime
backup.BackupSizeKb = res.BackupSize / 1024
switch res.BackupStatus {
case "Success":
backup.Status = cloudprovider.MongoDBBackupStatusAvailable
case "Failed":
backup.Status = cloudprovider.MongoDBBackupStatusFailed
default:
backup.Status = cloudprovider.TMongoDBBackupStatus(strings.ToLower(res.BackupStatus))
}
backup.BackupMethod = cloudprovider.TMongoDBBackupMethod(strings.ToLower(res.BackupMethod))
backup.BackupType = cloudprovider.MongoDBBackupTypeAuto
if res.BackupMode == "Manual" {
backup.BackupType = cloudprovider.MongoDBBackupTypeManual
}
ret = append(ret, backup)
}
return ret, nil
}
+13 -1
View File
@@ -40,6 +40,10 @@ type SRegion struct {
client *SAliyunClient
sdkClient *sdk.Client
ossClient *oss.Client
mongoSkus map[string]struct {
CpuCount int
MemSizeGb int
}
RegionId string
LocalName string
@@ -153,7 +157,15 @@ func (self *SRegion) rdsRequest(apiName string, params map[string]string) (jsonu
if err != nil {
return nil, err
}
return jsonRequest(client, "rds.aliyuncs.com", ALIYUN_API_VERION_RDS, apiName, params, self.client.debug)
return jsonRequest(client, "rds.aliyuncs.com", ALIYUN_RDS_API_VERSION, apiName, params, self.client.debug)
}
func (self *SRegion) mongodbRequest(apiName string, params map[string]string) (jsonutils.JSONObject, error) {
client, err := self.getSdkClient()
if err != nil {
return nil, err
}
return jsonRequest(client, "mongodb.aliyuncs.com", ALIYUN_MONGO_DB_API_VERSION, apiName, params, self.client.debug)
}
func (self *SRegion) vpcRequest(action string, params map[string]string) (jsonutils.JSONObject, error) {
+87
View File
@@ -0,0 +1,87 @@
// 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 (
"time"
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/multicloud/aliyun"
"yunion.io/x/onecloud/pkg/util/shellutils"
)
func init() {
type MongoDBListOptions struct {
Id string
Offset int
Limit int
}
shellutils.R(&MongoDBListOptions{}, "mongodb-list", "List mongodb", func(cli *aliyun.SRegion, args *MongoDBListOptions) error {
dbs, _, err := cli.GetMongoDBs(args.Limit, args.Offset)
if err != nil {
return err
}
printList(dbs, 0, 0, 0, []string{})
return nil
})
type MongoDBIdOptions struct {
ID string
}
shellutils.R(&MongoDBIdOptions{}, "mongodb-show", "Show mongodb", func(cli *aliyun.SRegion, args *MongoDBIdOptions) error {
db, err := cli.GetMongoDB(args.ID)
if err != nil {
return errors.Wrapf(err, "GetMongoDB(%s)", args.ID)
}
printObject(db)
return nil
})
shellutils.R(&MongoDBIdOptions{}, "mongodb-delete", "Delete mongodb", func(cli *aliyun.SRegion, args *MongoDBIdOptions) error {
return cli.DeleteMongoDB(args.ID)
})
type MongoDBBackupListOptions struct {
ID string
START time.Time
END time.Time
PageSize int
PageNumber int
}
shellutils.R(&MongoDBBackupListOptions{}, "mongodb-backup-list", "List mongodb backups", func(cli *aliyun.SRegion, args *MongoDBBackupListOptions) error {
backups, _, err := cli.GetMongoDBBackups(args.ID, args.START, args.END, args.PageSize, args.PageNumber)
if err != nil {
return err
}
printList(backups, 0, 0, 0, nil)
return nil
})
type MongoDBSkuListOptions struct {
}
shellutils.R(&MongoDBSkuListOptions{}, "mongodb-sku-list", "List mongodb skus", func(cli *aliyun.SRegion, args *MongoDBSkuListOptions) error {
skus, err := cli.GetchMongoSkus()
if err != nil {
return err
}
printObject(skus)
return nil
})
}
+387
View File
@@ -0,0 +1,387 @@
// 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 qcloud
import (
"fmt"
"strings"
"time"
sdkerrors "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/utils"
billing_api "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"
)
type SMongoDB struct {
multicloud.QcloudTags
multicloud.SVirtualResourceBase
multicloud.SBillingBase
region *SRegion
AutoRenewFlag int `json:"AutoRenewFlag"`
CloneInstances []interface{} `json:"CloneInstances"`
ClusterType int `json:"ClusterType"`
ClusterVer int `json:"ClusterVer"`
ConfigServerCpuNum int `json:"ConfigServerCpuNum"`
ConfigServerMemory int `json:"ConfigServerMemory"`
ConfigServerNodeNum int `json:"ConfigServerNodeNum"`
ConfigServerVolume int `json:"ConfigServerVolume"`
CpuNum int `json:"CpuNum"`
CreateTime time.Time `json:"CreateTime"`
DeadLine string `json:"DeadLine"`
InstanceId string `json:"InstanceId"`
InstanceName string `json:"InstanceName"`
InstanceStatusDesc string `json:"InstanceStatusDesc"`
InstanceTaskDesc string `json:"InstanceTaskDesc"`
InstanceTaskId int `json:"InstanceTaskId"`
InstanceType int `json:"InstanceType"`
InstanceVer int `json:"InstanceVer"`
MachineType string `json:"MachineType"`
MaintenanceEnd string `json:"MaintenanceEnd"`
MaintenanceStart string `json:"MaintenanceStart"`
Memory int `json:"Memory"`
MongoVersion string `json:"MongoVersion"`
MongosCpuNum int `json:"MongosCpuNum"`
MongosMemory int `json:"MongosMemory"`
MongosNodeNum int `json:"MongosNodeNum"`
NetType int `json:"NetType"`
PayMode int `json:"PayMode"`
ProjectId int `json:"ProjectId"`
Protocol int `json:"Protocol"`
Readonlyinstances []interface{} `json:"ReadonlyInstances"`
RealInstanceId string `json:"RealInstanceId"`
Region string `json:"Region"`
Relatedinstance struct {
InstanceId string `json:"InstanceId"`
Region string `json:"Region"`
} `json:"RelatedInstance"`
Replicasets []struct {
Memory int `json:"Memory"`
OplogSize int `json:"OplogSize"`
RealReplicasetId string `json:"RealReplicaSetId"`
ReplicaSetId string `json:"ReplicaSetId"`
ReplicaSetName string `json:"ReplicaSetName"`
SecondaryNum int `json:"SecondaryNum"`
UsedVolume int `json:"UsedVolume"`
Volume int `json:"Volume"`
} `json:"ReplicaSets"`
ReplicationSetNum int `json:"ReplicationSetNum"`
SecondaryNum int `json:"SecondaryNum"`
StandbyInstances []interface{} `json:"StandbyInstances"`
Status int `json:"Status"`
SubnetId string `json:"SubnetId"`
UsedVolume int `json:"UsedVolume"`
Vip string `json:"Vip"`
Volume int `json:"Volume"`
VpcId string `json:"VpcId"`
Vport int `json:"Vport"`
Zone string `json:"Zone"`
}
func (self *SMongoDB) GetGlobalId() string {
return self.InstanceId
}
func (self *SMongoDB) GetId() string {
return self.InstanceId
}
func (self *SMongoDB) GetName() string {
return self.InstanceName
}
func (self *SMongoDB) GetStatus() string {
switch self.Status {
case 0, 1:
return api.MONGO_DB_STATUS_CREATING
case 2:
return api.MONGO_DB_STATUS_RUNNING
case -2, -3:
return api.MONGO_DB_STATUS_DELETING
}
return fmt.Sprintf("%d", self.Status)
}
func (self *SMongoDB) Refresh() error {
ins, err := self.region.GetMongoDB(self.InstanceId)
if err != nil {
return errors.Wrapf(err, "GetMongoDB")
}
return jsonutils.Update(self, ins)
}
func (self *SMongoDB) GetProjectId() string {
return fmt.Sprintf("%d", self.ProjectId)
}
func (self *SMongoDB) GetVpcId() string {
return self.VpcId
}
func (self *SMongoDB) GetNetworkId() string {
return self.SubnetId
}
func (self *SMongoDB) GetCreatedAt() time.Time {
return self.CreateTime.Add(time.Hour * -8)
}
func (self *SMongoDB) GetExpiredAt() time.Time {
return time.Time{}
}
func (self *SMongoDB) GetIpAddr() string {
return self.Vip
}
func (self *SMongoDB) GetVcpuCount() int {
return self.CpuNum
}
func (self *SMongoDB) GetVmemSizeMb() int {
return self.Memory
}
func (self *SMongoDB) GetReplicationNum() int {
return self.ReplicationSetNum
}
func (self *SMongoDB) GetDiskSizeMb() int {
return self.Volume
}
func (self *SMongoDB) GetZoneId() string {
zone, err := self.region.getZoneById(self.Zone)
if err != nil {
return ""
}
return zone.GetGlobalId()
}
func (self *SMongoDB) GetBillingType() string {
// 计费模式:0-按量计费,1-包年包月
if self.PayMode == 1 {
return billing_api.BILLING_TYPE_PREPAID
} else {
return billing_api.BILLING_TYPE_POSTPAID
}
}
func (self *SMongoDB) IsAutoRenew() bool {
return self.AutoRenewFlag == 1
}
func (self *SMongoDB) GetCategory() string {
switch self.ClusterType {
case 0:
return api.MONGO_DB_CATEGORY_REPLICATE
case 1:
return api.MONGO_DB_CATEGORY_SHARDING
default:
return fmt.Sprintf("%d", self.ClusterType)
}
}
func (self *SMongoDB) GetEngine() string {
if utils.IsInStringArray("WT", strings.Split(self.MongoVersion, "_")) {
return api.MONGO_DB_ENGINE_WIRED_TIGER
}
return api.MONGO_DB_ENGINE_ROCKS
}
func (self *SMongoDB) GetEngineVersion() string {
vers := strings.Split(self.MongoVersion, "_")
if len(vers) > 1 {
return strings.Join(strings.Split(vers[1], ""), ".")
}
return ""
}
func (self *SMongoDB) GetInstanceType() string {
return self.MachineType
}
func (self *SMongoDB) GetMaintainTime() string {
return fmt.Sprintf("%s-%s", self.MaintenanceStart, self.MaintenanceEnd)
}
func (self *SMongoDB) GetPort() int {
return self.Vport
}
func (self *SMongoDB) Delete() error {
return self.region.DeleteMongoDB(self.InstanceId)
}
func (self *SRegion) DeleteMongoDB(id string) error {
err := self.IsolateMongoDB(id)
if err != nil {
return errors.Wrapf(err, "IsolateDBInstance")
}
return cloudprovider.Wait(time.Second*10, time.Minute*3, func() (bool, error) {
err = self.OfflineIsolatedMongoDB(id)
if err == nil {
return true, nil
}
if e, ok := errors.Cause(err).(*sdkerrors.TencentCloudSDKError); ok && e.Code == "InvalidParameterValue.LockFailed" {
return false, nil
}
return true, err
})
}
func (self *SMongoDB) GetIBackups() ([]cloudprovider.SMongoDBBackup, error) {
return self.region.GetMongoDBBackups(self.InstanceId)
}
func (self *SRegion) IsolateMongoDB(id string) error {
params := map[string]string{
"InstanceId": id,
}
_, err := self.mongodbRequest("IsolateDBInstance", params)
return errors.Wrapf(err, "IsolateDBInstance")
}
func (self *SRegion) OfflineIsolatedMongoDB(id string) error {
params := map[string]string{
"InstanceId": id,
}
_, err := self.mongodbRequest("OfflineIsolatedDBInstance", params)
return errors.Wrapf(err, "OfflineIsolatedDBInstance")
}
func (self *SRegion) GetMongoDBs(ids []string, limit, offset int) ([]SMongoDB, int, error) {
if limit < 1 || limit > 100 {
limit = 100
}
params := map[string]string{
"Limit": fmt.Sprintf("%d", limit),
"Offset": fmt.Sprintf("%d", offset),
}
for i, id := range ids {
params[fmt.Sprintf("InstanceIds.%d", i)] = id
}
resp, err := self.mongodbRequest("DescribeDBInstances", params)
if err != nil {
return nil, 0, errors.Wrapf(err, "DescribeDBInstances")
}
dbs := []SMongoDB{}
err = resp.Unmarshal(&dbs, "InstanceDetails")
if err != nil {
return nil, 0, errors.Wrapf(err, "resp.Unmarshal")
}
totalCount, _ := resp.Float("TotalCount")
return dbs, int(totalCount), nil
}
func (self *SRegion) GetICloudMongoDBs() ([]cloudprovider.ICloudMongoDB, error) {
dbs := []SMongoDB{}
for {
part, total, err := self.GetMongoDBs(nil, 100, len(dbs))
if err != nil {
return nil, errors.Wrapf(err, "GetMongoDBs")
}
dbs = append(dbs, part...)
if len(dbs) >= total {
break
}
}
ret := []cloudprovider.ICloudMongoDB{}
for i := range dbs {
dbs[i].region = self
ret = append(ret, &dbs[i])
}
return ret, nil
}
func (self *SRegion) GetMongoDBBackups(id string) ([]cloudprovider.SMongoDBBackup, error) {
params := map[string]string{
"InstanceId": id,
}
resp, err := self.mongodbRequest("DescribeDBBackups", params)
if err != nil {
return nil, errors.Wrapf(err, "DescribeDBBackups")
}
backups := []struct {
InstanceId string
BackupType int
BackupName string
BackupDesc string
BackupSize int
StartTime time.Time
EndTime time.Time
Status int
BackupMethod int
}{}
err = resp.Unmarshal(&backups, "BackupList")
if err != nil {
return nil, errors.Wrapf(err, "resp.Unmarshal")
}
ret := []cloudprovider.SMongoDBBackup{}
for _, backup := range backups {
b := cloudprovider.SMongoDBBackup{
Name: backup.BackupName,
Description: backup.BackupDesc,
BackupSizeKb: backup.BackupSize,
}
b.StartTime = backup.StartTime.Add(time.Hour * -8)
b.EndTime = backup.EndTime.Add(time.Hour * -8)
switch backup.Status {
case 1:
b.Status = cloudprovider.MongoDBBackupStatusCreating
case 2:
b.Status = cloudprovider.MongoDBBackupStatusAvailable
default:
b.Status = cloudprovider.MongoDBBackupStatusUnknown
}
b.BackupMethod = cloudprovider.MongoDBBackupMethodLogical
if backup.BackupMethod == 0 {
b.BackupMethod = cloudprovider.MongoDBBackupMethodPhysical
}
b.BackupType = cloudprovider.MongoDBBackupTypeAuto
if backup.BackupType == 1 {
b.BackupType = cloudprovider.MongoDBBackupTypeManual
}
ret = append(ret, b)
}
return ret, nil
}
func (self *SRegion) GetMongoDB(id string) (*SMongoDB, error) {
dbs, _, err := self.GetMongoDBs([]string{id}, 1, 0)
if err != nil {
return nil, errors.Wrapf(err, "GetMongoDB(%s)", id)
}
for i := range dbs {
dbs[i].region = self
return &dbs[i], nil
}
return nil, errors.Wrapf(cloudprovider.ErrNotFound, id)
}
func (self *SRegion) GetICloudMongoDBById(id string) (cloudprovider.ICloudMongoDB, error) {
db, err := self.GetMongoDB(id)
if err != nil {
return nil, errors.Wrapf(err, "GetMongoDB")
}
return db, nil
}
+17
View File
@@ -63,6 +63,7 @@ const (
QCLOUD_MEMCACHED_API_VERSION = "2019-03-18"
QCLOUD_SSL_API_VERSION = "2019-12-05"
QCLOUD_CDN_API_VERSION = "2018-06-06"
QCLOUD_MONGODB_API_VERSION = "2019-07-25"
)
type QcloudClientConfig struct {
@@ -177,6 +178,12 @@ func redisRequest(client *common.Client, apiName string, params map[string]strin
return _jsonRequest(client, domain, QCLOUD_REDIS_API_VERSION, apiName, params, debug, true)
}
// mongodb
func mongodbRequest(client *common.Client, apiName string, params map[string]string, debug bool) (jsonutils.JSONObject, error) {
domain := apiDomain("mongodb", params)
return _jsonRequest(client, domain, QCLOUD_MONGODB_API_VERSION, apiName, params, debug, true)
}
// memcached
func memcachedRequest(client *common.Client, apiName string, params map[string]string, debug bool) (jsonutils.JSONObject, error) {
domain := apiDomain("memcached", params)
@@ -630,6 +637,15 @@ func (client *SQcloudClient) redisRequest(apiName string, params map[string]stri
return redisRequest(cli, apiName, params, client.debug)
}
func (client *SQcloudClient) mongodbRequest(apiName string, params map[string]string) (jsonutils.JSONObject, error) {
cli, err := client.getDefaultClient()
if err != nil {
return nil, err
}
return mongodbRequest(cli, apiName, params, client.debug)
}
func (client *SQcloudClient) memcachedRequest(apiName string, params map[string]string) (jsonutils.JSONObject, error) {
cli, err := client.getDefaultClient()
if err != nil {
@@ -1027,6 +1043,7 @@ func (self *SQcloudClient) GetCapabilities() []string {
cloudprovider.CLOUD_CAPABILITY_PUBLIC_IP,
cloudprovider.CLOUD_CAPABILITY_INTERVPCNETWORK,
cloudprovider.CLOUD_CAPABILITY_SAML_AUTH,
cloudprovider.CLOUD_CAPABILITY_MONGO_DB,
}
return caps
}
+5
View File
@@ -686,6 +686,11 @@ func (self *SRegion) redisRequest(apiName string, params map[string]string) (jso
return self.client.redisRequest(apiName, params)
}
func (self *SRegion) mongodbRequest(apiName string, params map[string]string) (jsonutils.JSONObject, error) {
params["Region"] = self.Region
return self.client.mongodbRequest(apiName, params)
}
func (self *SRegion) memcachedRequest(apiName string, params map[string]string) (jsonutils.JSONObject, error) {
params["Region"] = self.Region
return self.client.memcachedRequest(apiName, params)
+14
View File
@@ -1,3 +1,17 @@
// 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 (
+53
View File
@@ -0,0 +1,53 @@
// 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/qcloud"
"yunion.io/x/onecloud/pkg/util/shellutils"
)
func init() {
type MongoDBListOptions struct {
Ids []string
Offset int
Limit int
}
shellutils.R(&MongoDBListOptions{}, "mongodb-list", "List mongodb", func(cli *qcloud.SRegion, args *MongoDBListOptions) error {
dbs, _, err := cli.GetMongoDBs(args.Ids, args.Limit, args.Offset)
if err != nil {
return err
}
printList(dbs, 0, 0, 0, []string{})
return nil
})
type MongoDBIdOptions struct {
ID string
}
shellutils.R(&MongoDBIdOptions{}, "mongodb-isoloate", "Isolate mongodb", func(cli *qcloud.SRegion, args *MongoDBIdOptions) error {
return cli.IsolateMongoDB(args.ID)
})
shellutils.R(&MongoDBIdOptions{}, "mongodb-offline", "Offlie mongodb", func(cli *qcloud.SRegion, args *MongoDBIdOptions) error {
return cli.OfflineIsolatedMongoDB(args.ID)
})
shellutils.R(&MongoDBIdOptions{}, "mongodb-delete", "Delete mongodb", func(cli *qcloud.SRegion, args *MongoDBIdOptions) error {
return cli.DeleteMongoDB(args.ID)
})
}
+8
View File
@@ -198,3 +198,11 @@ func (self *SRegion) CreateICloudWafInstance(opts *cloudprovider.WafCreateOption
func (self *SRegion) GetICloudWafRuleGroups() ([]cloudprovider.ICloudWafRuleGroup, error) {
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetICloudWafRuleGroups")
}
func (self *SRegion) GetICloudMongoDBs() ([]cloudprovider.ICloudMongoDB, error) {
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetICloudMongoDBs")
}
func (self *SRegion) GetICloudMongoDBById(id string) (cloudprovider.ICloudMongoDB, error) {
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetICloudMongoDBById")
}