yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/apsara/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 apsara 16 17 import ( 18 "fmt" 19 20 "yunion.io/x/jsonutils" 21 "yunion.io/x/log" 22 23 api "yunion.io/x/cloudmux/pkg/apis/compute" 24 "yunion.io/x/cloudmux/pkg/cloudprovider" 25 "yunion.io/x/cloudmux/pkg/multicloud" 26 "yunion.io/x/onecloud/pkg/util/billing" 27 ) 28 29 type SHost struct { 30 multicloud.SHostBase 31 zone *SZone 32 } 33 34 func (self *SHost) GetIWires() ([]cloudprovider.ICloudWire, error) { 35 return self.zone.GetIWires() 36 } 37 38 func (self *SHost) GetIStorages() ([]cloudprovider.ICloudStorage, error) { 39 return self.zone.GetIStorages() 40 } 41 42 func (self *SHost) GetIStorageById(id string) (cloudprovider.ICloudStorage, error) { 43 return self.zone.GetIStorageById(id) 44 } 45 46 func (self *SHost) GetIVMs() ([]cloudprovider.ICloudVM, error) { 47 vms := make([]SInstance, 0) 48 for { 49 parts, total, err := self.zone.region.GetInstances(self.zone.ZoneId, nil, len(vms), 50) 50 if err != nil { 51 return nil, err 52 } 53 vms = append(vms, parts...) 54 if len(vms) >= total { 55 break 56 } 57 } 58 ivms := make([]cloudprovider.ICloudVM, len(vms)) 59 for i := 0; i < len(vms); i += 1 { 60 vms[i].host = self 61 ivms[i] = &vms[i] 62 } 63 return ivms, nil 64 } 65 66 func (self *SHost) VMGlobalId2Id(gid string) string { 67 return gid 68 } 69 70 func (self *SHost) GetIVMById(gid string) (cloudprovider.ICloudVM, error) { 71 id := self.VMGlobalId2Id(gid) 72 parts, _, err := self.zone.region.GetInstances(self.zone.ZoneId, []string{id}, 0, 1) 73 if err != nil { 74 return nil, err 75 } 76 if len(parts) == 0 { 77 return nil, cloudprovider.ErrNotFound 78 } 79 if len(parts) > 1 { 80 return nil, cloudprovider.ErrDuplicateId 81 } 82 parts[0].host = self 83 return &parts[0], nil 84 } 85 86 func (self *SHost) GetId() string { 87 return fmt.Sprintf("%s-%s", self.zone.region.client.cpcfg.Id, self.zone.GetId()) 88 } 89 90 func (self *SHost) GetName() string { 91 return fmt.Sprintf("%s-%s", self.zone.region.client.cpcfg.Name, self.zone.GetId()) 92 } 93 94 func (self *SHost) GetGlobalId() string { 95 return fmt.Sprintf("%s-%s", self.zone.region.client.cpcfg.Id, self.zone.GetId()) 96 } 97 98 func (self *SHost) IsEmulated() bool { 99 return true 100 } 101 102 func (self *SHost) GetStatus() string { 103 return api.HOST_STATUS_RUNNING 104 } 105 106 func (self *SHost) Refresh() error { 107 return nil 108 } 109 110 func (self *SHost) GetHostStatus() string { 111 return api.HOST_ONLINE 112 } 113 114 func (self *SHost) GetEnabled() bool { 115 return true 116 } 117 118 func (self *SHost) GetAccessIp() string { 119 return "" 120 } 121 122 func (self *SHost) GetAccessMac() string { 123 return "" 124 } 125 126 func (self *SHost) GetSysInfo() jsonutils.JSONObject { 127 info := jsonutils.NewDict() 128 info.Add(jsonutils.NewString(CLOUD_PROVIDER_APSARA), "manufacture") 129 return info 130 } 131 132 func (self *SHost) GetSN() string { 133 return "" 134 } 135 136 func (self *SHost) GetCpuCount() int { 137 return 0 138 } 139 140 func (self *SHost) GetNodeCount() int8 { 141 return 0 142 } 143 144 func (self *SHost) GetCpuDesc() string { 145 return "" 146 } 147 148 func (self *SHost) GetCpuMhz() int { 149 return 0 150 } 151 152 func (self *SHost) GetMemSizeMB() int { 153 return 0 154 } 155 156 func (self *SHost) GetStorageSizeMB() int { 157 return 0 158 } 159 160 func (self *SHost) GetStorageType() string { 161 return api.DISK_TYPE_HYBRID 162 } 163 164 func (self *SHost) GetHostType() string { 165 return api.HOST_TYPE_APSARA 166 } 167 168 func (self *SHost) GetInstanceById(instanceId string) (*SInstance, error) { 169 inst, err := self.zone.region.GetInstance(instanceId) 170 if err != nil { 171 return nil, err 172 } 173 inst.host = self 174 return inst, nil 175 } 176 177 func (self *SHost) CreateVM(desc *cloudprovider.SManagedVMCreateConfig) (cloudprovider.ICloudVM, error) { 178 vmId, err := self._createVM(desc.Name, desc.Hostname, desc.ExternalImageId, desc.SysDisk, desc.Cpu, desc.MemoryMB, 179 desc.InstanceType, desc.ExternalNetworkId, desc.IpAddr, desc.Description, desc.Password, 180 desc.DataDisks, desc.PublicKey, desc.ExternalSecgroupId, desc.UserData, desc.BillingCycle, 181 desc.ProjectId, desc.OsType, desc.Tags) 182 if err != nil { 183 return nil, err 184 } 185 vm, err := self.GetInstanceById(vmId) 186 if err != nil { 187 return nil, err 188 } 189 // err = vm.waitStatus(InstanceStatusStopped, time.Second*10, time.Second*1800) 190 return vm, err 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, 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) 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) 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 APSARA_API_VERSION 295 }