| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573 |
- // 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/cloudmux/pkg/apis/compute"
- "yunion.io/x/cloudmux/pkg/cloudprovider"
- "yunion.io/x/cloudmux/pkg/multicloud"
- )
- type SMOngoDBAttribute struct {
- // 实例最大IOPS
- MaxIops int
- ReplicaSets struct {
- ReplicaSet []struct {
- ConnectionDomain string `json:"ConnectionDomain"`
- }
- }
- MaxConnections int
- }
- type SMongoDB struct {
- region *SRegion
- AliyunTags
- multicloud.SBillingBase
- multicloud.SResourceBase
- ConnectionDomain string `json:"ConnectionDomain"`
- NetworkAddress string
- 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"`
- KindCode string `json:"KindCode"`
- }
- 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) GetSysTags() map[string]string {
- ret := self.AliyunTags.GetSysTags()
- if len(self.KindCode) == 0 {
- self.Refresh()
- }
- // 用户需要通过KindCode区分是否是快照备份
- ret["KindCode"] = self.KindCode
- return ret
- }
- 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 {
- nets, err := self.region.DescribeShardingNetworkAddress(self.DBInstanceId)
- if err != nil {
- return ""
- }
- ret := []string{}
- for _, n := range nets {
- ret = append(ret, n.IPAddress)
- }
- return strings.Join(ret, ",")
- }
- 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 index := strings.Index(self.ZoneId, ",") - 1; index > 0 {
- return fmt.Sprintf("%s-%s", self.region.RegionId, string(self.ZoneId[index]))
- }
- 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 self.DBInstanceType == "sharding" {
- return len(self.ShardList.ShardAttribute)
- }
- 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 *SMongoDB) GetIops() int {
- iops, _ := self.region.GetIops(self.DBInstanceId)
- return iops
- }
- func (self *SMongoDB) GetMaxConnections() int {
- maxConnection, _ := self.region.GetMaxConnections(self.DBInstanceId)
- return maxConnection
- }
- func (self *SMongoDB) GetNetworkAddress() string {
- addr, _ := self.region.GetNetworkAddress(self.DBInstanceId)
- return addr
- }
- func (self *SRegion) GetMongoDBsByType(mongoType string) ([]SMongoDB, error) {
- dbs := []SMongoDB{}
- for {
- part, total, err := self.GetMongoDBs(mongoType, 100, len(dbs)/100)
- if err != nil {
- return nil, errors.Wrapf(err, "GetMongoDB")
- }
- dbs = append(dbs, part...)
- if len(dbs) >= total {
- break
- }
- }
- return dbs, nil
- }
- func (self *SMongoDB) SetTags(tags map[string]string, replace bool) error {
- return self.region.SetResourceTags(ALIYUN_SERVICE_MONGO_DB, "INSTANCE", self.GetId(), tags, replace)
- }
- func (self *SRegion) GetICloudMongoDBById(id string) (cloudprovider.ICloudMongoDB, error) {
- db, err := self.GetMongoDB(id)
- if err != nil {
- return nil, errors.Wrapf(err, "GetMongoDB(%s)", id)
- }
- return db, nil
- }
- func (self *SRegion) GetICloudMongoDBs() ([]cloudprovider.ICloudMongoDB, error) {
- dbs := []SMongoDB{}
- for _, mongoType := range []string{"sharding", "replicate", "serverless"} {
- part, err := self.GetMongoDBsByType(mongoType)
- if err != nil {
- return nil, err
- }
- dbs = append(dbs, part...)
- }
- ret := []cloudprovider.ICloudMongoDB{}
- for i := range dbs {
- dbs[i].region = self
- ret = append(ret, &dbs[i])
- }
- return ret, nil
- }
- func (self *SRegion) GetIops(id string) (int, error) {
- ret, err := self.GetMongoDBAttribute(id)
- if err != nil {
- return 0, errors.Wrapf(err, "DescribeDBInstanceAttribute err")
- }
- if len(ret) == 0 {
- return 0, errors.Wrapf(err, "ret missing err")
- }
- return ret[0].MaxIops, nil
- }
- func (self *SRegion) GetMaxConnections(id string) (int, error) {
- ret, err := self.GetMongoDBAttribute(id)
- if err != nil {
- return 0, errors.Wrapf(err, "DescribeDBInstanceAttribute err")
- }
- if len(ret) == 0 {
- return 0, errors.Wrapf(err, "ret missing err")
- }
- return ret[0].MaxConnections, nil
- }
- func (self *SRegion) GetNetworkAddress(id string) (string, error) {
- ret, err := self.GetMongoDBAttribute(id)
- if err != nil {
- return "", errors.Wrapf(err, "DescribeDBInstanceAttribute err")
- }
- addrList := make([]string, 0)
- for _, v := range ret[0].ReplicaSets.ReplicaSet {
- addrList = append(addrList, v.ConnectionDomain)
- }
- addrs := strings.Join(addrList, ",")
- return addrs, nil
- }
- func (self *SRegion) GetMongoDBAttribute(id string) ([]SMOngoDBAttribute, error) {
- params := map[string]string{
- "Action": "DescribeDBInstanceAttribute",
- "DBInstanceId": id,
- }
- resp, err := self.mongodbRequest("DescribeDBInstanceAttribute", params)
- if err != nil {
- return nil, errors.Wrapf(err, "DescribeDBInstanceAttribute err")
- }
- ret := []SMOngoDBAttribute{}
- err = resp.Unmarshal(&ret, "DBInstances", "DBInstance")
- if err != nil {
- return nil, errors.Wrapf(err, "unmarshal err")
- }
- return ret, err
- }
- func (self *SRegion) GetMongoDBs(mongoType string, 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),
- }
- if len(mongoType) > 0 {
- params["DBInstanceType"] = mongoType
- }
- 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")
- }
- for i := range ret {
- ret[i].region = self
- if ret[i].DBInstanceId == id {
- return &ret[i], nil
- }
- }
- return nil, errors.Wrapf(cloudprovider.ErrNotFound, "%s", 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
- }
- type SMongoDBNetworkAddress struct {
- IPAddress string
- NetworkAddress string
- NetworkType string
- Port int
- Role string
- VpcId string
- VswitchId string
- }
- func (region *SRegion) DescribeShardingNetworkAddress(id string) ([]SMongoDBNetworkAddress, error) {
- params := map[string]string{
- "DBInstanceId": id,
- }
- resp, err := region.mongodbRequest("DescribeShardingNetworkAddress", params)
- if err != nil {
- return nil, errors.Wrapf(err, "DescribeAvailableResource")
- }
- ret := []SMongoDBNetworkAddress{}
- err = resp.Unmarshal(&ret, "NetworkAddresses", "NetworkAddress")
- if err != nil {
- return nil, err
- }
- return ret, nil
- }
- 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
- }
|