region.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624
  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 openstack
  15. import (
  16. "fmt"
  17. "io"
  18. "net/url"
  19. "time"
  20. "yunion.io/x/jsonutils"
  21. "yunion.io/x/pkg/errors"
  22. "yunion.io/x/pkg/util/httputils"
  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. multicloud.SRegion
  29. client *SOpenStackClient
  30. Name string
  31. vpcs []SVpc
  32. storageCache *SStoragecache
  33. routers []SRouter
  34. }
  35. func (region *SRegion) GetClient() *SOpenStackClient {
  36. return region.client
  37. }
  38. func (region *SRegion) GetId() string {
  39. return region.Name
  40. }
  41. func (region *SRegion) GetName() string {
  42. return fmt.Sprintf("%s-%s", region.client.cpcfg.Name, region.Name)
  43. }
  44. func (region *SRegion) GetI18n() cloudprovider.SModelI18nTable {
  45. table := cloudprovider.SModelI18nTable{}
  46. table["name"] = cloudprovider.NewSModelI18nEntry(region.GetName()).CN(region.GetName())
  47. return table
  48. }
  49. func (region *SRegion) GetGlobalId() string {
  50. return fmt.Sprintf("%s/%s/%s", CLOUD_PROVIDER_OPENSTACK, region.client.cpcfg.Id, region.Name)
  51. }
  52. func (region *SRegion) IsEmulated() bool {
  53. return false
  54. }
  55. func (region *SRegion) GetProvider() string {
  56. return CLOUD_PROVIDER_OPENSTACK
  57. }
  58. func (region *SRegion) GetCloudEnv() string {
  59. return ""
  60. }
  61. func (region *SRegion) GetGeographicInfo() cloudprovider.SGeographicInfo {
  62. return cloudprovider.SGeographicInfo{}
  63. }
  64. func (region *SRegion) GetStatus() string {
  65. return api.CLOUD_REGION_STATUS_INSERVER
  66. }
  67. func (region *SRegion) Refresh() error {
  68. // do nothing
  69. return nil
  70. }
  71. func (region *SRegion) GetMaxVersion(service string) (string, error) {
  72. return region.client.GetMaxVersion(region.Name, service)
  73. }
  74. func (region *SRegion) CreateIVpc(opts *cloudprovider.VpcCreateOptions) (cloudprovider.ICloudVpc, error) {
  75. vpc, err := region.CreateVpc(opts.NAME, opts.Desc)
  76. if err != nil {
  77. return nil, errors.Wrap(err, "CreateVp")
  78. }
  79. return vpc, nil
  80. }
  81. func (region *SRegion) GetIHostById(id string) (cloudprovider.ICloudHost, error) {
  82. izones, err := region.GetIZones()
  83. if err != nil {
  84. return nil, err
  85. }
  86. for i := 0; i < len(izones); i++ {
  87. ihost, err := izones[i].GetIHostById(id)
  88. if err == nil {
  89. return ihost, nil
  90. } else if errors.Cause(err) != cloudprovider.ErrNotFound {
  91. return nil, err
  92. }
  93. }
  94. return nil, cloudprovider.ErrNotFound
  95. }
  96. func (region *SRegion) GetIStorageById(id string) (cloudprovider.ICloudStorage, error) {
  97. izones, err := region.GetIZones()
  98. if err != nil {
  99. return nil, err
  100. }
  101. for i := 0; i < len(izones); i++ {
  102. istore, err := izones[i].GetIStorageById(id)
  103. if err == nil {
  104. return istore, nil
  105. } else if errors.Cause(err) != cloudprovider.ErrNotFound {
  106. return nil, err
  107. }
  108. }
  109. return nil, cloudprovider.ErrNotFound
  110. }
  111. func (region *SRegion) GetIHosts() ([]cloudprovider.ICloudHost, error) {
  112. iHosts := []cloudprovider.ICloudHost{}
  113. izones, err := region.GetIZones()
  114. if err != nil {
  115. return nil, err
  116. }
  117. for i := 0; i < len(izones); i++ {
  118. iZoneHost, err := izones[i].GetIHosts()
  119. if err != nil {
  120. return nil, err
  121. }
  122. iHosts = append(iHosts, iZoneHost...)
  123. }
  124. return iHosts, nil
  125. }
  126. func (region *SRegion) GetIStorages() ([]cloudprovider.ICloudStorage, error) {
  127. izones, err := region.GetIZones()
  128. if err != nil {
  129. return nil, err
  130. }
  131. iStorages := []cloudprovider.ICloudStorage{}
  132. for i := 0; i < len(izones); i++ {
  133. iZoneStores, err := izones[i].GetIStorages()
  134. if err != nil {
  135. return nil, err
  136. }
  137. iStorages = append(iStorages, iZoneStores...)
  138. }
  139. return iStorages, nil
  140. }
  141. func (region *SRegion) getStoragecache() *SStoragecache {
  142. if region.storageCache == nil {
  143. region.storageCache = &SStoragecache{region: region}
  144. }
  145. return region.storageCache
  146. }
  147. func (region *SRegion) GetIStoragecacheById(id string) (cloudprovider.ICloudStoragecache, error) {
  148. storageCache := region.getStoragecache()
  149. if storageCache.GetGlobalId() == id {
  150. return region.storageCache, nil
  151. }
  152. return nil, cloudprovider.ErrNotFound
  153. }
  154. func (region *SRegion) GetIStoragecaches() ([]cloudprovider.ICloudStoragecache, error) {
  155. storageCache := region.getStoragecache()
  156. return []cloudprovider.ICloudStoragecache{storageCache}, nil
  157. }
  158. func (region *SRegion) GetIVMById(id string) (cloudprovider.ICloudVM, error) {
  159. instance, err := region.GetInstance(id)
  160. if err != nil {
  161. return nil, errors.Wrapf(err, "GetInstance(%s)", id)
  162. }
  163. hosts, err := region.GetIHosts()
  164. if err != nil {
  165. return nil, err
  166. }
  167. for i := range hosts {
  168. host := hosts[i].(*SHypervisor)
  169. if instance.HypervisorHostname == host.HypervisorHostname {
  170. instance.host = host
  171. }
  172. }
  173. return instance, nil
  174. }
  175. func (region *SRegion) GetIDiskById(id string) (cloudprovider.ICloudDisk, error) {
  176. disk, err := region.GetDisk(id)
  177. if err != nil {
  178. _, err := region.GetInstance(id)
  179. if err == nil {
  180. return &SNovaDisk{region: region, instanceId: id}, nil
  181. }
  182. return nil, errors.Wrapf(err, "GetDisk(%s)", id)
  183. }
  184. return disk, nil
  185. }
  186. func (region *SRegion) GetIVpcById(id string) (cloudprovider.ICloudVpc, error) {
  187. vpc, err := region.GetVpc(id)
  188. if err != nil {
  189. return nil, errors.Wrapf(err, "GetVpc(%s)", id)
  190. }
  191. return vpc, nil
  192. }
  193. func (region *SRegion) GetIZoneById(id string) (cloudprovider.ICloudZone, error) {
  194. izones, err := region.GetIZones()
  195. if err != nil {
  196. return nil, errors.Wrap(err, "GetIZones")
  197. }
  198. for i := 0; i < len(izones); i++ {
  199. if izones[i].GetGlobalId() == id {
  200. return izones[i], nil
  201. }
  202. }
  203. return nil, cloudprovider.ErrNotFound
  204. }
  205. func (region *SRegion) GetZones() ([]SZone, error) {
  206. zones, err := region.getZones()
  207. if err != nil {
  208. return nil, errors.Wrap(err, "getZones")
  209. }
  210. ret := []SZone{}
  211. for i := 0; i < len(zones); i++ {
  212. if zones[i].ZoneName == "internal" {
  213. continue
  214. }
  215. zones[i].region = region
  216. ret = append(ret, zones[i])
  217. }
  218. return ret, nil
  219. }
  220. func (region *SRegion) fetchVpcs() error {
  221. if len(region.vpcs) > 0 {
  222. return nil
  223. }
  224. var err error
  225. region.vpcs, err = region.GetVpcs("")
  226. if err != nil {
  227. return errors.Wrap(err, "GetVpcs")
  228. }
  229. return nil
  230. }
  231. func (region *SRegion) ecsList(resource string, query url.Values) (jsonutils.JSONObject, error) {
  232. return region.client.ecsRequest(region.Name, httputils.GET, resource, query, nil)
  233. }
  234. func (region *SRegion) ecsGet(resource string) (jsonutils.JSONObject, error) {
  235. return region.client.ecsRequest(region.Name, httputils.GET, resource, nil, nil)
  236. }
  237. func (region *SRegion) ecsUpdate(resource string, params interface{}) (jsonutils.JSONObject, error) {
  238. return region.client.ecsRequest(region.Name, httputils.PUT, resource, nil, params)
  239. }
  240. func (region *SRegion) ecsPost(resource string, params interface{}) (jsonutils.JSONObject, error) {
  241. return region.client.ecsRequest(region.Name, httputils.POST, resource, nil, params)
  242. }
  243. func (region *SRegion) ecsDo(projectId, resource string, params interface{}) (jsonutils.JSONObject, error) {
  244. return region.client.ecsDo(projectId, region.Name, resource, params)
  245. }
  246. func (region *SRegion) ecsDelete(resource string) (jsonutils.JSONObject, error) {
  247. return region.client.ecsRequest(region.Name, httputils.DELETE, resource, nil, nil)
  248. }
  249. func (region *SRegion) ecsCreate(projectId, resource string, params interface{}) (jsonutils.JSONObject, error) {
  250. return region.client.ecsCreate(projectId, region.Name, resource, params)
  251. }
  252. func (region *SRegion) vpcList(resource string, query url.Values) (jsonutils.JSONObject, error) {
  253. return region.client.vpcRequest(region.Name, httputils.GET, resource, query, nil)
  254. }
  255. func (region *SRegion) vpcGet(resource string) (jsonutils.JSONObject, error) {
  256. return region.client.vpcRequest(region.Name, httputils.GET, resource, nil, nil)
  257. }
  258. func (region *SRegion) vpcUpdate(resource string, params interface{}) (jsonutils.JSONObject, error) {
  259. return region.client.vpcRequest(region.Name, httputils.PUT, resource, nil, params)
  260. }
  261. func (region *SRegion) vpcPost(resource string, params interface{}) (jsonutils.JSONObject, error) {
  262. return region.client.vpcRequest(region.Name, httputils.POST, resource, nil, params)
  263. }
  264. func (region *SRegion) vpcDelete(resource string) (jsonutils.JSONObject, error) {
  265. return region.client.vpcRequest(region.Name, httputils.DELETE, resource, nil, nil)
  266. }
  267. func (region *SRegion) imageList(resource string, query url.Values) (jsonutils.JSONObject, error) {
  268. return region.client.imageRequest(region.Name, httputils.GET, resource, query, nil)
  269. }
  270. func (region *SRegion) imageGet(resource string) (jsonutils.JSONObject, error) {
  271. return region.client.imageRequest(region.Name, httputils.GET, resource, nil, nil)
  272. }
  273. func (region *SRegion) imagePost(resource string, params interface{}) (jsonutils.JSONObject, error) {
  274. return region.client.imageRequest(region.Name, httputils.POST, resource, nil, params)
  275. }
  276. func (region *SRegion) imageDelete(resource string) (jsonutils.JSONObject, error) {
  277. return region.client.imageRequest(region.Name, httputils.DELETE, resource, nil, nil)
  278. }
  279. func (region *SRegion) imageUpload(url string, size int64, body io.Reader, callback func(progress float32)) error {
  280. resp, err := region.client.imageUpload(region.Name, url, size, body, callback)
  281. _, _, err = httputils.ParseResponse("", resp, err, region.client.debug)
  282. return err
  283. }
  284. // Block Storage
  285. func (region *SRegion) bsList(resource string, query url.Values) (jsonutils.JSONObject, error) {
  286. return region.client.bsRequest(region.Name, httputils.GET, resource, query, nil)
  287. }
  288. func (region *SRegion) bsGet(resource string) (jsonutils.JSONObject, error) {
  289. return region.client.bsRequest(region.Name, httputils.GET, resource, nil, nil)
  290. }
  291. func (region *SRegion) bsUpdate(resource string, params interface{}) (jsonutils.JSONObject, error) {
  292. return region.client.bsRequest(region.Name, httputils.PUT, resource, nil, params)
  293. }
  294. func (region *SRegion) bsPost(resource string, params interface{}) (jsonutils.JSONObject, error) {
  295. return region.client.bsRequest(region.Name, httputils.POST, resource, nil, params)
  296. }
  297. func (region *SRegion) bsDelete(resource string) (jsonutils.JSONObject, error) {
  298. return region.client.bsRequest(region.Name, httputils.DELETE, resource, nil, nil)
  299. }
  300. func (region *SRegion) bsCreate(projectId, resource string, params interface{}) (jsonutils.JSONObject, error) {
  301. return region.client.bsCreate(projectId, region.Name, resource, params)
  302. }
  303. //loadbalancer
  304. func (region *SRegion) lbList(resource string, query url.Values) (jsonutils.JSONObject, error) {
  305. return region.client.lbRequest(region.Name, httputils.GET, resource, query, nil)
  306. }
  307. func (region *SRegion) lbGet(resource string) (jsonutils.JSONObject, error) {
  308. return region.client.lbRequest(region.Name, httputils.GET, resource, nil, nil)
  309. }
  310. func (region *SRegion) lbUpdate(resource string, params interface{}) (jsonutils.JSONObject, error) {
  311. return region.client.lbRequest(region.Name, httputils.PUT, resource, nil, params)
  312. }
  313. func (region *SRegion) lbPost(resource string, params interface{}) (jsonutils.JSONObject, error) {
  314. return region.client.lbRequest(region.Name, httputils.POST, resource, nil, params)
  315. }
  316. func (region *SRegion) lbDelete(resource string) (jsonutils.JSONObject, error) {
  317. return region.client.lbRequest(region.Name, httputils.DELETE, resource, nil, nil)
  318. }
  319. func (region *SRegion) ProjectId() string {
  320. return region.client.tokenCredential.GetProjectId()
  321. }
  322. func (region *SRegion) GetIZones() ([]cloudprovider.ICloudZone, error) {
  323. zones, err := region.GetZones()
  324. if err != nil {
  325. return nil, errors.Wrapf(err, "GetZones")
  326. }
  327. ret := []cloudprovider.ICloudZone{}
  328. for i := range zones {
  329. ret = append(ret, &zones[i])
  330. }
  331. return ret, nil
  332. }
  333. func (region *SRegion) GetIVpcs() ([]cloudprovider.ICloudVpc, error) {
  334. err := region.fetchVpcs()
  335. if err != nil {
  336. return nil, errors.Wrap(err, "fetchVpcs")
  337. }
  338. ivpcs := []cloudprovider.ICloudVpc{}
  339. for i := range region.vpcs {
  340. region.vpcs[i].region = region
  341. ivpcs = append(ivpcs, &region.vpcs[i])
  342. }
  343. return ivpcs, nil
  344. }
  345. func (region *SRegion) GetIEips() ([]cloudprovider.ICloudEIP, error) {
  346. eips, err := region.GetEips("")
  347. if err != nil {
  348. return nil, err
  349. }
  350. ieips := []cloudprovider.ICloudEIP{}
  351. for i := 0; i < len(eips); i++ {
  352. eips[i].region = region
  353. ieips = append(ieips, &eips[i])
  354. }
  355. return ieips, nil
  356. }
  357. func (region *SRegion) CreateEIP(eip *cloudprovider.SEip) (cloudprovider.ICloudEIP, error) {
  358. network, err := region.GetNetwork(eip.NetworkExternalId)
  359. if err != nil {
  360. return nil, errors.Wrapf(err, "GetNetwork(%s)", eip.NetworkExternalId)
  361. }
  362. ieip, err := region.CreateEip(network.NetworkId, eip.NetworkExternalId, eip.Ip, eip.ProjectId)
  363. if err != nil {
  364. return nil, errors.Wrap(err, "CreateEip")
  365. }
  366. return ieip, nil
  367. }
  368. func (region *SRegion) GetIEipById(eipId string) (cloudprovider.ICloudEIP, error) {
  369. return region.GetEip(eipId)
  370. }
  371. func (region *SRegion) GetILoadBalancers() ([]cloudprovider.ICloudLoadbalancer, error) {
  372. loadbalancers := []cloudprovider.ICloudLoadbalancer{}
  373. sloadbalancers, err := region.GetLoadbalancers()
  374. if err != nil {
  375. return nil, errors.Wrap(err, "region.GetLoadbalancers()")
  376. }
  377. for i := 0; i < len(sloadbalancers); i++ {
  378. loadbalancers = append(loadbalancers, &sloadbalancers[i])
  379. }
  380. return loadbalancers, nil
  381. }
  382. func (region *SRegion) GetILoadBalancerById(loadbalancerId string) (cloudprovider.ICloudLoadbalancer, error) {
  383. sloadbalancer, err := region.GetLoadbalancerbyId(loadbalancerId)
  384. if err != nil {
  385. return nil, errors.Wrapf(err, "region.GetLoadbalancerbyId(%s)", loadbalancerId)
  386. }
  387. return sloadbalancer, nil
  388. }
  389. func (region *SRegion) GetILoadBalancerAclById(aclId string) (cloudprovider.ICloudLoadbalancerAcl, error) {
  390. return region.GetLoadbalancerAclDetail(aclId)
  391. }
  392. func (region *SRegion) GetILoadBalancerCertificateById(certId string) (cloudprovider.ICloudLoadbalancerCertificate, error) {
  393. return nil, cloudprovider.ErrNotImplemented
  394. }
  395. func (region *SRegion) CreateILoadBalancerCertificate(cert *cloudprovider.SLoadbalancerCertificate) (cloudprovider.ICloudLoadbalancerCertificate, error) {
  396. return nil, cloudprovider.ErrNotImplemented
  397. }
  398. func (region *SRegion) GetILoadBalancerAcls() ([]cloudprovider.ICloudLoadbalancerAcl, error) {
  399. iloadbalancerAcls := []cloudprovider.ICloudLoadbalancerAcl{}
  400. acls, err := region.GetLoadBalancerAcls()
  401. if err != nil {
  402. return nil, errors.Wrap(err, "region.GetLoadBalancerAcls")
  403. }
  404. for i := 0; i < len(acls); i++ {
  405. iloadbalancerAcls = append(iloadbalancerAcls, &acls[i])
  406. }
  407. return iloadbalancerAcls, nil
  408. }
  409. func (region *SRegion) GetILoadBalancerCertificates() ([]cloudprovider.ICloudLoadbalancerCertificate, error) {
  410. return nil, cloudprovider.ErrNotImplemented
  411. }
  412. func (region *SRegion) CreateILoadBalancer(loadbalancer *cloudprovider.SLoadbalancerCreateOptions) (cloudprovider.ICloudLoadbalancer, error) {
  413. sloadbalancer, err := region.CreateLoadBalancer(loadbalancer)
  414. if err != nil {
  415. return nil, errors.Wrap(err, "region.CreateLoadBalancer")
  416. }
  417. return sloadbalancer, nil
  418. }
  419. func (region *SRegion) CreateILoadBalancerAcl(acl *cloudprovider.SLoadbalancerAccessControlList) (cloudprovider.ICloudLoadbalancerAcl, error) {
  420. sacl, err := region.CreateLoadBalancerAcl(acl)
  421. if err != nil {
  422. return nil, errors.Wrap(err, "region.CreateLoadBalancerAcl(acl)")
  423. }
  424. err = cloudprovider.WaitMultiStatus(sacl.listener, []string{api.LB_STATUS_ENABLED, api.LB_STATUS_UNKNOWN}, 10*time.Second, 8*time.Minute)
  425. if err != nil {
  426. return nil, errors.Wrap(err, "cloudprovider.WaitMultiStatus")
  427. }
  428. if sacl.listener.GetStatus() == api.LB_STATUS_UNKNOWN {
  429. return nil, errors.Wrap(fmt.Errorf("status error"), "check status")
  430. }
  431. return sacl, nil
  432. }
  433. func (region *SRegion) GetISkus() ([]cloudprovider.ICloudSku, error) {
  434. flavors, err := region.GetFlavors()
  435. if err != nil {
  436. return nil, err
  437. }
  438. iskus := make([]cloudprovider.ICloudSku, len(flavors))
  439. for i := 0; i < len(flavors); i++ {
  440. flavors[i].region = region
  441. iskus[i] = &flavors[i]
  442. }
  443. return iskus, nil
  444. }
  445. func (region *SRegion) GetIBuckets() ([]cloudprovider.ICloudBucket, error) {
  446. return nil, cloudprovider.ErrNotImplemented
  447. }
  448. func (region *SRegion) CreateIBucket(name string, storageClassStr string, acl string) error {
  449. return cloudprovider.ErrNotImplemented
  450. }
  451. func (region *SRegion) DeleteIBucket(name string) error {
  452. return cloudprovider.ErrNotImplemented
  453. }
  454. func (region *SRegion) IBucketExist(name string) (bool, error) {
  455. return false, cloudprovider.ErrNotImplemented
  456. }
  457. func (region *SRegion) GetIBucketById(name string) (cloudprovider.ICloudBucket, error) {
  458. return nil, cloudprovider.ErrNotImplemented
  459. }
  460. func (region *SRegion) GetIBucketByName(name string) (cloudprovider.ICloudBucket, error) {
  461. return nil, cloudprovider.ErrNotImplemented
  462. }
  463. func (region *SRegion) GetISecurityGroupById(secgroupId string) (cloudprovider.ICloudSecurityGroup, error) {
  464. return region.GetSecurityGroup(secgroupId)
  465. }
  466. func (region *SRegion) GetISecurityGroups() ([]cloudprovider.ICloudSecurityGroup, error) {
  467. err := region.client.fetchProjects()
  468. if err != nil {
  469. return nil, errors.Wrap(err, "fetchProjects")
  470. }
  471. iSecgroups := []cloudprovider.ICloudSecurityGroup{}
  472. for _, project := range region.client.projects {
  473. secgroups, err := region.GetSecurityGroups(project.Id, "")
  474. if err != nil {
  475. return nil, errors.Wrapf(err, "GetSecurityGroups(%s)", project.Id)
  476. }
  477. for i := 0; i < len(secgroups); i++ {
  478. secgroups[i].region = region
  479. iSecgroups = append(iSecgroups, &secgroups[i])
  480. }
  481. }
  482. return iSecgroups, nil
  483. }
  484. func (region *SRegion) CreateISecurityGroup(opts *cloudprovider.SecurityGroupCreateInput) (cloudprovider.ICloudSecurityGroup, error) {
  485. return region.CreateSecurityGroup(opts)
  486. }
  487. func (region *SRegion) GetCapabilities() []string {
  488. return region.client.GetCapabilities()
  489. }
  490. func (region *SRegion) GetRouters() ([]SRouter, error) {
  491. resource := "/v2.0/routers"
  492. resp, err := region.vpcList(resource, nil)
  493. if err != nil {
  494. return nil, errors.Wrap(err, "vpcList.routes")
  495. }
  496. routers := []SRouter{}
  497. err = resp.Unmarshal(&routers, "routers")
  498. if err != nil {
  499. return nil, errors.Wrap(err, "resp.Unmarshal")
  500. }
  501. for i := 0; i < len(routers); i++ {
  502. ports, err := region.GetPorts("", routers[i].Id)
  503. if err != nil {
  504. return nil, errors.Wrap(err, "vpc.region.GetPortsByDeviceId")
  505. }
  506. routers[i].ports = ports
  507. }
  508. return routers, nil
  509. }
  510. func (region *SRegion) fetchrouters() error {
  511. if len(region.routers) > 0 {
  512. return nil
  513. }
  514. routers, err := region.GetRouters()
  515. if err != nil {
  516. return errors.Wrap(err, "region.GetRouters()")
  517. }
  518. region.routers = routers
  519. return nil
  520. }
  521. func (region *SRegion) GetIVMs() ([]cloudprovider.ICloudVM, error) {
  522. vms, err := region.GetInstances("")
  523. if err != nil {
  524. return nil, errors.Wrapf(err, "GetInstances")
  525. }
  526. ret := []cloudprovider.ICloudVM{}
  527. for i := range vms {
  528. ret = append(ret, &vms[i])
  529. }
  530. return ret, nil
  531. }