yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/aliyun/host.go (about) 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 15 package aliyun 16 17 import ( 18 "fmt" 19 20 "yunion.io/x/jsonutils" 21 "yunion.io/x/log" 22 "yunion.io/x/pkg/errors" 23 24 api "yunion.io/x/cloudmux/pkg/apis/compute" 25 "yunion.io/x/cloudmux/pkg/cloudprovider" 26 "yunion.io/x/cloudmux/pkg/multicloud" 27 "yunion.io/x/onecloud/pkg/util/billing" 28 ) 29 30 type SHost struct { 31 multicloud.SHostBase 32 zone *SZone 33 } 34 35 func (self *SHost) GetIWires() ([]cloudprovider.ICloudWire, error) { 36 return self.zone.GetIWires() 37 } 38 39 func (self *SHost) GetIStorages() ([]cloudprovider.ICloudStorage, error) { 40 return self.zone.GetIStorages() 41 } 42 43 func (self *SHost) GetIStorageById(id string) (cloudprovider.ICloudStorage, error) { 44 return self.zone.GetIStorageById(id) 45 } 46 47 func (self *SHost) GetIVMs() ([]cloudprovider.ICloudVM, error) { 48 vms := make([]SInstance, 0) 49 for { 50 parts, total, err := self.zone.region.GetInstances(self.zone.ZoneId, nil, len(vms), 50) 51 if err != nil { 52 return nil, err 53 } 54 vms = append(vms, parts...) 55 if len(vms) >= total { 56 break 57 } 58 } 59 ivms := make([]cloudprovider.ICloudVM, len(vms)) 60 for i := 0; i < len(vms); i += 1 { 61 vms[i].host = self 62 ivms[i] = &vms[i] 63 } 64 return ivms, nil 65 } 66 67 func (self *SHost) VMGlobalId2Id(gid string) string { 68 return gid 69 } 70 71 func (self *SHost) GetIVMById(gid string) (cloudprovider.ICloudVM, error) { 72 id := self.VMGlobalId2Id(gid) 73 parts, _, err := self.zone.region.GetInstances(self.zone.ZoneId, []string{id}, 0, 1) 74 if err != nil { 75 return nil, err 76 } 77 if len(parts) == 0 { 78 return nil, cloudprovider.ErrNotFound 79 } 80 if len(parts) > 1 { 81 return nil, cloudprovider.ErrDuplicateId 82 } 83 parts[0].host = self 84 return &parts[0], nil 85 } 86 87 func (self *SHost) GetId() string { 88 return fmt.Sprintf("%s-%s", self.zone.region.client.cpcfg.Id, self.zone.GetId()) 89 } 90 91 func (self *SHost) GetName() string { 92 return fmt.Sprintf("%s-%s", self.zone.region.client.cpcfg.Name, self.zone.GetId()) 93 } 94 95 func (self *SHost) GetGlobalId() string { 96 return fmt.Sprintf("%s-%s", self.zone.region.client.cpcfg.Id, self.zone.GetId()) 97 } 98 99 func (self *SHost) IsEmulated() bool { 100 return true 101 } 102 103 func (self *SHost) GetStatus() string { 104 return api.HOST_STATUS_RUNNING 105 } 106 107 func (self *SHost) Refresh() error { 108 return nil 109 } 110 111 func (self *SHost) GetHostStatus() string { 112 return api.HOST_ONLINE 113 } 114 115 func (self *SHost) GetEnabled() bool { 116 return true 117 } 118 119 func (self *SHost) GetAccessIp() string { 120 return "" 121 } 122 123 func (self *SHost) GetAccessMac() string { 124 return "" 125 } 126 127 func (self *SHost) GetSysInfo() jsonutils.JSONObject { 128 info := jsonutils.NewDict() 129 info.Add(jsonutils.NewString(CLOUD_PROVIDER_ALIYUN), "manufacture") 130 return info 131 } 132 133 func (self *SHost) GetSN() string { 134 return "" 135 } 136 137 func (self *SHost) GetCpuCount() int { 138 return 0 139 } 140 141 func (self *SHost) GetNodeCount() int8 { 142 return 0 143 } 144 145 func (self *SHost) GetCpuDesc() string { 146 return "" 147 } 148 149 func (self *SHost) GetCpuMhz() int { 150 return 0 151 } 152 153 func (self *SHost) GetMemSizeMB() int { 154 return 0 155 } 156 157 func (self *SHost) GetStorageSizeMB() int { 158 return 0 159 } 160 161 func (self *SHost) GetStorageType() string { 162 return api.DISK_TYPE_HYBRID 163 } 164 165 func (self *SHost) GetHostType() string { 166 return api.HOST_TYPE_ALIYUN 167 } 168 169 func (self *SHost) GetInstanceById(instanceId string) (*SInstance, error) { 170 inst, err := self.zone.region.GetInstance(instanceId) 171 if err != nil { 172 return nil, err 173 } 174 inst.host = self 175 return inst, nil 176 } 177 178 func (self *SHost) CreateVM(desc *cloudprovider.SManagedVMCreateConfig) (cloudprovider.ICloudVM, error) { 179 vmId, err := self._createVM(desc.Name, desc.Hostname, desc.ExternalImageId, desc.SysDisk, desc.Cpu, desc.MemoryMB, 180 desc.InstanceType, desc.ExternalNetworkId, desc.IpAddr, desc.Description, desc.Password, 181 desc.DataDisks, desc.PublicKey, desc.ExternalSecgroupId, desc.UserData, desc.BillingCycle, 182 desc.ProjectId, desc.OsType, desc.Tags, desc.SPublicIpInfo) 183 if err != nil { 184 return nil, err 185 } 186 vm, err := self.GetInstanceById(vmId) 187 if err != nil { 188 return nil, errors.Wrapf(err, "GetInstanceById") 189 } 190 return vm, nil 191 } 192 193 func (self *SHost) _createVM(name, hostname string, imgId string, 194 sysDisk cloudprovider.SDiskInfo, cpu int, memMB int, instanceType string, 195 vswitchId string, ipAddr string, desc string, passwd string, 196 dataDisks []cloudprovider.SDiskInfo, publicKey string, secgroupId string, 197 userData string, bc *billing.SBillingCycle, projectId, osType string, 198 tags map[string]string, publicIp cloudprovider.SPublicIpInfo, 199 ) (string, error) { 200 net := self.zone.getNetworkById(vswitchId) 201 if net == nil { 202 return "", fmt.Errorf("invalid switch ID %s", vswitchId) 203 } 204 if net.wire == nil { 205 log.Errorf("vsiwtch's wire is empty") 206 return "", fmt.Errorf("vsiwtch's wire is empty") 207 } 208 if net.wire.vpc == nil { 209 log.Errorf("vsiwtch's wire' vpc is empty") 210 return "", fmt.Errorf("vsiwtch's wire's vpc is empty") 211 } 212 213 var err error 214 keypair := "" 215 if len(publicKey) > 0 { 216 keypair, err = self.zone.region.syncKeypair(publicKey) 217 if err != nil { 218 return "", err 219 } 220 } 221 222 img, err := self.zone.region.GetImage(imgId) 223 if err != nil { 224 log.Errorf("GetImage fail %s", err) 225 return "", err 226 } 227 if img.Status != ImageStatusAvailable { 228 log.Errorf("image %s status %s", imgId, img.Status) 229 return "", fmt.Errorf("image not ready") 230 } 231 232 disks := make([]SDisk, len(dataDisks)+1) 233 disks[0].Size = img.Size 234 if sysDisk.SizeGB > 0 && sysDisk.SizeGB > img.Size { 235 disks[0].Size = sysDisk.SizeGB 236 } 237 storage, err := self.zone.getStorageByCategory(sysDisk.StorageType) 238 if err != nil { 239 return "", fmt.Errorf("Storage %s not avaiable: %s", sysDisk.StorageType, err) 240 } 241 disks[0].Category = storage.storageType 242 243 for i, dataDisk := range dataDisks { 244 disks[i+1].Size = dataDisk.SizeGB 245 storage, err := self.zone.getStorageByCategory(dataDisk.StorageType) 246 if err != nil { 247 return "", fmt.Errorf("Storage %s not avaiable: %s", dataDisk.StorageType, err) 248 } 249 disks[i+1].Category = storage.storageType 250 } 251 252 if len(instanceType) > 0 { 253 log.Debugf("Try instancetype : %s", instanceType) 254 vmId, err := self.zone.region.CreateInstance(name, hostname, imgId, instanceType, secgroupId, self.zone.ZoneId, desc, passwd, disks, vswitchId, ipAddr, keypair, userData, bc, projectId, osType, tags, publicIp) 255 if err != nil { 256 log.Errorf("Failed for %s: %s", instanceType, err) 257 return "", fmt.Errorf("Failed to create specification %s.%s", instanceType, err.Error()) 258 } 259 return vmId, nil 260 } 261 262 instanceTypes, err := self.zone.region.GetMatchInstanceTypes(cpu, memMB, 0, self.zone.ZoneId) 263 if err != nil { 264 return "", err 265 } 266 if len(instanceTypes) == 0 { 267 return "", fmt.Errorf("instance type %dC%dMB not avaiable", cpu, memMB) 268 } 269 270 var vmId string 271 for _, instType := range instanceTypes { 272 instanceTypeId := instType.InstanceTypeId 273 log.Debugf("Try instancetype : %s", instanceTypeId) 274 vmId, err = self.zone.region.CreateInstance(name, hostname, imgId, instanceTypeId, secgroupId, self.zone.ZoneId, desc, passwd, disks, vswitchId, ipAddr, keypair, userData, bc, projectId, osType, tags, publicIp) 275 if err != nil { 276 log.Errorf("Failed for %s: %s", instanceTypeId, err) 277 } else { 278 return vmId, nil 279 } 280 } 281 282 return "", fmt.Errorf("Failed to create, %s", err.Error()) 283 } 284 285 func (host *SHost) GetIHostNics() ([]cloudprovider.ICloudHostNetInterface, error) { 286 return nil, cloudprovider.ErrNotSupported 287 } 288 289 func (host *SHost) GetIsMaintenance() bool { 290 return false 291 } 292 293 func (host *SHost) GetVersion() string { 294 return ALIYUN_API_VERSION 295 }