region.go 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package aliyun
  15. import (
  16. "fmt"
  17. "strings"
  18. "time"
  19. "github.com/aliyun/alibaba-cloud-sdk-go/sdk"
  20. alierr "github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors"
  21. "github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
  22. "github.com/aliyun/aliyun-oss-go-sdk/oss"
  23. "yunion.io/x/jsonutils"
  24. "yunion.io/x/log"
  25. "yunion.io/x/pkg/errors"
  26. "yunion.io/x/pkg/util/regutils"
  27. "yunion.io/x/pkg/utils"
  28. api "yunion.io/x/cloudmux/pkg/apis/compute"
  29. "yunion.io/x/cloudmux/pkg/cloudprovider"
  30. "yunion.io/x/cloudmux/pkg/multicloud"
  31. )
  32. type SRegion struct {
  33. multicloud.SRegion
  34. client *SAliyunClient
  35. sdkClient *sdk.Client
  36. ossClient *oss.Client
  37. mongoSkus map[string]struct {
  38. CpuCount int
  39. MemSizeGb int
  40. }
  41. RegionId string
  42. LocalName string
  43. RegionEndpoint string
  44. izones []cloudprovider.ICloudZone
  45. ivpcs []cloudprovider.ICloudVpc
  46. lbEndpints map[string]string
  47. storageCache *SStoragecache
  48. instanceTypes []SInstanceType
  49. latitude float64
  50. longitude float64
  51. fetchLocation bool
  52. }
  53. func (self *SRegion) GetClient() *SAliyunClient {
  54. return self.client
  55. }
  56. func (self *SRegion) getSdkClient() (*sdk.Client, error) {
  57. if self.sdkClient == nil {
  58. cli, err := self.client.getSdkClient(self.RegionId)
  59. if err != nil {
  60. return nil, err
  61. }
  62. self.sdkClient = cli
  63. }
  64. return self.sdkClient, nil
  65. }
  66. func (self *SRegion) getEcsClient() (*ecs.Client, error) {
  67. sdkClient, err := self.getSdkClient()
  68. if err != nil {
  69. return nil, errors.Wrap(err, "getSdkClient")
  70. }
  71. ecsClient := &ecs.Client{
  72. Client: *sdkClient,
  73. }
  74. return ecsClient, nil
  75. }
  76. func (self *SRegion) getOSSExternalDomain() string {
  77. return getOSSExternalDomain(self.RegionId)
  78. }
  79. func (self *SRegion) getOSSInternalDomain() string {
  80. return getOSSInternalDomain(self.RegionId)
  81. }
  82. func (self *SRegion) getRegionId() string {
  83. if self.client.cloudEnv == ALIYUN_FINANCE_CLOUDENV {
  84. switch self.RegionId {
  85. case "cn-hangzhou":
  86. return "cn-hzfinance"
  87. case "cn-shanghai-finance-1":
  88. return "cn-shanghai-finance-1-pub"
  89. case "cn-shenzhen-finance-1":
  90. return "cn-szfinance"
  91. }
  92. }
  93. return self.RegionId
  94. }
  95. func (self *SRegion) GetOssClient() (*oss.Client, error) {
  96. if self.ossClient == nil {
  97. cli, err := self.client.getOssClient(self.getRegionId())
  98. if err != nil {
  99. return nil, errors.Wrap(err, "self.client.getOssClient")
  100. }
  101. self.ossClient = cli
  102. }
  103. return self.ossClient, nil
  104. }
  105. func (self *SRegion) ecsRequest(apiName string, params map[string]string) (jsonutils.JSONObject, error) {
  106. client, err := self.getSdkClient()
  107. if err != nil {
  108. return nil, err
  109. }
  110. endpoint := self.RegionEndpoint
  111. if len(endpoint) == 0 {
  112. endpoint = "ecs.aliyuncs.com"
  113. }
  114. params = self.client.SetResourceGropuId(params)
  115. return jsonRequest(client, endpoint, ALIYUN_API_VERSION, apiName, params, self.client.debug)
  116. }
  117. func (self *SRegion) wafRequest(apiName string, params map[string]string) (jsonutils.JSONObject, error) {
  118. client, err := self.getSdkClient()
  119. if err != nil {
  120. return nil, err
  121. }
  122. if self.RegionId != "cn-hangzhou" && self.RegionId != "ap-southeast-1" {
  123. return nil, cloudprovider.ErrNotSupported
  124. }
  125. params = self.client.SetResourceGropuId(params)
  126. endpoint := fmt.Sprintf("wafopenapi.%s.aliyuncs.com", self.RegionId)
  127. return jsonRequest(client, endpoint, ALIYUN_WAF_API_VERSION, apiName, params, self.client.debug)
  128. }
  129. func (self *SRegion) wafv2Request(apiName string, params map[string]string) (jsonutils.JSONObject, error) {
  130. client, err := self.getSdkClient()
  131. if err != nil {
  132. return nil, err
  133. }
  134. if self.RegionId != "cn-hangzhou" && self.RegionId != "ap-southeast-1" {
  135. return nil, cloudprovider.ErrNotSupported
  136. }
  137. params = self.client.SetResourceGropuId(params)
  138. endpoint := fmt.Sprintf("wafopenapi.%s.aliyuncs.com", self.RegionId)
  139. return jsonRequest(client, endpoint, ALIYUN_WAF_V2_API_VERSION, apiName, params, self.client.debug)
  140. }
  141. func (self *SRegion) esRequest(apiName string, params map[string]string, body interface{}) (jsonutils.JSONObject, error) {
  142. client, err := self.getSdkClient()
  143. if err != nil {
  144. return nil, err
  145. }
  146. params = self.client.SetResourceGropuId(params)
  147. domain := fmt.Sprintf("elasticsearch.%s.aliyuncs.com", self.RegionId)
  148. return doRequest(client, domain, ALIYUN_ES_API_VERSION, apiName, params, body, self.client.debug)
  149. }
  150. func (self *SRegion) kafkaRequest(apiName string, params map[string]string) (jsonutils.JSONObject, error) {
  151. client, err := self.getSdkClient()
  152. if err != nil {
  153. return nil, err
  154. }
  155. params = self.client.SetResourceGropuId(params)
  156. domain := fmt.Sprintf("alikafka.%s.aliyuncs.com", self.RegionId)
  157. return jsonRequest(client, domain, ALIYUN_KAFKA_API_VERSION, apiName, params, self.client.debug)
  158. }
  159. func (self *SRegion) rdsRequest(apiName string, params map[string]string) (jsonutils.JSONObject, error) {
  160. client, err := self.getSdkClient()
  161. if err != nil {
  162. return nil, err
  163. }
  164. params = self.client.SetResourceGropuId(params)
  165. return jsonRequest(client, "rds.aliyuncs.com", ALIYUN_RDS_API_VERSION, apiName, params, self.client.debug)
  166. }
  167. func (self *SRegion) k8sRequest(apiName string, params map[string]string, body interface{}) (jsonutils.JSONObject, error) {
  168. client, err := self.getSdkClient()
  169. if err != nil {
  170. return nil, err
  171. }
  172. params = self.client.SetResourceGropuId(params)
  173. return doRequest(client, fmt.Sprintf("cs.%s.aliyuncs.com", self.RegionId), ALIYUN_K8S_API_VERSION, apiName, params, body, self.client.debug)
  174. }
  175. func (self *SRegion) mongodbRequest(apiName string, params map[string]string) (jsonutils.JSONObject, error) {
  176. client, err := self.getSdkClient()
  177. if err != nil {
  178. return nil, err
  179. }
  180. params = self.client.SetResourceGropuId(params)
  181. return jsonRequest(client, "mongodb.aliyuncs.com", ALIYUN_MONGO_DB_API_VERSION, apiName, params, self.client.debug)
  182. }
  183. func (self *SRegion) vpcRequest(action string, params map[string]string) (jsonutils.JSONObject, error) {
  184. client, err := self.getSdkClient()
  185. if err != nil {
  186. return nil, err
  187. }
  188. params = self.client.SetResourceGropuId(params)
  189. endpoint := self.GetClient().getVpcEndpoint(self.RegionId)
  190. return jsonRequest(client, endpoint, ALIYUN_API_VERSION_VPC, action, params, self.client.debug)
  191. }
  192. func (self *SRegion) nasRequest(action string, params map[string]string) (jsonutils.JSONObject, error) {
  193. client, err := self.getSdkClient()
  194. if err != nil {
  195. return nil, err
  196. }
  197. switch self.GetCloudEnv() {
  198. case ALIYUN_FINANCE_CLOUDENV:
  199. if strings.Contains(action, "FileSystem") {
  200. if self.RegionId == "cn-hangzhou" {
  201. params["RegionId"] = "cn-hangzhou-dg-a01"
  202. }
  203. }
  204. if strings.Contains(action, "Access") || strings.Contains(action, "MountTarget") {
  205. if self.RegionId == "cn-hangzhou" {
  206. params["RegionId"] = "cn-hangzhou-finance"
  207. }
  208. }
  209. }
  210. params = self.client.SetResourceGropuId(params)
  211. endpint := self.GetClient().getNasEndpoint(self.RegionId)
  212. return jsonRequest(client, endpint, ALIYUN_NAS_API_VERSION, action, params, self.client.debug)
  213. }
  214. func (self *SRegion) kvsRequest(action string, params map[string]string) (jsonutils.JSONObject, error) {
  215. client, err := self.getSdkClient()
  216. if err != nil {
  217. return nil, err
  218. }
  219. if _, ok := params["RegionId"]; ok {
  220. params["RegionId"] = transRegionIdFromEcsRegionId(self, "redis")
  221. }
  222. params = self.client.SetResourceGropuId(params)
  223. return jsonRequest(client, "r-kvstore.aliyuncs.com", ALIYUN_API_VERSION_KVS, action, params, self.client.debug)
  224. }
  225. func (self *SRegion) scRequest(apiName string, params map[string]string) (jsonutils.JSONObject, error) {
  226. client, err := self.getSdkClient()
  227. if err != nil {
  228. return nil, err
  229. }
  230. domain := "cas.aliyuncs.com"
  231. return jsonRequest(client, domain, ALIYUN_CAS_API_VERSION, apiName, params, self.client.debug)
  232. }
  233. type LBRegion struct {
  234. RegionEndpoint string
  235. RegionId string
  236. }
  237. func (self *SRegion) fetchLBRegions(client *sdk.Client) error {
  238. if len(self.lbEndpints) > 0 {
  239. return nil
  240. }
  241. params := map[string]string{}
  242. result, err := self._lbRequest(client, "DescribeRegions", "slb.aliyuncs.com", params)
  243. if err != nil {
  244. return err
  245. }
  246. self.lbEndpints = map[string]string{}
  247. regions := []LBRegion{}
  248. if err := result.Unmarshal(&regions, "Regions", "Region"); err != nil {
  249. return err
  250. }
  251. for _, region := range regions {
  252. self.lbEndpints[region.RegionId] = region.RegionEndpoint
  253. }
  254. return nil
  255. }
  256. func (self *SRegion) lbRequest(apiName string, params map[string]string) (jsonutils.JSONObject, error) {
  257. client, err := self.getSdkClient()
  258. if err != nil {
  259. return nil, err
  260. }
  261. domain := "slb.aliyuncs.com"
  262. if !utils.IsInStringArray(apiName, []string{"DescribeRegions", "DescribeZones"}) {
  263. if regionId, ok := params["RegionId"]; ok {
  264. if err := self.fetchLBRegions(client); err != nil {
  265. return nil, err
  266. }
  267. endpoint, ok := self.lbEndpints[regionId]
  268. if !ok {
  269. return nil, fmt.Errorf("failed to find endpoint for lb region %s", regionId)
  270. }
  271. domain = endpoint
  272. }
  273. }
  274. params = self.client.SetResourceGropuId(params)
  275. return self._lbRequest(client, apiName, domain, params)
  276. }
  277. func (self *SRegion) _lbRequest(client *sdk.Client, apiName string, domain string, params map[string]string) (jsonutils.JSONObject, error) {
  278. return jsonRequest(client, domain, ALIYUN_API_VERSION_LB, apiName, params, self.client.debug)
  279. }
  280. func (self *SRegion) albRequest(apiName string, params map[string]string) (jsonutils.JSONObject, error) {
  281. client, err := self.getSdkClient()
  282. if err != nil {
  283. return nil, err
  284. }
  285. params = self.client.SetResourceGropuId(params)
  286. domain := fmt.Sprintf("alb.%s.aliyuncs.com", self.RegionId)
  287. return jsonRequest(client, domain, ALIYUN_API_VERSION_ALB, apiName, params, self.client.debug)
  288. }
  289. func (self *SRegion) nlbRequest(apiName string, params map[string]string) (jsonutils.JSONObject, error) {
  290. client, err := self.getSdkClient()
  291. if err != nil {
  292. return nil, err
  293. }
  294. params = self.client.SetResourceGropuId(params)
  295. domain := fmt.Sprintf("nlb.%s.aliyuncs.com", self.RegionId)
  296. return jsonRequest(client, domain, ALIYUN_API_VERSION_NLB, apiName, params, self.client.debug)
  297. }
  298. // ///////////////////////////////////////////////////////////////////////////
  299. func (self *SRegion) GetId() string {
  300. return self.RegionId
  301. }
  302. func (self *SRegion) GetName() string {
  303. if self.GetCloudEnv() == ALIYUN_FINANCE_CLOUDENV && !strings.Contains(self.LocalName, "金融") {
  304. return fmt.Sprintf("%s %s %s", CLOUD_PROVIDER_ALIYUN_CN, self.LocalName, "金融云")
  305. } else {
  306. return fmt.Sprintf("%s %s", CLOUD_PROVIDER_ALIYUN_CN, self.LocalName)
  307. }
  308. }
  309. func (self *SRegion) GetI18n() cloudprovider.SModelI18nTable {
  310. en := fmt.Sprintf("%s %s", CLOUD_PROVIDER_ALIYUN_EN, self.LocalName)
  311. table := cloudprovider.SModelI18nTable{}
  312. table["name"] = cloudprovider.NewSModelI18nEntry(self.GetName()).CN(self.GetName()).EN(en)
  313. return table
  314. }
  315. func (self *SRegion) GetGlobalId() string {
  316. return fmt.Sprintf("%s/%s", self.client.GetAccessEnv(), self.RegionId)
  317. }
  318. func (self *SRegion) IsEmulated() bool {
  319. return false
  320. }
  321. func (self *SRegion) GetProvider() string {
  322. return CLOUD_PROVIDER_ALIYUN
  323. }
  324. func (self *SRegion) GetCloudEnv() string {
  325. return self.client.cloudEnv
  326. }
  327. func (self *SRegion) GetGeographicInfo() cloudprovider.SGeographicInfo {
  328. if info, ok := LatitudeAndLongitude[self.RegionId]; ok {
  329. return info
  330. }
  331. return cloudprovider.SGeographicInfo{}
  332. }
  333. func (self *SRegion) GetStatus() string {
  334. return api.CLOUD_REGION_STATUS_INSERVER
  335. }
  336. func (self *SRegion) Refresh() error {
  337. // do nothing
  338. return nil
  339. }
  340. func (self *SRegion) GetIZones() ([]cloudprovider.ICloudZone, error) {
  341. if self.izones == nil {
  342. var err error
  343. err = self.fetchInfrastructure()
  344. if err != nil {
  345. return nil, err
  346. }
  347. }
  348. return self.izones, nil
  349. }
  350. func (self *SRegion) GetIZoneById(id string) (cloudprovider.ICloudZone, error) {
  351. izones, err := self.GetIZones()
  352. if err != nil {
  353. return nil, err
  354. }
  355. for i := 0; i < len(izones); i += 1 {
  356. if izones[i].GetGlobalId() == id {
  357. return izones[i], nil
  358. }
  359. }
  360. return nil, cloudprovider.ErrNotFound
  361. }
  362. func (self *SRegion) getStoragecache() *SStoragecache {
  363. if self.storageCache == nil {
  364. self.storageCache = &SStoragecache{region: self}
  365. }
  366. return self.storageCache
  367. }
  368. func (self *SRegion) _fetchZones(chargeType TChargeType, spotStrategy SpotStrategyType) error {
  369. params := make(map[string]string)
  370. params["RegionId"] = self.RegionId
  371. if len(chargeType) > 0 {
  372. params["InstanceChargeType"] = string(chargeType)
  373. }
  374. if len(spotStrategy) > 0 {
  375. params["SpotStrategy"] = string(spotStrategy)
  376. }
  377. body, err := self.ecsRequest("DescribeZones", params)
  378. if err != nil {
  379. return err
  380. }
  381. zones := make([]SZone, 0)
  382. err = body.Unmarshal(&zones, "Zones", "Zone")
  383. if err != nil {
  384. return err
  385. }
  386. self.izones = make([]cloudprovider.ICloudZone, len(zones))
  387. for i := 0; i < len(zones); i += 1 {
  388. zones[i].region = self
  389. self.izones[i] = &zones[i]
  390. }
  391. return nil
  392. }
  393. func (self *SRegion) getZoneById(id string) (*SZone, error) {
  394. izones, err := self.GetIZones()
  395. if err != nil {
  396. return nil, err
  397. }
  398. for i := 0; i < len(izones); i += 1 {
  399. zone := izones[i].(*SZone)
  400. if zone.ZoneId == id {
  401. return zone, nil
  402. }
  403. }
  404. return nil, fmt.Errorf("no such zone %s", id)
  405. }
  406. func (self *SRegion) GetIVMById(id string) (cloudprovider.ICloudVM, error) {
  407. return self.GetInstance(id)
  408. }
  409. func (self *SRegion) GetIDiskById(id string) (cloudprovider.ICloudDisk, error) {
  410. return self.getDisk(id)
  411. }
  412. func (self *SRegion) GetIVpcs() ([]cloudprovider.ICloudVpc, error) {
  413. if self.ivpcs == nil {
  414. err := self.fetchInfrastructure()
  415. if err != nil {
  416. return nil, err
  417. }
  418. }
  419. return self.ivpcs, nil
  420. }
  421. func (self *SRegion) GetIVpcById(id string) (cloudprovider.ICloudVpc, error) {
  422. ivpcs, err := self.GetIVpcs()
  423. if err != nil {
  424. return nil, err
  425. }
  426. for i := 0; i < len(ivpcs); i += 1 {
  427. if ivpcs[i].GetGlobalId() == id {
  428. return ivpcs[i], nil
  429. }
  430. }
  431. return nil, cloudprovider.ErrNotFound
  432. }
  433. func (self *SRegion) fetchIVpcs() error {
  434. vpcs := make([]SVpc, 0)
  435. for {
  436. part, total, err := self.GetVpcs(nil, len(vpcs), 50)
  437. if err != nil {
  438. return err
  439. }
  440. vpcs = append(vpcs, part...)
  441. if len(vpcs) >= total {
  442. break
  443. }
  444. }
  445. self.ivpcs = make([]cloudprovider.ICloudVpc, len(vpcs))
  446. for i := 0; i < len(vpcs); i += 1 {
  447. vpcs[i].region = self
  448. self.ivpcs[i] = &vpcs[i]
  449. }
  450. return nil
  451. }
  452. func (self *SRegion) fetchInfrastructure() error {
  453. err := self._fetchZones(PostPaidInstanceChargeType, NoSpotStrategy)
  454. if err != nil {
  455. return err
  456. }
  457. err = self.fetchIVpcs()
  458. if err != nil {
  459. return err
  460. }
  461. for i := 0; i < len(self.ivpcs); i += 1 {
  462. for j := 0; j < len(self.izones); j += 1 {
  463. zone := self.izones[j].(*SZone)
  464. vpc := self.ivpcs[i].(*SVpc)
  465. wire := SWire{zone: zone, vpc: vpc}
  466. zone.addWire(&wire)
  467. vpc.addWire(&wire)
  468. }
  469. }
  470. return nil
  471. }
  472. func (self *SRegion) GetVpcs(vpcId []string, offset int, limit int) ([]SVpc, int, error) {
  473. if limit > 50 || limit <= 0 {
  474. limit = 50
  475. }
  476. params := make(map[string]string)
  477. params["RegionId"] = self.RegionId
  478. params["PageSize"] = fmt.Sprintf("%d", limit)
  479. params["PageNumber"] = fmt.Sprintf("%d", (offset/limit)+1)
  480. if vpcId != nil && len(vpcId) > 0 {
  481. params["VpcId"] = strings.Join(vpcId, ",")
  482. }
  483. body, err := self.vpcRequest("DescribeVpcs", params)
  484. if err != nil {
  485. log.Errorf("GetVpcs fail %s", err)
  486. return nil, 0, err
  487. }
  488. vpcs := make([]SVpc, 0)
  489. err = body.Unmarshal(&vpcs, "Vpcs", "Vpc")
  490. if err != nil {
  491. log.Errorf("Unmarshal vpc fail %s", err)
  492. return nil, 0, err
  493. }
  494. total, _ := body.Int("TotalCount")
  495. return vpcs, int(total), nil
  496. }
  497. func (self *SRegion) getVpc(vpcId string) (*SVpc, error) {
  498. vpcs, total, err := self.GetVpcs([]string{vpcId}, 0, 1)
  499. if err != nil {
  500. return nil, err
  501. }
  502. if total != 1 {
  503. return nil, cloudprovider.ErrNotFound
  504. }
  505. vpcs[0].region = self
  506. return &vpcs[0], nil
  507. }
  508. func (self *SRegion) GetVRouters(offset int, limit int) ([]SVRouter, int, error) {
  509. if limit > 50 || limit <= 0 {
  510. limit = 50
  511. }
  512. params := make(map[string]string)
  513. params["RegionId"] = self.RegionId
  514. params["PageSize"] = fmt.Sprintf("%d", limit)
  515. params["PageNumber"] = fmt.Sprintf("%d", (offset/limit)+1)
  516. body, err := self.ecsRequest("DescribeVRouters", params)
  517. if err != nil {
  518. log.Errorf("GetVRouters fail %s", err)
  519. return nil, 0, err
  520. }
  521. vrouters := make([]SVRouter, 0)
  522. err = body.Unmarshal(&vrouters, "VRouters", "VRouter")
  523. if err != nil {
  524. log.Errorf("Unmarshal vrouter fail %s", err)
  525. return nil, 0, err
  526. }
  527. total, _ := body.Int("TotalCount")
  528. return vrouters, int(total), nil
  529. }
  530. func (self *SRegion) GetRouteTables(ids []string, offset int, limit int) ([]SRouteTable, int, error) {
  531. if limit > 50 || limit <= 0 {
  532. limit = 50
  533. }
  534. params := make(map[string]string)
  535. params["RegionId"] = self.RegionId
  536. params["PageSize"] = fmt.Sprintf("%d", limit)
  537. params["PageNumber"] = fmt.Sprintf("%d", (offset/limit)+1)
  538. if ids != nil && len(ids) > 0 {
  539. params["RouteTableId"] = strings.Join(ids, ",")
  540. }
  541. body, err := self.ecsRequest("DescribeRouteTables", params)
  542. if err != nil {
  543. log.Errorf("GetRouteTables fail %s", err)
  544. return nil, 0, err
  545. }
  546. routetables := make([]SRouteTable, 0)
  547. err = body.Unmarshal(&routetables, "RouteTables", "RouteTable")
  548. if err != nil {
  549. log.Errorf("Unmarshal routetables fail %s", err)
  550. return nil, 0, err
  551. }
  552. total, _ := body.Int("TotalCount")
  553. return routetables, int(total), nil
  554. }
  555. func (self *SRegion) GetMatchInstanceTypes(cpu int, memMB int, gpu int, zoneId string) ([]SInstanceType, error) {
  556. if self.instanceTypes == nil {
  557. types, err := self.GetInstanceTypes()
  558. if err != nil {
  559. log.Errorf("GetInstanceTypes %s", err)
  560. return nil, err
  561. }
  562. self.instanceTypes = types
  563. }
  564. var available []string
  565. if len(zoneId) > 0 {
  566. zone, err := self.getZoneById(zoneId)
  567. if err != nil {
  568. return nil, err
  569. }
  570. available = zone.AvailableInstanceTypes.InstanceTypes
  571. }
  572. ret := make([]SInstanceType, 0)
  573. for _, t := range self.instanceTypes {
  574. if t.CpuCoreCount == cpu && memMB == t.memoryMB() && gpu == t.GPUAmount {
  575. if available == nil || utils.IsInStringArray(t.InstanceTypeId, available) {
  576. ret = append(ret, t)
  577. }
  578. }
  579. }
  580. return ret, nil
  581. }
  582. func (self *SRegion) CreateInstanceSimple(name string, imgId string, cpu int, memGB int, storageType string, dataDiskSizesGB []int, vswitchId string, passwd string, publicKey string) (*SInstance, error) {
  583. izones, err := self.GetIZones()
  584. if err != nil {
  585. return nil, err
  586. }
  587. for i := 0; i < len(izones); i += 1 {
  588. z := izones[i].(*SZone)
  589. log.Debugf("Search in zone %s", z.LocalName)
  590. net := z.getNetworkById(vswitchId)
  591. if net != nil {
  592. desc := &cloudprovider.SManagedVMCreateConfig{
  593. Name: name,
  594. ExternalImageId: imgId,
  595. SysDisk: cloudprovider.SDiskInfo{SizeGB: 0, StorageType: storageType},
  596. Cpu: cpu,
  597. MemoryMB: memGB * 1024,
  598. ExternalNetworkId: vswitchId,
  599. Password: passwd,
  600. DataDisks: []cloudprovider.SDiskInfo{},
  601. PublicKey: publicKey,
  602. }
  603. for _, sizeGB := range dataDiskSizesGB {
  604. desc.DataDisks = append(desc.DataDisks, cloudprovider.SDiskInfo{SizeGB: sizeGB, StorageType: storageType})
  605. }
  606. inst, err := z.getHost().CreateVM(desc)
  607. if err != nil {
  608. return nil, err
  609. }
  610. return inst.(*SInstance), nil
  611. }
  612. }
  613. return nil, fmt.Errorf("cannot find vswitch %s", vswitchId)
  614. }
  615. func (self *SRegion) instanceOperation(instanceId string, opname string, extra map[string]string) error {
  616. params := make(map[string]string)
  617. params["RegionId"] = self.RegionId
  618. params["InstanceId"] = instanceId
  619. if extra != nil && len(extra) > 0 {
  620. for k, v := range extra {
  621. params[k] = v
  622. }
  623. }
  624. _, err := self.ecsRequest(opname, params)
  625. return err
  626. }
  627. func (self *SRegion) GetInstanceStatus(instanceId string) (string, error) {
  628. instance, err := self.GetInstance(instanceId)
  629. if err != nil {
  630. return "", err
  631. }
  632. return instance.Status, nil
  633. }
  634. func (self *SRegion) GetInstanceVNCUrl(instanceId string) (string, error) {
  635. params := make(map[string]string)
  636. params["RegionId"] = self.RegionId
  637. params["InstanceId"] = instanceId
  638. body, err := self.ecsRequest("DescribeInstanceVncUrl", params)
  639. if err != nil {
  640. return "", err
  641. }
  642. return body.GetString("VncUrl")
  643. }
  644. func (self *SRegion) ModifyInstanceVNCUrlPassword(instanceId string, passwd string) error {
  645. params := make(map[string]string)
  646. params["RegionId"] = self.RegionId
  647. params["InstanceId"] = instanceId
  648. params["VncPassword"] = passwd // must be 6 digital + alphabet
  649. _, err := self.ecsRequest("ModifyInstanceVncPasswd", params)
  650. return err
  651. }
  652. func (self *SRegion) CreateVpc(opts *cloudprovider.VpcCreateOptions) (*SVpc, error) {
  653. params := make(map[string]string)
  654. if len(opts.CIDR) > 0 {
  655. params["CidrBlock"] = opts.CIDR
  656. }
  657. if len(opts.NAME) > 0 {
  658. params["VpcName"] = opts.NAME
  659. }
  660. if len(opts.Desc) > 0 {
  661. params["Description"] = opts.Desc
  662. }
  663. params["ClientToken"] = utils.GenRequestId(20)
  664. body, err := self.ecsRequest("CreateVpc", params)
  665. if err != nil {
  666. return nil, err
  667. }
  668. vpcId, err := body.GetString("VpcId")
  669. if err != nil {
  670. return nil, err
  671. }
  672. err = self.fetchInfrastructure()
  673. if err != nil {
  674. return nil, err
  675. }
  676. return self.getVpc(vpcId)
  677. }
  678. func (self *SRegion) CreateIVpc(opts *cloudprovider.VpcCreateOptions) (cloudprovider.ICloudVpc, error) {
  679. vpc, err := self.CreateVpc(opts)
  680. if err != nil {
  681. return nil, err
  682. }
  683. return vpc, nil
  684. }
  685. func (self *SRegion) DeleteVpc(vpcId string) error {
  686. params := make(map[string]string)
  687. params["VpcId"] = vpcId
  688. _, err := self.ecsRequest("DeleteVpc", params)
  689. return err
  690. }
  691. func (self *SRegion) GetIHostById(id string) (cloudprovider.ICloudHost, error) {
  692. izones, err := self.GetIZones()
  693. if err != nil {
  694. return nil, err
  695. }
  696. for i := 0; i < len(izones); i += 1 {
  697. ihost, err := izones[i].GetIHostById(id)
  698. if err == nil {
  699. return ihost, nil
  700. } else if errors.Cause(err) != cloudprovider.ErrNotFound {
  701. return nil, err
  702. }
  703. }
  704. return nil, cloudprovider.ErrNotFound
  705. }
  706. func (self *SRegion) GetIStorageById(id string) (cloudprovider.ICloudStorage, error) {
  707. izones, err := self.GetIZones()
  708. if err != nil {
  709. return nil, err
  710. }
  711. for i := 0; i < len(izones); i += 1 {
  712. istore, err := izones[i].GetIStorageById(id)
  713. if err == nil {
  714. return istore, nil
  715. } else if errors.Cause(err) != cloudprovider.ErrNotFound {
  716. return nil, err
  717. }
  718. }
  719. return nil, cloudprovider.ErrNotFound
  720. }
  721. func (self *SRegion) GetIHosts() ([]cloudprovider.ICloudHost, error) {
  722. iHosts := make([]cloudprovider.ICloudHost, 0)
  723. izones, err := self.GetIZones()
  724. if err != nil {
  725. return nil, err
  726. }
  727. for i := 0; i < len(izones); i += 1 {
  728. iZoneHost, err := izones[i].GetIHosts()
  729. if err != nil {
  730. return nil, err
  731. }
  732. iHosts = append(iHosts, iZoneHost...)
  733. }
  734. return iHosts, nil
  735. }
  736. func (self *SRegion) GetIStorages() ([]cloudprovider.ICloudStorage, error) {
  737. iStores := make([]cloudprovider.ICloudStorage, 0)
  738. izones, err := self.GetIZones()
  739. if err != nil {
  740. return nil, err
  741. }
  742. for i := 0; i < len(izones); i += 1 {
  743. iZoneStores, err := izones[i].GetIStorages()
  744. if err != nil {
  745. return nil, err
  746. }
  747. iStores = append(iStores, iZoneStores...)
  748. }
  749. return iStores, nil
  750. }
  751. func (self *SRegion) updateInstance(instId string, name, desc, passwd, hostname, userData string) error {
  752. params := make(map[string]string)
  753. params["InstanceId"] = instId
  754. if len(name) > 0 {
  755. params["InstanceName"] = name
  756. }
  757. if len(desc) > 0 {
  758. params["Description"] = desc
  759. }
  760. if len(passwd) > 0 {
  761. params["Password"] = passwd
  762. }
  763. if len(hostname) > 0 {
  764. params["HostName"] = hostname
  765. }
  766. if len(userData) > 0 {
  767. params["UserData"] = userData
  768. }
  769. _, err := self.ecsRequest("ModifyInstanceAttribute", params)
  770. return err
  771. }
  772. func (self *SRegion) UpdateInstancePassword(instId string, passwd string) error {
  773. return self.updateInstance(instId, "", "", passwd, "", "")
  774. }
  775. func (self *SRegion) GetIEips() ([]cloudprovider.ICloudEIP, error) {
  776. eips, err := self.GetEips("", "", "")
  777. if err != nil {
  778. return nil, err
  779. }
  780. ret := make([]cloudprovider.ICloudEIP, len(eips))
  781. for i := range eips {
  782. eips[i].region = self
  783. ret[i] = &eips[i]
  784. }
  785. return ret, nil
  786. }
  787. func (self *SRegion) GetIEipById(eipId string) (cloudprovider.ICloudEIP, error) {
  788. eip, err := self.GetEip(eipId)
  789. if err != nil {
  790. return nil, err
  791. }
  792. return eip, nil
  793. }
  794. func (region *SRegion) GetISecurityGroupById(secgroupId string) (cloudprovider.ICloudSecurityGroup, error) {
  795. secgroup, err := region.GetSecurityGroup(secgroupId)
  796. if err != nil {
  797. return nil, err
  798. }
  799. return secgroup, nil
  800. }
  801. func (region *SRegion) CreateISecurityGroup(opts *cloudprovider.SecurityGroupCreateInput) (cloudprovider.ICloudSecurityGroup, error) {
  802. externalId, err := region.CreateSecurityGroup(opts)
  803. if err != nil {
  804. return nil, err
  805. }
  806. return region.GetISecurityGroupById(externalId)
  807. }
  808. func (region *SRegion) GetILoadBalancers() ([]cloudprovider.ICloudLoadbalancer, error) {
  809. lbs, err := region.GetLoadbalancers(nil)
  810. if err != nil {
  811. return nil, err
  812. }
  813. ilbs := []cloudprovider.ICloudLoadbalancer{}
  814. for i := 0; i < len(lbs); i++ {
  815. lbs[i].region = region
  816. ilbs = append(ilbs, &lbs[i])
  817. }
  818. // 获取ALB实例
  819. albs, err := region.GetAlbs()
  820. if err != nil {
  821. return nil, err
  822. }
  823. for i := 0; i < len(albs); i++ {
  824. albs[i].region = region
  825. ilbs = append(ilbs, &albs[i])
  826. }
  827. // 获取NLB实例
  828. nlbs, err := region.GetNlbs()
  829. if err != nil {
  830. return nil, err
  831. }
  832. for i := 0; i < len(nlbs); i++ {
  833. nlbs[i].region = region
  834. ilbs = append(ilbs, &nlbs[i])
  835. }
  836. return ilbs, nil
  837. }
  838. func (region *SRegion) GetILoadBalancerById(loadbalancerId string) (cloudprovider.ICloudLoadbalancer, error) {
  839. if strings.HasPrefix(loadbalancerId, "alb-") {
  840. return region.GetAlbDetail(loadbalancerId)
  841. } else if strings.HasPrefix(loadbalancerId, "nlb-") {
  842. return region.GetNlbDetail(loadbalancerId)
  843. }
  844. return region.GetLoadbalancerDetail(loadbalancerId)
  845. }
  846. func (region *SRegion) GetILoadBalancerCertificateById(certId string) (cloudprovider.ICloudLoadbalancerCertificate, error) {
  847. certs, err := region.GetLoadbalancerServerCertificates()
  848. if err != nil {
  849. return nil, err
  850. }
  851. for i := 0; i < len(certs); i++ {
  852. if certs[i].GetGlobalId() == certId {
  853. certs[i].region = region
  854. return &certs[i], nil
  855. }
  856. }
  857. return nil, cloudprovider.ErrNotFound
  858. }
  859. func (region *SRegion) CreateILoadBalancerCertificate(cert *cloudprovider.SLoadbalancerCertificate) (cloudprovider.ICloudLoadbalancerCertificate, error) {
  860. params := map[string]string{}
  861. params["RegionId"] = region.RegionId
  862. params["ServerCertificateName"] = cert.Name
  863. params["PrivateKey"] = cert.PrivateKey
  864. params["ServerCertificate"] = cert.Certificate
  865. body, err := region.lbRequest("UploadServerCertificate", params)
  866. if err != nil {
  867. return nil, err
  868. }
  869. certID, err := body.GetString("ServerCertificateId")
  870. if err != nil {
  871. return nil, err
  872. }
  873. return region.GetILoadBalancerCertificateById(certID)
  874. }
  875. func (region *SRegion) GetILoadBalancerAclById(aclId string) (cloudprovider.ICloudLoadbalancerAcl, error) {
  876. return region.GetLoadbalancerAclDetail(aclId)
  877. }
  878. func (region *SRegion) GetILoadBalancerAcls() ([]cloudprovider.ICloudLoadbalancerAcl, error) {
  879. acls, err := region.GetLoadBalancerAcls()
  880. if err != nil {
  881. return nil, err
  882. }
  883. iAcls := []cloudprovider.ICloudLoadbalancerAcl{}
  884. for i := 0; i < len(acls); i++ {
  885. acls[i].region = region
  886. iAcls = append(iAcls, &acls[i])
  887. }
  888. return iAcls, nil
  889. }
  890. func (region *SRegion) GetILoadBalancerCertificates() ([]cloudprovider.ICloudLoadbalancerCertificate, error) {
  891. certificates, err := region.GetLoadbalancerServerCertificates()
  892. if err != nil {
  893. return nil, err
  894. }
  895. iCertificates := []cloudprovider.ICloudLoadbalancerCertificate{}
  896. for i := 0; i < len(certificates); i++ {
  897. certificates[i].region = region
  898. iCertificates = append(iCertificates, &certificates[i])
  899. }
  900. return iCertificates, nil
  901. }
  902. func (region *SRegion) CreateILoadBalancer(loadbalancer *cloudprovider.SLoadbalancerCreateOptions) (cloudprovider.ICloudLoadbalancer, error) {
  903. params := map[string]string{}
  904. params["RegionId"] = region.RegionId
  905. params["LoadBalancerName"] = loadbalancer.Name
  906. if len(loadbalancer.ZoneId) > 0 {
  907. params["MasterZoneId"] = transZoneIdFromEcsZoneId(region, "elb", loadbalancer.ZoneId)
  908. }
  909. if len(loadbalancer.VpcId) > 0 {
  910. params["VpcId"] = loadbalancer.VpcId
  911. }
  912. if len(loadbalancer.NetworkIds) > 0 {
  913. params["VSwitchId"] = loadbalancer.NetworkIds[0]
  914. }
  915. if len(loadbalancer.Address) > 0 {
  916. params["Address"] = loadbalancer.Address
  917. }
  918. if len(loadbalancer.AddressType) > 0 {
  919. params["AddressType"] = loadbalancer.AddressType
  920. }
  921. if len(loadbalancer.LoadbalancerSpec) > 0 {
  922. params["LoadBalancerSpec"] = loadbalancer.LoadbalancerSpec
  923. }
  924. if len(loadbalancer.ChargeType) > 0 {
  925. params["InternetChargeType"] = "payby" + loadbalancer.ChargeType
  926. }
  927. if len(loadbalancer.ProjectId) > 0 {
  928. params["ResourceGroupId"] = loadbalancer.ProjectId
  929. }
  930. if loadbalancer.ChargeType == api.LB_CHARGE_TYPE_BY_BANDWIDTH && loadbalancer.EgressMbps > 0 {
  931. params["Bandwidth"] = fmt.Sprintf("%d", loadbalancer.EgressMbps)
  932. }
  933. body, err := region.lbRequest("CreateLoadBalancer", params)
  934. if err != nil {
  935. return nil, err
  936. }
  937. loadBalancerID, err := body.GetString("LoadBalancerId")
  938. if err != nil {
  939. return nil, err
  940. }
  941. region.SetResourceTags(ALIYUN_SERVICE_SLB, "instance", loadBalancerID, loadbalancer.Tags, false)
  942. iLoadbalancer, err := region.GetLoadbalancerDetail(loadBalancerID)
  943. if err != nil {
  944. return nil, err
  945. }
  946. return iLoadbalancer, cloudprovider.WaitStatus(iLoadbalancer, api.LB_STATUS_ENABLED, time.Second*5, time.Minute*5)
  947. }
  948. func (region *SRegion) AddAccessControlListEntry(aclId string, entrys []cloudprovider.SLoadbalancerAccessControlListEntry) error {
  949. params := map[string]string{}
  950. params["RegionId"] = region.RegionId
  951. params["AclId"] = aclId
  952. aclArray := jsonutils.NewArray()
  953. for i := 0; i < len(entrys); i++ {
  954. //阿里云AclEntrys参数必须是CIDR格式的。
  955. if regutils.MatchIPAddr(entrys[i].CIDR) {
  956. entrys[i].CIDR += "/32"
  957. }
  958. aclArray.Add(jsonutils.Marshal(map[string]string{"entry": entrys[i].CIDR, "comment": entrys[i].Comment}))
  959. }
  960. if aclArray.Length() == 0 {
  961. return nil
  962. }
  963. params["AclEntrys"] = aclArray.String()
  964. _, err := region.lbRequest("AddAccessControlListEntry", params)
  965. return err
  966. }
  967. func (region *SRegion) CreateILoadBalancerAcl(acl *cloudprovider.SLoadbalancerAccessControlList) (cloudprovider.ICloudLoadbalancerAcl, error) {
  968. params := map[string]string{}
  969. params["RegionId"] = region.RegionId
  970. params["AclName"] = acl.Name
  971. var body jsonutils.JSONObject
  972. var err error
  973. for i := 0; i < 20; i++ {
  974. body, err = region.lbRequest("CreateAccessControlList", params)
  975. if err == nil {
  976. break
  977. }
  978. if e, ok := errors.Cause(err).(*alierr.ServerError); ok && e.ErrorCode() == "AclNameExist" {
  979. params["AclName"] = fmt.Sprintf("%s-%d", acl.Name, i)
  980. continue
  981. }
  982. return nil, err
  983. }
  984. aclId, err := body.GetString("AclId")
  985. if err != nil {
  986. return nil, err
  987. }
  988. iAcl, err := region.GetLoadbalancerAclDetail(aclId)
  989. if err != nil {
  990. return nil, err
  991. }
  992. return iAcl, region.AddAccessControlListEntry(aclId, acl.Entrys)
  993. }
  994. func (region *SRegion) GetIBuckets() ([]cloudprovider.ICloudBucket, error) {
  995. iBuckets, err := region.client.getIBuckets()
  996. if err != nil {
  997. return nil, errors.Wrap(err, "getIBuckets")
  998. }
  999. ret := make([]cloudprovider.ICloudBucket, 0)
  1000. for i := range iBuckets {
  1001. if iBuckets[i].GetIRegion().GetId() != region.GetId() {
  1002. continue
  1003. }
  1004. ret = append(ret, iBuckets[i])
  1005. }
  1006. return ret, nil
  1007. }
  1008. func str2StorageClass(storageClassStr string) (oss.StorageClassType, error) {
  1009. storageClass := oss.StorageStandard
  1010. if strings.EqualFold(storageClassStr, string(oss.StorageStandard)) {
  1011. //
  1012. } else if strings.EqualFold(storageClassStr, string(oss.StorageIA)) {
  1013. storageClass = oss.StorageIA
  1014. } else if strings.EqualFold(storageClassStr, string(oss.StorageArchive)) {
  1015. storageClass = oss.StorageArchive
  1016. } else {
  1017. return storageClass, errors.Error("not supported storageClass")
  1018. }
  1019. return storageClass, nil
  1020. }
  1021. func str2Acl(aclStr string) (oss.ACLType, error) {
  1022. acl := oss.ACLPrivate
  1023. if strings.EqualFold(aclStr, string(oss.ACLPrivate)) {
  1024. // private, default
  1025. } else if strings.EqualFold(aclStr, string(oss.ACLPublicRead)) {
  1026. acl = oss.ACLPublicRead
  1027. } else if strings.EqualFold(aclStr, string(oss.ACLPublicReadWrite)) {
  1028. acl = oss.ACLPublicReadWrite
  1029. } else {
  1030. return acl, errors.Error("not supported acl")
  1031. }
  1032. return acl, nil
  1033. }
  1034. func (region *SRegion) CreateIBucket(name string, storageClassStr string, aclStr string) error {
  1035. osscli, err := region.GetOssClient()
  1036. if err != nil {
  1037. return errors.Wrap(err, "region.GetOssClient")
  1038. }
  1039. opts := make([]oss.Option, 0)
  1040. if len(storageClassStr) > 0 {
  1041. storageClass, err := str2StorageClass(storageClassStr)
  1042. if err != nil {
  1043. return err
  1044. }
  1045. opts = append(opts, oss.StorageClass(storageClass))
  1046. }
  1047. if len(aclStr) > 0 {
  1048. acl, err := str2Acl(aclStr)
  1049. if err != nil {
  1050. return err
  1051. }
  1052. opts = append(opts, oss.ACL(acl))
  1053. }
  1054. err = osscli.CreateBucket(name, opts...)
  1055. if err != nil {
  1056. return errors.Wrap(err, "oss.CreateBucket")
  1057. }
  1058. region.client.invalidateIBuckets()
  1059. return nil
  1060. }
  1061. func ossErrorCode(err error) int {
  1062. if srvErr, ok := err.(oss.ServiceError); ok {
  1063. return srvErr.StatusCode
  1064. }
  1065. if srvErr, ok := err.(*oss.ServiceError); ok {
  1066. return srvErr.StatusCode
  1067. }
  1068. return -1
  1069. }
  1070. func (region *SRegion) DeleteIBucket(name string) error {
  1071. osscli, err := region.GetOssClient()
  1072. if err != nil {
  1073. return errors.Wrap(err, "region.GetOssClient")
  1074. }
  1075. err = osscli.DeleteBucket(name)
  1076. if err != nil {
  1077. if ossErrorCode(err) == 404 {
  1078. return nil
  1079. }
  1080. return errors.Wrap(err, "DeleteBucket")
  1081. }
  1082. region.client.invalidateIBuckets()
  1083. return nil
  1084. }
  1085. func (region *SRegion) IBucketExist(name string) (bool, error) {
  1086. osscli, err := region.GetOssClient()
  1087. if err != nil {
  1088. return false, errors.Wrap(err, "region.GetOssClient")
  1089. }
  1090. exist, err := osscli.IsBucketExist(name)
  1091. if err != nil {
  1092. return false, errors.Wrap(err, "IsBucketExist")
  1093. }
  1094. return exist, nil
  1095. }
  1096. func (region *SRegion) GetIBucketById(name string) (cloudprovider.ICloudBucket, error) {
  1097. osscli, err := region.GetOssClient()
  1098. if err != nil {
  1099. return nil, errors.Wrap(err, "region.GetOssClient")
  1100. }
  1101. bi, err := osscli.GetBucketInfo(name)
  1102. if err != nil {
  1103. return nil, errors.Wrap(err, "Bucket")
  1104. }
  1105. bInfo := bi.BucketInfo
  1106. b := SBucket{
  1107. region: region,
  1108. Name: bInfo.Name,
  1109. Location: bInfo.Location,
  1110. CreationDate: bInfo.CreationDate,
  1111. StorageClass: bInfo.StorageClass,
  1112. }
  1113. return &b, nil
  1114. }
  1115. func (region *SRegion) GetIBucketByName(name string) (cloudprovider.ICloudBucket, error) {
  1116. return region.GetIBucketById(name)
  1117. }
  1118. func (self *SRegion) GetIElasticcaches() ([]cloudprovider.ICloudElasticcache, error) {
  1119. caches, err := self.GetElasticCaches(nil)
  1120. if err != nil {
  1121. return nil, err
  1122. }
  1123. icaches := make([]cloudprovider.ICloudElasticcache, len(caches))
  1124. for i := range caches {
  1125. caches[i].region = self
  1126. icaches[i] = &caches[i]
  1127. }
  1128. return icaches, nil
  1129. }
  1130. func (region *SRegion) GetCapabilities() []string {
  1131. return region.client.GetCapabilities()
  1132. }
  1133. func (self *SRegion) trialRequest(apiName string, params map[string]string) (jsonutils.JSONObject, error) {
  1134. client, err := self.getSdkClient()
  1135. if err != nil {
  1136. return nil, err
  1137. }
  1138. domain := fmt.Sprintf("actiontrail.%s.aliyuncs.com", self.RegionId)
  1139. return jsonRequest(client, domain, ALIYUN_API_VERSION_TRIAL, apiName, params, self.client.debug)
  1140. }
  1141. func (self *SRegion) GetIVMs() ([]cloudprovider.ICloudVM, error) {
  1142. instances, err := self.GetInstances("", nil)
  1143. if err != nil {
  1144. return nil, err
  1145. }
  1146. ret := []cloudprovider.ICloudVM{}
  1147. for i := range instances {
  1148. ret = append(ret, &instances[i])
  1149. }
  1150. return ret, nil
  1151. }