mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-21 06:09:39 +08:00
Merge pull request #215 in YUNIONIO/onecloud from ~QIUJIAN/onecloud:hotfix/qj-bugfix-misc-20180914 to release/2.1.0
* commit 'd9e401249e5ccd4108e011a47e6145d7ee8e7002': adjust import order fix typos 增加eip操作的状态变化 network/wire/vpc增加zone/region信息 修正:1. 主机创建/rebuild root密码设置问题 2. climc 密码设置问题 3. billing_type字段为空导致创建主机失败问题
This commit is contained in:
@@ -50,6 +50,11 @@ func init() {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if opts.NoAccountInit != nil && *opts.NoAccountInit {
|
||||
params.Add(jsonutils.JSONFalse, "reset_password")
|
||||
}
|
||||
|
||||
count := options.IntV(opts.Count)
|
||||
if options.BoolV(opts.DryRun) {
|
||||
results, err := modules.SchedManager.DoScheduleListResult(s, params, count)
|
||||
@@ -328,6 +333,11 @@ func init() {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if opts.NoAccountInit != nil && *opts.NoAccountInit {
|
||||
params.Add(jsonutils.JSONFalse, "reset_password")
|
||||
}
|
||||
|
||||
srv, err := modules.Servers.PerformAction(s, opts.ID, "rebuild-root", params)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -338,6 +348,13 @@ func init() {
|
||||
|
||||
R(&options.ServerChangeConfigOptions{}, "server-change-config", "Change configuration of VM", func(s *mcclient.ClientSession, opts *options.ServerChangeConfigOptions) error {
|
||||
params, err := options.StructToParams(opts)
|
||||
if len(opts.Disk) > 0 {
|
||||
params.Remove("disk.0")
|
||||
for i, d := range opts.Disk {
|
||||
params.Set(fmt.Sprintf("disk.%d", i+1), jsonutils.NewString(d))
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ const (
|
||||
)
|
||||
|
||||
type SBillingResourceBase struct {
|
||||
BillingType string `width:"36" charset:"ascii" nullable:"true" default:"postpaid" list:"user" create:"required"`
|
||||
BillingType string `width:"36" charset:"ascii" nullable:"true" default:"postpaid" list:"user" create:"optional"`
|
||||
ExpiredAt time.Time `nullable:"true" list:"user" create:"optional"`
|
||||
}
|
||||
|
||||
|
||||
@@ -51,6 +51,7 @@ func getHypervisors(zone *SZone) []string {
|
||||
if zone != nil {
|
||||
q = q.Equals("zone_id", zone.Id)
|
||||
}
|
||||
q = q.IsNotEmpty("host_type").IsNotNull("host_type")
|
||||
q = q.Distinct()
|
||||
rows, err := q.Rows()
|
||||
if err != nil {
|
||||
@@ -72,6 +73,8 @@ func getStorageTypes(zone *SZone) []string {
|
||||
if zone != nil {
|
||||
q = q.Equals("zone_id", zone.Id)
|
||||
}
|
||||
q = q.IsNotEmpty("storage_type").IsNotNull("storage_type")
|
||||
q = q.IsNotEmpty("medium_type").IsNotNull("medium_type")
|
||||
q = q.Distinct()
|
||||
rows, err := q.Rows()
|
||||
if err != nil {
|
||||
|
||||
@@ -39,6 +39,8 @@ const (
|
||||
EIP_STATUS_DISSOCIATE = "dissociate"
|
||||
EIP_STATUS_DISSOCIATE_FAIL = "dissociate_fail"
|
||||
|
||||
EIP_STATUS_CHANGE_BANDWIDTH = "change_bandwidth"
|
||||
|
||||
EIP_CHARGE_TYPE_BY_TRAFFIC = "traffic"
|
||||
EIP_CHARGE_TYPE_BY_BANDWIDTH = "bandwidth"
|
||||
EIP_CHARGE_TYPE_DEFAULT = EIP_CHARGE_TYPE_BY_TRAFFIC
|
||||
@@ -178,7 +180,7 @@ func (manager *SElasticipManager) SyncEips(ctx context.Context, userCred mcclien
|
||||
}
|
||||
|
||||
func (self *SElasticip) SyncInstanceWithCloudEip(ctx context.Context, userCred mcclient.TokenCredential, ext cloudprovider.ICloudEIP) error {
|
||||
vm := self.getVM()
|
||||
vm := self.GetAssociateVM()
|
||||
vmExtId := ext.GetAssociationExternalId()
|
||||
|
||||
if vm == nil && len(vmExtId) == 0 {
|
||||
@@ -281,7 +283,7 @@ func (manager *SElasticipManager) getEipForInstance(instanceType string, instanc
|
||||
return &eip, nil
|
||||
}
|
||||
|
||||
func (self *SElasticip) getVM() *SGuest {
|
||||
func (self *SElasticip) GetAssociateVM() *SGuest {
|
||||
if self.AssociateType == "server" && len(self.AssociateId) > 0 {
|
||||
return GuestManager.FetchGuestById(self.AssociateId)
|
||||
}
|
||||
@@ -292,7 +294,7 @@ func (self *SElasticip) Dissociate(ctx context.Context, userCred mcclient.TokenC
|
||||
if len(self.AssociateType) == 0 {
|
||||
return nil
|
||||
}
|
||||
vm := self.getVM()
|
||||
vm := self.GetAssociateVM()
|
||||
if vm == nil {
|
||||
log.Errorf("dissociate VM not exists???")
|
||||
}
|
||||
@@ -305,7 +307,9 @@ func (self *SElasticip) Dissociate(ctx context.Context, userCred mcclient.TokenC
|
||||
return err
|
||||
}
|
||||
if vm != nil {
|
||||
db.OpsLog.LogDetachEvent(vm, self, userCred, self.GetShortDesc())
|
||||
db.OpsLog.LogEvent(self, db.ACT_EIP_DETACH, vm.GetShortDesc(), userCred)
|
||||
db.OpsLog.LogEvent(vm, db.ACT_EIP_DETACH, self.GetShortDesc(), userCred)
|
||||
}
|
||||
if self.Mode == EIP_MODE_INSTANCE_PUBLICIP {
|
||||
self.Delete(ctx, userCred)
|
||||
@@ -325,7 +329,11 @@ func (self *SElasticip) AssociateVM(userCred mcclient.TokenCredential, vm *SGues
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
db.OpsLog.LogAttachEvent(vm, self, userCred, self.GetShortDesc())
|
||||
db.OpsLog.LogEvent(self, db.ACT_EIP_ATTACH, vm.GetShortDesc(), userCred)
|
||||
db.OpsLog.LogEvent(vm, db.ACT_EIP_ATTACH, self.GetShortDesc(), userCred)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -638,7 +646,7 @@ func (self *SElasticip) GetCustomizeColumns(ctx context.Context, userCred mcclie
|
||||
}
|
||||
|
||||
func (self *SElasticip) getMoreDetails(extra *jsonutils.JSONDict) *jsonutils.JSONDict {
|
||||
vm := self.getVM()
|
||||
vm := self.GetAssociateVM()
|
||||
if vm != nil {
|
||||
extra.Add(jsonutils.NewString(vm.GetName()), "associate_name")
|
||||
}
|
||||
@@ -704,6 +712,9 @@ func (self *SElasticip) PerformChangeBandwidth(ctx context.Context, userCred mcc
|
||||
}
|
||||
|
||||
func (self *SElasticip) StartEipChangeBandwidthTask(ctx context.Context, userCred mcclient.TokenCredential, bandwidth int64) error {
|
||||
|
||||
self.SetStatus(userCred, EIP_STATUS_CHANGE_BANDWIDTH, "change bandwidth")
|
||||
|
||||
params := jsonutils.NewDict()
|
||||
params.Add(jsonutils.NewInt(bandwidth), "bandwidth")
|
||||
|
||||
@@ -722,6 +733,8 @@ func (self *SElasticip) DoChangeBandwidth(userCred mcclient.TokenCredential, ban
|
||||
return nil
|
||||
})
|
||||
|
||||
self.SetStatus(userCred, EIP_STATUS_READY, "finish change bandwidth")
|
||||
|
||||
if err != nil {
|
||||
log.Errorf("DoChangeBandwidth update fail %s", err)
|
||||
return err
|
||||
|
||||
+117
-43
@@ -36,6 +36,7 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/mcclient/auth"
|
||||
"yunion.io/x/onecloud/pkg/util/httputils"
|
||||
"yunion.io/x/onecloud/pkg/util/logclient"
|
||||
"yunion.io/x/onecloud/pkg/util/seclib2"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -99,6 +100,9 @@ const (
|
||||
VM_RESTORE_STATE = "restore_state"
|
||||
VM_RESTORE_FAILED = "restore_failed"
|
||||
|
||||
VM_ASSOCIATE_EIP = "associate_eip"
|
||||
VM_DISSOCIATE_EIP = "dissociate_eip"
|
||||
|
||||
VM_REMOVE_STATEFILE = "remove_state"
|
||||
|
||||
VM_ADMIN = "admin"
|
||||
@@ -272,8 +276,8 @@ func (manager *SGuestManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQ
|
||||
if count > 0 {
|
||||
sgq := guestdisks.Query(guestdisks.Field("guest_id")).
|
||||
Filter(sqlchemy.AND(
|
||||
sqlchemy.Equals(guestdisks.Field("disk_id"), disk.Id),
|
||||
sqlchemy.IsFalse(guestdisks.Field("deleted"))))
|
||||
sqlchemy.Equals(guestdisks.Field("disk_id"), disk.Id),
|
||||
sqlchemy.IsFalse(guestdisks.Field("deleted"))))
|
||||
q = q.Filter(sqlchemy.In(q.Field("id"), sgq))
|
||||
} else {
|
||||
hosts := HostManager.Query().SubQuery()
|
||||
@@ -281,11 +285,11 @@ func (manager *SGuestManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQ
|
||||
storages := StorageManager.Query().SubQuery()
|
||||
sq := hosts.Query(hosts.Field("id")).
|
||||
Join(hoststorages, sqlchemy.AND(
|
||||
sqlchemy.Equals(hoststorages.Field("host_id"), hosts.Field("id")),
|
||||
sqlchemy.IsFalse(hoststorages.Field("deleted")))).
|
||||
sqlchemy.Equals(hoststorages.Field("host_id"), hosts.Field("id")),
|
||||
sqlchemy.IsFalse(hoststorages.Field("deleted")))).
|
||||
Join(storages, sqlchemy.AND(
|
||||
sqlchemy.Equals(storages.Field("id"), hoststorages.Field("storage_id")),
|
||||
sqlchemy.IsFalse(storages.Field("deleted")))).
|
||||
sqlchemy.Equals(storages.Field("id"), hoststorages.Field("storage_id")),
|
||||
sqlchemy.IsFalse(storages.Field("deleted")))).
|
||||
Filter(sqlchemy.Equals(storages.Field("id"), disk.StorageId)).SubQuery()
|
||||
q = q.In("host_id", sq)
|
||||
}
|
||||
@@ -339,8 +343,8 @@ func (manager *SGuestManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQ
|
||||
isodev := IsolatedDeviceManager.Query().SubQuery()
|
||||
sgq := isodev.Query(isodev.Field("guest_id")).
|
||||
Filter(sqlchemy.AND(
|
||||
sqlchemy.IsNotNull(isodev.Field("guest_id")),
|
||||
sqlchemy.Startswith(isodev.Field("dev_type"), "GPU")))
|
||||
sqlchemy.IsNotNull(isodev.Field("guest_id")),
|
||||
sqlchemy.Startswith(isodev.Field("dev_type"), "GPU")))
|
||||
showGpu := utils.ToBool(gpu)
|
||||
cond := sqlchemy.NotIn
|
||||
if showGpu {
|
||||
@@ -561,6 +565,14 @@ func (manager *SGuestManager) ValidateCreateData(ctx context.Context, userCred m
|
||||
data.Add(jsonutils.NewInt(int64(vmemSize)), "vmem_size")
|
||||
data.Add(jsonutils.NewInt(int64(vcpuCount)), "vcpu_count")
|
||||
|
||||
resetPassword := jsonutils.QueryBoolean(data, "reset_password", true)
|
||||
passwd, _ := data.GetString("password")
|
||||
if resetPassword && len(passwd) > 0 {
|
||||
if ! seclib2.MeetComplxity(passwd) {
|
||||
return nil, httperrors.NewWeakPasswordError()
|
||||
}
|
||||
}
|
||||
|
||||
disk0Json, _ := data.Get("disk.0")
|
||||
if disk0Json == nil {
|
||||
return nil, httperrors.NewInputParameterError("No disk information provided")
|
||||
@@ -2411,41 +2423,81 @@ func (self *SGuest) PerformPurge(ctx context.Context, userCred mcclient.TokenCre
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func (self *SGuest) setKeypairId(userCred mcclient.TokenCredential, keypairId string) error {
|
||||
diff, err := self.GetModelManager().TableSpec().Update(self, func() error {
|
||||
self.KeypairId = keypairId
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
db.OpsLog.LogEvent(self, db.ACT_UPDATE, diff, userCred)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (self *SGuest) AllowPerformRebuildRoot(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
|
||||
return self.IsOwner(userCred)
|
||||
}
|
||||
|
||||
func (self *SGuest) PerformRebuildRoot(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
imageId, _ := data.GetString("image_id")
|
||||
if utils.IsInStringArray(self.Status, []string{VM_READY, VM_RUNNING, VM_ADMIN}) {
|
||||
if !data.Contains("image_id") {
|
||||
gdc := self.CategorizeDisks()
|
||||
imageId = gdc.Root.GetTemplateId()
|
||||
if len(imageId) == 0 {
|
||||
return nil, httperrors.NewBadRequestError("No template for root disk")
|
||||
}
|
||||
img, err := CachedimageManager.getImageInfo(ctx, userCred, imageId, false)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewBadRequestError("Template %s not accessible: %s", imageId, err.Error())
|
||||
}
|
||||
osType, _ := img.Properties["os_type"]
|
||||
osName := self.GetMetadata("os_name", userCred)
|
||||
if len(osName) == 0 && len(osType) == 0 && strings.ToLower(osType) != strings.ToLower(osName) {
|
||||
return nil, httperrors.NewBadRequestError("Cannot switch OS between %s-%s", osName, osType)
|
||||
}
|
||||
}
|
||||
autoStart := jsonutils.QueryBoolean(data, "auto_start", false)
|
||||
var needStop = false
|
||||
if self.Status == VM_RUNNING {
|
||||
needStop = true
|
||||
}
|
||||
err := self.StartRebuildRootTask(ctx, userCred, imageId, needStop, autoStart)
|
||||
return nil, err
|
||||
if ! utils.IsInStringArray(self.Status, []string{VM_READY, VM_RUNNING, VM_ADMIN}) {
|
||||
return nil, httperrors.NewInvalidStatusError("Cannot reset root in status %s", self.Status)
|
||||
}
|
||||
return nil, httperrors.NewInvalidStatusError("Cannot reset root in status %s", self.Status)
|
||||
|
||||
if !data.Contains("image_id") {
|
||||
gdc := self.CategorizeDisks()
|
||||
imageId = gdc.Root.GetTemplateId()
|
||||
if len(imageId) == 0 {
|
||||
return nil, httperrors.NewBadRequestError("No template for root disk")
|
||||
}
|
||||
img, err := CachedimageManager.getImageInfo(ctx, userCred, imageId, false)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewBadRequestError("Template %s not accessible: %s", imageId, err.Error())
|
||||
}
|
||||
osType, _ := img.Properties["os_type"]
|
||||
osName := self.GetMetadata("os_name", userCred)
|
||||
if len(osName) == 0 && len(osType) == 0 && strings.ToLower(osType) != strings.ToLower(osName) {
|
||||
return nil, httperrors.NewBadRequestError("Cannot switch OS between %s-%s", osName, osType)
|
||||
}
|
||||
}
|
||||
|
||||
autoStart := jsonutils.QueryBoolean(data, "auto_start", false)
|
||||
var needStop = false
|
||||
if self.Status == VM_RUNNING {
|
||||
needStop = true
|
||||
}
|
||||
resetPasswd := jsonutils.QueryBoolean(data, "reset_password", true)
|
||||
passwd, _ := data.GetString("password")
|
||||
if len(passwd) > 0 {
|
||||
if ! seclib2.MeetComplxity(passwd) {
|
||||
return nil, httperrors.NewWeakPasswordError()
|
||||
}
|
||||
}
|
||||
|
||||
keypairStr := jsonutils.GetAnyString(data, []string{"keypair", "keypair_id"})
|
||||
if len(keypairStr) > 0 {
|
||||
keypairObj, err := KeypairManager.FetchByIdOrName(userCred.GetUserId(), keypairStr)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, httperrors.NewResourceNotFoundError("keypair %s not found", keypairStr)
|
||||
} else {
|
||||
return nil, httperrors.NewGeneralError(err)
|
||||
}
|
||||
}
|
||||
if self.KeypairId != keypairObj.GetId() {
|
||||
err = self.setKeypairId(userCred, keypairObj.GetId())
|
||||
if err != nil {
|
||||
return nil, httperrors.NewGeneralError(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err := self.StartRebuildRootTask(ctx, userCred, imageId, needStop, autoStart, passwd, resetPasswd)
|
||||
return nil, err
|
||||
|
||||
}
|
||||
|
||||
func (self *SGuest) StartRebuildRootTask(ctx context.Context, userCred mcclient.TokenCredential, imageId string, needStop, autoStart bool) error {
|
||||
func (self *SGuest) StartRebuildRootTask(ctx context.Context, userCred mcclient.TokenCredential, imageId string, needStop, autoStart bool, passwd string, resetPasswd bool) error {
|
||||
data := jsonutils.NewDict()
|
||||
data.Set("image_id", jsonutils.NewString(imageId))
|
||||
if needStop {
|
||||
@@ -2454,6 +2506,14 @@ func (self *SGuest) StartRebuildRootTask(ctx context.Context, userCred mcclient.
|
||||
if autoStart {
|
||||
data.Set("auto_start", jsonutils.JSONTrue)
|
||||
}
|
||||
if resetPasswd {
|
||||
data.Set("reset_password", jsonutils.JSONTrue)
|
||||
} else {
|
||||
data.Set("reset_password", jsonutils.JSONFalse)
|
||||
}
|
||||
if len(passwd) > 0 {
|
||||
data.Set("password", jsonutils.NewString(passwd))
|
||||
}
|
||||
if self.GetHypervisor() == HYPERVISOR_BAREMETAL {
|
||||
task, err := taskman.TaskManager.NewTask(ctx, "BaremetalServerRebuildRootTask", self, userCred, data, "", "", nil)
|
||||
if err != nil {
|
||||
@@ -2875,12 +2935,12 @@ func (self *SGuest) PerformChangeConfig(ctx context.Context, userCred mcclient.T
|
||||
}
|
||||
|
||||
provider, e := self.GetHost().GetDriver()
|
||||
if e != nil {
|
||||
/*if e != nil {
|
||||
log.Errorf("Get Provider Error: %s", e)
|
||||
return nil, httperrors.NewInsufficientResourceError("Provider Not Found")
|
||||
}
|
||||
}*/
|
||||
|
||||
if !provider.IsPublicCloud() {
|
||||
if e != nil || !provider.IsPublicCloud() {
|
||||
for storageId, needSize := range diskSizes {
|
||||
iStorage, err := StorageManager.FetchById(storageId)
|
||||
if err != nil {
|
||||
@@ -2904,6 +2964,9 @@ func (self *SGuest) PerformChangeConfig(ctx context.Context, userCred mcclient.T
|
||||
if jsonutils.QueryBoolean(data, "auto_start", false) {
|
||||
confs.Add(jsonutils.NewBool(true), "auto_start")
|
||||
}
|
||||
|
||||
log.Debugf("%s", confs.String())
|
||||
|
||||
pendingUsage := &SQuota{}
|
||||
if addCpu > 0 {
|
||||
pendingUsage.Cpu = addCpu
|
||||
@@ -3140,17 +3203,23 @@ func (self *SGuest) GetDeployConfigOnHost(ctx context.Context, host *SHost, para
|
||||
deployAction = "deploy"
|
||||
}
|
||||
|
||||
resetPasswd := true
|
||||
if deployAction == "deploy" {
|
||||
resetPasswd = jsonutils.QueryBoolean(params, "reset_password", false)
|
||||
}
|
||||
// resetPasswd := true
|
||||
// if deployAction == "deploy" {
|
||||
resetPasswd := jsonutils.QueryBoolean(params, "reset_password", true)
|
||||
//}
|
||||
|
||||
if resetPasswd {
|
||||
config.Add(jsonutils.JSONTrue, "reset_password")
|
||||
passwd, _ := params.GetString("password")
|
||||
if len(passwd) > 0 {
|
||||
config.Add(jsonutils.NewString(passwd), "password")
|
||||
}
|
||||
keypair := self.getKeypair()
|
||||
if keypair != nil {
|
||||
config.Add(jsonutils.NewString(keypair.PublicKey), "public_key")
|
||||
}
|
||||
} else {
|
||||
config.Add(jsonutils.JSONFalse, "reset_password")
|
||||
}
|
||||
|
||||
config.Add(jsonutils.NewString(deployAction), "action")
|
||||
@@ -3939,7 +4008,7 @@ func (manager *SGuestManager) GetIpInProjectWithName(projectId, name string, isE
|
||||
sqlchemy.IsFalse(guests.Field("pending_deleted"))),
|
||||
sqlchemy.IsFalse(guests.Field("deleted")))).
|
||||
Join(networks, sqlchemy.AND(sqlchemy.Equals(networks.Field("id"), guestnics.Field("network_id")),
|
||||
sqlchemy.IsFalse(networks.Field("deleted")))).
|
||||
sqlchemy.IsFalse(networks.Field("deleted")))).
|
||||
Filter(sqlchemy.Equals(guests.Field("name"), name)).
|
||||
Filter(sqlchemy.NotEquals(guestnics.Field("ip_addr"), "")).
|
||||
Filter(sqlchemy.IsNotNull(guestnics.Field("ip_addr"))).
|
||||
@@ -4138,7 +4207,7 @@ func (self *SGuest) PerformAssociateEip(ctx context.Context, userCred mcclient.T
|
||||
return nil, httperrors.NewUnsupportOperationError("fixed eip cannot be associated")
|
||||
}
|
||||
|
||||
eipVm := eip.getVM()
|
||||
eipVm := eip.GetAssociateVM()
|
||||
if eipVm != nil {
|
||||
return nil, httperrors.NewConflictError("eip has been associated")
|
||||
}
|
||||
@@ -4156,6 +4225,8 @@ func (self *SGuest) PerformAssociateEip(ctx context.Context, userCred mcclient.T
|
||||
return nil, httperrors.NewInputParameterError("cannot associate eip and instance in different provider")
|
||||
}
|
||||
|
||||
self.SetStatus(userCred, VM_ASSOCIATE_EIP, "associate eip")
|
||||
|
||||
params := jsonutils.NewDict()
|
||||
params.Add(jsonutils.NewString(self.ExternalId), "instance_external_id")
|
||||
params.Add(jsonutils.NewString(self.Id), "instance_id")
|
||||
@@ -4179,6 +4250,9 @@ func (self *SGuest) PerformDissociateEip(ctx context.Context, userCred mcclient.
|
||||
if eip == nil {
|
||||
return nil, httperrors.NewInvalidStatusError("No eip to dissociate")
|
||||
}
|
||||
|
||||
self.SetStatus(userCred, VM_DISSOCIATE_EIP, "associate eip")
|
||||
|
||||
err = eip.StartEipDissociateTask(ctx, userCred, "")
|
||||
if err != nil {
|
||||
log.Errorf("fail to start dissociate task %s", err)
|
||||
|
||||
@@ -734,6 +734,30 @@ func isExitNetworkInfo(netConfig *SNetworkConfig) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SNetwork) getZone() *SZone {
|
||||
wire := self.GetWire()
|
||||
if wire != nil {
|
||||
return wire.GetZone()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SNetwork) getVpc() *SVpc {
|
||||
wire := self.GetWire()
|
||||
if wire != nil {
|
||||
return wire.getVpc()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SNetwork) getRegion() *SCloudregion {
|
||||
wire := self.GetWire()
|
||||
if wire != nil {
|
||||
return wire.getRegion()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SNetwork) getMoreDetails(extra *jsonutils.JSONDict) *jsonutils.JSONDict {
|
||||
wire := self.GetWire()
|
||||
extra.Add(jsonutils.NewString(wire.Name), "wire")
|
||||
@@ -747,6 +771,34 @@ func (self *SNetwork) getMoreDetails(extra *jsonutils.JSONDict) *jsonutils.JSOND
|
||||
extra.Add(jsonutils.NewInt(int64(self.GetBaremetalNicsCount())), "bm_vnics")
|
||||
extra.Add(jsonutils.NewInt(int64(self.GetGroupNicsCount())), "group_vnics")
|
||||
extra.Add(jsonutils.NewInt(int64(self.GetReservedNicsCount())), "reserve_vnics")
|
||||
|
||||
zone := self.getZone()
|
||||
if zone != nil {
|
||||
extra.Add(jsonutils.NewString(zone.GetId()), "zone_id")
|
||||
extra.Add(jsonutils.NewString(zone.GetName()), "zone")
|
||||
if len(zone.GetExternalId()) > 0 {
|
||||
extra.Add(jsonutils.NewString(zone.GetExternalId()), "zone_external_id")
|
||||
}
|
||||
}
|
||||
|
||||
region := self.getRegion()
|
||||
if region != nil {
|
||||
extra.Add(jsonutils.NewString(region.GetId()), "region_id")
|
||||
extra.Add(jsonutils.NewString(region.GetName()), "region")
|
||||
if len(region.GetExternalId()) > 0 {
|
||||
extra.Add(jsonutils.NewString(region.GetExternalId()), "region_external_id")
|
||||
}
|
||||
}
|
||||
|
||||
vpc := self.getVpc()
|
||||
if vpc != nil {
|
||||
extra.Add(jsonutils.NewString(vpc.GetId()), "vpc_id")
|
||||
extra.Add(jsonutils.NewString(vpc.GetName()), "vpc")
|
||||
if len(vpc.GetExternalId()) > 0 {
|
||||
extra.Add(jsonutils.NewString(vpc.GetExternalId()), "vpc_external_id")
|
||||
}
|
||||
}
|
||||
|
||||
return extra
|
||||
}
|
||||
|
||||
|
||||
@@ -124,7 +124,12 @@ func (self *SVpc) getMoreDetails(extra *jsonutils.JSONDict) *jsonutils.JSONDict
|
||||
extra.Add(jsonutils.NewInt(int64(self.GetWireCount())), "wire_count")
|
||||
extra.Add(jsonutils.NewInt(int64(self.GetNetworkCount())), "network_count")
|
||||
region := self.GetRegion()
|
||||
extra.Add(jsonutils.NewString(region.GetName()), "region")
|
||||
if region != nil {
|
||||
extra.Add(jsonutils.NewString(region.GetName()), "region")
|
||||
if len(region.GetExternalId()) > 0 {
|
||||
extra.Add(jsonutils.NewString(region.GetExternalId()), "region_external_id")
|
||||
}
|
||||
}
|
||||
return extra
|
||||
}
|
||||
|
||||
|
||||
@@ -561,3 +561,48 @@ func (manager *SWireManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQu
|
||||
|
||||
return q, err
|
||||
}
|
||||
|
||||
func (self *SWire) getRegion() *SCloudregion {
|
||||
zone := self.GetZone()
|
||||
if zone != nil {
|
||||
return zone.GetRegion()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SWire) GetCustomizeColumns(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) *jsonutils.JSONDict {
|
||||
extra := self.SStandaloneResourceBase.GetCustomizeColumns(ctx, userCred, query)
|
||||
return self.getMoreDetails(extra)
|
||||
}
|
||||
|
||||
func (self *SWire) GetExtraDetails(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) *jsonutils.JSONDict {
|
||||
extra := self.SStandaloneResourceBase.GetExtraDetails(ctx, userCred, query)
|
||||
return self.getMoreDetails(extra)
|
||||
}
|
||||
|
||||
func (self *SWire) getMoreDetails(extra *jsonutils.JSONDict) *jsonutils.JSONDict {
|
||||
extra.Add(jsonutils.NewInt(int64(self.NetworkCount())), "networks")
|
||||
zone := self.GetZone()
|
||||
if zone != nil {
|
||||
extra.Add(jsonutils.NewString(zone.GetName()), "zone")
|
||||
if len(zone.GetExternalId()) > 0 {
|
||||
extra.Add(jsonutils.NewString(zone.GetExternalId()), "zone_external_id")
|
||||
}
|
||||
}
|
||||
region := self.getRegion()
|
||||
if region != nil {
|
||||
extra.Add(jsonutils.NewString(region.GetId()), "region_id")
|
||||
extra.Add(jsonutils.NewString(region.GetName()), "region")
|
||||
if len(region.GetExternalId()) > 0 {
|
||||
extra.Add(jsonutils.NewString(region.GetExternalId()), "region_external_id")
|
||||
}
|
||||
}
|
||||
vpc := self.getVpc()
|
||||
if vpc != nil {
|
||||
extra.Add(jsonutils.NewString(vpc.GetName()), "vpc")
|
||||
if len(vpc.GetExternalId()) > 0 {
|
||||
extra.Add(jsonutils.NewString(vpc.GetExternalId()), "vpc_external_id")
|
||||
}
|
||||
}
|
||||
return extra
|
||||
}
|
||||
@@ -32,6 +32,11 @@ func (self *EipAssociateTask) OnInit(ctx context.Context, obj db.IStandaloneMode
|
||||
|
||||
instanceId, _ := self.Params.GetString("instance_id")
|
||||
server := models.GuestManager.FetchGuestById(instanceId)
|
||||
|
||||
if server.Status != models.VM_ASSOCIATE_EIP {
|
||||
server.SetStatus(self.UserCred, models.VM_ASSOCIATE_EIP, "associate eip")
|
||||
}
|
||||
|
||||
if server == nil {
|
||||
msg := fmt.Sprintf("fail to find server for instanceId %s", instanceId)
|
||||
eip.SetStatus(self.UserCred, models.EIP_STATUS_ASSOCIATE_FAIL, msg)
|
||||
@@ -57,5 +62,7 @@ func (self *EipAssociateTask) OnInit(ctx context.Context, obj db.IStandaloneMode
|
||||
|
||||
eip.SetStatus(self.UserCred, models.EIP_STATUS_READY, "associate")
|
||||
|
||||
server.StartSyncstatus(ctx, self.UserCred, "")
|
||||
|
||||
self.SetStageComplete(ctx, nil)
|
||||
}
|
||||
@@ -23,33 +23,43 @@ func init() {
|
||||
func (self *EipDissociateTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
|
||||
eip := obj.(*models.SElasticip)
|
||||
|
||||
extEip, err := eip.GetIEip()
|
||||
if err != nil {
|
||||
msg := fmt.Sprintf("fail to find iEIP for eip %s", err)
|
||||
eip.SetStatus(self.UserCred, models.EIP_STATUS_DISSOCIATE_FAIL, msg)
|
||||
self.SetStageFailed(ctx, msg)
|
||||
return
|
||||
}
|
||||
server := eip.GetAssociateVM()
|
||||
if server != nil {
|
||||
|
||||
if len(extEip.GetAssociationExternalId()) > 0 {
|
||||
err = extEip.Dissociate()
|
||||
if server.Status != models.VM_DISSOCIATE_EIP {
|
||||
server.SetStatus(self.UserCred, models.VM_DISSOCIATE_EIP, "dissociate eip")
|
||||
}
|
||||
|
||||
extEip, err := eip.GetIEip()
|
||||
if err != nil {
|
||||
msg := fmt.Sprintf("fail to remote dissociate eip %s", err)
|
||||
msg := fmt.Sprintf("fail to find iEIP for eip %s", err)
|
||||
eip.SetStatus(self.UserCred, models.EIP_STATUS_DISSOCIATE_FAIL, msg)
|
||||
self.SetStageFailed(ctx, msg)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
err = eip.Dissociate(ctx, self.UserCred)
|
||||
if err != nil {
|
||||
msg := fmt.Sprintf("fail to local dissociate eip %s", err)
|
||||
eip.SetStatus(self.UserCred, models.EIP_STATUS_DISSOCIATE_FAIL, msg)
|
||||
self.SetStageFailed(ctx, msg)
|
||||
return
|
||||
}
|
||||
if len(extEip.GetAssociationExternalId()) > 0 {
|
||||
err = extEip.Dissociate()
|
||||
if err != nil {
|
||||
msg := fmt.Sprintf("fail to remote dissociate eip %s", err)
|
||||
eip.SetStatus(self.UserCred, models.EIP_STATUS_DISSOCIATE_FAIL, msg)
|
||||
self.SetStageFailed(ctx, msg)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
eip.SetStatus(self.UserCred, models.EIP_STATUS_READY, "dissociate")
|
||||
err = eip.Dissociate(ctx, self.UserCred)
|
||||
if err != nil {
|
||||
msg := fmt.Sprintf("fail to local dissociate eip %s", err)
|
||||
eip.SetStatus(self.UserCred, models.EIP_STATUS_DISSOCIATE_FAIL, msg)
|
||||
self.SetStageFailed(ctx, msg)
|
||||
return
|
||||
}
|
||||
|
||||
eip.SetStatus(self.UserCred, models.EIP_STATUS_READY, "dissociate")
|
||||
|
||||
server.StartSyncstatus(ctx, self.UserCred, "")
|
||||
}
|
||||
|
||||
self.SetStageComplete(ctx, nil)
|
||||
|
||||
|
||||
@@ -139,9 +139,17 @@ func (self *KVMGuestRebuildRootTask) OnRebuildRootDiskComplete(ctx context.Conte
|
||||
|
||||
self.SetStage("OnGuestDeployComplete", nil)
|
||||
guest.SetStatus(self.UserCred, models.VM_DEPLOYING, "")
|
||||
params := jsonutils.NewDict()
|
||||
params.Set("reset_password", jsonutils.JSONTrue)
|
||||
guest.StartGuestDeployTask(ctx, self.UserCred, params, "deploy", self.GetTaskId())
|
||||
// params := jsonutils.NewDict()
|
||||
// params.Set("reset_password", jsonutils.JSONTrue)
|
||||
|
||||
// clear logininfo
|
||||
loginParams := make(map[string]interface{})
|
||||
loginParams["login_account"] = "none"
|
||||
loginParams["login_key"] = "none"
|
||||
loginParams["login_key_timestamp"] = "none"
|
||||
guest.SetAllMetadata(ctx, loginParams, self.UserCred)
|
||||
|
||||
guest.StartGuestDeployTask(ctx, self.UserCred, self.GetParams(), "deploy", self.GetTaskId())
|
||||
}
|
||||
|
||||
func (self *KVMGuestRebuildRootTask) OnRebuildRootDiskCompleteFailed(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
|
||||
|
||||
@@ -100,6 +100,11 @@ func NewInputParameterError(msg string, params ...interface{}) *httputils.JSONCl
|
||||
return NewJsonClientError(400, "InputParameterError", msg, err)
|
||||
}
|
||||
|
||||
func NewWeakPasswordError() *httputils.JSONClientError {
|
||||
msg, err := errorMessage("password must be 12 chars of at least one digit, letter, uppercase letter and punctuate", nil)
|
||||
return NewJsonClientError(400, "WeakPasswordError", msg, err)
|
||||
}
|
||||
|
||||
func NewInsufficientResourceError(msg string, params ...interface{}) *httputils.JSONClientError {
|
||||
msg, err := errorMessage(msg, params)
|
||||
return NewJsonClientError(400, "InsufficientResourceError", msg, err)
|
||||
|
||||
@@ -98,7 +98,7 @@ type ServerCreateOptions struct {
|
||||
Bios string `help:"BIOS" choices:"BIOS|UEFI"`
|
||||
Desc string `help:"Description" metavar:"<DESCRIPTION>" json:"description"`
|
||||
Boot string `help:"Boot device" metavar:"<BOOT_DEVICE>" choices:"disk|cdrom" json:"-"`
|
||||
NoAccountInit *bool `help:"Not reset account password" json:"reset_password"`
|
||||
NoAccountInit *bool `help:"Not reset account password"`
|
||||
AllowDelete *bool `help:"Unlock server to allow deleting" json:"-"`
|
||||
ShutdownBehavior string `help:"Behavior after VM server shutdown, stop or terminate server" metavar:"<SHUTDOWN_BEHAVIOR>" choices:"stop|terminate"`
|
||||
AutoStart *bool `help:"Auto start server after it is created"`
|
||||
@@ -264,11 +264,12 @@ type ServerSaveImageOptions struct {
|
||||
}
|
||||
|
||||
type ServerRebuildRootOptions struct {
|
||||
ID string `help:"Server to rebuild root" json:"-"`
|
||||
Image string `help:"New root Image template ID" json:"image_id"`
|
||||
Keypair string `help:"ssh Keypair used for login"`
|
||||
Password string `help:"Default user password"`
|
||||
AutoStart *bool `help:"Auto start server after it is created"`
|
||||
ID string `help:"Server to rebuild root" json:"-"`
|
||||
Image string `help:"New root Image template ID" json:"image_id"`
|
||||
Keypair string `help:"ssh Keypair used for login"`
|
||||
Password string `help:"Default user password"`
|
||||
NoAccountInit *bool `help:"Not reset account password"`
|
||||
AutoStart *bool `help:"Auto start server after it is created"`
|
||||
}
|
||||
|
||||
type ServerChangeConfigOptions struct {
|
||||
|
||||
@@ -88,10 +88,17 @@ func (self *SStoragecache) GetIImages() ([]cloudprovider.ICloudImage, error) {
|
||||
func (self *SStoragecache) UploadImage(userCred mcclient.TokenCredential, imageId string, osArch, osType, osDist string, extId string, isForce bool) (string, error) {
|
||||
|
||||
if len(extId) > 0 {
|
||||
status, _ := self.region.GetImageStatus(extId)
|
||||
log.Debugf("UploadImage: Image external ID exists %s", extId)
|
||||
|
||||
status, err := self.region.GetImageStatus(extId)
|
||||
if err != nil {
|
||||
log.Errorf("GetImageStatus error %s", err)
|
||||
}
|
||||
if status == ImageStatusAvailable && !isForce {
|
||||
return extId, nil
|
||||
}
|
||||
} else {
|
||||
log.Debugf("UploadImage: no external ID")
|
||||
}
|
||||
|
||||
return self.uploadImage(userCred, imageId, osArch, osType, osDist, isForce)
|
||||
|
||||
@@ -16,7 +16,7 @@ const (
|
||||
ALL_DIGITS = "0123456789"
|
||||
ALL_LETTERS = "abcdefghijklmnopqrstuvwxyz"
|
||||
ALL_UPPERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
ALL_PUNC = PUNC
|
||||
ALL_PUNC = "~`!@#$%^&*()-_=+[]{}|:':\",./<>?"
|
||||
)
|
||||
|
||||
type PasswordStrength struct {
|
||||
@@ -72,3 +72,20 @@ func AnalyzePasswordStrenth(passwd string) PasswordStrength {
|
||||
}
|
||||
return ps
|
||||
}
|
||||
|
||||
func (ps PasswordStrength) Len() int {
|
||||
return ps.Punctuats + ps.Uppercases + ps.Lowercases + ps.Digits
|
||||
}
|
||||
|
||||
func (ps PasswordStrength) MeetComplexity() bool {
|
||||
if ps.Punctuats > 0 && ps.Digits > 0 && ps.Lowercases > 0 && ps.Uppercases > 0 && ps.Len() >= 12 {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func MeetComplxity(passwd string) bool {
|
||||
ps := AnalyzePasswordStrenth(passwd)
|
||||
return ps.MeetComplexity()
|
||||
}
|
||||
|
||||
@@ -10,3 +10,18 @@ func TestRandomPassword2(t *testing.T) {
|
||||
rand.Seed(time.Now().Unix())
|
||||
t.Logf("%s", RandomPassword2(12))
|
||||
}
|
||||
|
||||
func TestMeetComplxity(t *testing.T) {
|
||||
cases := [] struct {
|
||||
in string
|
||||
want bool
|
||||
} {
|
||||
{"123456", false},
|
||||
{"123abcABC!@#", true},
|
||||
}
|
||||
for _, c := range cases {
|
||||
if c.want != MeetComplxity(c.in) {
|
||||
t.Errorf("%s != %v", c.in, c.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user