region.go 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900
  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 google
  15. import (
  16. "fmt"
  17. "strings"
  18. "time"
  19. "yunion.io/x/jsonutils"
  20. "yunion.io/x/log"
  21. "yunion.io/x/pkg/errors"
  22. "yunion.io/x/pkg/utils"
  23. api "yunion.io/x/cloudmux/pkg/apis/compute"
  24. "yunion.io/x/cloudmux/pkg/cloudprovider"
  25. "yunion.io/x/cloudmux/pkg/multicloud"
  26. )
  27. type SRegion struct {
  28. cloudprovider.SFakeOnPremiseRegion
  29. multicloud.SRegion
  30. client *SGoogleClient
  31. capabilities []string
  32. Quotas []SQuota
  33. Description string
  34. ID string
  35. Kind string
  36. Name string
  37. Status string
  38. SelfLink string
  39. CreationTimestamp time.Time
  40. }
  41. func (region *SRegion) GetClient() *SGoogleClient {
  42. return region.client
  43. }
  44. func (region *SRegion) GetName() string {
  45. if name, ok := RegionNames[region.Name]; ok {
  46. return fmt.Sprintf("%s %s", CLOUD_PROVIDER_GOOGLE_CN, name)
  47. }
  48. return fmt.Sprintf("%s %s", CLOUD_PROVIDER_GOOGLE_CN, region.Name)
  49. }
  50. func (self *SRegion) GetI18n() cloudprovider.SModelI18nTable {
  51. en := fmt.Sprintf("%s %s", CLOUD_PROVIDER_GOOGLE, self.Name)
  52. table := cloudprovider.SModelI18nTable{}
  53. table["name"] = cloudprovider.NewSModelI18nEntry(self.GetName()).CN(self.GetName()).EN(en)
  54. return table
  55. }
  56. func (region *SRegion) GetId() string {
  57. return region.Name
  58. }
  59. func (region *SRegion) GetGlobalId() string {
  60. return fmt.Sprintf("%s/%s", CLOUD_PROVIDER_GOOGLE, region.Name)
  61. }
  62. func (region *SRegion) GetGeographicInfo() cloudprovider.SGeographicInfo {
  63. if geoInfo, ok := LatitudeAndLongitude[region.Name]; ok {
  64. return geoInfo
  65. }
  66. return cloudprovider.SGeographicInfo{}
  67. }
  68. func (self *SRegion) GetCreatedAt() time.Time {
  69. return self.CreationTimestamp
  70. }
  71. func (region *SRegion) GetProvider() string {
  72. return CLOUD_PROVIDER_GOOGLE
  73. }
  74. func (region *SRegion) GetStatus() string {
  75. if region.Status == "UP" || utils.IsInStringArray(region.Name, MultiRegions) || utils.IsInStringArray(region.Name, DualRegions) {
  76. return api.CLOUD_REGION_STATUS_INSERVER
  77. }
  78. return api.CLOUD_REGION_STATUS_OUTOFSERVICE
  79. }
  80. func (region *SRegion) CreateIBucket(name string, storageClassStr string, acl string) error {
  81. _, err := region.CreateBucket(name, storageClassStr, cloudprovider.TBucketACLType(acl))
  82. return err
  83. }
  84. func (region *SRegion) DeleteIBucket(name string) error {
  85. return region.DeleteBucket(name)
  86. }
  87. func (region *SRegion) IBucketExist(name string) (bool, error) {
  88. //{"error":{"code":403,"details":"200420163731-compute@developer.gserviceaccount.com does not have storage.buckets.get access to test."}}
  89. //{"error":{"code":404,"details":"Not Found"}}
  90. _, err := region.GetBucket(name)
  91. if err == nil {
  92. return true, nil
  93. }
  94. if errors.Cause(err) == cloudprovider.ErrNotFound || strings.Contains(err.Error(), "storage.buckets.get access") {
  95. return false, nil
  96. }
  97. return false, err
  98. }
  99. func (region *SRegion) GetIBucketById(id string) (cloudprovider.ICloudBucket, error) {
  100. return cloudprovider.GetIBucketById(region, id)
  101. }
  102. func (region *SRegion) GetIBucketByName(name string) (cloudprovider.ICloudBucket, error) {
  103. return region.GetIBucketById(name)
  104. }
  105. func (region *SRegion) GetIBuckets() ([]cloudprovider.ICloudBucket, error) {
  106. iBuckets, err := region.client.getIBuckets()
  107. if err != nil {
  108. return nil, errors.Wrap(err, "getIBuckets")
  109. }
  110. ret := []cloudprovider.ICloudBucket{}
  111. for i := range iBuckets {
  112. if iBuckets[i].GetLocation() != region.GetId() {
  113. continue
  114. }
  115. ret = append(ret, iBuckets[i])
  116. }
  117. return ret, nil
  118. }
  119. func (region *SRegion) IsEmulated() bool {
  120. return false
  121. }
  122. func (region *SRegion) GetIZones() ([]cloudprovider.ICloudZone, error) {
  123. if utils.IsInStringArray(region.Name, MultiRegions) || utils.IsInStringArray(region.Name, DualRegions) {
  124. return []cloudprovider.ICloudZone{}, nil
  125. }
  126. zones, err := region.GetZones(region.Name, 0, "")
  127. if err != nil {
  128. return nil, err
  129. }
  130. izones := []cloudprovider.ICloudZone{}
  131. for i := 0; i < len(zones); i++ {
  132. zones[i].region = region
  133. izones = append(izones, &zones[i])
  134. }
  135. return izones, nil
  136. }
  137. func (region *SRegion) GetIZoneById(id string) (cloudprovider.ICloudZone, error) {
  138. if utils.IsInStringArray(region.Name, MultiRegions) || utils.IsInStringArray(region.Name, DualRegions) {
  139. return nil, cloudprovider.ErrNotFound
  140. }
  141. zones, err := region.GetIZones()
  142. if err != nil {
  143. return nil, err
  144. }
  145. for i := range zones {
  146. if zones[i].GetGlobalId() == id {
  147. return zones[i], nil
  148. }
  149. }
  150. return nil, cloudprovider.ErrNotFound
  151. }
  152. func (self *SRegion) GetIVpcs() ([]cloudprovider.ICloudVpc, error) {
  153. if utils.IsInStringArray(self.Name, MultiRegions) || utils.IsInStringArray(self.Name, DualRegions) {
  154. return []cloudprovider.ICloudVpc{}, nil
  155. }
  156. vpcs, err := self.GetVpcs()
  157. if err != nil {
  158. return nil, errors.Wrapf(err, "GetVpcs")
  159. }
  160. ret := []cloudprovider.ICloudVpc{}
  161. for i := range vpcs {
  162. vpcs[i].region = self
  163. ret = append(ret, &vpcs[i])
  164. }
  165. sharedNetworks, err := self.client.GetSharedGlobalNetworks()
  166. if err != nil {
  167. return nil, errors.Wrapf(err, "GetSharedGlobalNetworks")
  168. }
  169. for i := range sharedNetworks {
  170. for j := range sharedNetworks[i].Subnetworks {
  171. if strings.Contains(sharedNetworks[i].Subnetworks[j].Subnetwork, fmt.Sprintf("/%s/", self.Name)) {
  172. sharedNetworks[i].Subnetworks[j].region = self
  173. ret = append(ret, &sharedNetworks[i].Subnetworks[j])
  174. }
  175. }
  176. }
  177. return ret, nil
  178. }
  179. func (self *SRegion) GetIVpcById(id string) (cloudprovider.ICloudVpc, error) {
  180. if utils.IsInStringArray(self.Name, MultiRegions) || utils.IsInStringArray(self.Name, DualRegions) {
  181. return nil, cloudprovider.ErrNotFound
  182. }
  183. if strings.Contains(id, "projects/") {
  184. vpcs, err := self.GetIVpcs()
  185. if err != nil {
  186. return nil, err
  187. }
  188. for i := range vpcs {
  189. if vpcs[i].GetGlobalId() == id {
  190. return vpcs[i], nil
  191. }
  192. }
  193. return nil, cloudprovider.ErrNotFound
  194. }
  195. vpc, err := self.GetVpc(id)
  196. if err != nil {
  197. return nil, errors.Wrapf(err, "GetVpc")
  198. }
  199. return vpc, nil
  200. }
  201. func (self *SRegion) CreateIVpc(opts *cloudprovider.VpcCreateOptions) (cloudprovider.ICloudVpc, error) {
  202. if utils.IsInStringArray(self.Name, MultiRegions) || utils.IsInStringArray(self.Name, DualRegions) {
  203. return nil, cloudprovider.ErrNotSupported
  204. }
  205. gvpc, err := self.client.GetGlobalNetwork(opts.GlobalVpcExternalId)
  206. if err != nil {
  207. return nil, errors.Wrapf(err, "GetGlobalNetwork")
  208. }
  209. return self.CreateVpc(opts.NAME, gvpc.SelfLink, opts.CIDR, opts.Desc)
  210. }
  211. func (region *SRegion) GetIStorageById(id string) (cloudprovider.ICloudStorage, error) {
  212. if utils.IsInStringArray(region.Name, MultiRegions) || utils.IsInStringArray(region.Name, DualRegions) {
  213. return nil, cloudprovider.ErrNotFound
  214. }
  215. storage, err := region.GetStorage(id)
  216. if err != nil {
  217. return nil, err
  218. }
  219. zone, err := region.GetZone(storage.Zone)
  220. if err != nil {
  221. return nil, errors.Wrapf(err, "region.GetZone(%s)", storage.Zone)
  222. }
  223. zone.region = region
  224. storage.zone = zone
  225. return storage, nil
  226. }
  227. func (region *SRegion) GetIHostById(id string) (cloudprovider.ICloudHost, error) {
  228. if utils.IsInStringArray(region.Name, MultiRegions) || utils.IsInStringArray(region.Name, DualRegions) {
  229. return nil, cloudprovider.ErrNotFound
  230. }
  231. izones, err := region.GetIZones()
  232. if err != nil {
  233. return nil, err
  234. }
  235. for i := 0; i < len(izones); i += 1 {
  236. ihost, err := izones[i].GetIHostById(id)
  237. if err == nil {
  238. return ihost, nil
  239. } else if errors.Cause(err) != cloudprovider.ErrNotFound {
  240. return nil, err
  241. }
  242. }
  243. return nil, cloudprovider.ErrNotFound
  244. }
  245. func (region *SRegion) GetProjectId() string {
  246. return region.client.projectId
  247. }
  248. func (region *SRegion) GetIEips() ([]cloudprovider.ICloudEIP, error) {
  249. if utils.IsInStringArray(region.Name, MultiRegions) || utils.IsInStringArray(region.Name, DualRegions) {
  250. return []cloudprovider.ICloudEIP{}, nil
  251. }
  252. eips, err := region.GetEips("", 0, "")
  253. if err != nil {
  254. return nil, err
  255. }
  256. ieips := []cloudprovider.ICloudEIP{}
  257. for i := range eips {
  258. eips[i].region = region
  259. ieips = append(ieips, &eips[i])
  260. }
  261. return ieips, nil
  262. }
  263. func (region *SRegion) GetIVMById(id string) (cloudprovider.ICloudVM, error) {
  264. if utils.IsInStringArray(region.Name, MultiRegions) || utils.IsInStringArray(region.Name, DualRegions) {
  265. return nil, cloudprovider.ErrNotFound
  266. }
  267. ivm, err := region.GetInstance(id)
  268. if err != nil {
  269. return nil, err
  270. }
  271. zone, err := region.GetZone(ivm.Zone)
  272. if err != nil {
  273. return nil, errors.Wrapf(err, "GetZone(%s)", ivm.Zone)
  274. }
  275. ivm.host = &SHost{zone: zone}
  276. return ivm, nil
  277. }
  278. func (region *SRegion) GetIDiskById(id string) (cloudprovider.ICloudDisk, error) {
  279. if utils.IsInStringArray(region.Name, MultiRegions) || utils.IsInStringArray(region.Name, DualRegions) {
  280. return nil, cloudprovider.ErrNotFound
  281. }
  282. disk, err := region.GetDisk(id)
  283. if err != nil {
  284. return nil, err
  285. }
  286. return disk, nil
  287. }
  288. func (region *SRegion) GetIEipById(id string) (cloudprovider.ICloudEIP, error) {
  289. if utils.IsInStringArray(region.Name, MultiRegions) || utils.IsInStringArray(region.Name, DualRegions) {
  290. return nil, cloudprovider.ErrNotFound
  291. }
  292. eip, err := region.GetEip(id)
  293. if err != nil {
  294. return nil, err
  295. }
  296. return eip, nil
  297. }
  298. func (region *SRegion) fetchSnapshots() error {
  299. if len(region.client.snapshots) > 0 {
  300. return nil
  301. }
  302. region.client.snapshots = map[string][]SSnapshot{}
  303. snapshots, err := region.GetSnapshots("", 0, "")
  304. if err != nil {
  305. return err
  306. }
  307. regionNames := []string{}
  308. for _, region := range region.client.iregions {
  309. regionNames = append(regionNames, region.GetId())
  310. }
  311. for _, snapshot := range snapshots {
  312. for _, location := range snapshot.StorageLocations {
  313. _regionName := ""
  314. if utils.IsInStringArray(location, regionNames) {
  315. _regionName = location
  316. } else {
  317. for _, regionName := range regionNames {
  318. if strings.HasPrefix(regionName, location) {
  319. _regionName = regionName
  320. break
  321. }
  322. }
  323. }
  324. if len(_regionName) > 0 {
  325. if _, ok := region.client.snapshots[_regionName]; !ok {
  326. region.client.snapshots[_regionName] = []SSnapshot{}
  327. }
  328. region.client.snapshots[_regionName] = append(region.client.snapshots[_regionName], snapshot)
  329. break
  330. }
  331. }
  332. }
  333. return nil
  334. }
  335. func (region *SRegion) GetISnapshots() ([]cloudprovider.ICloudSnapshot, error) {
  336. if utils.IsInStringArray(region.Name, MultiRegions) || utils.IsInStringArray(region.Name, DualRegions) {
  337. return []cloudprovider.ICloudSnapshot{}, nil
  338. }
  339. region.fetchSnapshots()
  340. isnapshots := []cloudprovider.ICloudSnapshot{}
  341. if snapshots, ok := region.client.snapshots[region.Name]; ok {
  342. for i := range snapshots {
  343. snapshots[i].region = region
  344. isnapshots = append(isnapshots, &snapshots[i])
  345. }
  346. }
  347. return isnapshots, nil
  348. }
  349. func (region *SRegion) GetISnapshotById(id string) (cloudprovider.ICloudSnapshot, error) {
  350. if utils.IsInStringArray(region.Name, MultiRegions) || utils.IsInStringArray(region.Name, DualRegions) {
  351. return nil, cloudprovider.ErrNotFound
  352. }
  353. snapshot, err := region.GetSnapshot(id)
  354. if err != nil {
  355. return nil, err
  356. }
  357. return snapshot, nil
  358. }
  359. func (region *SRegion) rdsDelete(id string) error {
  360. operation := &SOperation{}
  361. err := region.client.rdsDelete(id, operation)
  362. if err != nil {
  363. return errors.Wrap(err, "client.rdsDelete")
  364. }
  365. _, err = region.WaitRdsOperation(operation.SelfLink, id, "delete")
  366. if err != nil {
  367. return errors.Wrapf(err, "region.WaitRdsOperation(%s)", operation.SelfLink)
  368. }
  369. return nil
  370. }
  371. func (region *SRegion) rdsDo(id string, action string, params map[string]string, body jsonutils.JSONObject) error {
  372. opId, err := region.client.rdsDo(id, action, params, body)
  373. if err != nil {
  374. return err
  375. }
  376. if strings.Index(opId, "/operations/") > 0 {
  377. _, err = region.WaitRdsOperation(opId, id, action)
  378. return err
  379. }
  380. return nil
  381. }
  382. func (region *SRegion) rdsPatch(id string, body jsonutils.JSONObject) error {
  383. opId, err := region.client.rdsPatch(id, body)
  384. if err != nil {
  385. return err
  386. }
  387. if strings.Index(opId, "/operations/") > 0 {
  388. _, err = region.WaitRdsOperation(opId, id, "update")
  389. return err
  390. }
  391. return nil
  392. }
  393. func (region *SRegion) rdsUpdate(id string, params map[string]string, body jsonutils.JSONObject) error {
  394. opId, err := region.client.rdsUpdate(id, params, body)
  395. if err != nil {
  396. return err
  397. }
  398. if strings.Index(opId, "/operations/") > 0 {
  399. _, err = region.WaitRdsOperation(opId, id, "update")
  400. return err
  401. }
  402. return nil
  403. }
  404. func (region *SRegion) rdsGet(resource string, retval interface{}) error {
  405. return region.client.rdsGet(resource, retval)
  406. }
  407. func (region *SRegion) rdsInsert(resource string, body jsonutils.JSONObject, retval interface{}) error {
  408. operation := SOperation{}
  409. err := region.client.rdsInsert(resource, body, &operation)
  410. if err != nil {
  411. return errors.Wrap(err, "rdsInsert")
  412. }
  413. resourceId, err := region.WaitRdsOperation(operation.SelfLink, resource, "insert")
  414. if err != nil {
  415. return errors.Wrapf(err, "region.WaitRdsOperation(%s)", operation.SelfLink)
  416. }
  417. return region.rdsGet(resourceId, retval)
  418. }
  419. func (region *SRegion) RdsListAll(resource string, params map[string]string, retval interface{}) error {
  420. return region.client.rdsListAll(resource, params, retval)
  421. }
  422. func (region *SRegion) RdsList(resource string, params map[string]string, maxResults int, pageToken string, retval interface{}) error {
  423. if maxResults == 0 && len(pageToken) == 0 {
  424. return region.RdsListAll(resource, params, retval)
  425. }
  426. if params == nil {
  427. params = map[string]string{}
  428. }
  429. params["maxResults"] = fmt.Sprintf("%d", maxResults)
  430. params["pageToken"] = pageToken
  431. resp, err := region.client.rdsList(resource, params)
  432. if err != nil {
  433. return errors.Wrap(err, "billingList")
  434. }
  435. if resp.Contains("items") && retval != nil {
  436. err = resp.Unmarshal(retval, "items")
  437. if err != nil {
  438. return errors.Wrap(err, "resp.Unmarshal")
  439. }
  440. }
  441. return nil
  442. }
  443. func (region *SRegion) BillingList(resource string, params map[string]string, pageSize int, pageToken string, retval interface{}) error {
  444. if pageSize == 0 && len(pageToken) == 0 {
  445. return region.BillingListAll(resource, params, retval)
  446. }
  447. if params == nil {
  448. params = map[string]string{}
  449. }
  450. params["pageSize"] = fmt.Sprintf("%d", pageSize)
  451. params["pageToken"] = pageToken
  452. resp, err := region.client.billingList(resource, params)
  453. if err != nil {
  454. return errors.Wrap(err, "billingList")
  455. }
  456. if resp.Contains("skus") && retval != nil {
  457. err = resp.Unmarshal(retval, "skus")
  458. if err != nil {
  459. return errors.Wrap(err, "resp.Unmarshal")
  460. }
  461. }
  462. return nil
  463. }
  464. func (region *SRegion) BillingListAll(resource string, params map[string]string, retval interface{}) error {
  465. return region.client.billingListAll(resource, params, retval)
  466. }
  467. func (region *SRegion) ListAll(resource string, params map[string]string, retval interface{}) error {
  468. return region.listAll("GET", resource, params, retval)
  469. }
  470. func (region *SRegion) listAll(method string, resource string, params map[string]string, retval interface{}) error {
  471. return region.client._ecsListAll(method, resource, params, retval)
  472. }
  473. func (region *SRegion) List(resource string, params map[string]string, maxResults int, pageToken string, retval interface{}) error {
  474. if maxResults == 0 && len(pageToken) == 0 {
  475. return region.ListAll(resource, params, retval)
  476. }
  477. if params == nil {
  478. params = map[string]string{}
  479. }
  480. params["maxResults"] = fmt.Sprintf("%d", maxResults)
  481. params["pageToken"] = pageToken
  482. resp, err := region.client.ecsList(resource, params)
  483. if err != nil {
  484. return errors.Wrap(err, "ecsList")
  485. }
  486. if resp.Contains("items") && retval != nil {
  487. err = resp.Unmarshal(retval, "items")
  488. if err != nil {
  489. return errors.Wrap(err, "resp.Unmarshal")
  490. }
  491. }
  492. return nil
  493. }
  494. func (region *SRegion) Get(resourceType, id string, retval interface{}) error {
  495. return region.client.ecsGet(resourceType, id, retval)
  496. }
  497. func (self *SGoogleClient) GetBySelfId(id string, retval interface{}) error {
  498. resp, err := jsonRequest(self.client, "GET", GOOGLE_COMPUTE_DOMAIN, GOOGLE_API_VERSION, id, nil, nil, self.debug)
  499. if err != nil {
  500. return err
  501. }
  502. if retval != nil {
  503. return resp.Unmarshal(retval)
  504. }
  505. return nil
  506. }
  507. func (self *SGoogleClient) PostBySelfId(id string, retval interface{}) error {
  508. resp, err := jsonRequest(self.client, "POST", GOOGLE_COMPUTE_DOMAIN, GOOGLE_API_VERSION, id, nil, nil, self.debug)
  509. if err != nil {
  510. return err
  511. }
  512. if retval != nil {
  513. return resp.Unmarshal(retval)
  514. }
  515. return nil
  516. }
  517. func (self *SRegion) GetBySelfId(id string, retval interface{}) error {
  518. return self.client.GetBySelfId(id, retval)
  519. }
  520. func (self *SRegion) PostBySelfId(id string, retval interface{}) error {
  521. return self.client.PostBySelfId(id, retval)
  522. }
  523. func (region *SRegion) StorageListAll(resource string, params map[string]string, retval interface{}) error {
  524. return region.client.storageListAll(resource, params, retval)
  525. }
  526. func (region *SRegion) StorageList(resource string, params map[string]string, maxResults int, pageToken string, retval interface{}) error {
  527. if maxResults == 0 && len(pageToken) == 0 {
  528. return region.client.storageListAll(resource, params, retval)
  529. }
  530. if params == nil {
  531. params = map[string]string{}
  532. }
  533. params["maxResults"] = fmt.Sprintf("%d", maxResults)
  534. params["pageToken"] = pageToken
  535. resp, err := region.client.storageList(resource, params)
  536. if err != nil {
  537. return errors.Wrap(err, "storageList")
  538. }
  539. if resp.Contains("items") && retval != nil {
  540. err = resp.Unmarshal(retval, "items")
  541. if err != nil {
  542. return errors.Wrap(err, "resp.Unmarshal")
  543. }
  544. }
  545. return nil
  546. }
  547. func (region *SRegion) StorageGet(id string, retval interface{}) error {
  548. return region.client.storageGet(id, retval)
  549. }
  550. func (region *SRegion) StoragePut(id string, body jsonutils.JSONObject, retval interface{}) error {
  551. return region.client.storagePut(id, body, retval)
  552. }
  553. func (region *SRegion) StorageDo(id string, action string, params map[string]string, body jsonutils.JSONObject) error {
  554. opId, err := region.client.storageDo(id, action, params, body)
  555. if err != nil {
  556. return err
  557. }
  558. if strings.Index(opId, "/operations/") > 0 {
  559. _, err = region.client.WaitOperation(opId, id, action)
  560. return err
  561. }
  562. return nil
  563. }
  564. func (region *SRegion) Do(id string, action string, params map[string]string, body jsonutils.JSONObject) error {
  565. opId, err := region.client.ecsDo(id, action, params, body)
  566. if err != nil {
  567. return err
  568. }
  569. if strings.Index(opId, "/operations/") > 0 {
  570. _, err = region.client.WaitOperation(opId, id, action)
  571. return err
  572. }
  573. return nil
  574. }
  575. func (region *SRegion) Patch(id string, action string, params map[string]string, body jsonutils.JSONObject) error {
  576. opId, err := region.client.ecsPatch(id, action, params, body)
  577. if err != nil {
  578. return err
  579. }
  580. if strings.Index(opId, "/operations/") > 0 {
  581. _, err = region.client.WaitOperation(opId, id, action)
  582. return err
  583. }
  584. return nil
  585. }
  586. func (region *SRegion) StorageDelete(id string) error {
  587. return region.client.storageDelete(id, nil)
  588. }
  589. func (region *SRegion) Delete(id string) error {
  590. operation := &SOperation{}
  591. err := region.client.ecsDelete(id, operation)
  592. if err != nil {
  593. return errors.Wrap(err, "client.ecsDelete")
  594. }
  595. _, err = region.client.WaitOperation(operation.SelfLink, id, "delete")
  596. if err != nil {
  597. return errors.Wrapf(err, "region.WaitOperation(%s)", operation.SelfLink)
  598. }
  599. return nil
  600. }
  601. func (region *SRegion) StorageInsert(resource string, body jsonutils.JSONObject, retval interface{}) error {
  602. return region.client.storageInsert(resource, body, retval)
  603. }
  604. func (region *SRegion) CloudbuildInsert(body jsonutils.JSONObject) error {
  605. result := &struct {
  606. Name string
  607. }{}
  608. resource := fmt.Sprintf("projects/%s/builds", region.GetProjectId())
  609. err := region.client.cloudbuildInsert(resource, body, result)
  610. if err != nil {
  611. return errors.Wrap(err, "insert")
  612. }
  613. err = cloudprovider.Wait(time.Second*10, time.Minute*40, func() (bool, error) {
  614. operation, err := region.GetCloudbuildOperation(result.Name)
  615. if err != nil {
  616. return false, errors.Wrapf(err, "region.GetCloudbuildOperation(%s)", result.Name)
  617. }
  618. status := operation.Metadata.Build.Status
  619. log.Debugf("cloudbuild %s status: %s", result.Name, status)
  620. if status == "FAILURE" {
  621. return false, fmt.Errorf("cloudbuild failed error log: %s", operation.Metadata.Build.LogUrl)
  622. }
  623. if status == "SUCCESS" {
  624. return true, nil
  625. }
  626. return false, nil
  627. })
  628. if err != nil {
  629. return errors.Wrap(err, "cloudprovider.Wait")
  630. }
  631. return nil
  632. }
  633. func (region *SRegion) cloudbuildGet(id string, retval interface{}) error {
  634. return region.client.cloudbuildGet(id, retval)
  635. }
  636. func (self *SGoogleClient) Insert(resource string, body jsonutils.JSONObject, retval interface{}) error {
  637. operation := &SOperation{}
  638. err := self.ecsInsert(resource, body, operation)
  639. if err != nil {
  640. return err
  641. }
  642. resourceId, err := self.WaitOperation(operation.SelfLink, resource, "insert")
  643. if err != nil {
  644. return errors.Wrapf(err, "region.WaitOperation(%s)", operation.SelfLink)
  645. }
  646. return self.GetBySelfId(resourceId, retval)
  647. }
  648. func (self *SRegion) Insert(resource string, body jsonutils.JSONObject, retval interface{}) error {
  649. return self.client.Insert(resource, body, retval)
  650. }
  651. func (region *SRegion) fetchResourcePolicies() ([]SResourcePolicy, error) {
  652. if len(region.client.resourcepolices) > 0 {
  653. return region.client.resourcepolices, nil
  654. }
  655. policies, err := region.GetResourcePolicies(0, "")
  656. if err != nil {
  657. return nil, err
  658. }
  659. region.client.resourcepolices = policies
  660. return policies, nil
  661. }
  662. func (region *SRegion) GetISnapshotPolicies() ([]cloudprovider.ICloudSnapshotPolicy, error) {
  663. if utils.IsInStringArray(region.Name, MultiRegions) || utils.IsInStringArray(region.Name, DualRegions) {
  664. return []cloudprovider.ICloudSnapshotPolicy{}, nil
  665. }
  666. policies, err := region.fetchResourcePolicies()
  667. if err != nil {
  668. return nil, err
  669. }
  670. ipolicies := []cloudprovider.ICloudSnapshotPolicy{}
  671. for i := range policies {
  672. policies[i].region = region
  673. if utils.IsInStringArray(region.Name, policies[i].SnapshotSchedulePolicy.SnapshotProperties.StorageLocations) {
  674. ipolicies = append(ipolicies, &policies[i])
  675. }
  676. }
  677. return ipolicies, nil
  678. }
  679. func (region *SRegion) GetISnapshotPolicyById(id string) (cloudprovider.ICloudSnapshotPolicy, error) {
  680. if utils.IsInStringArray(region.Name, MultiRegions) || utils.IsInStringArray(region.Name, DualRegions) {
  681. return nil, cloudprovider.ErrNotFound
  682. }
  683. policy, err := region.GetResourcePolicy(id)
  684. if err != nil {
  685. return nil, err
  686. }
  687. if !strings.Contains(region.Name, policy.SnapshotSchedulePolicy.SnapshotProperties.StorageLocations[0]) {
  688. return nil, cloudprovider.ErrNotFound
  689. }
  690. return policy, nil
  691. }
  692. func (region *SRegion) CreateEIP(args *cloudprovider.SEip) (cloudprovider.ICloudEIP, error) {
  693. if utils.IsInStringArray(region.Name, MultiRegions) || utils.IsInStringArray(region.Name, DualRegions) {
  694. return nil, cloudprovider.ErrNotSupported
  695. }
  696. eip, err := region.CreateEip(args.Name, "")
  697. if err != nil {
  698. return nil, err
  699. }
  700. return eip, nil
  701. }
  702. func (region *SRegion) GetCapabilities() []string {
  703. if utils.IsInStringArray(region.Name, MultiRegions) || utils.IsInStringArray(region.Name, DualRegions) {
  704. return []string{cloudprovider.CLOUD_CAPABILITY_OBJECTSTORE}
  705. }
  706. if region.capabilities == nil {
  707. return region.client.GetCapabilities()
  708. }
  709. return region.capabilities
  710. }
  711. func (region *SRegion) GetIDBInstances() ([]cloudprovider.ICloudDBInstance, error) {
  712. if utils.IsInStringArray(region.Name, MultiRegions) || utils.IsInStringArray(region.Name, DualRegions) {
  713. return []cloudprovider.ICloudDBInstance{}, nil
  714. }
  715. instances, err := region.GetDBInstances(0, "")
  716. if err != nil {
  717. return nil, errors.Wrap(err, "GetDBInstances")
  718. }
  719. ret := []cloudprovider.ICloudDBInstance{}
  720. for i := range instances {
  721. instances[i].region = region
  722. ret = append(ret, &instances[i])
  723. }
  724. return ret, nil
  725. }
  726. func (region *SRegion) GetIDBInstanceById(instanceId string) (cloudprovider.ICloudDBInstance, error) {
  727. if utils.IsInStringArray(region.Name, MultiRegions) || utils.IsInStringArray(region.Name, DualRegions) {
  728. return nil, cloudprovider.ErrNotFound
  729. }
  730. instance, err := region.GetDBInstance(instanceId)
  731. if err != nil {
  732. return nil, errors.Wrapf(err, "GetDBInstance(%s)", instanceId)
  733. }
  734. return instance, nil
  735. }
  736. func (region *SRegion) GetIDBInstanceBackups() ([]cloudprovider.ICloudDBInstanceBackup, error) {
  737. if utils.IsInStringArray(region.Name, MultiRegions) || utils.IsInStringArray(region.Name, DualRegions) {
  738. return []cloudprovider.ICloudDBInstanceBackup{}, nil
  739. }
  740. instances, err := region.GetDBInstances(0, "")
  741. if err != nil {
  742. return nil, errors.Wrap(err, "GetDBInstances")
  743. }
  744. ret := []cloudprovider.ICloudDBInstanceBackup{}
  745. for i := range instances {
  746. instances[i].region = region
  747. backups, err := region.GetDBInstanceBackups(instances[i].Name)
  748. if err != nil {
  749. return nil, errors.Wrapf(err, "GetDBInstanceBackups(%s)", instances[i].Name)
  750. }
  751. for j := range backups {
  752. backups[j].rds = &instances[i]
  753. ret = append(ret, &backups[j])
  754. }
  755. }
  756. return ret, nil
  757. }
  758. func (region *SRegion) GetIDBInstanceBackupById(backupId string) (cloudprovider.ICloudDBInstanceBackup, error) {
  759. if utils.IsInStringArray(region.Name, MultiRegions) || utils.IsInStringArray(region.Name, DualRegions) {
  760. return nil, cloudprovider.ErrNotFound
  761. }
  762. backup, err := region.GetDBInstanceBackup(backupId)
  763. if err != nil {
  764. return nil, errors.Wrapf(err, "GetDBInstanceBackup(%s)", backupId)
  765. }
  766. return backup, nil
  767. }
  768. func (region *SRegion) CreateIDBInstance(desc *cloudprovider.SManagedDBInstanceCreateConfig) (cloudprovider.ICloudDBInstance, error) {
  769. if utils.IsInStringArray(region.Name, MultiRegions) || utils.IsInStringArray(region.Name, DualRegions) {
  770. return nil, cloudprovider.ErrNotSupported
  771. }
  772. rds, err := region.CreateDBInstance(desc)
  773. if err != nil {
  774. return nil, errors.Wrap(err, "CreateDBInstance")
  775. }
  776. return rds, nil
  777. }
  778. func (region *SRegion) GetIVMs() ([]cloudprovider.ICloudVM, error) {
  779. if utils.IsInStringArray(region.Name, MultiRegions) || utils.IsInStringArray(region.Name, DualRegions) {
  780. return []cloudprovider.ICloudVM{}, nil
  781. }
  782. zones, err := region.GetIZones()
  783. if err != nil {
  784. return nil, err
  785. }
  786. ret := []cloudprovider.ICloudVM{}
  787. for i := range zones {
  788. hosts, err := zones[i].GetIHosts()
  789. if err != nil {
  790. return nil, err
  791. }
  792. for j := range hosts {
  793. instances, err := hosts[j].GetIVMs()
  794. if err != nil {
  795. return nil, err
  796. }
  797. ret = append(ret, instances...)
  798. }
  799. }
  800. return ret, nil
  801. }