diff --git a/pkg/cloudprovider/instance.go b/pkg/cloudprovider/instance.go index a41212a5b6..331ba0224f 100644 --- a/pkg/cloudprovider/instance.go +++ b/pkg/cloudprovider/instance.go @@ -1,28 +1,84 @@ package cloudprovider import ( + "yunion.io/x/jsonutils" + "yunion.io/x/onecloud/pkg/util/ansible" "yunion.io/x/onecloud/pkg/util/billing" - "yunion.io/x/pkg/util/secrules" + "yunion.io/x/onecloud/pkg/util/cloudinit" + "yunion.io/x/onecloud/pkg/util/seclib2" ) +type SDiskInfo struct { + StorageType string + SizeGB int +} + type SManagedVMCreateConfig struct { - Name string - ExternalImageId string - OsDistribution string - OsVersion string - InstanceType string // InstanceType 不为空时,直接采用InstanceType创建机器。 - Cpu int - Memory int - ExternalNetworkId string - IpAddr string - Description string - StorageType string - SysDiskSize int - DataDisks []int - PublicKey string - SecGroupId string - SecGroupName string - SecRules []secrules.SecurityRule - - BillingCycle billing.SBillingCycle + Name string + ExternalImageId string + OsDistribution string + OsVersion string + InstanceType string // InstanceType 不为空时,直接采用InstanceType创建机器。 + Cpu int + MemoryMB int + ExternalNetworkId string + IpAddr string + Description string + SysDisk SDiskInfo + DataDisks []SDiskInfo + PublicKey string + ExternalSecgroupId string + ExternalSecgroupIds []string + Password string + UserData string + + BillingCycle *billing.SBillingCycle +} + +func (vmConfig *SManagedVMCreateConfig) GetConfig(config *jsonutils.JSONDict) error { + if err := config.Unmarshal(vmConfig, "desc"); err != nil { + return err + } + if publicKey, _ := config.GetString("public_key"); len(publicKey) > 0 { + vmConfig.PublicKey = publicKey + } + + adminPublicKey, _ := config.GetString("admin_public_key") + projectPublicKey, _ := config.GetString("project_public_key") + oUserData, _ := config.GetString("user_data") + + vmConfig.UserData = generateUserData(adminPublicKey, projectPublicKey, oUserData) + + resetPassword := jsonutils.QueryBoolean(config, "reset_password", false) + vmConfig.Password, _ = config.GetString("password") + if resetPassword && len(vmConfig.Password) == 0 { + vmConfig.Password = seclib2.RandomPassword2(12) + } + return nil +} + +func generateUserData(adminPublicKey, projectPublicKey, oUserData string) string { + var oCloudConfig *cloudinit.SCloudConfig + + if len(oUserData) > 0 { + oCloudConfig, _ = cloudinit.ParseUserDataBase64(oUserData) + } + + ansibleUser := cloudinit.NewUser(ansible.PUBLIC_CLOUD_ANSIBLE_USER) + ansibleUser.SshKey(adminPublicKey).SshKey(projectPublicKey).SudoPolicy(cloudinit.USER_SUDO_NOPASSWD) + + cloudConfig := cloudinit.SCloudConfig{ + DisableRoot: 0, + SshPwauth: 1, + + Users: []cloudinit.SUser{ + ansibleUser, + }, + } + + if oCloudConfig != nil { + cloudConfig.Merge(oCloudConfig) + } + + return cloudConfig.UserDataBase64() } diff --git a/pkg/cloudprovider/resources.go b/pkg/cloudprovider/resources.go index 47bf731fab..0f46c7268d 100644 --- a/pkg/cloudprovider/resources.go +++ b/pkg/cloudprovider/resources.go @@ -8,7 +8,6 @@ import ( "yunion.io/x/pkg/tristate" "yunion.io/x/pkg/util/secrules" - "yunion.io/x/onecloud/pkg/cloudprovider" "yunion.io/x/onecloud/pkg/mcclient" "yunion.io/x/onecloud/pkg/util/billing" ) @@ -173,11 +172,7 @@ type ICloudHost interface { GetManagerId() string - CreateVM(desc *cloudprovider.SManagedVMCreateConfig) (ICloudVM, error) - // 使用instanceType创建实例。 - // CreateVM2(name string, imgId string, sysDiskSize int, instanceType string, vswitchId string, ipAddr string, desc string, - // passwd string, storageType string, diskSizes []int, publicKey string, extSecGrpId string, userData string, billingCycle *billing.SBillingCycle) (ICloudVM, error) - + CreateVM(desc *SManagedVMCreateConfig) (ICloudVM, error) GetIHostNics() ([]ICloudHostNetInterface, error) } diff --git a/pkg/compute/guestdrivers/aliyun.go b/pkg/compute/guestdrivers/aliyun.go index bda4b29b26..cbfc35c656 100644 --- a/pkg/compute/guestdrivers/aliyun.go +++ b/pkg/compute/guestdrivers/aliyun.go @@ -15,7 +15,6 @@ import ( "yunion.io/x/onecloud/pkg/httperrors" "yunion.io/x/onecloud/pkg/mcclient" "yunion.io/x/onecloud/pkg/util/billing" - "yunion.io/x/onecloud/pkg/util/seclib2" ) type SAliyunGuestDriver struct { @@ -97,82 +96,32 @@ func (self *SAliyunGuestDriver) ValidateCreateData(ctx context.Context, userCred } func (self *SAliyunGuestDriver) RequestDeployGuestOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error { - config := guest.GetDeployConfigOnHost(ctx, host, task.GetParams()) + config, err := guest.GetDeployConfigOnHost(ctx, task.GetUserCred(), host, task.GetParams()) + if err != nil { + log.Errorf("GetDeployConfigOnHost error: %v", err) + return err + } log.Debugf("RequestDeployGuestOnHost: %s", config) + desc := cloudprovider.SManagedVMCreateConfig{} + if err := desc.GetConfig(config); err != nil { + return err + } + action, err := config.GetString("action") if err != nil { return err } - publicKey, _ := config.GetString("public_key") - - adminPublicKey, _ := config.GetString("admin_public_key") - projectPublicKey, _ := config.GetString("project_public_key") - oUserData, _ := config.GetString("user_data") - - userData := generateUserData(adminPublicKey, projectPublicKey, oUserData) - - resetPassword := jsonutils.QueryBoolean(config, "reset_password", false) - passwd, _ := config.GetString("password") - if resetPassword && len(passwd) == 0 { - passwd = seclib2.RandomPassword2(12) - } - ihost, err := host.GetIHost() if err != nil { return err } - desc := cloudprovider.SManagedVMCreateConfig{} - err = config.Unmarshal(&desc, "desc") - if err != nil { - return err - } - if action == "create" { taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { - nets := guest.GetNetworks() - net := nets[0].GetNetwork() - vpc := net.GetVpc() - iregion, err := host.GetIRegion() - if err != nil { - return nil, err - } - - secgroupCache := models.SecurityGroupCacheManager.Register(ctx, task.GetUserCred(), desc.SecGroupId, vpc.Id, vpc.CloudregionId, vpc.ManagerId) - if secgroupCache == nil { - return nil, fmt.Errorf("failed to registor secgroupCache for secgroup: %s, vpc: %s", desc.SecGroupId, vpc.Name) - } - - secgroupExtId, err := iregion.SyncSecurityGroup(secgroupCache.ExternalId, vpc.ExternalId, desc.SecGroupName, "", desc.SecRules) - if err != nil { - log.Errorf("SyncSecurityGroup fail %s", err) - return nil, err - } - if err := secgroupCache.SetExternalId(secgroupExtId); err != nil { - return nil, fmt.Errorf("failed to set externalId for secgroup %s externalId %s: error: %v", desc.SecGroupId, secgroupExtId, err) - } - - // var createErr error - // var iVM cloudprovider.ICloudVM - - var bc *billing.SBillingCycle - if desc.BillingCycle.IsValid() { - bc = &desc.BillingCycle - } - iVM, createErr := ihost.CreateVM(&desc) - - // if len(desc.InstanceType) > 0 { - // iVM, createErr = ihost.CreateVM2(desc.Name, desc.ExternalImageId, desc.SysDiskSize, desc.InstanceType, desc.ExternalNetworkId, - // desc.IpAddr, desc.Description, passwd, desc.StorageType, desc.DataDisks, publicKey, secgroupExtId, userData, bc) - // } else { - // iVM, createErr = ihost.CreateVM(desc.Name, desc.ExternalImageId, desc.SysDiskSize, desc.Cpu, desc.Memory, desc.ExternalNetworkId, - // desc.IpAddr, desc.Description, passwd, desc.StorageType, desc.DataDisks, publicKey, secgroupExtId, userData, bc) - // } - if createErr != nil { return nil, createErr } @@ -189,7 +138,7 @@ func (self *SAliyunGuestDriver) RequestDeployGuestOnHost(ctx context.Context, gu return nil, err } - data := fetchIVMinfo(desc, iVM, guest.Id, "root", passwd, action) + data := fetchIVMinfo(desc, iVM, guest.Id, "root", desc.Password, action) return data, nil }) @@ -203,37 +152,23 @@ func (self *SAliyunGuestDriver) RequestDeployGuestOnHost(ctx context.Context, gu params := task.GetParams() log.Debugf("Deploy VM params %s", params.String()) - name, _ := params.GetString("name") - description, _ := params.GetString("description") - publicKey, _ := config.GetString("public_key") - // resetPassword := jsonutils.QueryBoolean(params, "reset_password", false) deleteKeypair := jsonutils.QueryBoolean(params, "__delete_keypair__", false) - //password, _ := params.GetString("password") - //if resetPassword && len(password) == 0 { - // password = seclib2.RandomPassword2(12) - //} - - /* - publicKey := "" - if k, e := config.GetString("public_key"); e == nil { - publicKey = k - }*/ taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { - if len(userData) > 0 { - err := iVM.UpdateUserData(userData) + if len(desc.UserData) > 0 { + err := iVM.UpdateUserData(desc.UserData) if err != nil { log.Errorf("update userdata fail %s", err) } } - err := iVM.DeployVM(ctx, name, passwd, publicKey, deleteKeypair, description) + err := iVM.DeployVM(ctx, desc.Name, desc.Password, desc.PublicKey, deleteKeypair, desc.Description) if err != nil { return nil, err } - data := fetchIVMinfo(desc, iVM, guest.Id, "root", passwd, action) + data := fetchIVMinfo(desc, iVM, guest.Id, "root", desc.Password, action) return data, nil }) @@ -246,14 +181,14 @@ func (self *SAliyunGuestDriver) RequestDeployGuestOnHost(ctx context.Context, gu } taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { - if len(userData) > 0 { - err := iVM.UpdateUserData(userData) + if len(desc.UserData) > 0 { + err := iVM.UpdateUserData(desc.UserData) if err != nil { log.Errorf("update userdata fail %s", err) } } - diskId, err := iVM.RebuildRoot(ctx, desc.ExternalImageId, passwd, publicKey, desc.SysDiskSize) + diskId, err := iVM.RebuildRoot(ctx, desc.ExternalImageId, desc.Password, desc.PublicKey, desc.SysDisk.SizeGB) if err != nil { return nil, err } @@ -294,7 +229,7 @@ func (self *SAliyunGuestDriver) RequestDeployGuestOnHost(ctx context.Context, gu } } - data := fetchIVMinfo(desc, iVM, guest.Id, "root", passwd, action) + data := fetchIVMinfo(desc, iVM, guest.Id, "root", desc.Password, action) return data, nil }) diff --git a/pkg/compute/guestdrivers/aws.go b/pkg/compute/guestdrivers/aws.go index 054121f0c6..f253ed4dfe 100644 --- a/pkg/compute/guestdrivers/aws.go +++ b/pkg/compute/guestdrivers/aws.go @@ -90,9 +90,16 @@ func (self *SAwsGuestDriver) ValidateResizeDisk(guest *models.SGuest, disk *mode } func (self *SAwsGuestDriver) RequestDeployGuestOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error { - config := guest.GetDeployConfigOnHost(ctx, host, task.GetParams()) + config, err := guest.GetDeployConfigOnHost(ctx, task.GetUserCred(), host, task.GetParams()) + if err != nil { + log.Errorf("GetDeployConfigOnHost error: %v", err) + return err + } log.Debugf("RequestDeployGuestOnHost: %s", config) - + desc := cloudprovider.SManagedVMCreateConfig{} + if err := desc.GetConfig(config); err != nil { + return err + } action, err := config.GetString("action") if err != nil { return err @@ -103,56 +110,11 @@ func (self *SAwsGuestDriver) RequestDeployGuestOnHost(ctx context.Context, guest return err } - desc := cloudprovider.SManagedVMCreateConfig{} - err = config.Unmarshal(&desc, "desc") - if err != nil { - return err - } - publicKey, _ := config.GetString("public_key") - passwd, _ := config.GetString("password") - - adminPublicKey, _ := config.GetString("admin_public_key") - projectPublicKey, _ := config.GetString("project_public_key") - oUserData, _ := config.GetString("user_data") - - userData := generateUserData(adminPublicKey, projectPublicKey, oUserData) - switch action { case "create": taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { - nets := guest.GetNetworks() - net := nets[0].GetNetwork() - vpc := net.GetVpc() - - iregion, err := host.GetIRegion() - if err != nil { - return nil, err - } - - secgroupCache := models.SecurityGroupCacheManager.Register(ctx, task.GetUserCred(), desc.SecGroupId, vpc.Id, vpc.CloudregionId, vpc.ManagerId) - if secgroupCache == nil { - return nil, fmt.Errorf("failed to registor secgroupCache for secgroup: %s, vpc: %s", desc.SecGroupId, vpc.Name) - } - - secgroupExtId, err := iregion.SyncSecurityGroup(secgroupCache.ExternalId, vpc.ExternalId, desc.SecGroupName, "", desc.SecRules) - if err != nil { - log.Errorf("SyncSecurityGroup fail %s", err) - return nil, err - } - if err := secgroupCache.SetExternalId(secgroupExtId); err != nil { - return nil, fmt.Errorf("failed to set externalId for secgroup %s externalId %s: error: %v", desc.SecGroupId, secgroupExtId, err) - } - - var createErr error - var iVM cloudprovider.ICloudVM - if len(desc.InstanceType) > 0 { - iVM, createErr = ihost.CreateVM2(desc.Name, desc.ExternalImageId, desc.SysDiskSize, desc.InstanceType, desc.ExternalNetworkId, - desc.IpAddr, desc.Description, passwd, desc.StorageType, desc.DataDisks, publicKey, secgroupExtId, userData, nil) - } else { - iVM, createErr = ihost.CreateVM(desc.Name, desc.ExternalImageId, desc.SysDiskSize, desc.Cpu, desc.Memory, desc.ExternalNetworkId, - desc.IpAddr, desc.Description, passwd, desc.StorageType, desc.DataDisks, publicKey, secgroupExtId, userData, nil) - } + iVM, createErr := ihost.CreateVM(&desc) if createErr != nil { return nil, createErr } @@ -170,7 +132,7 @@ func (self *SAwsGuestDriver) RequestDeployGuestOnHost(ctx context.Context, guest return nil, err } - data := fetchIVMinfo(desc, iVM, guest.Id, "root", passwd, action) + data := fetchIVMinfo(desc, iVM, guest.Id, "root", desc.Password, action) return data, nil }) case "deploy": @@ -182,19 +144,15 @@ func (self *SAwsGuestDriver) RequestDeployGuestOnHost(ctx context.Context, guest params := task.GetParams() log.Debugf("Deploy VM params %s", params.String()) - - name, _ := params.GetString("name") - description, _ := params.GetString("description") - publicKey, _ := config.GetString("public_key") deleteKeypair := jsonutils.QueryBoolean(params, "__delete_keypair__", false) taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { - err := iVM.DeployVM(ctx, name, passwd, publicKey, deleteKeypair, description) + err := iVM.DeployVM(ctx, desc.Name, desc.Password, desc.PublicKey, deleteKeypair, desc.Description) if err != nil { return nil, err } - data := fetchIVMinfo(desc, iVM, guest.Id, ansible.PUBLIC_CLOUD_ANSIBLE_USER, passwd, action) + data := fetchIVMinfo(desc, iVM, guest.Id, ansible.PUBLIC_CLOUD_ANSIBLE_USER, desc.Password, action) return data, nil }) case "rebuild": @@ -205,7 +163,7 @@ func (self *SAwsGuestDriver) RequestDeployGuestOnHost(ctx context.Context, guest } taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { - diskId, err := iVM.RebuildRoot(ctx, desc.ExternalImageId, passwd, publicKey, desc.SysDiskSize) + diskId, err := iVM.RebuildRoot(ctx, desc.ExternalImageId, desc.Password, desc.PublicKey, desc.SysDisk.SizeGB) if err != nil { return nil, err } @@ -246,7 +204,7 @@ func (self *SAwsGuestDriver) RequestDeployGuestOnHost(ctx context.Context, guest } } - data := fetchIVMinfo(desc, iVM, guest.Id, ansible.PUBLIC_CLOUD_ANSIBLE_USER, passwd, action) + data := fetchIVMinfo(desc, iVM, guest.Id, ansible.PUBLIC_CLOUD_ANSIBLE_USER, desc.Password, action) return data, nil }) diff --git a/pkg/compute/guestdrivers/azure.go b/pkg/compute/guestdrivers/azure.go index e4d57e9122..b97880efb4 100644 --- a/pkg/compute/guestdrivers/azure.go +++ b/pkg/compute/guestdrivers/azure.go @@ -116,24 +116,16 @@ func (self *SAzureGuestDriver) ValidateUpdateData(ctx context.Context, userCred } func (self *SAzureGuestDriver) RequestDeployGuestOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error { - config := guest.GetDeployConfigOnHost(ctx, host, task.GetParams()) - publicKey, _ := config.GetString("public_key") - resetPassword := jsonutils.QueryBoolean(config, "reset_password", false) - passwd, _ := config.GetString("password") - if resetPassword && len(passwd) == 0 { - passwd = seclib2.RandomPassword2(12) - } - - adminPublicKey, _ := config.GetString("admin_public_key") - projectPublicKey, _ := config.GetString("project_public_key") - oUserData, _ := config.GetString("user_data") - - userData := generateUserData(adminPublicKey, projectPublicKey, oUserData) - - desc := cloudprovider.SManagedVMCreateConfig{} - if err := config.Unmarshal(&desc, "desc"); err != nil { + config, err := guest.GetDeployConfigOnHost(ctx, task.GetUserCred(), host, task.GetParams()) + if err != nil { + log.Errorf("GetDeployConfigOnHost error: %v", err) return err } + desc := cloudprovider.SManagedVMCreateConfig{} + if err := desc.GetConfig(config); err != nil { + return err + } + action, err := config.GetString("action") if err != nil { return err @@ -144,48 +136,12 @@ func (self *SAzureGuestDriver) RequestDeployGuestOnHost(ctx context.Context, gue } if action == "create" { taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { - if len(passwd) == 0 { + if len(desc.Password) == 0 { //Azure创建必须要设置密码 - passwd = seclib2.RandomPassword2(12) + desc.Password = seclib2.RandomPassword2(12) } - nets := guest.GetNetworks() - net := nets[0].GetNetwork() - vpc := net.GetVpc() - - iregion, err := host.GetIRegion() - if err != nil { - return nil, err - } - - vpcId := "normal" - if strings.HasSuffix(host.Name, "-classic") { - vpcId = "classic" - } - - secgroupCache := models.SecurityGroupCacheManager.Register(ctx, task.GetUserCred(), desc.SecGroupId, vpcId, vpc.CloudregionId, vpc.ManagerId) - if secgroupCache == nil { - return nil, fmt.Errorf("failed to registor secgroupCache for secgroup: %s, vpc: %s", desc.SecGroupId, vpc.Name) - } - - secgroupExtId, err := iregion.SyncSecurityGroup(secgroupCache.ExternalId, vpcId, desc.SecGroupName, "", desc.SecRules) - if err != nil { - log.Errorf("SyncSecurityGroup fail %s", err) - return nil, err - } - if err := secgroupCache.SetExternalId(secgroupExtId); err != nil { - return nil, fmt.Errorf("failed to set externalId for secgroup %s externalId %s: error: %v", desc.SecGroupId, secgroupExtId, err) - } - - var createErr error - var iVM cloudprovider.ICloudVM - if len(desc.InstanceType) > 0 { - iVM, createErr = ihost.CreateVM2(desc.Name, desc.ExternalImageId, desc.SysDiskSize, desc.InstanceType, desc.ExternalNetworkId, - desc.IpAddr, desc.Description, passwd, desc.StorageType, desc.DataDisks, publicKey, secgroupExtId, userData, nil) - } else { - iVM, createErr = ihost.CreateVM(desc.Name, desc.ExternalImageId, desc.SysDiskSize, desc.Cpu, desc.Memory, desc.ExternalNetworkId, - desc.IpAddr, desc.Description, passwd, desc.StorageType, desc.DataDisks, publicKey, secgroupExtId, userData, nil) - } + iVM, createErr := ihost.CreateVM(&desc) if createErr != nil { return nil, createErr @@ -200,7 +156,7 @@ func (self *SAzureGuestDriver) RequestDeployGuestOnHost(ctx context.Context, gue return nil, err } - data := fetchIVMinfo(desc, iVM, guest.Id, ansible.PUBLIC_CLOUD_ANSIBLE_USER, passwd, action) + data := fetchIVMinfo(desc, iVM, guest.Id, ansible.PUBLIC_CLOUD_ANSIBLE_USER, desc.Password, action) return data, nil }) } else if action == "deploy" { @@ -211,18 +167,14 @@ func (self *SAzureGuestDriver) RequestDeployGuestOnHost(ctx context.Context, gue } params := task.GetParams() log.Debugf("Deploy VM params %s", params.String()) - - name, _ := params.GetString("name") - description, _ := params.GetString("description") - publicKey, _ := config.GetString("public_key") deleteKeypair := jsonutils.QueryBoolean(params, "__delete_keypair__", false) taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { - err := iVM.DeployVM(ctx, name, passwd, publicKey, deleteKeypair, description) + err := iVM.DeployVM(ctx, desc.Name, desc.Password, desc.PublicKey, deleteKeypair, desc.Description) if err != nil { return nil, err } - data := fetchIVMinfo(desc, iVM, guest.Id, ansible.PUBLIC_CLOUD_ANSIBLE_USER, passwd, action) + data := fetchIVMinfo(desc, iVM, guest.Id, ansible.PUBLIC_CLOUD_ANSIBLE_USER, desc.Password, action) return data, nil }) } else if action == "rebuild" { @@ -233,13 +185,13 @@ func (self *SAzureGuestDriver) RequestDeployGuestOnHost(ctx context.Context, gue } taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { - _, err := iVM.RebuildRoot(ctx, desc.ExternalImageId, passwd, publicKey, desc.SysDiskSize) + _, err := iVM.RebuildRoot(ctx, desc.ExternalImageId, desc.Password, desc.PublicKey, desc.SysDisk.SizeGB) if err != nil { return nil, err } log.Debugf("VMrebuildRoot %s, and status is ready", iVM.GetGlobalId()) - data := fetchIVMinfo(desc, iVM, guest.Id, ansible.PUBLIC_CLOUD_ANSIBLE_USER, passwd, action) + data := fetchIVMinfo(desc, iVM, guest.Id, ansible.PUBLIC_CLOUD_ANSIBLE_USER, desc.Password, action) return data, nil }) diff --git a/pkg/compute/guestdrivers/baremetals.go b/pkg/compute/guestdrivers/baremetals.go index ef8dabb121..53312f5fe0 100644 --- a/pkg/compute/guestdrivers/baremetals.go +++ b/pkg/compute/guestdrivers/baremetals.go @@ -289,7 +289,7 @@ func (self *SBaremetalGuestDriver) ValidateCreateHostData(ctx context.Context, u return data, nil } -func (self *SBaremetalGuestDriver) GetJsonDescAtHost(ctx context.Context, guest *models.SGuest, host *models.SHost) jsonutils.JSONObject { +func (self *SBaremetalGuestDriver) GetJsonDescAtHost(ctx context.Context, userCred mcclient.TokenCredential, guest *models.SGuest, host *models.SHost) jsonutils.JSONObject { return guest.GetJsonDescAtBaremetal(ctx, host) } @@ -352,7 +352,11 @@ func (self *SBaremetalGuestDriver) OnGuestDeployTaskDataReceived(ctx context.Con } func (self *SBaremetalGuestDriver) RequestDeployGuestOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error { - config := guest.GetDeployConfigOnHost(ctx, host, task.GetParams()) + config, err := guest.GetDeployConfigOnHost(ctx, task.GetUserCred(), host, task.GetParams()) + if err != nil { + log.Errorf("GetDeployConfigOnHost error: %v", err) + return err + } val, _ := config.GetString("action") if len(val) == 0 { val = "deploy" @@ -362,7 +366,7 @@ func (self *SBaremetalGuestDriver) RequestDeployGuestOnHost(ctx context.Context, } url := fmt.Sprintf("/baremetals/%s/servers/%s/%s", host.Id, guest.Id, val) headers := task.GetTaskRequestHeader() - _, err := host.BaremetalSyncRequest(ctx, "POST", url, headers, config) + _, err = host.BaremetalSyncRequest(ctx, "POST", url, headers, config) return err } diff --git a/pkg/compute/guestdrivers/container.go b/pkg/compute/guestdrivers/container.go index 635a6b30e0..ed49d2d6bf 100644 --- a/pkg/compute/guestdrivers/container.go +++ b/pkg/compute/guestdrivers/container.go @@ -5,6 +5,7 @@ import ( "fmt" "yunion.io/x/jsonutils" + "yunion.io/x/log" "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" "yunion.io/x/onecloud/pkg/compute/models" @@ -126,12 +127,16 @@ func (self *SContainerDriver) OnGuestDeployTaskComplete(ctx context.Context, gue return nil } -func (self *SContainerDriver) GetJsonDescAtHost(ctx context.Context, guest *models.SGuest, host *models.SHost) jsonutils.JSONObject { +func (self *SContainerDriver) GetJsonDescAtHost(ctx context.Context, userCred mcclient.TokenCredential, guest *models.SGuest, host *models.SHost) jsonutils.JSONObject { return guest.GetJsonDescAtHypervisor(ctx, host) } func (self *SContainerDriver) RequestDeployGuestOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error { - config := guest.GetDeployConfigOnHost(ctx, host, task.GetParams()) + config, err := guest.GetDeployConfigOnHost(ctx, task.GetUserCred(), host, task.GetParams()) + if err != nil { + log.Errorf("GetDeployConfigOnHost error: %v", err) + return err + } config.Add(jsonutils.JSONTrue, "k8s_pod") action, err := config.GetString("action") if err != nil { diff --git a/pkg/compute/guestdrivers/esxi.go b/pkg/compute/guestdrivers/esxi.go index fbc5fc9778..7de0c265af 100644 --- a/pkg/compute/guestdrivers/esxi.go +++ b/pkg/compute/guestdrivers/esxi.go @@ -11,6 +11,7 @@ import ( "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" "yunion.io/x/onecloud/pkg/compute/models" + "yunion.io/x/onecloud/pkg/mcclient" "yunion.io/x/onecloud/pkg/util/billing" "yunion.io/x/onecloud/pkg/util/httputils" ) @@ -93,12 +94,16 @@ func (self *SESXiGuestDriver) RequestDetachDisk(ctx context.Context, guest *mode return guest.StartSyncTask(ctx, task.GetUserCred(), false, task.GetTaskId()) } -func (self *SESXiGuestDriver) GetJsonDescAtHost(ctx context.Context, guest *models.SGuest, host *models.SHost) jsonutils.JSONObject { +func (self *SESXiGuestDriver) GetJsonDescAtHost(ctx context.Context, userCred mcclient.TokenCredential, guest *models.SGuest, host *models.SHost) jsonutils.JSONObject { return guest.GetJsonDescAtHypervisor(ctx, host) } func (self *SESXiGuestDriver) RequestDeployGuestOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error { - config := guest.GetDeployConfigOnHost(ctx, host, task.GetParams()) + config, err := guest.GetDeployConfigOnHost(ctx, task.GetUserCred(), host, task.GetParams()) + if err != nil { + log.Errorf("GetDeployConfigOnHost error: %v", err) + return err + } log.Debugf("RequestDeployGuestOnHost: %s", config) if !host.IsEsxiAgentReady() { diff --git a/pkg/compute/guestdrivers/huawei.go b/pkg/compute/guestdrivers/huawei.go index ddf3443f59..53e0d01de0 100644 --- a/pkg/compute/guestdrivers/huawei.go +++ b/pkg/compute/guestdrivers/huawei.go @@ -12,7 +12,6 @@ import ( "yunion.io/x/onecloud/pkg/compute/models" "yunion.io/x/onecloud/pkg/mcclient" "yunion.io/x/onecloud/pkg/util/billing" - "yunion.io/x/onecloud/pkg/util/seclib2" "yunion.io/x/pkg/utils" ) @@ -87,80 +86,32 @@ func (self *SHuaweiGuestDriver) ValidateResizeDisk(guest *models.SGuest, disk *m } func (self *SHuaweiGuestDriver) RequestDeployGuestOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error { - config := guest.GetDeployConfigOnHost(ctx, host, task.GetParams()) + config, err := guest.GetDeployConfigOnHost(ctx, task.GetUserCred(), host, task.GetParams()) + if err != nil { + log.Errorf("GetDeployConfigOnHost error: %v", err) + return err + } log.Debugf("RequestDeployGuestOnHost: %s", config) + desc := cloudprovider.SManagedVMCreateConfig{} + if err := desc.GetConfig(config); err != nil { + return err + } + action, err := config.GetString("action") if err != nil { return err } - publicKey, _ := config.GetString("public_key") - - adminPublicKey, _ := config.GetString("admin_public_key") - projectPublicKey, _ := config.GetString("project_public_key") - oUserData, _ := config.GetString("user_data") - - userData := generateUserData(adminPublicKey, projectPublicKey, oUserData) - - resetPassword := jsonutils.QueryBoolean(config, "reset_password", false) - passwd, _ := config.GetString("password") - if resetPassword && len(passwd) == 0 { - passwd = seclib2.RandomPassword2(12) - } - ihost, err := host.GetIHost() if err != nil { return err } - desc := SManagedVMCreateConfig{} - err = config.Unmarshal(&desc, "desc") - if err != nil { - return err - } - if action == "create" { taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { - nets := guest.GetNetworks() - net := nets[0].GetNetwork() - vpc := net.GetVpc() - iregion, err := host.GetIRegion() - if err != nil { - return nil, err - } - - secgroupCache := models.SecurityGroupCacheManager.Register(ctx, task.GetUserCred(), desc.SecGroupId, vpc.Id, vpc.CloudregionId, vpc.ManagerId) - if secgroupCache == nil { - return nil, fmt.Errorf("failed to registor secgroupCache for secgroup: %s, vpc: %s", desc.SecGroupId, vpc.Name) - } - - secgroupExtId, err := iregion.SyncSecurityGroup(secgroupCache.ExternalId, vpc.ExternalId, desc.SecGroupName, "", desc.SecRules) - if err != nil { - log.Errorf("SyncSecurityGroup fail %s", err) - return nil, err - } - if err := secgroupCache.SetExternalId(secgroupExtId); err != nil { - return nil, fmt.Errorf("failed to set externalId for secgroup %s externalId %s: error: %v", desc.SecGroupId, secgroupExtId, err) - } - - var createErr error - var iVM cloudprovider.ICloudVM - - var bc *billing.SBillingCycle - if desc.BillingCycle.IsValid() { - bc = &desc.BillingCycle - } - - if len(desc.InstanceType) > 0 { - iVM, createErr = ihost.CreateVM2(desc.Name, desc.ExternalImageId, desc.SysDiskSize, desc.InstanceType, desc.ExternalNetworkId, - desc.IpAddr, desc.Description, passwd, desc.StorageType, desc.DataDisks, publicKey, secgroupExtId, userData, bc) - } else { - iVM, createErr = ihost.CreateVM(desc.Name, desc.ExternalImageId, desc.SysDiskSize, desc.Cpu, desc.Memory, desc.ExternalNetworkId, - desc.IpAddr, desc.Description, passwd, desc.StorageType, desc.DataDisks, publicKey, secgroupExtId, userData, bc) - } - + iVM, createErr := ihost.CreateVM(&desc) if createErr != nil { return nil, createErr } @@ -177,7 +128,7 @@ func (self *SHuaweiGuestDriver) RequestDeployGuestOnHost(ctx context.Context, gu return nil, err } - data := fetchIVMinfo(desc, iVM, guest.Id, "root", passwd, action) + data := fetchIVMinfo(desc, iVM, guest.Id, "root", desc.Password, action) return data, nil }) @@ -191,25 +142,22 @@ func (self *SHuaweiGuestDriver) RequestDeployGuestOnHost(ctx context.Context, gu params := task.GetParams() log.Debugf("Deploy VM params %s", params.String()) - name, _ := params.GetString("name") - description, _ := params.GetString("description") - publicKey, _ := config.GetString("public_key") deleteKeypair := jsonutils.QueryBoolean(params, "__delete_keypair__", false) taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { - if len(userData) > 0 { - err := iVM.UpdateUserData(userData) + if len(desc.UserData) > 0 { + err := iVM.UpdateUserData(desc.UserData) if err != nil { log.Errorf("update userdata fail %s", err) } } - err := iVM.DeployVM(ctx, name, passwd, publicKey, deleteKeypair, description) + err := iVM.DeployVM(ctx, desc.Name, desc.Password, desc.PublicKey, deleteKeypair, desc.Description) if err != nil { return nil, err } - data := fetchIVMinfo(desc, iVM, guest.Id, "root", passwd, action) + data := fetchIVMinfo(desc, iVM, guest.Id, "root", desc.Password, action) return data, nil }) @@ -222,14 +170,14 @@ func (self *SHuaweiGuestDriver) RequestDeployGuestOnHost(ctx context.Context, gu } taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { - if len(userData) > 0 { - err := iVM.UpdateUserData(userData) + if len(desc.UserData) > 0 { + err := iVM.UpdateUserData(desc.UserData) if err != nil { log.Errorf("update userdata fail %s", err) } } - diskId, err := iVM.RebuildRoot(ctx, desc.ExternalImageId, passwd, publicKey, desc.SysDiskSize) + diskId, err := iVM.RebuildRoot(ctx, desc.ExternalImageId, desc.Password, desc.PublicKey, desc.SysDisk.SizeGB) if err != nil { return nil, err } @@ -270,7 +218,7 @@ func (self *SHuaweiGuestDriver) RequestDeployGuestOnHost(ctx context.Context, gu } } - data := fetchIVMinfo(desc, iVM, guest.Id, "root", passwd, action) + data := fetchIVMinfo(desc, iVM, guest.Id, "root", desc.Password, action) return data, nil }) diff --git a/pkg/compute/guestdrivers/kvm.go b/pkg/compute/guestdrivers/kvm.go index 1624d37548..374e15eeaf 100644 --- a/pkg/compute/guestdrivers/kvm.go +++ b/pkg/compute/guestdrivers/kvm.go @@ -179,12 +179,16 @@ func (self *SKVMGuestDriver) RequestUndeployGuestOnHost(ctx context.Context, gue return nil } -func (self *SKVMGuestDriver) GetJsonDescAtHost(ctx context.Context, guest *models.SGuest, host *models.SHost) jsonutils.JSONObject { +func (self *SKVMGuestDriver) GetJsonDescAtHost(ctx context.Context, userCred mcclient.TokenCredential, guest *models.SGuest, host *models.SHost) jsonutils.JSONObject { return guest.GetJsonDescAtHypervisor(ctx, host) } func (self *SKVMGuestDriver) RequestDeployGuestOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error { - config := guest.GetDeployConfigOnHost(ctx, host, task.GetParams()) + config, err := guest.GetDeployConfigOnHost(ctx, task.GetUserCred(), host, task.GetParams()) + if err != nil { + log.Errorf("GetDeployConfigOnHost error: %v", err) + return err + } log.Debugf("RequestDeployGuestOnHost: %s", config) if config.Contains("container") { // ... @@ -211,7 +215,7 @@ func (self *SKVMGuestDriver) RequestStartOnHost(ctx context.Context, guest *mode header := self.getTaskRequestHeader(task) config := jsonutils.NewDict() - desc := guest.GetDriver().GetJsonDescAtHost(ctx, guest, host) + desc := guest.GetDriver().GetJsonDescAtHost(ctx, userCred, guest, host) config.Add(desc, "desc") params := task.GetParams() if params.Length() > 0 { @@ -288,7 +292,7 @@ func (self *SKVMGuestDriver) ValidateResizeDisk(guest *models.SGuest, disk *mode } func (self *SKVMGuestDriver) RequestSyncConfigOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error { - desc := guest.GetDriver().GetJsonDescAtHost(ctx, guest, host) + desc := guest.GetDriver().GetJsonDescAtHost(ctx, task.GetUserCred(), guest, host) body := jsonutils.NewDict() body.Add(desc, "desc") if fw_only, _ := task.GetParams().Bool("fw_only"); fw_only { diff --git a/pkg/compute/guestdrivers/managedvirtual.go b/pkg/compute/guestdrivers/managedvirtual.go index 96ba96fff4..69dd148d3b 100644 --- a/pkg/compute/guestdrivers/managedvirtual.go +++ b/pkg/compute/guestdrivers/managedvirtual.go @@ -8,7 +8,6 @@ import ( "yunion.io/x/jsonutils" "yunion.io/x/log" "yunion.io/x/pkg/util/compare" - "yunion.io/x/pkg/util/secrules" "yunion.io/x/onecloud/pkg/cloudcommon/db" "yunion.io/x/onecloud/pkg/cloudcommon/db/lockman" @@ -23,33 +22,11 @@ type SManagedVirtualizedGuestDriver struct { SVirtualizedGuestDriver } -type SManagedVMCreateConfig struct { - Name string - ExternalImageId string - OsDistribution string - OsVersion string - InstanceType string // InstanceType 不为空时,直接采用InstanceType创建机器。 - Cpu int - Memory int - ExternalNetworkId string - IpAddr string - Description string - StorageType string - SysDiskSize int - DataDisks []int - PublicKey string - SecGroupId string - SecGroupName string - SecRules []secrules.SecurityRule - - BillingCycle billing.SBillingCycle -} - -func (self *SManagedVirtualizedGuestDriver) GetJsonDescAtHost(ctx context.Context, guest *models.SGuest, host *models.SHost) jsonutils.JSONObject { +func (self *SManagedVirtualizedGuestDriver) GetJsonDescAtHost(ctx context.Context, userCred mcclient.TokenCredential, guest *models.SGuest, host *models.SHost) jsonutils.JSONObject { config := cloudprovider.SManagedVMCreateConfig{} config.Name = guest.Name config.Cpu = int(guest.VcpuCount) - config.Memory = guest.VmemSize + config.MemoryMB = guest.VmemSize config.Description = guest.Description config.InstanceType = guest.InstanceType @@ -63,18 +40,15 @@ func (self *SManagedVirtualizedGuestDriver) GetJsonDescAtHost(ctx context.Contex config.ExternalNetworkId = net.ExternalId config.IpAddr = nics[0].IpAddr - config.SecGroupId = guest.SecgrpId - config.SecGroupName = guest.GetSecgroupName() - config.SecRules = guest.GetSecRules() - disks := guest.GetDisks() - config.DataDisks = make([]int, len(disks)-1) + config.DataDisks = []cloudprovider.SDiskInfo{} for i := 0; i < len(disks); i += 1 { disk := disks[i].GetDisk() + storage := disk.GetStorage() if i == 0 { - storage := disk.GetStorage() - config.StorageType = storage.StorageType + config.SysDisk.StorageType = storage.StorageType + config.SysDisk.SizeGB = disk.DiskSize / 1024 cache := storage.GetStoragecache() imageId := disk.GetTemplateId() //避免因同步过来的instance没有对应的imagecache信息,重置密码时引发空指针访问 @@ -84,9 +58,12 @@ func (self *SManagedVirtualizedGuestDriver) GetJsonDescAtHost(ctx context.Contex config.OsDistribution, _ = img.Info.GetString("properties", "os_distribution") config.OsVersion, _ = img.Info.GetString("properties", "os_version") } - config.SysDiskSize = disk.DiskSize / 1024 // MB => GB } else { - config.DataDisks[i-1] = disk.DiskSize / 1024 // MB => GB + dataDisk := cloudprovider.SDiskInfo{ + SizeGB: disk.DiskSize / 1024, + StorageType: storage.StorageType, + } + config.DataDisks = append(config.DataDisks, dataDisk) } } @@ -95,7 +72,9 @@ func (self *SManagedVirtualizedGuestDriver) GetJsonDescAtHost(ctx context.Contex if err != nil { log.Errorf("fail to parse billing cycle %s: %s", guest.BillingCycle, err) } - config.BillingCycle = bc + if bc.IsValid() { + config.BillingCycle = &bc + } } return jsonutils.Marshal(&config) diff --git a/pkg/compute/guestdrivers/qcloud.go b/pkg/compute/guestdrivers/qcloud.go index 943e1dd1e1..d994717c76 100644 --- a/pkg/compute/guestdrivers/qcloud.go +++ b/pkg/compute/guestdrivers/qcloud.go @@ -17,7 +17,6 @@ import ( "yunion.io/x/onecloud/pkg/httperrors" "yunion.io/x/onecloud/pkg/mcclient" "yunion.io/x/onecloud/pkg/util/billing" - "yunion.io/x/onecloud/pkg/util/seclib2" ) type SQcloudGuestDriver struct { @@ -114,30 +113,25 @@ func (self *SQcloudGuestDriver) ValidateCreateData(ctx context.Context, userCred } func (self *SQcloudGuestDriver) RequestDeployGuestOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error { - config := guest.GetDeployConfigOnHost(ctx, host, task.GetParams()) + config, err := guest.GetDeployConfigOnHost(ctx, task.GetUserCred(), host, task.GetParams()) + if err != nil { + log.Errorf("GetDeployConfigOnHost error: %v", err) + return err + } log.Debugf("RequestDeployGuestOnHost: %s", config) /* onfinish, err := config.GetString("on_finish") if err != nil { return err } */ - action, err := config.GetString("action") - if err != nil { + desc := cloudprovider.SManagedVMCreateConfig{} + if err := desc.GetConfig(config); err != nil { return err } - publicKey, _ := config.GetString("public_key") - - adminPublicKey, _ := config.GetString("admin_public_key") - projectPublicKey, _ := config.GetString("project_public_key") - oUserData, _ := config.GetString("user_data") - - userData := generateUserData(adminPublicKey, projectPublicKey, oUserData) - - resetPassword := jsonutils.QueryBoolean(config, "reset_password", false) - passwd, _ := config.GetString("password") - if resetPassword && len(passwd) == 0 { - passwd = seclib2.RandomPassword2(12) + action, err := config.GetString("action") + if err != nil { + return err } ihost, err := host.GetIHost() @@ -145,52 +139,10 @@ func (self *SQcloudGuestDriver) RequestDeployGuestOnHost(ctx context.Context, gu return err } - desc := cloudprovider.SManagedVMCreateConfig{} - err = config.Unmarshal(&desc, "desc") - if err != nil { - return err - } - if action == "create" { taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { - nets := guest.GetNetworks() - net := nets[0].GetNetwork() - vpc := net.GetVpc() - - iregion, err := host.GetIRegion() - if err != nil { - return nil, err - } - - secgroupCache := models.SecurityGroupCacheManager.Register(ctx, task.GetUserCred(), desc.SecGroupId, "normal", vpc.CloudregionId, vpc.ManagerId) - if secgroupCache == nil { - return nil, fmt.Errorf("failed to registor secgroupCache for secgroup: %s, vpc: %s", desc.SecGroupId, vpc.Name) - } - - secgroupExtId, err := iregion.SyncSecurityGroup(secgroupCache.ExternalId, vpc.ExternalId, desc.SecGroupName, "", desc.SecRules) - if err != nil { - log.Errorf("SyncSecurityGroup fail %s", err) - return nil, err - } - if err := secgroupCache.SetExternalId(secgroupExtId); err != nil { - return nil, fmt.Errorf("failed to set externalId for secgroup %s externalId %s: error: %v", desc.SecGroupId, secgroupExtId, err) - } - - var createErr error - var iVM cloudprovider.ICloudVM - var bc *billing.SBillingCycle - if desc.BillingCycle.IsValid() { - bc = &desc.BillingCycle - } - if len(desc.InstanceType) > 0 { - iVM, createErr = ihost.CreateVM2(desc.Name, desc.ExternalImageId, desc.SysDiskSize, desc.InstanceType, desc.ExternalNetworkId, - desc.IpAddr, desc.Description, passwd, desc.StorageType, desc.DataDisks, publicKey, secgroupExtId, userData, bc) - } else { - iVM, createErr = ihost.CreateVM(desc.Name, desc.ExternalImageId, desc.SysDiskSize, desc.Cpu, desc.Memory, desc.ExternalNetworkId, - desc.IpAddr, desc.Description, passwd, desc.StorageType, desc.DataDisks, publicKey, secgroupExtId, userData, bc) - } - + iVM, createErr := ihost.CreateVM(&desc) if createErr != nil { return nil, createErr } @@ -224,7 +176,7 @@ func (self *SQcloudGuestDriver) RequestDeployGuestOnHost(ctx context.Context, gu return nil, err } - data := fetchIVMinfo(desc, iVM, guest.Id, "root", passwd, action) + data := fetchIVMinfo(desc, iVM, guest.Id, "root", desc.Password, action) return data, nil }) } else if action == "deploy" { @@ -237,9 +189,6 @@ func (self *SQcloudGuestDriver) RequestDeployGuestOnHost(ctx context.Context, gu params := task.GetParams() log.Debugf("Deploy VM params %s", params.String()) - name, _ := params.GetString("name") - description, _ := params.GetString("description") - publicKey, _ := config.GetString("public_key") deleteKeypair := jsonutils.QueryBoolean(params, "__delete_keypair__", false) taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { @@ -251,12 +200,12 @@ func (self *SQcloudGuestDriver) RequestDeployGuestOnHost(ctx context.Context, gu // } // } - err := iVM.DeployVM(ctx, name, passwd, publicKey, deleteKeypair, description) + err := iVM.DeployVM(ctx, desc.Name, desc.Password, desc.PublicKey, deleteKeypair, desc.Description) if err != nil { return nil, err } - data := fetchIVMinfo(desc, iVM, guest.Id, "root", passwd, action) + data := fetchIVMinfo(desc, iVM, guest.Id, "root", desc.Password, action) return data, nil }) } else if action == "rebuild" { @@ -276,7 +225,7 @@ func (self *SQcloudGuestDriver) RequestDeployGuestOnHost(ctx context.Context, gu // } // } - diskId, err := iVM.RebuildRoot(ctx, desc.ExternalImageId, passwd, publicKey, desc.SysDiskSize) + diskId, err := iVM.RebuildRoot(ctx, desc.ExternalImageId, desc.Password, desc.PublicKey, desc.SysDisk.SizeGB) if err != nil { return nil, err } @@ -317,7 +266,7 @@ func (self *SQcloudGuestDriver) RequestDeployGuestOnHost(ctx context.Context, gu } } - data := fetchIVMinfo(desc, iVM, guest.Id, "root", passwd, action) + data := fetchIVMinfo(desc, iVM, guest.Id, "root", desc.Password, action) return data, nil }) diff --git a/pkg/compute/models/guest_actions.go b/pkg/compute/models/guest_actions.go index 111b77d2a7..af9cb07d28 100644 --- a/pkg/compute/models/guest_actions.go +++ b/pkg/compute/models/guest_actions.go @@ -82,7 +82,7 @@ func (self *SGuest) GetDetailsDesc(ctx context.Context, userCred mcclient.TokenC if host == nil { return nil, httperrors.NewInvalidStatusError("No host for server") } - desc := self.GetDriver().GetJsonDescAtHost(ctx, self, host) + desc := self.GetDriver().GetJsonDescAtHost(ctx, userCred, self, host) return desc, nil } diff --git a/pkg/compute/models/guestdrivers.go b/pkg/compute/models/guestdrivers.go index cb7e7845f8..42a040c602 100644 --- a/pkg/compute/models/guestdrivers.go +++ b/pkg/compute/models/guestdrivers.go @@ -4,6 +4,7 @@ import ( "context" "time" + "yunion.io/x/jsonutils" "yunion.io/x/log" "yunion.io/x/onecloud/pkg/cloudcommon/db/quotas" @@ -23,7 +24,7 @@ type IGuestDriver interface { RequestRenewInstance(guest *SGuest, bc billing.SBillingCycle) (time.Time, error) - GetJsonDescAtHost(ctx context.Context, guest *SGuest, host *SHost) jsonutils.JSONObject + GetJsonDescAtHost(ctx context.Context, userCred mcclient.TokenCredential, guest *SGuest, host *SHost) jsonutils.JSONObject ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) diff --git a/pkg/compute/models/guests.go b/pkg/compute/models/guests.go index b009681319..1b9fe1b1d4 100644 --- a/pkg/compute/models/guests.go +++ b/pkg/compute/models/guests.go @@ -2682,10 +2682,10 @@ type SDeployConfig struct { Content string } -func (self *SGuest) GetDeployConfigOnHost(ctx context.Context, host *SHost, params *jsonutils.JSONDict) *jsonutils.JSONDict { +func (self *SGuest) GetDeployConfigOnHost(ctx context.Context, userCred mcclient.TokenCredential, host *SHost, params *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { config := jsonutils.NewDict() - desc := self.GetDriver().GetJsonDescAtHost(ctx, self, host) + desc := self.GetDriver().GetJsonDescAtHost(ctx, userCred, self, host) config.Add(desc, "desc") deploys := make([]SDeployConfig, 0) @@ -2754,7 +2754,55 @@ func (self *SGuest) GetDeployConfigOnHost(ctx context.Context, host *SHost, para config.Add(jsonutils.NewString(onFinish), "on_finish") - return config + if deployAction == "create" && !utils.IsInStringArray(self.Hypervisor, []string{HYPERVISOR_KVM, HYPERVISOR_BAREMETAL, HYPERVISOR_CONTAINER, HYPERVISOR_ESXI, HYPERVISOR_XEN}) { + nets := self.GetNetworks() + if len(nets) == 0 { + return nil, fmt.Errorf("failed to find network for guest %s", self.Name) + } + net := nets[0].GetNetwork() + vpc := net.GetVpc() + registerVpcId := vpc.ExternalId + externalVpcId := vpc.ExternalId + switch self.Hypervisor { + case HYPERVISOR_ALIYUN, HYPERVISOR_AWS, HYPERVISOR_OPENSTACK, HYPERVISOR_HUAWEI: + break + case HYPERVISOR_QCLOUD: + registerVpcId = "normal" + case HYPERVISOR_AZURE: + registerVpcId, externalVpcId = "normal", "normal" + if strings.HasSuffix(host.Name, "-classic") { + registerVpcId, externalVpcId = "classic", "classic" + } + default: + return nil, fmt.Errorf("Unknown guest %s hypervisor %s for sync secgroup", self.Name, self.Hypervisor) + } + iregion, err := host.GetIRegion() + if err != nil { + return nil, fmt.Errorf("failed to get iregion for host %s error: %v", host.Name, err) + } + secgroupIds := jsonutils.NewArray() + secgroups := self.GetSecgroups() + for i, secgroup := range secgroups { + secgroupCache := SecurityGroupCacheManager.Register(ctx, userCred, secgroup.Id, registerVpcId, vpc.CloudregionId, vpc.ManagerId) + if secgroupCache == nil { + return nil, fmt.Errorf("failed to registor secgroupCache for secgroup: %s(%s), vpc: %s", secgroup.Name, secgroup.Id, vpc.Name) + } + + externalSecgroupId, err := iregion.SyncSecurityGroup(secgroupCache.ExternalId, externalVpcId, secgroup.Name, secgroup.Description, secgroup.GetSecRules("")) + if err != nil { + return nil, fmt.Errorf("SyncSecurityGroup fail %s", err) + } + if err := secgroupCache.SetExternalId(externalSecgroupId); err != nil { + return nil, fmt.Errorf("failed to set externalId for secgroup %s(%s) externalId %s: error: %v", secgroup.Name, secgroup.Id, externalSecgroupId, err) + } + secgroupIds.Add(jsonutils.NewString(externalSecgroupId)) + if i == 0 { + config.Add(jsonutils.NewString(externalSecgroupId), "desc", "external_secgroup_id") + } + } + config.Add(secgroupIds, "desc", "external_secgroup_ids") + } + return config, nil } func (self *SGuest) getVga() string { diff --git a/pkg/util/aliyun/host.go b/pkg/util/aliyun/host.go index 21d970a436..488ca19655 100644 --- a/pkg/util/aliyun/host.go +++ b/pkg/util/aliyun/host.go @@ -166,11 +166,8 @@ func (self *SHost) GetInstanceById(instanceId string) (*SInstance, error) { return inst, nil } -func (self *SHost) CreateVM(name string, imgId string, sysDiskSize int, cpu int, memMB int, - vswitchId string, ipAddr string, desc string, passwd string, - storageType string, diskSizes []int, publicKey string, secgroupId string, userData string, - bc *billing.SBillingCycle) (cloudprovider.ICloudVM, error) { - vmId, err := self._createVM(name, imgId, sysDiskSize, cpu, memMB, "", vswitchId, ipAddr, desc, passwd, storageType, diskSizes, publicKey, secgroupId, userData, bc) +func (self *SHost) CreateVM(desc *cloudprovider.SManagedVMCreateConfig) (cloudprovider.ICloudVM, error) { + vmId, err := self._createVM(desc.Name, desc.ExternalImageId, desc.SysDisk, desc.Cpu, desc.MemoryMB, desc.InstanceType, desc.ExternalNetworkId, desc.IpAddr, desc.Description, desc.Password, desc.DataDisks, desc.PublicKey, desc.ExternalSecgroupId, desc.UserData, desc.BillingCycle) if err != nil { return nil, err } @@ -182,25 +179,9 @@ func (self *SHost) CreateVM(name string, imgId string, sysDiskSize int, cpu int, return vm, err } -func (self *SHost) CreateVM2(name string, imgId string, sysDiskSize int, instanceType string, +func (self *SHost) _createVM(name string, imgId string, sysDisk cloudprovider.SDiskInfo, cpu int, memMB int, instanceType string, vswitchId string, ipAddr string, desc string, passwd string, - storageType string, diskSizes []int, publicKey string, secgroupId string, - userData string, bc *billing.SBillingCycle) (cloudprovider.ICloudVM, error) { - vmId, err := self._createVM(name, imgId, sysDiskSize, 0, 0, instanceType, vswitchId, ipAddr, desc, passwd, storageType, diskSizes, publicKey, secgroupId, userData, bc) - if err != nil { - return nil, err - } - vm, err := self.GetInstanceById(vmId) - if err != nil { - return nil, err - } - // err = vm.waitStatus(InstanceStatusStopped, time.Second*10, time.Second*1800) - return vm, err -} - -func (self *SHost) _createVM(name string, imgId string, sysDiskSize int, cpu int, memMB int, instanceType string, - vswitchId string, ipAddr string, desc string, passwd string, - storageType string, diskSizes []int, publicKey string, secgroupId string, + dataDisks []cloudprovider.SDiskInfo, publicKey string, secgroupId string, userData string, bc *billing.SBillingCycle) (string, error) { net := self.zone.getNetworkById(vswitchId) if net == nil { @@ -234,21 +215,24 @@ func (self *SHost) _createVM(name string, imgId string, sysDiskSize int, cpu int return "", fmt.Errorf("image not ready") } - _, err = self.zone.getStorageByCategory(storageType) - if err != nil { - return "", fmt.Errorf("Storage %s not avaiable: %s", storageType, err) - } - - disks := make([]SDisk, len(diskSizes)+1) + disks := make([]SDisk, len(dataDisks)+1) disks[0].Size = img.Size - if sysDiskSize > 0 && sysDiskSize > img.Size { - disks[0].Size = sysDiskSize + if sysDisk.SizeGB > 0 && sysDisk.SizeGB > img.Size { + disks[0].Size = sysDisk.SizeGB } - disks[0].Category = storageType + storage, err := self.zone.getStorageByCategory(sysDisk.StorageType) + if err != nil { + return "", fmt.Errorf("Storage %s not avaiable: %s", sysDisk.StorageType, err) + } + disks[0].Category = storage.storageType - for i, sz := range diskSizes { - disks[i+1].Size = sz - disks[i+1].Category = storageType + for i, dataDisk := range dataDisks { + disks[i+1].Size = dataDisk.SizeGB + storage, err := self.zone.getStorageByCategory(dataDisk.StorageType) + if err != nil { + return "", fmt.Errorf("Storage %s not avaiable: %s", dataDisk.StorageType, err) + } + disks[i+1].Category = storage.storageType } if len(instanceType) > 0 { diff --git a/pkg/util/aliyun/region.go b/pkg/util/aliyun/region.go index ed8b309fe8..611e3f057b 100644 --- a/pkg/util/aliyun/region.go +++ b/pkg/util/aliyun/region.go @@ -413,7 +413,21 @@ func (self *SRegion) CreateInstanceSimple(name string, imgId string, cpu int, me log.Debugf("Search in zone %s", z.LocalName) net := z.getNetworkById(vswitchId) if net != nil { - inst, err := z.getHost().CreateVM(name, imgId, 0, cpu, memGB*1024, vswitchId, "", "", passwd, storageType, dataDiskSizesGB, publicKey, "", "", nil) + desc := &cloudprovider.SManagedVMCreateConfig{ + Name: name, + ExternalImageId: imgId, + SysDisk: cloudprovider.SDiskInfo{SizeGB: 0, StorageType: storageType}, + Cpu: cpu, + MemoryMB: memGB * 1024, + ExternalNetworkId: vswitchId, + Password: passwd, + DataDisks: []cloudprovider.SDiskInfo{}, + PublicKey: publicKey, + } + for _, sizeGB := range dataDiskSizesGB { + desc.DataDisks = append(desc.DataDisks, cloudprovider.SDiskInfo{SizeGB: sizeGB, StorageType: storageType}) + } + inst, err := z.getHost().CreateVM(desc) if err != nil { return nil, err } diff --git a/pkg/util/aws/host.go b/pkg/util/aws/host.go index 473f0e3f48..0e678087ff 100644 --- a/pkg/util/aws/host.go +++ b/pkg/util/aws/host.go @@ -8,7 +8,6 @@ import ( "yunion.io/x/onecloud/pkg/cloudprovider" "yunion.io/x/onecloud/pkg/compute/models" - "yunion.io/x/onecloud/pkg/util/billing" ) type SHost struct { @@ -161,10 +160,8 @@ func (self *SHost) GetInstanceById(instanceId string) (*SInstance, error) { return inst, nil } -func (self *SHost) CreateVM(name, imgId string, sysDiskSize, cpu, memMB int, networkId, ipAddr, desc, - passwd, storageType string, diskSizes []int, publicKey string, secgroupId string, userData string, - bc *billing.SBillingCycle) (cloudprovider.ICloudVM, error) { - vmId, err := self._createVM(name, imgId, sysDiskSize, cpu, memMB, "", networkId, ipAddr, desc, passwd, storageType, diskSizes, publicKey, secgroupId, userData) +func (self *SHost) CreateVM(desc *cloudprovider.SManagedVMCreateConfig) (cloudprovider.ICloudVM, error) { + vmId, err := self._createVM(desc.Name, desc.ExternalImageId, desc.SysDisk, desc.Cpu, desc.MemoryMB, desc.InstanceType, desc.ExternalNetworkId, desc.IpAddr, desc.Description, desc.Password, desc.DataDisks, desc.PublicKey, desc.ExternalSecgroupId, desc.UserData) if err != nil { return nil, err } @@ -177,24 +174,9 @@ func (self *SHost) CreateVM(name, imgId string, sysDiskSize, cpu, memMB int, net return vm, err } -func (self *SHost) CreateVM2(name, imgId string, sysDiskSize int, instanceType string, networkId, ipAddr, desc, - passwd, storageType string, diskSizes []int, publicKey string, secgroupId string, userData string, bc *billing.SBillingCycle) (cloudprovider.ICloudVM, error) { - vmId, err := self._createVM(name, imgId, sysDiskSize, 0, 0, instanceType, networkId, ipAddr, desc, passwd, storageType, diskSizes, publicKey, secgroupId, userData) - if err != nil { - return nil, err - } - - vm, err := self.GetInstanceById(vmId) - if err != nil { - return nil, err - } - - return vm, err -} - -func (self *SHost) _createVM(name, imgId string, sysDiskSize int, cpu, memMB int, instanceType string, - networkId, ipAddr, desc, passwd, - storageType string, diskSizes []int, publicKey string, secgroupId string, userData string) (string, error) { +func (self *SHost) _createVM(name, imgId string, sysDisk cloudprovider.SDiskInfo, cpu, memMB int, instanceType string, + networkId, ipAddr, desc, passwd string, + dataDisks []cloudprovider.SDiskInfo, publicKey string, secgroupId string, userData string) (string, error) { // 网络配置及安全组绑定 net := self.zone.getNetworkById(networkId) if net == nil { @@ -250,16 +232,16 @@ func (self *SHost) _createVM(name, imgId string, sysDiskSize int, cpu, memMB int return "", fmt.Errorf("image not ready") } - disks := make([]SDisk, len(diskSizes)+1) + disks := make([]SDisk, len(dataDisks)+1) disks[0].Size = img.SizeGB - if sysDiskSize > 0 && sysDiskSize > img.SizeGB { - disks[0].Size = sysDiskSize + if sysDisk.SizeGB > 0 && sysDisk.SizeGB > img.SizeGB { + disks[0].Size = sysDisk.SizeGB } - disks[0].Category = storageType + disks[0].Category = sysDisk.StorageType - for i, sz := range diskSizes { - disks[i+1].Size = sz - disks[i+1].Category = storageType + for i, dataDisk := range dataDisks { + disks[i+1].Size = dataDisk.SizeGB + disks[i+1].Category = dataDisk.StorageType } // 创建实例 diff --git a/pkg/util/aws/region.go b/pkg/util/aws/region.go index 626192516d..074f2cde06 100644 --- a/pkg/util/aws/region.go +++ b/pkg/util/aws/region.go @@ -441,7 +441,20 @@ func (self *SRegion) CreateInstanceSimple(name string, imgId string, cpu int, me log.Debugf("Search in zone %s", z.LocalName) net := z.getNetworkById(networkId) if net != nil { - inst, err := z.getHost().CreateVM(name, imgId, 0, cpu, memGB*1024, networkId, "", "", "", storageType, dataDiskSizesGB, publicKey, "", "", nil) + desc := &cloudprovider.SManagedVMCreateConfig{ + Name: name, + ExternalImageId: imgId, + SysDisk: cloudprovider.SDiskInfo{SizeGB: 0, StorageType: storageType}, + Cpu: cpu, + MemoryMB: memGB * 1024, + ExternalNetworkId: networkId, + DataDisks: []cloudprovider.SDiskInfo{}, + PublicKey: publicKey, + } + for _, sizeGB := range dataDiskSizesGB { + desc.DataDisks = append(desc.DataDisks, cloudprovider.SDiskInfo{SizeGB: sizeGB, StorageType: storageType}) + } + inst, err := z.getHost().CreateVM(desc) if err != nil { return nil, err } diff --git a/pkg/util/azure/classic_host.go b/pkg/util/azure/classic_host.go index 85988cc207..66e714b413 100644 --- a/pkg/util/azure/classic_host.go +++ b/pkg/util/azure/classic_host.go @@ -8,7 +8,6 @@ import ( "yunion.io/x/onecloud/pkg/cloudprovider" "yunion.io/x/onecloud/pkg/compute/models" - "yunion.io/x/onecloud/pkg/util/billing" ) type SClassicHost struct { @@ -43,15 +42,7 @@ func (self *SClassicHost) Refresh() error { return nil } -func (self *SClassicHost) CreateVM(name string, imgId string, sysDiskSize int, cpu int, memMB int, - networkId string, ipAddr string, desc string, passwd string, storageType string, - diskSizes []int, publicKey string, secgroupId string, userData string, bc *billing.SBillingCycle) (cloudprovider.ICloudVM, error) { - return nil, cloudprovider.ErrNotImplemented -} - -func (self *SClassicHost) CreateVM2(name string, imgId string, sysDiskSize int, skuId string, - networkId string, ipAddr string, desc string, passwd string, storageType string, - diskSizes []int, publicKey string, secgroupId string, userData string, bc *billing.SBillingCycle) (cloudprovider.ICloudVM, error) { +func (self *SClassicHost) CreateVM(desc *cloudprovider.SManagedVMCreateConfig) (cloudprovider.ICloudVM, error) { return nil, cloudprovider.ErrNotImplemented } diff --git a/pkg/util/azure/host.go b/pkg/util/azure/host.go index 380884ba0e..f012a921d0 100644 --- a/pkg/util/azure/host.go +++ b/pkg/util/azure/host.go @@ -10,7 +10,6 @@ import ( "yunion.io/x/onecloud/pkg/cloudprovider" "yunion.io/x/onecloud/pkg/compute/models" "yunion.io/x/onecloud/pkg/util/ansible" - "yunion.io/x/onecloud/pkg/util/billing" ) type SHost struct { @@ -67,18 +66,15 @@ func (self *SHost) searchNetorkInterface(IPAddr string, networkId string, secgro return nil, cloudprovider.ErrNotFound } -func (self *SHost) CreateVM(name string, imgId string, sysDiskSize int, cpu int, memMB int, - networkId string, ipAddr string, desc string, passwd string, storageType string, - diskSizes []int, publicKey string, secgroupId string, userData string, - bc *billing.SBillingCycle) (cloudprovider.ICloudVM, error) { - net := self.zone.getNetworkById(networkId) +func (self *SHost) CreateVM(desc *cloudprovider.SManagedVMCreateConfig) (cloudprovider.ICloudVM, error) { + net := self.zone.getNetworkById(desc.ExternalNetworkId) if net == nil { - return nil, fmt.Errorf("invalid network ID %s", networkId) + return nil, fmt.Errorf("invalid network ID %s", desc.ExternalNetworkId) } - nic, err := self.searchNetorkInterface(ipAddr, net.GetId(), secgroupId) + nic, err := self.searchNetorkInterface(desc.IpAddr, net.GetId(), desc.ExternalSecgroupId) if err != nil { if err == cloudprovider.ErrNotFound { - nic, err = self.zone.region.CreateNetworkInterface(fmt.Sprintf("%s-ipconfig", name), ipAddr, net.GetId(), secgroupId) + nic, err = self.zone.region.CreateNetworkInterface(fmt.Sprintf("%s-ipconfig", desc.Name), desc.IpAddr, net.GetId(), desc.ExternalSecgroupId) if err != nil { return nil, err } @@ -86,7 +82,7 @@ func (self *SHost) CreateVM(name string, imgId string, sysDiskSize int, cpu int, return nil, err } } - vmId, err := self._createVM(name, imgId, int32(sysDiskSize), cpu, memMB, "", nic.ID, ipAddr, desc, passwd, storageType, diskSizes, publicKey, userData) + vmId, err := self._createVM(desc.Name, desc.ExternalImageId, desc.SysDisk, desc.Cpu, desc.MemoryMB, desc.InstanceType, desc.ExternalNetworkId, desc.IpAddr, desc.Description, desc.Password, desc.DataDisks, desc.PublicKey, desc.UserData) if err != nil { self.zone.region.DeleteNetworkInterface(nic.ID) return nil, err @@ -99,38 +95,7 @@ func (self *SHost) CreateVM(name string, imgId string, sysDiskSize int, cpu int, } } -func (self *SHost) CreateVM2(name string, imgId string, sysDiskSize int, instanceType string, - networkId string, ipAddr string, desc string, passwd string, storageType string, - diskSizes []int, publicKey string, secgroupId string, userData string, bc *billing.SBillingCycle) (cloudprovider.ICloudVM, error) { - net := self.zone.getNetworkById(networkId) - if net == nil { - return nil, fmt.Errorf("invalid network ID %s", networkId) - } - nic, err := self.searchNetorkInterface(ipAddr, net.GetId(), secgroupId) - if err != nil { - if err == cloudprovider.ErrNotFound { - nic, err = self.zone.region.CreateNetworkInterface(fmt.Sprintf("%s-ipconfig", name), ipAddr, net.GetId(), secgroupId) - if err != nil { - return nil, err - } - } else { - return nil, err - } - } - vmId, err := self._createVM(name, imgId, int32(sysDiskSize), 0, 0, instanceType, nic.ID, ipAddr, desc, passwd, storageType, diskSizes, publicKey, userData) - if err != nil { - self.zone.region.DeleteNetworkInterface(nic.ID) - return nil, err - } - if vm, err := self.zone.region.GetInstance(vmId); err != nil { - return nil, err - } else { - vm.host = self - return vm, err - } -} - -func (self *SHost) _createVM(name string, imgId string, sysDiskSize int32, cpu int, memMB int, instanceType string, nicId string, ipAddr string, desc string, passwd string, storageType string, diskSizes []int, publicKey string, userData string) (string, error) { +func (self *SHost) _createVM(name string, imgId string, sysDisk cloudprovider.SDiskInfo, cpu int, memMB int, instanceType string, nicId string, ipAddr string, desc string, passwd string, dataDisks []cloudprovider.SDiskInfo, publicKey string, userData string) (string, error) { image, err := self.zone.region.GetImageById(imgId) if err != nil { log.Errorf("Get Image %s fail %s", imgId, err) @@ -141,11 +106,11 @@ func (self *SHost) _createVM(name string, imgId string, sysDiskSize int32, cpu i log.Errorf("image %s status %s", imgId, image.Properties.ProvisioningState) return "", fmt.Errorf("image not ready") } - storage, err := self.zone.getStorageByType(storageType) + storage, err := self.zone.getStorageByType(sysDisk.StorageType) if err != nil { - return "", fmt.Errorf("Storage %s not avaiable: %s", storageType, err) + return "", fmt.Errorf("Storage %s not avaiable: %s", sysDisk.StorageType, err) } - + sysDiskSize := int32(sysDisk.SizeGB) instance := SInstance{ Name: name, Location: self.zone.region.Name, @@ -193,20 +158,20 @@ func (self *SHost) _createVM(name string, imgId string, sysDiskSize int32, cpu i } } - dataDisks := []DataDisk{} - for i := 0; i < len(diskSizes); i++ { + _dataDisks := []DataDisk{} + for i := 0; i < len(dataDisks); i++ { diskName := fmt.Sprintf("vdisk_%s_%d", name, time.Now().UnixNano()) - size := int32(diskSizes[i]) + size := int32(dataDisks[i].SizeGB) lun := int32(i) - dataDisks = append(dataDisks, DataDisk{ + _dataDisks = append(_dataDisks, DataDisk{ Name: diskName, DiskSizeGB: &size, CreateOption: "Empty", Lun: lun, }) } - if len(dataDisks) > 0 { - instance.Properties.StorageProfile.DataDisks = dataDisks + if len(_dataDisks) > 0 { + instance.Properties.StorageProfile.DataDisks = _dataDisks } if len(instanceType) > 0 { diff --git a/pkg/util/azure/region.go b/pkg/util/azure/region.go index 00ebbac4df..b5ed9d1e10 100644 --- a/pkg/util/azure/region.go +++ b/pkg/util/azure/region.go @@ -407,8 +407,21 @@ func (self *SRegion) CreateInstanceSimple(name string, imgId string, cpu int, me log.Debugf("Search in zone %s", z.Name) net := z.getNetworkById(networkId) if net != nil { - passwd := seclib2.RandomPassword2(12) - inst, err := z.getHost().CreateVM(name, imgId, 30, cpu, memGB*1024, networkId, "", "", passwd, storageType, dataDiskSizesGB, publicKey, "", "", nil) + desc := &cloudprovider.SManagedVMCreateConfig{ + Name: name, + ExternalImageId: imgId, + SysDisk: cloudprovider.SDiskInfo{SizeGB: 0, StorageType: storageType}, + Cpu: cpu, + MemoryMB: memGB * 1024, + ExternalNetworkId: networkId, + Password: seclib2.RandomPassword2(12), + DataDisks: []cloudprovider.SDiskInfo{}, + PublicKey: publicKey, + } + for _, sizeGB := range dataDiskSizesGB { + desc.DataDisks = append(desc.DataDisks, cloudprovider.SDiskInfo{SizeGB: sizeGB, StorageType: storageType}) + } + inst, err := z.getHost().CreateVM(desc) if err != nil { return nil, err } diff --git a/pkg/util/esxi/host.go b/pkg/util/esxi/host.go index acd4f99073..8cdd3bd18e 100644 --- a/pkg/util/esxi/host.go +++ b/pkg/util/esxi/host.go @@ -14,7 +14,6 @@ import ( "yunion.io/x/onecloud/pkg/cloudprovider" "yunion.io/x/onecloud/pkg/compute/models" - "yunion.io/x/onecloud/pkg/util/billing" ) var HOST_SYSTEM_PROPS = []string{"name", "parent", "summary", "config", "hardware", "vm", "datastore"} @@ -507,13 +506,7 @@ func (self *SHost) GetVersion() string { return fmt.Sprintf("%s-%s", about.Version, about.Build) } -func (self *SHost) CreateVM(name string, imgId string, sysDiskSize int, cpu int, memMB int, vswitchId string, ipAddr string, desc string, - passwd string, storageType string, diskSizes []int, publicKey string, secGrpId string, userData string, bc *billing.SBillingCycle) (cloudprovider.ICloudVM, error) { - return nil, cloudprovider.ErrNotImplemented -} - -func (self *SHost) CreateVM2(name string, imgId string, sysDiskSize int, instanceType string, vswitchId string, ipAddr string, desc string, - passwd string, storageType string, diskSizes []int, publicKey string, secGrpId string, userData string, bc *billing.SBillingCycle) (cloudprovider.ICloudVM, error) { +func (self *SHost) CreateVM(desc *cloudprovider.SManagedVMCreateConfig) (cloudprovider.ICloudVM, error) { return nil, cloudprovider.ErrNotImplemented } diff --git a/pkg/util/huawei/host.go b/pkg/util/huawei/host.go index ab9d7d3222..d860f953d5 100644 --- a/pkg/util/huawei/host.go +++ b/pkg/util/huawei/host.go @@ -180,24 +180,8 @@ func (self *SHost) GetInstanceById(instanceId string) (*SInstance, error) { return &instance, nil } -func (self *SHost) CreateVM(name string, imgId string, sysDiskSize int, cpu int, memMB int, networkId string, ipAddr string, desc string, - passwd string, storageType string, diskSizes []int, publicKey string, extSecGrpId string, userData string, bc *billing.SBillingCycle) (cloudprovider.ICloudVM, error) { - vmId, err := self._createVM(name, imgId, sysDiskSize, cpu, memMB, "", networkId, ipAddr, desc, passwd, storageType, diskSizes, publicKey, extSecGrpId, userData, bc) - if err != nil { - return nil, err - } - - vm, err := self.GetInstanceById(vmId) - if err != nil { - return nil, err - } - - return vm, err -} - -func (self *SHost) CreateVM2(name string, imgId string, sysDiskSize int, instanceType string, networkId string, ipAddr string, desc string, - passwd string, storageType string, diskSizes []int, publicKey string, extSecGrpId string, userData string, bc *billing.SBillingCycle) (cloudprovider.ICloudVM, error) { - vmId, err := self._createVM(name, imgId, sysDiskSize, 0, 0, instanceType, networkId, ipAddr, desc, passwd, storageType, diskSizes, publicKey, extSecGrpId, userData, bc) +func (self *SHost) CreateVM(desc *cloudprovider.SManagedVMCreateConfig) (cloudprovider.ICloudVM, error) { + vmId, err := self._createVM(desc.Name, desc.ExternalImageId, desc.SysDisk, desc.Cpu, desc.MemoryMB, desc.InstanceType, desc.ExternalNetworkId, desc.IpAddr, desc.Description, desc.Password, desc.DataDisks, desc.PublicKey, desc.ExternalSecgroupId, desc.UserData, desc.BillingCycle) if err != nil { return nil, err } @@ -214,9 +198,9 @@ func (self *SHost) GetIHostNics() ([]cloudprovider.ICloudHostNetInterface, error return nil, cloudprovider.ErrNotSupported } -func (self *SHost) _createVM(name string, imgId string, sysDiskSize int, cpu int, memMB int, instanceType string, +func (self *SHost) _createVM(name string, imgId string, sysDisk cloudprovider.SDiskInfo, cpu int, memMB int, instanceType string, networkId string, ipAddr string, desc string, passwd string, - storageType string, diskSizes []int, publicKey string, secgroupId string, + diskSizes []cloudprovider.SDiskInfo, publicKey string, secgroupId string, userData string, bc *billing.SBillingCycle) (string, error) { net := self.zone.getNetworkById(networkId) if net == nil { @@ -256,14 +240,14 @@ func (self *SHost) _createVM(name string, imgId string, sysDiskSize int, cpu int disks := make([]SDisk, len(diskSizes)+1) disks[0].SizeGB = img.SizeGB - if sysDiskSize > 0 && sysDiskSize > img.SizeGB { - disks[0].SizeGB = sysDiskSize + if sysDisk.SizeGB > 0 && sysDisk.SizeGB > img.SizeGB { + disks[0].SizeGB = sysDisk.SizeGB } - disks[0].VolumeType = storageType + disks[0].VolumeType = sysDisk.StorageType - for i, sz := range diskSizes { - disks[i+1].SizeGB = sz - disks[i+1].VolumeType = storageType + for i, dataDisk := range diskSizes { + disks[i+1].SizeGB = dataDisk.SizeGB + disks[i+1].VolumeType = dataDisk.StorageType } secgroup, err := self.zone.region.GetSecurityGroupDetails(secgroupId) diff --git a/pkg/util/openstack/hostv2.go b/pkg/util/openstack/hostv2.go index ca6a3091a4..b582471791 100644 --- a/pkg/util/openstack/hostv2.go +++ b/pkg/util/openstack/hostv2.go @@ -6,7 +6,6 @@ import ( "yunion.io/x/jsonutils" "yunion.io/x/onecloud/pkg/cloudprovider" "yunion.io/x/onecloud/pkg/compute/models" - "yunion.io/x/onecloud/pkg/util/billing" ) type SResource struct { @@ -75,17 +74,7 @@ func (host *SHostV2) GetIVMById(gid string) (cloudprovider.ICloudVM, error) { return instance, nil } -func (host *SHostV2) CreateVM(name string, imgId string, sysDiskSize int, cpu int, memMB int, - vswitchId string, ipAddr string, desc string, passwd string, - storageType string, diskSizes []int, publicKey string, secgroupId string, userData string, - bc *billing.SBillingCycle) (cloudprovider.ICloudVM, error) { - return nil, cloudprovider.ErrNotImplemented -} - -func (host *SHostV2) CreateVM2(name string, imgId string, sysDiskSize int, instanceType string, - vswitchId string, ipAddr string, desc string, passwd string, - storageType string, diskSizes []int, publicKey string, secgroupId string, - userData string, bc *billing.SBillingCycle) (cloudprovider.ICloudVM, error) { +func (host *SHostV2) CreateVM(desc *cloudprovider.SManagedVMCreateConfig) (cloudprovider.ICloudVM, error) { return nil, cloudprovider.ErrNotImplemented } diff --git a/pkg/util/openstack/hostv3.go b/pkg/util/openstack/hostv3.go index 6a06e82053..c95855c001 100644 --- a/pkg/util/openstack/hostv3.go +++ b/pkg/util/openstack/hostv3.go @@ -4,7 +4,6 @@ import ( "yunion.io/x/jsonutils" "yunion.io/x/onecloud/pkg/cloudprovider" "yunion.io/x/onecloud/pkg/compute/models" - "yunion.io/x/onecloud/pkg/util/billing" ) type CpuInfo struct { @@ -97,17 +96,7 @@ func (host *SHostV3) GetIVMById(gid string) (cloudprovider.ICloudVM, error) { return instance, nil } -func (host *SHostV3) CreateVM(name string, imgId string, sysDiskSize int, cpu int, memMB int, - vswitchId string, ipAddr string, desc string, passwd string, - storageType string, diskSizes []int, publicKey string, secgroupId string, userData string, - bc *billing.SBillingCycle) (cloudprovider.ICloudVM, error) { - return nil, cloudprovider.ErrNotImplemented -} - -func (host *SHostV3) CreateVM2(name string, imgId string, sysDiskSize int, instanceType string, - vswitchId string, ipAddr string, desc string, passwd string, - storageType string, diskSizes []int, publicKey string, secgroupId string, - userData string, bc *billing.SBillingCycle) (cloudprovider.ICloudVM, error) { +func (host *SHostV3) CreateVM(desc *cloudprovider.SManagedVMCreateConfig) (cloudprovider.ICloudVM, error) { return nil, cloudprovider.ErrNotImplemented } diff --git a/pkg/util/qcloud/host.go b/pkg/util/qcloud/host.go index 167f27e7df..85a10d8b2b 100644 --- a/pkg/util/qcloud/host.go +++ b/pkg/util/qcloud/host.go @@ -41,11 +41,8 @@ func (self *SHost) GetInstanceById(instanceId string) (*SInstance, error) { return inst, nil } -func (self *SHost) CreateVM(name string, imgId string, sysDiskSize int, cpu int, memMB int, - vswitchId string, ipAddr string, desc string, passwd string, - storageType string, diskSizes []int, publicKey string, secgroupId string, userData string, - bc *billing.SBillingCycle) (cloudprovider.ICloudVM, error) { - vmId, err := self._createVM(name, imgId, sysDiskSize, cpu, memMB, "", vswitchId, ipAddr, desc, passwd, storageType, diskSizes, publicKey, secgroupId, userData, bc) +func (self *SHost) CreateVM(desc *cloudprovider.SManagedVMCreateConfig) (cloudprovider.ICloudVM, error) { + vmId, err := self._createVM(desc.Name, desc.ExternalImageId, desc.SysDisk, desc.Cpu, desc.MemoryMB, desc.InstanceType, desc.ExternalNetworkId, desc.IpAddr, desc.Description, desc.Password, desc.DataDisks, desc.PublicKey, desc.ExternalSecgroupId, desc.UserData, desc.BillingCycle) if err != nil { return nil, err } @@ -56,24 +53,9 @@ func (self *SHost) CreateVM(name string, imgId string, sysDiskSize int, cpu int, return vm, err } -func (self *SHost) CreateVM2(name string, imgId string, sysDiskSize int, instanceType string, - vswitchId string, ipAddr string, desc string, passwd string, - storageType string, diskSizes []int, publicKey string, secgroupId string, userData string, - bc *billing.SBillingCycle) (cloudprovider.ICloudVM, error) { - vmId, err := self._createVM(name, imgId, sysDiskSize, 0, 0, instanceType, vswitchId, ipAddr, desc, passwd, storageType, diskSizes, publicKey, secgroupId, userData, bc) - if err != nil { - return nil, err - } - vm, err := self.GetInstanceById(vmId) - if err != nil { - return nil, err - } - return vm, err -} - -func (self *SHost) _createVM(name string, imgId string, sysDiskSize int, cpu int, memMB int, instanceType string, +func (self *SHost) _createVM(name string, imgId string, sysDisk cloudprovider.SDiskInfo, cpu int, memMB int, instanceType string, networkId string, ipAddr string, desc string, passwd string, - storageType string, diskSizes []int, publicKey string, secgroupId string, userData string, bc *billing.SBillingCycle) (string, error) { + diskSizes []cloudprovider.SDiskInfo, publicKey string, secgroupId string, userData string, bc *billing.SBillingCycle) (string, error) { net := self.zone.getNetworkById(networkId) if net == nil { return "", fmt.Errorf("invalid network ID %s", networkId) @@ -125,24 +107,28 @@ func (self *SHost) _createVM(name string, imgId string, sysDiskSize int, cpu int return "", fmt.Errorf("image not ready") } - err = self.zone.validateStorageType(storageType) + err = self.zone.validateStorageType(sysDisk.StorageType) if err != nil { - return "", fmt.Errorf("Storage %s not avaiable: %s", storageType, err) + return "", fmt.Errorf("Storage %s not avaiable: %s", sysDisk.StorageType, err) } disks := make([]SDisk, len(diskSizes)+1) disks[0].DiskSize = img.ImageSize - if sysDiskSize > 0 && sysDiskSize > img.ImageSize { - disks[0].DiskSize = sysDiskSize + if sysDisk.SizeGB > 0 && sysDisk.SizeGB > img.ImageSize { + disks[0].DiskSize = sysDisk.SizeGB } if disks[0].DiskSize < 50 { disks[0].DiskSize = 50 } - disks[0].DiskType = strings.ToUpper(storageType) + disks[0].DiskType = strings.ToUpper(sysDisk.StorageType) - for i, sz := range diskSizes { - disks[i+1].DiskSize = sz - disks[i+1].DiskType = strings.ToUpper(storageType) + for i, dataDisk := range diskSizes { + disks[i+1].DiskSize = dataDisk.SizeGB + err = self.zone.validateStorageType(dataDisk.StorageType) + if err != nil { + return "", fmt.Errorf("Storage %s not avaiable: %s", dataDisk.StorageType, err) + } + disks[i+1].DiskType = strings.ToUpper(dataDisk.StorageType) } if len(instanceType) > 0 { diff --git a/pkg/util/qcloud/region.go b/pkg/util/qcloud/region.go index 0c90e551f3..a623922f82 100644 --- a/pkg/util/qcloud/region.go +++ b/pkg/util/qcloud/region.go @@ -534,7 +534,21 @@ func (self *SRegion) CreateInstanceSimple(name string, imgId string, cpu int, me log.Debugf("Search in zone %s", z.Zone) net := z.getNetworkById(networkId) if net != nil { - inst, err := z.getHost().CreateVM(name, imgId, 0, cpu, memGB*1024, networkId, "", "", passwd, storageType, dataDiskSizesGB, publicKey, "", "", nil) + desc := &cloudprovider.SManagedVMCreateConfig{ + Name: name, + ExternalImageId: imgId, + SysDisk: cloudprovider.SDiskInfo{SizeGB: 0, StorageType: storageType}, + Cpu: cpu, + MemoryMB: memGB * 1024, + ExternalNetworkId: networkId, + Password: passwd, + DataDisks: []cloudprovider.SDiskInfo{}, + PublicKey: publicKey, + } + for _, sizeGB := range dataDiskSizesGB { + desc.DataDisks = append(desc.DataDisks, cloudprovider.SDiskInfo{SizeGB: sizeGB, StorageType: storageType}) + } + inst, err := z.getHost().CreateVM(desc) if err != nil { return nil, err }