host.go 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  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 ksyun
  15. import (
  16. "fmt"
  17. "time"
  18. api "yunion.io/x/cloudmux/pkg/apis/compute"
  19. "yunion.io/x/cloudmux/pkg/cloudprovider"
  20. "yunion.io/x/cloudmux/pkg/multicloud"
  21. "yunion.io/x/pkg/errors"
  22. "yunion.io/x/pkg/utils"
  23. "yunion.io/x/jsonutils"
  24. )
  25. type SHost struct {
  26. multicloud.SHostBase
  27. zone *SZone
  28. }
  29. func (host *SHost) GetIVMs() ([]cloudprovider.ICloudVM, error) {
  30. instances, err := host.zone.region.GetInstances(host.zone.GetName(), []string{})
  31. if err != nil {
  32. return nil, err
  33. }
  34. ivms := make([]cloudprovider.ICloudVM, len(instances))
  35. for i := 0; i < len(instances); i += 1 {
  36. instances[i].host = host
  37. ivms[i] = &instances[i]
  38. }
  39. return ivms, nil
  40. }
  41. func (host *SHost) GetIVMById(vmId string) (cloudprovider.ICloudVM, error) {
  42. ins, err := host.zone.region.GetInstance(vmId)
  43. if err != nil {
  44. return nil, errors.Wrap(err, "GetInstance")
  45. }
  46. ins.host = host
  47. return ins, nil
  48. }
  49. func (host *SHost) CreateVM(opts *cloudprovider.SManagedVMCreateConfig) (cloudprovider.ICloudVM, error) {
  50. vm, err := host.zone.region.CreateVM(opts)
  51. if err != nil {
  52. return nil, err
  53. }
  54. vm.host = host
  55. return vm, nil
  56. }
  57. func (region *SRegion) syncKeypair(keyName, publicKey string) (string, error) {
  58. keypairs, err := region.client.GetKeypairs()
  59. if err != nil {
  60. return "", err
  61. }
  62. for i := range keypairs {
  63. if keypairs[i].PublicKey == publicKey {
  64. return keypairs[i].KeyId, nil
  65. }
  66. }
  67. keypair, err := region.client.CreateKeypair(keyName, publicKey)
  68. if err != nil {
  69. return "", err
  70. }
  71. return keypair.KeyId, nil
  72. }
  73. func (region *SRegion) CreateVM(opts *cloudprovider.SManagedVMCreateConfig) (*SInstance, error) {
  74. params := map[string]interface{}{
  75. "InstanceName": opts.Name,
  76. "ImageId": opts.ExternalImageId,
  77. "InstanceType": opts.InstanceType,
  78. "MaxCount": "1",
  79. "MinCount": "1",
  80. "SubnetId": opts.ExternalNetworkId,
  81. "ChargeType": "HourlyInstantSettlement",
  82. "SystemDisk.DiskType": opts.SysDisk.StorageType,
  83. "SystemDisk.DiskSize": fmt.Sprintf("%d", opts.SysDisk.SizeGB),
  84. "SyncTag": "true",
  85. }
  86. if utils.IsInStringArray(opts.KsyunPostpaidChargeType, []string{"HourlyInstantSettlement", "Daily"}) {
  87. params["ChargeType"] = opts.KsyunPostpaidChargeType
  88. }
  89. if len(opts.Hostname) > 0 {
  90. params["HostName"] = opts.Hostname
  91. }
  92. if len(opts.Password) > 0 {
  93. params["InstancePassword"] = opts.Password
  94. }
  95. if opts.BillingCycle != nil {
  96. params["ChargeType"] = "Monthly"
  97. params["PurchaseTime"] = fmt.Sprintf("%d", opts.BillingCycle.GetMonths())
  98. }
  99. for i, group := range opts.ExternalSecgroupIds {
  100. params[fmt.Sprintf("SecurityGroupId.%d", i+1)] = group
  101. }
  102. if len(opts.IpAddr) > 0 {
  103. params["PrivateIpAddress"] = opts.IpAddr
  104. }
  105. if len(opts.ProjectId) > 0 {
  106. params["ProjectId"] = opts.ProjectId
  107. }
  108. if len(opts.UserData) > 0 {
  109. params["UserData"] = opts.UserData
  110. }
  111. if len(opts.PublicKey) > 0 {
  112. var err error
  113. params["KeyId.1"], err = region.syncKeypair(opts.Name, opts.PublicKey)
  114. if err != nil {
  115. return nil, err
  116. }
  117. }
  118. for i, disk := range opts.DataDisks {
  119. params[fmt.Sprintf("DataDisk.%d.DeleteWithInstance", i+1)] = "true"
  120. params[fmt.Sprintf("DataDisk.%d.Size", i+1)] = fmt.Sprintf("%d", disk.SizeGB)
  121. params[fmt.Sprintf("DataDisk.%d.Type", i+1)] = disk.StorageType
  122. }
  123. tagIdx := 1
  124. for k, v := range opts.Tags {
  125. params[fmt.Sprintf("Tag.%d.Key", tagIdx)] = k
  126. params[fmt.Sprintf("Tag.%d.Value", tagIdx)] = v
  127. tagIdx++
  128. }
  129. resp, err := region.ecsRequest("RunInstances", params)
  130. if err != nil {
  131. return nil, errors.Wrapf(err, "RunInstances")
  132. }
  133. ret := []struct {
  134. InstanceId string
  135. InstanceName string
  136. }{}
  137. err = resp.Unmarshal(&ret, "InstancesSet")
  138. if err != nil {
  139. return nil, errors.Wrapf(err, "Unmarshal")
  140. }
  141. if len(ret) == 0 {
  142. return nil, errors.Wrapf(cloudprovider.ErrNotFound, "after created")
  143. }
  144. vmId := ret[0].InstanceId
  145. err = cloudprovider.Wait(time.Second*3, time.Minute, func() (bool, error) {
  146. _, err := region.GetInstance(vmId)
  147. if err != nil {
  148. if errors.Cause(err) == cloudprovider.ErrNotFound {
  149. return false, nil
  150. }
  151. return false, err
  152. }
  153. return true, nil
  154. })
  155. if err != nil {
  156. return nil, errors.Wrapf(cloudprovider.ErrNotFound, "after vm %s created", vmId)
  157. }
  158. return region.GetInstance(vmId)
  159. }
  160. func (host *SHost) GetAccessIp() string {
  161. return ""
  162. }
  163. func (host *SHost) IsEmulated() bool {
  164. return true
  165. }
  166. func (host *SHost) GetAccessMac() string {
  167. return ""
  168. }
  169. func (host *SHost) GetName() string {
  170. return host.zone.AvailabilityZone
  171. }
  172. func (host *SHost) GetNodeCount() int8 {
  173. return 0
  174. }
  175. func (host *SHost) GetSN() string {
  176. return ""
  177. }
  178. func (host *SHost) GetStatus() string {
  179. return api.HOST_STATUS_RUNNING
  180. }
  181. func (host *SHost) GetCpuCount() int {
  182. return 0
  183. }
  184. func (host *SHost) GetCpuDesc() string {
  185. return ""
  186. }
  187. func (host *SHost) GetCpuMhz() int {
  188. return 0
  189. }
  190. func (host *SHost) GetMemSizeMB() int {
  191. return 0
  192. }
  193. func (host *SHost) GetStorageSizeMB() int64 {
  194. return 0
  195. }
  196. func (host *SHost) GetStorageClass() string {
  197. return ""
  198. }
  199. func (host *SHost) GetStorageType() string {
  200. return ""
  201. }
  202. func (host *SHost) GetEnabled() bool {
  203. return true
  204. }
  205. func (host *SHost) GetIsMaintenance() bool {
  206. return false
  207. }
  208. func (host *SHost) GetGlobalId() string {
  209. return host.zone.GetId()
  210. }
  211. func (host *SHost) GetId() string {
  212. return host.zone.GetId()
  213. }
  214. func (host *SHost) GetHostStatus() string {
  215. return api.HOST_ONLINE
  216. }
  217. func (host *SHost) GetHostType() string {
  218. return api.HOST_TYPE_KSYUN
  219. }
  220. func (host *SHost) GetIHostNics() ([]cloudprovider.ICloudHostNetInterface, error) {
  221. wires, err := host.zone.GetIWires()
  222. if err != nil {
  223. return nil, errors.Wrap(err, "GetIWires")
  224. }
  225. return cloudprovider.GetHostNetifs(host, wires), nil
  226. }
  227. func (host *SHost) GetIStorageById(storageId string) (cloudprovider.ICloudStorage, error) {
  228. return host.zone.GetIStorageById(storageId)
  229. }
  230. func (host *SHost) GetIStorages() ([]cloudprovider.ICloudStorage, error) {
  231. return host.zone.GetIStorages()
  232. }
  233. func (host *SHost) GetSysInfo() jsonutils.JSONObject {
  234. info := jsonutils.NewDict()
  235. info.Add(jsonutils.NewString(CLOUD_PROVIDER_KSYUN_CN), "manufacture")
  236. return info
  237. }
  238. func (host *SHost) GetVersion() string {
  239. return ""
  240. }