region.go 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  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 jdcloud
  15. import (
  16. "fmt"
  17. "github.com/jdcloud-api/jdcloud-sdk-go/core"
  18. api "yunion.io/x/cloudmux/pkg/apis/compute"
  19. "yunion.io/x/cloudmux/pkg/cloudprovider"
  20. "yunion.io/x/cloudmux/pkg/multicloud"
  21. )
  22. const (
  23. CLOUD_PROVIDER_JDCLOUD = api.CLOUD_PROVIDER_JDCLOUD
  24. CLOUD_PROVIDER_JDCLOUD_CN = "京东云"
  25. CLOUD_PROVIDER_JDCLOUD_EN = "JDcloud"
  26. JDCLOUD_DEFAULT_REGION = "cn-north-1"
  27. )
  28. // https://docs.jdcloud.com/cn/common-declaration/api/introduction
  29. var regionList = map[string]string{
  30. "cn-north-1": "华北-北京",
  31. "cn-east-1": "华东-宿迁",
  32. "cn-east-2": "华东-上海",
  33. "cn-south-1": "华南-广州",
  34. }
  35. type SRegion struct {
  36. cloudprovider.SFakeOnPremiseRegion
  37. multicloud.SRegion
  38. multicloud.SNoObjectStorageRegion
  39. client *SJDCloudClient
  40. cpcfg cloudprovider.ProviderConfig
  41. storageCache *SStoragecache
  42. ID string `json:"id"`
  43. Name string `json:"Name"`
  44. izones []cloudprovider.ICloudZone
  45. ivpcs []cloudprovider.ICloudVpc
  46. }
  47. func (self *SRegion) GetClient() *SJDCloudClient {
  48. return self.client
  49. }
  50. func (self *SRegion) getCredential() *core.Credential {
  51. return self.client.getCredential()
  52. }
  53. func (r *SRegion) GetId() string {
  54. return r.ID
  55. }
  56. func (r *SRegion) GetName() string {
  57. return r.Name
  58. }
  59. func (r *SRegion) GetGlobalId() string {
  60. return fmt.Sprintf("%s/%s", api.CLOUD_ACCESS_ENV_JDCLOUD_CHINA, r.GetId())
  61. }
  62. func (r *SRegion) GetStatus() string {
  63. return api.CLOUD_REGION_STATUS_INSERVER
  64. }
  65. func (r *SRegion) Refresh() error {
  66. return nil
  67. }
  68. func (r *SRegion) IsEmulated() bool {
  69. return false
  70. }
  71. func (r *SRegion) GetI18n() cloudprovider.SModelI18nTable {
  72. en := fmt.Sprintf("%s %s", CLOUD_PROVIDER_JDCLOUD_EN, r.Name)
  73. table := cloudprovider.SModelI18nTable{}
  74. table["name"] = cloudprovider.NewSModelI18nEntry(r.GetName()).CN(r.GetName()).EN(en)
  75. return table
  76. }
  77. func (r *SRegion) GetGeographicInfo() cloudprovider.SGeographicInfo {
  78. if info, ok := LatitudeAndLongitude[r.ID]; ok {
  79. return info
  80. }
  81. return cloudprovider.SGeographicInfo{}
  82. }
  83. func (r *SRegion) GetIZones() ([]cloudprovider.ICloudZone, error) {
  84. if r.izones == nil {
  85. err := r.fetchZones()
  86. if err != nil {
  87. return nil, err
  88. }
  89. }
  90. return r.izones, nil
  91. }
  92. func (r *SRegion) fetchZones() error {
  93. zoneIdens := ZonesInRegion[r.ID]
  94. r.izones = make([]cloudprovider.ICloudZone, 0, len(zoneIdens))
  95. for _, iden := range zoneIdens {
  96. zone := SZone{
  97. region: r,
  98. ID: iden.Id,
  99. Name: iden.Name,
  100. }
  101. r.izones = append(r.izones, &zone)
  102. }
  103. return nil
  104. }
  105. func (r *SRegion) fetchVpcs() error {
  106. vpcs := make([]SVpc, 0)
  107. n := 1
  108. for {
  109. part, total, err := r.GetVpcs(n, 100)
  110. if err != nil {
  111. return err
  112. }
  113. vpcs = append(vpcs, part...)
  114. if len(vpcs) >= total {
  115. break
  116. }
  117. n++
  118. }
  119. r.ivpcs = make([]cloudprovider.ICloudVpc, len(vpcs))
  120. for i := 0; i < len(vpcs); i++ {
  121. r.ivpcs[i] = &vpcs[i]
  122. }
  123. return nil
  124. }
  125. func (r *SRegion) GetIVpcs() ([]cloudprovider.ICloudVpc, error) {
  126. if r.ivpcs == nil {
  127. err := r.fetchVpcs()
  128. if err != nil {
  129. return nil, err
  130. }
  131. }
  132. return r.ivpcs, nil
  133. }
  134. func (r *SRegion) GetIEips() ([]cloudprovider.ICloudEIP, error) {
  135. return nil, nil
  136. }
  137. func (r *SRegion) GetIVpcById(id string) (cloudprovider.ICloudVpc, error) {
  138. vpc, err := r.GetVpcById(id)
  139. if err != nil {
  140. return nil, err
  141. }
  142. return vpc, nil
  143. }
  144. func (r *SRegion) GetIZoneById(id string) (cloudprovider.ICloudZone, error) {
  145. izones, err := r.GetIZones()
  146. if err != nil {
  147. return nil, err
  148. }
  149. for i := 0; i < len(izones); i += 1 {
  150. if izones[i].GetGlobalId() == id {
  151. return izones[i], nil
  152. }
  153. }
  154. return nil, cloudprovider.ErrNotFound
  155. }
  156. func (r *SRegion) getIZoneByRealId(id string) (cloudprovider.ICloudZone, error) {
  157. izones, err := r.GetIZones()
  158. if err != nil {
  159. return nil, err
  160. }
  161. for i := 0; i < len(izones); i += 1 {
  162. if izones[i].GetId() == id {
  163. return izones[i], nil
  164. }
  165. }
  166. return nil, cloudprovider.ErrNotFound
  167. }
  168. func (r *SRegion) GetIEipById(id string) (cloudprovider.ICloudEIP, error) {
  169. return nil, cloudprovider.ErrNotImplemented
  170. }
  171. func (r *SRegion) GetIVMById(id string) (cloudprovider.ICloudVM, error) {
  172. vm, err := r.GetInstanceById(id)
  173. if err != nil {
  174. return nil, err
  175. }
  176. izone, err := r.getIZoneByRealId(vm.Az)
  177. if err != nil {
  178. return nil, err
  179. }
  180. zone := izone.(*SZone)
  181. vm.host = &SHost{
  182. zone: zone,
  183. }
  184. return vm, nil
  185. }
  186. func (r *SRegion) GetIDiskById(id string) (cloudprovider.ICloudDisk, error) {
  187. return r.GetDiskById(id)
  188. }
  189. func (r *SRegion) GetIHosts() ([]cloudprovider.ICloudHost, error) {
  190. izones, err := r.GetIZones()
  191. if err != nil {
  192. return nil, err
  193. }
  194. iHosts := make([]cloudprovider.ICloudHost, 0, len(izones))
  195. for i := range izones {
  196. hosts, err := izones[i].GetIHosts()
  197. if err != nil {
  198. return nil, err
  199. }
  200. iHosts = append(iHosts, hosts...)
  201. }
  202. return iHosts, nil
  203. }
  204. func (r *SRegion) GetIHostById(id string) (cloudprovider.ICloudHost, error) {
  205. hosts, err := r.GetIHosts()
  206. if err != nil {
  207. return nil, err
  208. }
  209. for i := range hosts {
  210. if hosts[i].GetGlobalId() == id {
  211. return hosts[i], nil
  212. }
  213. }
  214. return nil, cloudprovider.ErrNotFound
  215. }
  216. func (r *SRegion) GetIStorages() ([]cloudprovider.ICloudStorage, error) {
  217. iStores := make([]cloudprovider.ICloudStorage, 0)
  218. izones, err := r.GetIZones()
  219. if err != nil {
  220. return nil, err
  221. }
  222. for i := 0; i < len(izones); i += 1 {
  223. iZoneStores, err := izones[i].GetIStorages()
  224. if err != nil {
  225. return nil, err
  226. }
  227. iStores = append(iStores, iZoneStores...)
  228. }
  229. return iStores, nil
  230. }
  231. func (r *SRegion) GetIStorageById(id string) (cloudprovider.ICloudStorage, error) {
  232. istores, err := r.GetIStorages()
  233. if err != nil {
  234. return nil, err
  235. }
  236. for i := range istores {
  237. if istores[i].GetGlobalId() == id {
  238. return istores[i], nil
  239. }
  240. }
  241. return nil, cloudprovider.ErrNotFound
  242. }
  243. func (r *SRegion) GetIStoragecaches() ([]cloudprovider.ICloudStoragecache, error) {
  244. sc := r.getStoragecache()
  245. return []cloudprovider.ICloudStoragecache{sc}, nil
  246. }
  247. func (s *SRegion) getStoragecache() *SStoragecache {
  248. if s.storageCache == nil {
  249. s.storageCache = &SStoragecache{region: s}
  250. }
  251. return s.storageCache
  252. }
  253. func (r *SRegion) GetIStoragecacheById(id string) (cloudprovider.ICloudStoragecache, error) {
  254. storageCache := r.getStoragecache()
  255. if storageCache.GetGlobalId() == id {
  256. return storageCache, nil
  257. }
  258. return nil, cloudprovider.ErrNotFound
  259. }
  260. func (r *SRegion) GetProvider() string {
  261. return api.CLOUD_PROVIDER_JDCLOUD
  262. }
  263. func (r *SRegion) GetCapabilities() []string {
  264. return []string{
  265. cloudprovider.CLOUD_CAPABILITY_COMPUTE + cloudprovider.READ_ONLY_SUFFIX,
  266. cloudprovider.CLOUD_CAPABILITY_NETWORK + cloudprovider.READ_ONLY_SUFFIX,
  267. cloudprovider.CLOUD_CAPABILITY_SECURITY_GROUP + cloudprovider.READ_ONLY_SUFFIX,
  268. cloudprovider.CLOUD_CAPABILITY_EIP + cloudprovider.READ_ONLY_SUFFIX,
  269. cloudprovider.CLOUD_CAPABILITY_RDS + cloudprovider.READ_ONLY_SUFFIX,
  270. }
  271. }
  272. func (region *SRegion) GetIVMs() ([]cloudprovider.ICloudVM, error) {
  273. vms := make([]SInstance, 0)
  274. n := 1
  275. for {
  276. parts, total, err := region.GetInstances("", nil, n, 100)
  277. if err != nil {
  278. return nil, err
  279. }
  280. vms = append(vms, parts...)
  281. if len(vms) >= total {
  282. break
  283. }
  284. n++
  285. }
  286. ivms := make([]cloudprovider.ICloudVM, len(vms))
  287. for i := range vms {
  288. ivms[i] = &vms[i]
  289. }
  290. return ivms, nil
  291. }