Merge pull request #860 from ioito/hotfix/qx-inject-password-by-cloud-init

Hotfix/qx inject password by cloud init
This commit is contained in:
yunion-ci-robot
2019-05-21 18:51:18 +08:00
committed by GitHub
9 changed files with 104 additions and 32 deletions
+40
View File
@@ -15,6 +15,8 @@
package cloudprovider
import (
"fmt"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/util/osprofile"
@@ -53,6 +55,7 @@ type SManagedVMCreateConfig struct {
PublicKey string
ExternalSecgroupId string
ExternalSecgroupIds []string
Account string
Password string
UserData string
UserDataType string
@@ -117,3 +120,40 @@ func generateUserData(adminPublicKey, projectPublicKey, oUserData string, userDa
return cloudConfig.UserDataBase64()
}
func (vmConfig *SManagedVMCreateConfig) InjectPasswordByCloudInit() error {
if vmConfig.OsType != osprofile.OS_TYPE_LINUX {
return fmt.Errorf("Only support inject Linux password, current osType is %s", vmConfig.OsType)
}
loginUser := cloudinit.NewUser(vmConfig.Account)
loginUser.SudoPolicy(cloudinit.USER_SUDO_NOPASSWD)
if len(vmConfig.PublicKey) > 0 {
loginUser.SshKey(vmConfig.PublicKey)
}
if len(vmConfig.Password) > 0 {
loginUser.Password(vmConfig.Password)
}
cloudconfig := cloudinit.SCloudConfig{
DisableRoot: 0,
SshPwauth: 1,
Users: []cloudinit.SUser{
loginUser,
},
}
if len(vmConfig.UserData) > 0 {
oCloudConfig, err := cloudinit.ParseUserDataBase64(vmConfig.UserData)
if err != nil {
return err
}
cloudconfig.Merge(oCloudConfig)
}
switch vmConfig.UserDataType {
case CLOUD_SHELL:
vmConfig.UserData = cloudconfig.UserDataScriptBase64()
default:
vmConfig.UserData = cloudconfig.UserDataBase64()
}
return nil
}
+4
View File
@@ -67,6 +67,10 @@ func fetchAwsUserName(desc cloudprovider.SManagedVMCreateConfig) string {
}
}
func (self *SAwsGuestDriver) IsNeedInjectPasswordByCloudInit() bool {
return true
}
func (self *SAwsGuestDriver) GetLinuxDefaultAccount(desc cloudprovider.SManagedVMCreateConfig) string {
// return fetchAwsUserName(desc)
return api.VM_AWS_DEFAULT_LOGIN_USER
+4
View File
@@ -247,6 +247,10 @@ func (self *SBaseGuestDriver) GetGuestInitialStateAfterRebuild() string {
return api.VM_READY
}
func (self *SBaseGuestDriver) IsNeedInjectPasswordByCloudInit() bool {
return false
}
func (self *SBaseGuestDriver) GetLinuxDefaultAccount(desc cloudprovider.SManagedVMCreateConfig) string {
userName := "root"
if desc.ImageType == "system" && desc.OsType == "Windows" {
+25 -7
View File
@@ -151,6 +151,15 @@ func (self *SManagedVirtualizedGuestDriver) ValidateCreateData(ctx context.Conte
if provider != cloudprovider.Provider {
return nil, httperrors.NewInputParameterError("image %s(%s) not support provider %s only support %s", image.Name, image.Id, provider, cloudprovider.Provider)
}
if len(input.PreferRegion) == 0 && len(input.PreferZone) == 0 && len(input.PreferHost) == 0 {
regions, err := image.GetRegions()
if err != nil {
log.Warningf("failed to get regions for image %s(%s) error: %v", image.Name, image.Id, err)
}
if len(regions) > 0 {
input.PreferRegion = regions[0].Id
}
}
}
return input, nil
@@ -206,6 +215,15 @@ func (self *SManagedVirtualizedGuestDriver) RequestDeployGuestOnHost(ctx context
return err
}
desc.Account = guest.GetDriver().GetLinuxDefaultAccount(desc)
if guest.GetDriver().IsNeedInjectPasswordByCloudInit() {
err = desc.InjectPasswordByCloudInit()
if err != nil {
log.Warningf("failed to inject password by cloud-init error: %v", err)
}
}
action, err := config.GetString("action")
if err != nil {
return err
@@ -248,6 +266,10 @@ func (self *SManagedVirtualizedGuestDriver) GetLinuxDefaultAccount(desc cloudpro
return "root"
}
func (self *SManagedVirtualizedGuestDriver) IsNeedInjectPasswordByCloudInit() bool {
return false
}
func (self *SManagedVirtualizedGuestDriver) RemoteDeployGuestForCreate(ctx context.Context, userCred mcclient.TokenCredential, guest *models.SGuest, host *models.SHost, desc cloudprovider.SManagedVMCreateConfig) (jsonutils.JSONObject, error) {
ihost, _ := host.GetIHost()
@@ -300,9 +322,7 @@ func (self *SManagedVirtualizedGuestDriver) RemoteDeployGuestForCreate(ctx conte
return nil, err
}
account := guest.GetDriver().GetLinuxDefaultAccount(desc)
data := fetchIVMinfo(desc, iVM, guest.Id, account, desc.Password, "create")
data := fetchIVMinfo(desc, iVM, guest.Id, desc.Account, desc.Password, "create")
return data, nil
}
@@ -335,8 +355,7 @@ func (self *SManagedVirtualizedGuestDriver) RemoteDeployGuestForDeploy(ctx conte
return nil, err
}
account := guest.GetDriver().GetLinuxDefaultAccount(desc)
data := fetchIVMinfo(desc, iVM, guest.Id, account, desc.Password, "deploy")
data := fetchIVMinfo(desc, iVM, guest.Id, desc.Account, desc.Password, "deploy")
return data, nil
}
@@ -404,8 +423,7 @@ func (self *SManagedVirtualizedGuestDriver) RemoteDeployGuestForRebuildRoot(ctx
}
}
account := guest.GetDriver().GetLinuxDefaultAccount(desc)
data := fetchIVMinfo(desc, iVM, guest.Id, account, desc.Password, "rebuild")
data := fetchIVMinfo(desc, iVM, guest.Id, desc.Account, desc.Password, "rebuild")
return data, nil
}
+13
View File
@@ -506,6 +506,19 @@ func (image *SCachedimage) getValidStoragecache() []SStoragecache {
return caches
}
func (image *SCachedimage) GetRegions() ([]SCloudregion, error) {
regions := []SCloudregion{}
caches := image.getValidStoragecache()
for _, cache := range caches {
region, err := cache.GetRegion()
if err != nil {
return nil, err
}
regions = append(regions, *region)
}
return regions, nil
}
func (image *SCachedimage) GetCloudprovider() (*SCloudprovider, error) {
caches := image.getValidStoragecache()
if len(caches) == 0 {
+2
View File
@@ -156,6 +156,8 @@ type IGuestDriver interface {
OnGuestChangeCpuMemFailed(ctx context.Context, guest *SGuest, data *jsonutils.JSONDict, task taskman.ITask) error
IsSupportGuestClone() bool
IsNeedInjectPasswordByCloudInit() bool
}
var guestDrivers map[string]IGuestDriver
+1 -22
View File
@@ -54,7 +54,6 @@ import (
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/auth"
"yunion.io/x/onecloud/pkg/util/billing"
"yunion.io/x/onecloud/pkg/util/cloudinit"
"yunion.io/x/onecloud/pkg/util/logclient"
"yunion.io/x/onecloud/pkg/util/netutils2"
"yunion.io/x/onecloud/pkg/util/seclib2"
@@ -3049,27 +3048,7 @@ func (self *SGuest) GetDeployConfigOnHost(ctx context.Context, userCred mcclient
case api.HYPERVISOR_ALIYUN, api.HYPERVISOR_HUAWEI, api.HYPERVISOR_UCLOUD:
break
case api.HYPERVISOR_AWS:
loginUser := cloudinit.NewUser(api.VM_AWS_DEFAULT_LOGIN_USER)
loginUser.SudoPolicy(cloudinit.USER_SUDO_NOPASSWD)
if pub, _ := config.GetString("public_key"); len(pub) > 0 {
loginUser.SshKey(pub)
} else if pwd, _ := config.GetString("password"); len(pwd) > 0 {
loginUser.Password(pwd)
}
cloudconfig := cloudinit.SCloudConfig{Users: []cloudinit.SUser{loginUser}}
if d, _ := config.GetString("user_data"); len(d) > 0 {
_d, err := cloudinit.ParseUserDataBase64(d)
if err != nil {
return nil, fmt.Errorf("invalid user data %s", d)
}
cloudconfig.Merge(_d)
}
userdata := cloudconfig.UserDataBase64()
config.Add(jsonutils.NewString(userdata), "user_data")
break
case api.HYPERVISOR_QCLOUD, api.HYPERVISOR_OPENSTACK:
registerVpcId = "normal"
case api.HYPERVISOR_AZURE:
+12
View File
@@ -121,6 +121,18 @@ func (self *SStoragecache) GetHost() (*SHost, error) {
return h, nil
}
func (self *SStoragecache) GetRegion() (*SCloudregion, error) {
host, err := self.GetHost()
if err != nil {
return nil, err
}
region := host.GetRegion()
if region == nil {
return nil, fmt.Errorf("failed to get region for host %s(%s)", host.Name, host.Id)
}
return region, nil
}
func (self *SStoragecache) getHostId() (string, error) {
hoststorages := HoststorageManager.Query().SubQuery()
storages := StorageManager.Query().SubQuery()
+3 -3
View File
@@ -56,7 +56,7 @@ type SWriteFile struct {
type SUser struct {
Name string
Passwd string
LockPassword string
LockPasswd string
SshAuthorizedKeys []string
Sudo string
}
@@ -162,7 +162,7 @@ func (u *SUser) Password(passwd string) *SUser {
} else {
u.Passwd = hash
}
u.LockPassword = "false"
u.LockPasswd = "false"
}
return u
}
@@ -281,7 +281,7 @@ func (conf *SCloudConfig) MergeUser(u SUser) {
// replace conf user password with input
if len(u.Passwd) > 0 {
conf.Users[i].Passwd = u.Passwd
conf.Users[i].LockPassword = u.LockPassword
conf.Users[i].LockPasswd = u.LockPasswd
}
// find user, merge keys