yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/hcs/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 hcs
    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  
    37  func (self *SHost) GetId() string {
    38  	return fmt.Sprintf("%s-%s", self.zone.region.client.cpcfg.Id, self.zone.GetId())
    39  }
    40  
    41  func (self *SHost) GetName() string {
    42  	return fmt.Sprintf("%s-%s", self.zone.region.client.cpcfg.Name, self.zone.GetId())
    43  }
    44  
    45  func (self *SHost) GetGlobalId() string {
    46  	return fmt.Sprintf("%s-%s", self.zone.region.client.cpcfg.Id, self.zone.GetId())
    47  }
    48  
    49  func (self *SHost) IsEmulated() bool {
    50  	return true
    51  }
    52  
    53  func (self *SHost) GetStatus() string {
    54  	return api.HOST_STATUS_RUNNING
    55  }
    56  
    57  func (self *SHost) GetIVMs() ([]cloudprovider.ICloudVM, error) {
    58  	vms, err := self.zone.region.GetInstances("")
    59  	if err != nil {
    60  		return nil, err
    61  	}
    62  
    63  	ret := []cloudprovider.ICloudVM{}
    64  	for i := range vms {
    65  		if vms[i].OSEXTAZAvailabilityZone == self.zone.GetId() {
    66  			vms[i].host = self
    67  			ret = append(ret, &vms[i])
    68  		}
    69  	}
    70  	return ret, nil
    71  }
    72  
    73  func (self *SHost) GetIVMById(id string) (cloudprovider.ICloudVM, error) {
    74  	vm, err := self.zone.region.GetInstance(id)
    75  	if err != nil {
    76  		return nil, err
    77  	}
    78  	vm.host = self
    79  	return vm, nil
    80  }
    81  
    82  func (self *SHost) GetIWires() ([]cloudprovider.ICloudWire, error) {
    83  	return self.zone.GetIWires()
    84  }
    85  
    86  func (self *SHost) GetIStorages() ([]cloudprovider.ICloudStorage, error) {
    87  	return self.zone.GetIStorages()
    88  }
    89  
    90  func (self *SHost) GetIStorageById(id string) (cloudprovider.ICloudStorage, error) {
    91  	return self.zone.GetIStorageById(id)
    92  }
    93  
    94  func (self *SHost) GetEnabled() bool {
    95  	return true
    96  }
    97  
    98  func (self *SHost) GetHostStatus() string {
    99  	return api.HOST_ONLINE
   100  }
   101  
   102  func (self *SHost) GetAccessIp() string {
   103  	return ""
   104  }
   105  
   106  func (self *SHost) GetAccessMac() string {
   107  	return ""
   108  }
   109  
   110  func (self *SHost) GetSysInfo() jsonutils.JSONObject {
   111  	info := jsonutils.NewDict()
   112  	info.Add(jsonutils.NewString(CLOUD_PROVIDER_HCS), "manufacture")
   113  	return info
   114  }
   115  
   116  func (self *SHost) GetSN() string {
   117  	return ""
   118  }
   119  
   120  func (self *SHost) GetCpuCount() int {
   121  	return 0
   122  }
   123  
   124  func (self *SHost) GetNodeCount() int8 {
   125  	return 0
   126  }
   127  
   128  func (self *SHost) GetCpuDesc() string {
   129  	return ""
   130  }
   131  
   132  func (self *SHost) GetCpuMhz() int {
   133  	return 0
   134  }
   135  
   136  func (self *SHost) GetMemSizeMB() int {
   137  	return 0
   138  }
   139  
   140  func (self *SHost) GetStorageSizeMB() int {
   141  	return 0
   142  }
   143  
   144  func (self *SHost) GetStorageType() string {
   145  	return api.DISK_TYPE_HYBRID
   146  }
   147  
   148  func (self *SHost) GetHostType() string {
   149  	return api.HOST_TYPE_HCS
   150  }
   151  
   152  func (self *SHost) GetIsMaintenance() bool {
   153  	return false
   154  }
   155  
   156  func (self *SHost) GetVersion() string {
   157  	return HCS_API_VERSION
   158  }
   159  
   160  func (self *SHost) CreateVM(desc *cloudprovider.SManagedVMCreateConfig) (cloudprovider.ICloudVM, error) {
   161  	vm, err := self._createVM(
   162  		desc.Name, desc.ExternalImageId, desc.SysDisk,
   163  		desc.Cpu, desc.MemoryMB, desc.InstanceType,
   164  		desc.ExternalNetworkId, desc.IpAddr,
   165  		desc.Description, desc.Account,
   166  		desc.Password, desc.DataDisks,
   167  		desc.PublicKey, desc.ExternalSecgroupId,
   168  		desc.UserData, desc.BillingCycle, desc.ProjectId, desc.Tags)
   169  	if err != nil {
   170  		return nil, err
   171  	}
   172  	return vm, err
   173  }
   174  
   175  func (self *SHost) GetIHostNics() ([]cloudprovider.ICloudHostNetInterface, error) {
   176  	return nil, cloudprovider.ErrNotSupported
   177  }
   178  
   179  func (self *SHost) _createVM(name string, imgId string, sysDisk cloudprovider.SDiskInfo, cpu int, memMB int, instanceType string,
   180  	networkId string, ipAddr string, desc string, account string, passwd string,
   181  	diskSizes []cloudprovider.SDiskInfo, publicKey string, secgroupId string,
   182  	userData string, bc *billing.SBillingCycle, projectId string, tags map[string]string) (*SInstance, error) {
   183  	net, err := self.zone.region.GetNetwork(networkId)
   184  	if err != nil {
   185  		return nil, errors.Wrapf(err, "GetNetwork(%s)", networkId)
   186  	}
   187  
   188  	keypair := ""
   189  	if len(publicKey) > 0 {
   190  		keypair, err = self.zone.region.syncKeypair(publicKey)
   191  		if err != nil {
   192  			return nil, err
   193  		}
   194  	}
   195  
   196  	//  镜像及硬盘配置
   197  	img, err := self.zone.region.GetImage(imgId)
   198  	if err != nil {
   199  		return nil, errors.Wrapf(err, "GetImage(%s)", imgId)
   200  	}
   201  	// passwd, windows机型直接使用密码比较方便
   202  	if strings.ToLower(img.Platform) == strings.ToLower(osprofile.OS_TYPE_WINDOWS) && len(passwd) > 0 {
   203  		keypair = ""
   204  	}
   205  
   206  	if strings.ToLower(img.Platform) == strings.ToLower(osprofile.OS_TYPE_WINDOWS) {
   207  		if u, err := updateWindowsUserData(userData, img.OSVersion, account, passwd); err == nil {
   208  			userData = u
   209  		} else {
   210  			return nil, errors.Wrap(err, "SHost.CreateVM.updateWindowsUserData")
   211  		}
   212  	}
   213  
   214  	if sysDisk.SizeGB > 0 && sysDisk.SizeGB < img.SizeGB {
   215  		sysDisk.SizeGB = img.SizeGB
   216  	}
   217  
   218  	// 创建实例
   219  	if len(instanceType) > 0 {
   220  		log.Debugf("Try instancetype : %s", instanceType)
   221  		vm, err := self.zone.region.CreateInstance(name, imgId, instanceType, networkId, secgroupId,
   222  			net.VpcId, self.zone.GetId(), desc, sysDisk, diskSizes, ipAddr, keypair,
   223  			passwd, userData, bc, projectId, tags)
   224  		if err != nil {
   225  			return nil, fmt.Errorf("create %s failed:%v", instanceType, err)
   226  		}
   227  		return vm, nil
   228  	}
   229  
   230  	// 匹配实例类型
   231  	instanceTypes, err := self.zone.region.GetMatchInstanceTypes(cpu, memMB, self.zone.GetId())
   232  	if err != nil {
   233  		return nil, err
   234  	}
   235  	if len(instanceTypes) == 0 {
   236  		return nil, fmt.Errorf("instance type %dC%dMB not avaiable", cpu, memMB)
   237  	}
   238  
   239  	var vm *SInstance
   240  	for _, instType := range instanceTypes {
   241  		instanceTypeId := instType.Name
   242  		log.Debugf("Try instancetype : %s", instanceTypeId)
   243  		vm, err = self.zone.region.CreateInstance(name, imgId, instanceTypeId, networkId, secgroupId,
   244  			net.VpcId, self.zone.GetId(), desc, sysDisk, diskSizes, ipAddr, keypair,
   245  			passwd, userData, bc, projectId, tags)
   246  		if err != nil {
   247  			log.Errorf("Failed for %s: %s", instanceTypeId, err)
   248  		} else {
   249  			return vm, nil
   250  		}
   251  	}
   252  
   253  	return nil, fmt.Errorf("create failed: %v", err)
   254  }