region.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  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 ctyun
  15. import (
  16. "fmt"
  17. "strings"
  18. "yunion.io/x/jsonutils"
  19. "yunion.io/x/pkg/errors"
  20. "yunion.io/x/pkg/gotypes"
  21. "yunion.io/x/pkg/utils"
  22. api "yunion.io/x/cloudmux/pkg/apis/compute"
  23. "yunion.io/x/cloudmux/pkg/cloudprovider"
  24. "yunion.io/x/cloudmux/pkg/multicloud"
  25. )
  26. type SRegion struct {
  27. multicloud.SRegion
  28. multicloud.SNoLbRegion
  29. multicloud.SNoObjectStorageRegion
  30. client *SCtyunClient
  31. product *SProduct
  32. IsMultiZones bool
  33. OpenapiAvailable bool
  34. RegionParent string
  35. RegionId string
  36. RegionCode string
  37. RegionType string
  38. ZoneList []string
  39. RegionName string
  40. }
  41. func (self *SRegion) list(service, res string, params map[string]interface{}) (jsonutils.JSONObject, error) {
  42. if gotypes.IsNil(params) {
  43. params = map[string]interface{}{}
  44. }
  45. params["regionID"] = self.RegionId
  46. return self.client.list(service, res, params)
  47. }
  48. func (self *SRegion) post(service, res string, params map[string]interface{}) (jsonutils.JSONObject, error) {
  49. if gotypes.IsNil(params) {
  50. params = map[string]interface{}{}
  51. }
  52. params["regionID"] = self.RegionId
  53. return self.client.post(service, res, params)
  54. }
  55. func (self *SRegion) CreateVpc(opts *cloudprovider.VpcCreateOptions) (*SVpc, error) {
  56. params := map[string]interface{}{
  57. "clientToken": utils.GenRequestId(20),
  58. "name": opts.NAME,
  59. "description": opts.Desc,
  60. "CIDR": opts.CIDR,
  61. }
  62. resp, err := self.post(SERVICE_VPC, "/v4/vpc/create", params)
  63. if err != nil {
  64. return nil, err
  65. }
  66. vpcId, err := resp.GetString("returnObj", "vpcID")
  67. if err != nil {
  68. return nil, errors.Wrapf(err, "get vpcID")
  69. }
  70. return self.GetVpc(vpcId)
  71. }
  72. func (self *SRegion) GetClient() *SCtyunClient {
  73. return self.client
  74. }
  75. func (self *SRegion) GetCloudEnv() string {
  76. return api.CLOUD_PROVIDER_CTYUN
  77. }
  78. func (self *SRegion) GetISecurityGroups() ([]cloudprovider.ICloudSecurityGroup, error) {
  79. secgroups, err := self.GetSecurityGroups()
  80. if err != nil {
  81. return nil, err
  82. }
  83. ret := []cloudprovider.ICloudSecurityGroup{}
  84. for i := range secgroups {
  85. secgroups[i].region = self
  86. ret = append(ret, &secgroups[i])
  87. }
  88. return ret, nil
  89. }
  90. func (self *SRegion) GetISecurityGroupById(secgroupId string) (cloudprovider.ICloudSecurityGroup, error) {
  91. sec, err := self.GetSecurityGroup(secgroupId)
  92. if err != nil {
  93. return nil, err
  94. }
  95. return sec, nil
  96. }
  97. func (self *SRegion) CreateISecurityGroup(opts *cloudprovider.SecurityGroupCreateInput) (cloudprovider.ICloudSecurityGroup, error) {
  98. secgroup, err := self.CreateSecurityGroup(opts)
  99. if err != nil {
  100. return nil, errors.Wrap(err, "CreateISecurityGroup")
  101. }
  102. return secgroup, nil
  103. }
  104. func (self *SRegion) GetId() string {
  105. if len(self.RegionCode) > 0 {
  106. return self.RegionCode
  107. }
  108. return self.RegionId
  109. }
  110. func (self *SRegion) GetName() string {
  111. return fmt.Sprintf("%s %s", CLOUD_PROVIDER_CTYUN_CN, self.RegionName)
  112. }
  113. func (self *SRegion) GetI18n() cloudprovider.SModelI18nTable {
  114. en := fmt.Sprintf("%s %s", CLOUD_PROVIDER_CTYUN_EN, self.RegionName)
  115. table := cloudprovider.SModelI18nTable{}
  116. table["name"] = cloudprovider.NewSModelI18nEntry(self.GetName()).CN(self.GetName()).EN(en)
  117. return table
  118. }
  119. func (self *SRegion) GetGlobalId() string {
  120. return fmt.Sprintf("%s/%s", self.client.GetAccessEnv(), self.GetId())
  121. }
  122. func (self *SRegion) GetStatus() string {
  123. if !self.OpenapiAvailable {
  124. return api.CLOUD_REGION_STATUS_OUTOFSERVICE
  125. }
  126. return api.CLOUD_REGION_STATUS_INSERVER
  127. }
  128. func (self *SRegion) GetGeographicInfo() cloudprovider.SGeographicInfo {
  129. id := self.GetId()
  130. if info, ok := LatitudeAndLongitude[id]; ok {
  131. return info
  132. }
  133. return cloudprovider.SGeographicInfo{}
  134. }
  135. func (self *SRegion) getDefaultZone() *SZone {
  136. return &SZone{
  137. region: self,
  138. AzDisplayName: "默认可用区",
  139. Name: "default",
  140. }
  141. }
  142. func (self *SRegion) GetIZones() ([]cloudprovider.ICloudZone, error) {
  143. zones, err := self.GetZones()
  144. if err != nil {
  145. return nil, err
  146. }
  147. ret := []cloudprovider.ICloudZone{}
  148. for i := range zones {
  149. zones[i].region = self
  150. ret = append(ret, &zones[i])
  151. }
  152. if len(ret) == 0 {
  153. ret = append(ret, self.getDefaultZone())
  154. }
  155. return ret, nil
  156. }
  157. func (self *SRegion) GetIVpcs() ([]cloudprovider.ICloudVpc, error) {
  158. vpcs, err := self.GetVpcs()
  159. if err != nil {
  160. return nil, err
  161. }
  162. ret := []cloudprovider.ICloudVpc{}
  163. for i := range vpcs {
  164. vpcs[i].region = self
  165. ret = append(ret, &vpcs[i])
  166. }
  167. return ret, nil
  168. }
  169. func (self *SRegion) GetIEips() ([]cloudprovider.ICloudEIP, error) {
  170. eips, err := self.GetEips("")
  171. if err != nil {
  172. return nil, errors.Wrap(err, "SRegion.GetIEips.GetEips")
  173. }
  174. ret := []cloudprovider.ICloudEIP{}
  175. for i := range eips {
  176. eips[i].region = self
  177. ret = append(ret, &eips[i])
  178. }
  179. return ret, nil
  180. }
  181. func (self *SRegion) GetIVpcById(id string) (cloudprovider.ICloudVpc, error) {
  182. ivpcs, err := self.GetIVpcs()
  183. if err != nil {
  184. return nil, err
  185. }
  186. for i := 0; i < len(ivpcs); i += 1 {
  187. if ivpcs[i].GetGlobalId() == id {
  188. return ivpcs[i], nil
  189. }
  190. }
  191. return nil, errors.Wrapf(cloudprovider.ErrNotFound, "%s", id)
  192. }
  193. func (self *SRegion) GetIZoneById(id string) (cloudprovider.ICloudZone, error) {
  194. izones, err := self.GetIZones()
  195. if err != nil {
  196. return nil, err
  197. }
  198. for i := 0; i < len(izones); i += 1 {
  199. if izones[i].GetGlobalId() == id {
  200. return izones[i], nil
  201. }
  202. }
  203. return nil, cloudprovider.ErrNotFound
  204. }
  205. func (self *SRegion) GetIEipById(id string) (cloudprovider.ICloudEIP, error) {
  206. eip, err := self.GetEip(id)
  207. if err != nil {
  208. return nil, err
  209. }
  210. return eip, nil
  211. }
  212. func (self *SRegion) GetIVMById(id string) (cloudprovider.ICloudVM, error) {
  213. vm, err := self.GetInstance(id)
  214. if err != nil {
  215. return nil, err
  216. }
  217. return vm, nil
  218. }
  219. func (self *SRegion) GetIDiskById(id string) (cloudprovider.ICloudDisk, error) {
  220. disk, err := self.GetDisk(id)
  221. if err != nil {
  222. return nil, err
  223. }
  224. return disk, nil
  225. }
  226. func (self *SRegion) CreateIVpc(opts *cloudprovider.VpcCreateOptions) (cloudprovider.ICloudVpc, error) {
  227. vpc, err := self.CreateVpc(opts)
  228. if err != nil {
  229. return nil, err
  230. }
  231. return vpc, nil
  232. }
  233. func (self *SRegion) CreateEIP(opts *cloudprovider.SEip) (cloudprovider.ICloudEIP, error) {
  234. eip, err := self.CreateEip(opts)
  235. if err != nil {
  236. return nil, err
  237. }
  238. return eip, nil
  239. }
  240. func (self *SRegion) GetISnapshots() ([]cloudprovider.ICloudSnapshot, error) {
  241. return []cloudprovider.ICloudSnapshot{}, nil
  242. }
  243. func (self *SRegion) GetISnapshotById(snapshotId string) (cloudprovider.ICloudSnapshot, error) {
  244. return nil, cloudprovider.ErrNotFound
  245. }
  246. func (self *SRegion) GetIHosts() ([]cloudprovider.ICloudHost, error) {
  247. iHosts := make([]cloudprovider.ICloudHost, 0)
  248. izones, err := self.GetIZones()
  249. if err != nil {
  250. return nil, err
  251. }
  252. for i := 0; i < len(izones); i += 1 {
  253. iZoneHost, err := izones[i].GetIHosts()
  254. if err != nil {
  255. return nil, err
  256. }
  257. iHosts = append(iHosts, iZoneHost...)
  258. }
  259. return iHosts, nil
  260. }
  261. func (self *SRegion) GetIHostById(id string) (cloudprovider.ICloudHost, error) {
  262. izones, err := self.GetIZones()
  263. if err != nil {
  264. return nil, err
  265. }
  266. for i := 0; i < len(izones); i += 1 {
  267. ihost, err := izones[i].GetIHostById(id)
  268. if err == nil {
  269. return ihost, nil
  270. } else if errors.Cause(err) != cloudprovider.ErrNotFound {
  271. return nil, err
  272. }
  273. }
  274. return nil, cloudprovider.ErrNotFound
  275. }
  276. func (self *SRegion) GetIStorages() ([]cloudprovider.ICloudStorage, error) {
  277. iStores := make([]cloudprovider.ICloudStorage, 0)
  278. izones, err := self.GetIZones()
  279. if err != nil {
  280. return nil, err
  281. }
  282. for i := 0; i < len(izones); i += 1 {
  283. iZoneStores, err := izones[i].GetIStorages()
  284. if err != nil {
  285. return nil, err
  286. }
  287. iStores = append(iStores, iZoneStores...)
  288. }
  289. return iStores, nil
  290. }
  291. func (self *SRegion) GetIStorageById(id string) (cloudprovider.ICloudStorage, error) {
  292. izones, err := self.GetIZones()
  293. if err != nil {
  294. return nil, err
  295. }
  296. for i := 0; i < len(izones); i += 1 {
  297. istore, err := izones[i].GetIStorageById(id)
  298. if err == nil {
  299. return istore, nil
  300. } else if errors.Cause(err) != cloudprovider.ErrNotFound {
  301. return nil, err
  302. }
  303. }
  304. return nil, cloudprovider.ErrNotFound
  305. }
  306. func (self *SRegion) GetIStoragecaches() ([]cloudprovider.ICloudStoragecache, error) {
  307. storageCache := self.getStoragecache()
  308. return []cloudprovider.ICloudStoragecache{storageCache}, nil
  309. }
  310. func (self *SRegion) GetIStoragecacheById(id string) (cloudprovider.ICloudStoragecache, error) {
  311. storageCache := self.getStoragecache()
  312. if storageCache.GetGlobalId() == id {
  313. return storageCache, nil
  314. }
  315. return nil, cloudprovider.ErrNotFound
  316. }
  317. func (self *SRegion) GetProvider() string {
  318. return api.CLOUD_PROVIDER_CTYUN
  319. }
  320. func (self *SRegion) GetInstance(id string) (*SInstance, error) {
  321. vms, err := self.GetInstances("", []string{id})
  322. if err != nil {
  323. return nil, err
  324. }
  325. for i := range vms {
  326. if vms[i].GetGlobalId() == id {
  327. return &vms[i], nil
  328. }
  329. }
  330. return nil, errors.Wrapf(cloudprovider.ErrNotFound, "%s", id)
  331. }
  332. func (self *SRegion) GetInstances(zoneId string, ids []string) ([]SInstance, error) {
  333. pageNo := 1
  334. params := map[string]interface{}{
  335. "pageNo": pageNo,
  336. "pageSize": 50,
  337. }
  338. if len(ids) > 0 {
  339. params["instanceIDList"] = strings.Join(ids, ",")
  340. }
  341. if len(zoneId) > 0 {
  342. params["azName"] = zoneId
  343. }
  344. ret := []SInstance{}
  345. for {
  346. resp, err := self.post(SERVICE_ECS, "/v4/ecs/list-instances", params)
  347. if err != nil {
  348. return nil, err
  349. }
  350. part := struct {
  351. ReturnObj struct {
  352. Results []SInstance
  353. }
  354. TotalCount int
  355. }{}
  356. err = resp.Unmarshal(&part)
  357. if err != nil {
  358. return nil, err
  359. }
  360. ret = append(ret, part.ReturnObj.Results...)
  361. if len(ret) >= part.TotalCount || len(part.ReturnObj.Results) == 0 {
  362. break
  363. }
  364. pageNo++
  365. params["pageNo"] = pageNo
  366. }
  367. return ret, nil
  368. }
  369. func (region *SRegion) GetCapabilities() []string {
  370. return region.client.GetCapabilities()
  371. }
  372. func (region *SRegion) GetIVMs() ([]cloudprovider.ICloudVM, error) {
  373. vms, err := region.GetInstances("", nil)
  374. if err != nil {
  375. return nil, err
  376. }
  377. ret := []cloudprovider.ICloudVM{}
  378. for i := range vms {
  379. ret = append(ret, &vms[i])
  380. }
  381. return ret, nil
  382. }