region.go 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  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 zstack
  15. import (
  16. "fmt"
  17. "net/url"
  18. "strings"
  19. "yunion.io/x/log"
  20. "yunion.io/x/pkg/errors"
  21. api "yunion.io/x/cloudmux/pkg/apis/compute"
  22. "yunion.io/x/cloudmux/pkg/cloudprovider"
  23. "yunion.io/x/cloudmux/pkg/multicloud"
  24. )
  25. type SRegion struct {
  26. multicloud.SRegion
  27. multicloud.SNoLbRegion
  28. multicloud.SNoObjectStorageRegion
  29. client *SZStackClient
  30. Name string
  31. izones []cloudprovider.ICloudZone
  32. ivpcs []cloudprovider.ICloudVpc
  33. }
  34. func (region *SRegion) GetClient() *SZStackClient {
  35. return region.client
  36. }
  37. func (region *SRegion) GetId() string {
  38. return region.Name
  39. }
  40. func (region *SRegion) GetName() string {
  41. return region.client.cpcfg.Name
  42. }
  43. func (region *SRegion) GetI18n() cloudprovider.SModelI18nTable {
  44. table := cloudprovider.SModelI18nTable{}
  45. table["name"] = cloudprovider.NewSModelI18nEntry(region.GetName()).CN(region.GetName())
  46. return table
  47. }
  48. func (region *SRegion) GetGlobalId() string {
  49. return fmt.Sprintf("%s/%s", CLOUD_PROVIDER_ZSTACK, region.client.cpcfg.Id)
  50. }
  51. func (region *SRegion) IsEmulated() bool {
  52. return false
  53. }
  54. func (region *SRegion) GetProvider() string {
  55. return CLOUD_PROVIDER_ZSTACK
  56. }
  57. func (region *SRegion) GetCloudEnv() string {
  58. return ""
  59. }
  60. func (region *SRegion) GetGeographicInfo() cloudprovider.SGeographicInfo {
  61. return cloudprovider.SGeographicInfo{}
  62. }
  63. func (region *SRegion) GetStatus() string {
  64. return api.CLOUD_REGION_STATUS_INSERVER
  65. }
  66. func (region *SRegion) Refresh() error {
  67. // do nothing
  68. return nil
  69. }
  70. func (self *SRegion) GetIVMById(id string) (cloudprovider.ICloudVM, error) {
  71. vm, err := self.GetInstance(id)
  72. if err != nil {
  73. return nil, err
  74. }
  75. return vm, nil
  76. }
  77. func (self *SRegion) GetIDiskById(id string) (cloudprovider.ICloudDisk, error) {
  78. disk, err := self.GetDisk(id)
  79. if err != nil {
  80. return nil, err
  81. }
  82. return disk, nil
  83. }
  84. func (region *SRegion) GetIHostById(id string) (cloudprovider.ICloudHost, error) {
  85. return region.GetHost(id)
  86. }
  87. func (region *SRegion) GetIStorageById(id string) (cloudprovider.ICloudStorage, error) {
  88. storages, err := region.getIStorages("")
  89. if err != nil {
  90. return nil, err
  91. }
  92. for i := 0; i < len(storages); i++ {
  93. if storages[i].GetGlobalId() == id {
  94. return storages[i], nil
  95. }
  96. }
  97. return nil, cloudprovider.ErrNotFound
  98. }
  99. func (region *SRegion) GetIHosts() ([]cloudprovider.ICloudHost, error) {
  100. hosts, err := region.GetHosts("", "")
  101. if err != nil {
  102. return nil, err
  103. }
  104. ihosts := []cloudprovider.ICloudHost{}
  105. for i := 0; i < len(hosts); i++ {
  106. ihosts = append(ihosts, &hosts[i])
  107. }
  108. return ihosts, nil
  109. }
  110. func (region *SRegion) GetIStorages() ([]cloudprovider.ICloudStorage, error) {
  111. return region.getIStorages("")
  112. }
  113. func (region *SRegion) GetIStoragecacheById(id string) (cloudprovider.ICloudStoragecache, error) {
  114. caches, err := region.GetIStoragecaches()
  115. if err != nil {
  116. return nil, err
  117. }
  118. for i := 0; i < len(caches); i++ {
  119. if caches[i].GetGlobalId() == id {
  120. return caches[i], nil
  121. }
  122. }
  123. return nil, cloudprovider.ErrNotFound
  124. }
  125. func (region *SRegion) GetIStoragecaches() ([]cloudprovider.ICloudStoragecache, error) {
  126. zones, err := region.GetZones("")
  127. if err != nil {
  128. return nil, err
  129. }
  130. icaches := []cloudprovider.ICloudStoragecache{}
  131. for i := 0; i < len(zones); i++ {
  132. icaches = append(icaches, &SStoragecache{ZoneId: zones[i].UUID, region: region})
  133. }
  134. return icaches, nil
  135. }
  136. func (region *SRegion) GetIVpcById(vpcId string) (cloudprovider.ICloudVpc, error) {
  137. return &SVpc{region: region}, nil
  138. }
  139. func (region *SRegion) GetIZoneById(id string) (cloudprovider.ICloudZone, error) {
  140. izones, err := region.GetIZones()
  141. if err != nil {
  142. return nil, err
  143. }
  144. for i := 0; i < len(izones); i++ {
  145. if izones[i].GetGlobalId() == id {
  146. return izones[i], nil
  147. }
  148. }
  149. return nil, cloudprovider.ErrNotFound
  150. }
  151. func (region *SRegion) GetZone(zoneId string) (*SZone, error) {
  152. zone := &SZone{region: region}
  153. return zone, region.client.getResource("zones", zoneId, zone)
  154. }
  155. func (region *SRegion) GetZones(zoneId string) ([]SZone, error) {
  156. zones := []SZone{}
  157. params := url.Values{}
  158. if len(zoneId) > 0 {
  159. params.Add("q", "uuid="+zoneId)
  160. }
  161. err := region.client.listAll("zones", params, &zones)
  162. if err != nil {
  163. return nil, err
  164. }
  165. for i := 0; i < len(zones); i++ {
  166. zones[i].region = region
  167. }
  168. return zones, nil
  169. }
  170. func (region *SRegion) fetchZones() {
  171. if region.izones == nil || len(region.izones) == 0 {
  172. zones, err := region.GetZones("")
  173. if err != nil {
  174. log.Errorf("failed to get zones error: %v", err)
  175. return
  176. }
  177. region.izones = []cloudprovider.ICloudZone{}
  178. for i := 0; i < len(zones); i++ {
  179. region.izones = append(region.izones, &zones[i])
  180. }
  181. }
  182. }
  183. func (region *SRegion) fetchInfrastructure() error {
  184. region.fetchZones()
  185. region.GetIVpcs()
  186. return nil
  187. }
  188. func (region *SRegion) GetIZones() ([]cloudprovider.ICloudZone, error) {
  189. if region.izones == nil {
  190. if err := region.fetchInfrastructure(); err != nil {
  191. return nil, err
  192. }
  193. }
  194. return region.izones, nil
  195. }
  196. func (region *SRegion) GetVpc() *SVpc {
  197. return &SVpc{region: region}
  198. }
  199. func (region *SRegion) GetIVpcs() ([]cloudprovider.ICloudVpc, error) {
  200. region.ivpcs = []cloudprovider.ICloudVpc{region.GetVpc()}
  201. return region.ivpcs, nil
  202. }
  203. func (region *SRegion) CreateIVpc(opts *cloudprovider.VpcCreateOptions) (cloudprovider.ICloudVpc, error) {
  204. return nil, cloudprovider.ErrNotSupported
  205. }
  206. func (region *SRegion) CreateEIP(eip *cloudprovider.SEip) (cloudprovider.ICloudEIP, error) {
  207. if len(eip.NetworkExternalId) == 0 {
  208. return nil, fmt.Errorf("networkId cannot be empty")
  209. }
  210. networkInfo := strings.Split(eip.NetworkExternalId, "/")
  211. if len(networkInfo) != 2 {
  212. return nil, fmt.Errorf("invalid network externalId, it should be `l3networId/networkId` format")
  213. }
  214. _, err := region.GetL3Network(networkInfo[0])
  215. if err != nil {
  216. return nil, err
  217. }
  218. vip, err := region.CreateVirtualIP(eip.Name, "", eip.Ip, networkInfo[0])
  219. if err != nil {
  220. return nil, err
  221. }
  222. return region.CreateEip(eip.Name, vip.UUID, "")
  223. }
  224. func (region *SRegion) GetIEipById(eipId string) (cloudprovider.ICloudEIP, error) {
  225. return region.GetEip(eipId)
  226. }
  227. func (region *SRegion) GetIEips() ([]cloudprovider.ICloudEIP, error) {
  228. eips, err := region.GetEips("", "")
  229. if err != nil {
  230. return nil, err
  231. }
  232. ieips := []cloudprovider.ICloudEIP{}
  233. for i := 0; i < len(eips); i++ {
  234. ieips = append(ieips, &eips[i])
  235. }
  236. return ieips, nil
  237. }
  238. func (region *SRegion) GetISnapshots() ([]cloudprovider.ICloudSnapshot, error) {
  239. snapshots, err := region.GetSnapshots("", "")
  240. if err != nil {
  241. return nil, err
  242. }
  243. isnapshots := []cloudprovider.ICloudSnapshot{}
  244. for i := 0; i < len(snapshots); i++ {
  245. snapshots[i].region = region
  246. isnapshots = append(isnapshots, &snapshots[i])
  247. }
  248. return isnapshots, nil
  249. }
  250. func (region *SRegion) GetISnapshotById(snapshotId string) (cloudprovider.ICloudSnapshot, error) {
  251. return region.GetSnapshot(snapshotId)
  252. }
  253. func (region *SRegion) GetISkus() ([]cloudprovider.ICloudSku, error) {
  254. offerings, err := region.GetInstanceOfferings("", "", 0, 0)
  255. if err != nil {
  256. return nil, err
  257. }
  258. iskus := []cloudprovider.ICloudSku{}
  259. for i := 0; i < len(offerings); i++ {
  260. offerings[i].region = region
  261. iskus = append(iskus, &offerings[i])
  262. }
  263. return iskus, nil
  264. }
  265. func (region *SRegion) DeleteISkuByName(name string) error {
  266. offerings, err := region.GetInstanceOfferings("", name, 0, 0)
  267. if err != nil {
  268. return errors.Wrap(err, "region.GetInstanceOfferings")
  269. }
  270. for _, offering := range offerings {
  271. err = offering.Delete()
  272. if err != nil {
  273. return err
  274. }
  275. }
  276. return nil
  277. }
  278. func (self *SRegion) GetISecurityGroups() ([]cloudprovider.ICloudSecurityGroup, error) {
  279. secgroups, err := self.GetSecurityGroups("", "", "")
  280. if err != nil {
  281. return nil, err
  282. }
  283. ret := []cloudprovider.ICloudSecurityGroup{}
  284. for i := 0; i < len(secgroups); i++ {
  285. secgroups[i].region = self
  286. ret = append(ret, &secgroups[i])
  287. }
  288. return ret, nil
  289. }
  290. func (region *SRegion) GetISecurityGroupById(secgroupId string) (cloudprovider.ICloudSecurityGroup, error) {
  291. return region.GetSecurityGroup(secgroupId)
  292. }
  293. func (region *SRegion) CreateISecurityGroup(opts *cloudprovider.SecurityGroupCreateInput) (cloudprovider.ICloudSecurityGroup, error) {
  294. return region.CreateSecurityGroup(opts)
  295. }
  296. func (region *SRegion) GetCapabilities() []string {
  297. return region.client.GetCapabilities()
  298. }
  299. func (region *SRegion) GetIVMs() ([]cloudprovider.ICloudVM, error) {
  300. vms, err := region.GetInstances("", "", "")
  301. if err != nil {
  302. return nil, err
  303. }
  304. ret := []cloudprovider.ICloudVM{}
  305. for i := range vms {
  306. ret = append(ret, &vms[i])
  307. }
  308. return ret, nil
  309. }