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