mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-19 02:37:24 +08:00
Merge branch 'release/2.4.0' of ssh://git.yunion.io/~qiujian/onecloud into feature/qj-vm-resource-pooling
This commit is contained in:
@@ -301,6 +301,19 @@ func init() {
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&options.ServerSecGroupOptions{}, "server-add-secgroup", "Add security group to a VM", func(s *mcclient.ClientSession, opts *options.ServerSecGroupOptions) error {
|
||||
params, err := options.StructToParams(opts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
srv, err := modules.Servers.PerformAction(s, opts.ID, "add-secgroup", params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(srv)
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&options.ServerSecGroupOptions{}, "server-assign-secgroup", "Assign security group to a VM", func(s *mcclient.ClientSession, opts *options.ServerSecGroupOptions) error {
|
||||
params, err := options.StructToParams(opts)
|
||||
if err != nil {
|
||||
@@ -327,10 +340,14 @@ func init() {
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&options.ServerIdOptions{}, "server-revoke-secgroup", "Assign security group to a VM", func(s *mcclient.ClientSession, opts *options.ServerIdOptions) error {
|
||||
srv, e := modules.Servers.PerformAction(s, opts.ID, "revoke-secgroup", nil)
|
||||
if e != nil {
|
||||
return e
|
||||
R(&options.ServerSecGroupOptions{}, "server-revoke-secgroup", "Revoke security group from VM", func(s *mcclient.ClientSession, opts *options.ServerSecGroupOptions) error {
|
||||
params, err := options.StructToParams(opts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
srv, err := modules.Servers.PerformAction(s, opts.ID, "revoke-secgroup", params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(srv)
|
||||
return nil
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
)
|
||||
|
||||
type GeneralUsageOptions struct {
|
||||
HostType []string `help:"Host types" choices:"hypervisor|baremetal|esxi|xen|kubelet|hyperv"`
|
||||
HostType []string `help:"Host types" choices:"hypervisor|baremetal|esxi|xen|kubelet|hyperv|aliyun|azure|aws|huawei|qcloud"`
|
||||
Project string
|
||||
}
|
||||
|
||||
|
||||
@@ -42,10 +42,11 @@ func (t *Timer2) Next(now time.Time) time.Time {
|
||||
}
|
||||
|
||||
type SCronJob struct {
|
||||
Name string
|
||||
job func(ctx context.Context, userCred mcclient.TokenCredential)
|
||||
Timer ICronTimer
|
||||
Next time.Time
|
||||
Name string
|
||||
job func(ctx context.Context, userCred mcclient.TokenCredential)
|
||||
Timer ICronTimer
|
||||
Next time.Time
|
||||
StartRun bool
|
||||
}
|
||||
|
||||
type CronJobTimerHeap []*SCronJob
|
||||
@@ -107,7 +108,7 @@ func (self *SCronJobManager) AddJob1(name string, interval time.Duration, jobFun
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SCronJobManager) AddJob2(name string, day, hour, min, sec int, jobFunc func(ctx context.Context, userCred mcclient.TokenCredential)) {
|
||||
func (self *SCronJobManager) AddJob2(name string, day, hour, min, sec int, jobFunc func(ctx context.Context, userCred mcclient.TokenCredential), startRun bool) {
|
||||
t := Timer2{
|
||||
day: day,
|
||||
hour: hour,
|
||||
@@ -115,9 +116,10 @@ func (self *SCronJobManager) AddJob2(name string, day, hour, min, sec int, jobFu
|
||||
sec: sec,
|
||||
}
|
||||
job := SCronJob{
|
||||
Name: name,
|
||||
job: jobFunc,
|
||||
Timer: &t,
|
||||
Name: name,
|
||||
job: jobFunc,
|
||||
Timer: &t,
|
||||
StartRun: startRun,
|
||||
}
|
||||
if !self.running {
|
||||
self.jobs = append(self.jobs, &job)
|
||||
@@ -155,6 +157,12 @@ func (self *SCronJobManager) run() {
|
||||
} else {
|
||||
timer = time.NewTimer(self.jobs[0].Next.Sub(now))
|
||||
}
|
||||
for i := 0; i < len(self.jobs); i += 1 {
|
||||
if self.jobs[i].StartRun {
|
||||
self.jobs[i].StartRun = false
|
||||
self.jobs[i].runJob()
|
||||
}
|
||||
}
|
||||
select {
|
||||
case now = <-timer.C:
|
||||
for i, job := range self.jobs {
|
||||
|
||||
@@ -187,6 +187,7 @@ type ICloudVM interface {
|
||||
GetInstanceType() string
|
||||
|
||||
AssignSecurityGroup(secgroupId string) error
|
||||
AssignSecurityGroups(secgroupIds []string) error
|
||||
|
||||
GetHypervisor() string
|
||||
|
||||
|
||||
@@ -52,6 +52,10 @@ func (self *SAzureGuestDriver) ChooseHostStorage(host *models.SHost, backend str
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SAzureGuestDriver) GetMaxSecurityGroupCount() int {
|
||||
return 1
|
||||
}
|
||||
|
||||
func (self *SAzureGuestDriver) GetDetachDiskStatus() ([]string, error) {
|
||||
return []string{models.VM_READY, models.VM_RUNNING}, nil
|
||||
}
|
||||
|
||||
@@ -34,6 +34,11 @@ func (self *SBaremetalGuestDriver) GetHypervisor() string {
|
||||
return models.HYPERVISOR_BAREMETAL
|
||||
}
|
||||
|
||||
func (self *SBaremetalGuestDriver) GetMaxSecurityGroupCount() int {
|
||||
//暂不支持绑定安全组
|
||||
return 0
|
||||
}
|
||||
|
||||
func (self *SBaremetalGuestDriver) GetMaxVCpuCount() int {
|
||||
return 1024
|
||||
}
|
||||
|
||||
@@ -197,6 +197,10 @@ func (self *SBaseGuestDriver) RequestSyncToBackup(ctx context.Context, guest *mo
|
||||
return fmt.Errorf("Not Implement")
|
||||
}
|
||||
|
||||
func (self *SBaseGuestDriver) GetMaxSecurityGroupCount() int {
|
||||
return 5
|
||||
}
|
||||
|
||||
func (self *SBaseGuestDriver) getTaskRequestHeader(task taskman.ITask) http.Header {
|
||||
return task.GetTaskRequestHeader()
|
||||
}
|
||||
|
||||
@@ -33,6 +33,11 @@ func (self *SESXiGuestDriver) RequestSyncConfigOnHost(ctx context.Context, guest
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SESXiGuestDriver) GetMaxSecurityGroupCount() int {
|
||||
//暂不支持绑定安全组
|
||||
return 0
|
||||
}
|
||||
|
||||
func (self *SESXiGuestDriver) GetDetachDiskStatus() ([]string, error) {
|
||||
return []string{models.VM_READY}, nil
|
||||
}
|
||||
|
||||
@@ -460,22 +460,26 @@ func (self *SManagedVirtualizedGuestDriver) RequestSyncConfigOnHost(ctx context.
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
secgroups := guest.GetSecgroups()
|
||||
externalIds := []string{}
|
||||
for _, secgroup := range secgroups {
|
||||
lockman.LockRawObject(ctx, "secgroupcache", fmt.Sprintf("%s-%s", guest.SecgrpId, vpcId))
|
||||
defer lockman.ReleaseRawObject(ctx, "secgroupcache", fmt.Sprintf("%s-%s", guest.SecgrpId, vpcId))
|
||||
|
||||
lockman.LockRawObject(ctx, "secgroupcache", fmt.Sprintf("%s-%s", guest.SecgrpId, vpcId))
|
||||
defer lockman.ReleaseRawObject(ctx, "secgroupcache", fmt.Sprintf("%s-%s", guest.SecgrpId, vpcId))
|
||||
|
||||
secgroupCache := models.SecurityGroupCacheManager.Register(ctx, task.GetUserCred(), guest.SecgrpId, vpcId, host.GetRegion().Id, host.ManagerId)
|
||||
if secgroupCache == nil {
|
||||
return nil, fmt.Errorf("failed to registor secgroupCache for secgroup: %s vpc: %s", guest.SecgrpId, vpcId)
|
||||
secgroupCache := models.SecurityGroupCacheManager.Register(ctx, task.GetUserCred(), secgroup.Id, vpcId, host.GetRegion().Id, host.ManagerId)
|
||||
if secgroupCache == nil {
|
||||
return nil, fmt.Errorf("failed to registor secgroupCache for secgroup: %s vpc: %s", secgroup.Id, vpcId)
|
||||
}
|
||||
extID, err := iregion.SyncSecurityGroup(secgroupCache.ExternalId, vpcId, secgroup.Name, secgroup.Description, secgroup.GetSecRules(""))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = secgroupCache.SetExternalId(extID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
externalIds = append(externalIds, extID)
|
||||
}
|
||||
extID, err := iregion.SyncSecurityGroup(secgroupCache.ExternalId, vpcId, guest.GetSecgroupName(), "", guest.GetSecRules())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = secgroupCache.SetExternalId(extID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil, iVM.AssignSecurityGroup(extID)
|
||||
return nil, iVM.AssignSecurityGroups(externalIds)
|
||||
}
|
||||
|
||||
iDisks, err := iVM.GetIDisks()
|
||||
|
||||
@@ -75,6 +75,9 @@ func (self *SQcloudGuestDriver) ValidateResizeDisk(guest *models.SGuest, disk *m
|
||||
if !utils.IsInStringArray(guest.Status, []string{models.VM_READY, models.VM_RUNNING}) {
|
||||
return fmt.Errorf("Cannot resize disk when guest in status %s", guest.Status)
|
||||
}
|
||||
if disk.DiskType == models.DISK_TYPE_SYS {
|
||||
return fmt.Errorf("Cannot resize system disk")
|
||||
}
|
||||
if utils.IsInStringArray(storage.StorageType, []string{models.STORAGE_LOCAL_BASIC, models.STORAGE_LOCAL_SSD}) {
|
||||
return fmt.Errorf("Cannot resize %s disk", storage.StorageType)
|
||||
}
|
||||
@@ -312,21 +315,27 @@ func (self *SQcloudGuestDriver) RequestSyncConfigOnHost(ctx context.Context, gue
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
lockman.LockRawObject(ctx, "secgroupcache", fmt.Sprintf("%s-normal", guest.SecgrpId))
|
||||
defer lockman.ReleaseRawObject(ctx, "secgroupcache", fmt.Sprintf("%s-normal", guest.SecgrpId))
|
||||
secgroups := guest.GetSecgroups()
|
||||
externalIds := []string{}
|
||||
for _, secgroup := range secgroups {
|
||||
|
||||
secgroupCache := models.SecurityGroupCacheManager.Register(ctx, task.GetUserCred(), guest.SecgrpId, "normal", host.GetRegion().Id, host.ManagerId)
|
||||
if secgroupCache == nil {
|
||||
return nil, fmt.Errorf("failed to registor secgroupCache for secgroup: %s", guest.SecgrpId)
|
||||
lockman.LockRawObject(ctx, "secgroupcache", fmt.Sprintf("%s-normal", guest.SecgrpId))
|
||||
defer lockman.ReleaseRawObject(ctx, "secgroupcache", fmt.Sprintf("%s-normal", guest.SecgrpId))
|
||||
|
||||
secgroupCache := models.SecurityGroupCacheManager.Register(ctx, task.GetUserCred(), secgroup.Id, "normal", host.GetRegion().Id, host.ManagerId)
|
||||
if secgroupCache == nil {
|
||||
return nil, fmt.Errorf("failed to registor secgroupCache for secgroup: %s", secgroup.Id)
|
||||
}
|
||||
extID, err := iregion.SyncSecurityGroup(secgroupCache.ExternalId, "", secgroup.Name, secgroup.Description, secgroup.GetSecRules(""))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = secgroupCache.SetExternalId(extID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
externalIds = append(externalIds, extID)
|
||||
}
|
||||
extID, err := iregion.SyncSecurityGroup(secgroupCache.ExternalId, "normal", guest.GetSecgroupName(), "", guest.GetSecRules())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = secgroupCache.SetExternalId(extID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil, iVM.AssignSecurityGroup(extID)
|
||||
return nil, iVM.AssignSecurityGroups(externalIds)
|
||||
}
|
||||
|
||||
iDisks, err := iVM.GetIDisks()
|
||||
|
||||
@@ -92,6 +92,7 @@ func InitHandlers(app *appsrv.Application) {
|
||||
models.HoststorageManager,
|
||||
models.HostschedtagManager,
|
||||
models.GuestnetworkManager,
|
||||
models.GuestsecgroupManager,
|
||||
models.LoadbalancernetworkManager,
|
||||
models.GuestdiskManager,
|
||||
models.GroupnetworkManager,
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/quotas"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/notifyclient"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/validators"
|
||||
"yunion.io/x/onecloud/pkg/compute/options"
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
@@ -633,6 +634,37 @@ func (self *SGuest) StartDeleteGuestTask(ctx context.Context, userCred mcclient.
|
||||
return self.GetDriver().StartDeleteGuestTask(ctx, userCred, self, params, parentTaskId)
|
||||
}
|
||||
|
||||
func (self *SGuest) AllowPerformAddSecgroup(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
|
||||
return self.IsOwner(userCred)
|
||||
}
|
||||
|
||||
func (self *SGuest) PerformAddSecgroup(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
if !utils.IsInStringArray(self.Status, []string{VM_READY, VM_RUNNING, VM_SUSPEND}) {
|
||||
return nil, httperrors.NewInputParameterError("Cannot assign security rules in status %s", self.Status)
|
||||
}
|
||||
|
||||
secgrpV := validators.NewModelIdOrNameValidator("secgrp", "secgroup", userCred.GetProjectId())
|
||||
if err := secgrpV.Validate(data.(*jsonutils.JSONDict)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
maxCount := self.GetDriver().GetMaxSecurityGroupCount()
|
||||
if maxCount == 0 {
|
||||
return nil, httperrors.NewUnsupportOperationError("Cannot assign security group for this guest %s", self.Name)
|
||||
}
|
||||
|
||||
secgroups := self.GetSecgroups()
|
||||
if len(secgroups) >= maxCount {
|
||||
return nil, httperrors.NewUnsupportOperationError("guest %s band to up to %d security groups", self.Name, maxCount)
|
||||
}
|
||||
|
||||
secgroup := secgrpV.Model.(*SSecurityGroup)
|
||||
if _, err := GuestsecgroupManager.newGuestSecgroup(ctx, userCred, self, secgroup); err != nil {
|
||||
return nil, httperrors.NewInputParameterError(err.Error())
|
||||
}
|
||||
return nil, self.StartSyncTask(ctx, userCred, true, "")
|
||||
}
|
||||
|
||||
func (self *SGuest) AllowPerformAssignSecgroup(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
|
||||
return self.IsOwner(userCred) || db.IsAdminAllowPerform(userCred, self, "assign-secgroup")
|
||||
}
|
||||
@@ -641,51 +673,75 @@ func (self *SGuest) AllowPerformRevokeSecgroup(ctx context.Context, userCred mcc
|
||||
return self.IsOwner(userCred) || db.IsAdminAllowPerform(userCred, self, "revoke-secgroup")
|
||||
}
|
||||
|
||||
func (self *SGuest) revokeSecgroup(ctx context.Context, userCred mcclient.TokenCredential, secgroup *SSecurityGroup) error {
|
||||
if secgroup == nil {
|
||||
return fmt.Errorf("failed to revoke null secgroup")
|
||||
}
|
||||
if self.SecgrpId != secgroup.Id {
|
||||
return GuestsecgroupManager.DeleteGuestSecgroup(ctx, userCred, self, secgroup)
|
||||
}
|
||||
secgroups := self.GetSecgroups()
|
||||
if len(secgroups) == 1 {
|
||||
_, err := self.GetModelManager().TableSpec().Update(self, func() error {
|
||||
self.SecgrpId = "default"
|
||||
return nil
|
||||
})
|
||||
return err
|
||||
}
|
||||
for _, _secgroup := range secgroups {
|
||||
if _secgroup.Id != secgroup.Id {
|
||||
err := GuestsecgroupManager.DeleteGuestSecgroup(ctx, userCred, self, &_secgroup)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = self.GetModelManager().TableSpec().Update(self, func() error {
|
||||
self.SecgrpId = _secgroup.Id
|
||||
return nil
|
||||
})
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SGuest) PerformRevokeSecgroup(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
if !utils.IsInStringArray(self.Status, []string{VM_READY, VM_RUNNING, VM_SUSPEND}) {
|
||||
return nil, httperrors.NewInputParameterError("Cannot revoke security rules in status %s", self.Status)
|
||||
} else {
|
||||
if _, err := self.GetModelManager().TableSpec().Update(self, func() error {
|
||||
self.SecgrpId = "default"
|
||||
return nil
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := self.StartSyncTask(ctx, userCred, true, ""); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
|
||||
secgrpV := validators.NewModelIdOrNameValidator("secgrp", "secgroup", userCred.GetProjectId())
|
||||
secgrpV.Optional(true)
|
||||
if err := secgrpV.Validate(data.(*jsonutils.JSONDict)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
secgroup, ok := secgrpV.Model.(*SSecurityGroup)
|
||||
if !ok {
|
||||
secgroup = self.getSecgroup()
|
||||
}
|
||||
if err := self.revokeSecgroup(ctx, userCred, secgroup); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil, self.StartSyncTask(ctx, userCred, true, "")
|
||||
}
|
||||
|
||||
func (self *SGuest) PerformAssignSecgroup(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
if !utils.IsInStringArray(self.Status, []string{VM_READY, VM_RUNNING, VM_SUSPEND}) {
|
||||
logclient.AddActionLog(self, logclient.ACT_VM_ASSIGNSECGROUP, "Cannot assign security rules in status "+self.Status, userCred, false)
|
||||
return nil, httperrors.NewInputParameterError("Cannot assign security rules in status %s", self.Status)
|
||||
} else {
|
||||
if secgrp, err := data.GetString("secgrp"); err != nil {
|
||||
logclient.AddActionLog(self, logclient.ACT_VM_ASSIGNSECGROUP, err, userCred, false)
|
||||
return nil, err
|
||||
} else if sg, err := SecurityGroupManager.FetchByIdOrName(userCred, secgrp); err != nil {
|
||||
msg := fmt.Sprintf("SecurityGroup %s not found", secgrp)
|
||||
logclient.AddActionLog(self, logclient.ACT_VM_ASSIGNSECGROUP, msg, userCred, false)
|
||||
return nil, httperrors.NewNotFoundError("SecurityGroup %s not found", secgrp)
|
||||
} else {
|
||||
if _, err := self.GetModelManager().TableSpec().Update(self, func() error {
|
||||
self.SecgrpId = sg.GetId()
|
||||
return nil
|
||||
}); err != nil {
|
||||
logclient.AddActionLog(self, logclient.ACT_VM_ASSIGNSECGROUP, err, userCred, false)
|
||||
return nil, err
|
||||
}
|
||||
if err := self.StartSyncTask(ctx, userCred, true, ""); err != nil {
|
||||
logclient.AddActionLog(self, logclient.ACT_VM_ASSIGNSECGROUP, err, userCred, false)
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
logclient.AddActionLog(self, logclient.ACT_VM_ASSIGNSECGROUP, nil, userCred, true)
|
||||
return nil, nil
|
||||
secgrpV := validators.NewModelIdOrNameValidator("secgrp", "secgroup", userCred.GetProjectId())
|
||||
if err := secgrpV.Validate(data.(*jsonutils.JSONDict)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if _, err := self.GetModelManager().TableSpec().Update(self, func() error {
|
||||
self.SecgrpId = secgrpV.Model.GetId()
|
||||
return nil
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return nil, self.StartSyncTask(ctx, userCred, true, "")
|
||||
}
|
||||
|
||||
func (self *SGuest) AllowPerformPurge(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
|
||||
|
||||
@@ -17,6 +17,7 @@ type IGuestDriver interface {
|
||||
|
||||
GetMaxVCpuCount() int
|
||||
GetMaxVMemSizeGB() int
|
||||
GetMaxSecurityGroupCount() int
|
||||
|
||||
IsSupportedBillingCycle(bc billing.SBillingCycle) bool
|
||||
|
||||
|
||||
+107
-16
@@ -8,6 +8,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/tristate"
|
||||
@@ -281,7 +282,12 @@ func (manager *SGuestManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQ
|
||||
if secgrp == nil {
|
||||
return nil, httperrors.NewResourceNotFoundError("secgroup %s not found", secgrpFilter)
|
||||
}
|
||||
q = q.Equals("secgrp_id", secgrp.GetId())
|
||||
q = q.Filter(
|
||||
sqlchemy.OR(
|
||||
sqlchemy.In(q.Field("id"), GuestsecgroupManager.Query("guest_id").Equals("secgroup_id", secgrp.GetId()).SubQuery()),
|
||||
sqlchemy.Equals(q.Field("secgrp_id"), secgrp.GetId()),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
zoneFilter, _ := queryDict.GetString("zone")
|
||||
@@ -1052,6 +1058,10 @@ func (self *SGuest) GetCustomizeColumns(ctx context.Context, userCred mcclient.T
|
||||
|
||||
extra.Add(jsonutils.NewString(self.GetSecgroupName()), "secgroup")
|
||||
|
||||
if secgroups := self.getSecgroupJson(); len(secgroups) > 0 {
|
||||
extra.Add(jsonutils.NewArray(secgroups...), "secgroups")
|
||||
}
|
||||
|
||||
if self.PendingDeleted {
|
||||
pendingDeletedAt := self.PendingDeletedAt.Add(time.Second * time.Duration(options.Options.PendingDeleteExpireSeconds))
|
||||
extra.Add(jsonutils.NewString(timeutils.FullIsoTime(pendingDeletedAt)), "auto_delete_at")
|
||||
@@ -1115,6 +1125,11 @@ func (self *SGuest) GetExtraDetails(ctx context.Context, userCred mcclient.Token
|
||||
// extra.Add(jsonutils.NewString(self.getFlavorName()), "flavor")
|
||||
extra.Add(jsonutils.NewString(self.getKeypairName()), "keypair")
|
||||
extra.Add(jsonutils.NewString(self.GetSecgroupName()), "secgroup")
|
||||
|
||||
if secgroups := self.getSecgroupJson(); len(secgroups) > 0 {
|
||||
extra.Add(jsonutils.NewArray(secgroups...), "secgroups")
|
||||
}
|
||||
|
||||
extra.Add(jsonutils.NewString(strings.Join(self.getIPs(), ",")), "ips")
|
||||
extra.Add(jsonutils.NewString(self.getSecurityRules()), "security_rules")
|
||||
extra.Add(jsonutils.NewString(self.getIsolatedDeviceDetails()), "isolated_devices")
|
||||
@@ -1416,6 +1431,30 @@ func (self *SGuest) IsWindows() bool {
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SGuest) getSecgroupJson() []jsonutils.JSONObject {
|
||||
secgroups := []jsonutils.JSONObject{}
|
||||
for _, secGrp := range self.GetSecgroups() {
|
||||
secgroups = append(secgroups, secGrp.getDesc())
|
||||
}
|
||||
return secgroups
|
||||
}
|
||||
|
||||
func (self *SGuest) GetSecgroups() []SSecurityGroup {
|
||||
secgrpQuery := SecurityGroupManager.Query()
|
||||
secgrpQuery.Filter(
|
||||
sqlchemy.OR(
|
||||
sqlchemy.Equals(secgrpQuery.Field("id"), self.SecgrpId),
|
||||
sqlchemy.In(secgrpQuery.Field("id"), GuestsecgroupManager.Query("secgroup_id").Equals("guest_id", self.Id).SubQuery()),
|
||||
),
|
||||
)
|
||||
secgroups := []SSecurityGroup{}
|
||||
if err := db.FetchModelObjects(SecurityGroupManager, secgrpQuery, &secgroups); err != nil {
|
||||
log.Errorf("Get security group error: %v", err)
|
||||
return nil
|
||||
}
|
||||
return secgroups
|
||||
}
|
||||
|
||||
func (self *SGuest) getSecgroup() *SSecurityGroup {
|
||||
return SecurityGroupManager.FetchSecgroupById(self.SecgrpId)
|
||||
}
|
||||
@@ -1446,7 +1485,7 @@ func (self *SGuest) GetSecRules() []secrules.SecurityRule {
|
||||
|
||||
func (self *SGuest) getSecRules() []secrules.SecurityRule {
|
||||
if secgrp := self.getSecgroup(); secgrp != nil {
|
||||
return secgrp.getSecRules("")
|
||||
return secgrp.GetSecRules("")
|
||||
}
|
||||
if rule, err := secrules.ParseSecurityRule(options.Options.DefaultSecurityRules); err == nil {
|
||||
return []secrules.SecurityRule{*rule}
|
||||
@@ -1465,6 +1504,27 @@ func (self *SGuest) getSecurityRules() string {
|
||||
}
|
||||
}
|
||||
|
||||
//获取多个安全组规则,优先级降序排序
|
||||
func (self *SGuest) getSecurityGroupsRules() string {
|
||||
secgroups := self.GetSecgroups()
|
||||
secgroupids := []string{}
|
||||
for _, secgroup := range secgroups {
|
||||
secgroupids = append(secgroupids, secgroup.Id)
|
||||
}
|
||||
q := SecurityGroupRuleManager.Query()
|
||||
q.Filter(sqlchemy.In(q.Field("secgroup_id"), secgroupids)).Desc(q.Field("priority"))
|
||||
secrules := []SSecurityGroupRule{}
|
||||
if err := db.FetchModelObjects(SecurityGroupRuleManager, q, &secrules); err != nil {
|
||||
log.Errorf("Get rules error: %v", err)
|
||||
return options.Options.DefaultSecurityRules
|
||||
}
|
||||
rules := []string{}
|
||||
for _, rule := range secrules {
|
||||
rules = append(rules, rule.String())
|
||||
}
|
||||
return strings.Join(rules, SECURITY_GROUP_SEPARATOR)
|
||||
}
|
||||
|
||||
func (self *SGuest) getAdminSecurityRules() string {
|
||||
secgrp := self.getAdminSecgroup()
|
||||
if secgrp != nil {
|
||||
@@ -1539,12 +1599,23 @@ func (self *SGuest) syncWithCloudVM(ctx context.Context, userCred mcclient.Token
|
||||
self.BillingType = extVM.GetBillingType()
|
||||
self.ExpiredAt = extVM.GetExpiredAt()
|
||||
|
||||
if metaData != nil && metaData.Contains("secgroupId") {
|
||||
if secgroupId, err := metaData.GetString("secgroupId"); err == nil && len(secgroupId) > 0 {
|
||||
if secgrp, err := SecurityGroupManager.FetchByExternalId(secgroupId); err == nil && secgrp != nil {
|
||||
self.SecgrpId = secgrp.GetId()
|
||||
} else {
|
||||
log.Errorf("Failed find secgroup %s for guest %s error: %v", secgroupId, self.Name, err)
|
||||
if metaData != nil && metaData.Contains("secgroupIds") {
|
||||
secgroupIds := []string{}
|
||||
if err := metaData.Unmarshal(&secgroupIds, "secgroupIds"); err == nil {
|
||||
for _, secgroupId := range secgroupIds {
|
||||
secgrp, err := SecurityGroupManager.FetchByExternalId(secgroupId)
|
||||
if err != nil {
|
||||
log.Errorf("Failed find secgroup %s for guest %s error: %v", secgroupId, self.Name, err)
|
||||
continue
|
||||
}
|
||||
secgroup := secgrp.(*SSecurityGroup)
|
||||
if len(self.SecgrpId) == 0 {
|
||||
self.SecgrpId = secgroup.Id
|
||||
} else {
|
||||
if _, err := GuestsecgroupManager.newGuestSecgroup(ctx, userCred, self, secgroup); err != nil {
|
||||
log.Errorf("failed to bind secgroup %s for guest %s error: %v", secgroup.Name, self.Name, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1634,12 +1705,22 @@ func (manager *SGuestManager) newCloudVM(ctx context.Context, userCred mcclient.
|
||||
guest.ProjectId = projectId
|
||||
}
|
||||
|
||||
if metaData != nil && metaData.Contains("secgroupId") {
|
||||
if secgroupId, err := metaData.GetString("secgroupId"); err == nil && len(secgroupId) > 0 {
|
||||
if secgrp, err := SecurityGroupManager.FetchByExternalId(secgroupId); err == nil && secgrp != nil {
|
||||
guest.SecgrpId = secgrp.GetId()
|
||||
} else {
|
||||
log.Errorf("Failed find secgroup %s for guest %s error: %v", secgroupId, guest.Name, err)
|
||||
extraSecgroups := []*SSecurityGroup{}
|
||||
if metaData != nil && metaData.Contains("secgroupIds") {
|
||||
secgroupIds := []string{}
|
||||
if err := metaData.Unmarshal(&secgroupIds, "secgroupIds"); err == nil {
|
||||
for _, secgroupId := range secgroupIds {
|
||||
secgrp, err := SecurityGroupManager.FetchByExternalId(secgroupId)
|
||||
if err != nil {
|
||||
log.Errorf("Failed find secgroup %s for guest %s error: %v", secgroupId, guest.Name, err)
|
||||
continue
|
||||
}
|
||||
secgroup := secgrp.(*SSecurityGroup)
|
||||
if len(guest.SecgrpId) == 0 {
|
||||
guest.SecgrpId = secgroup.Id
|
||||
} else {
|
||||
extraSecgroups = append(extraSecgroups, secgroup)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1650,6 +1731,12 @@ func (manager *SGuestManager) newCloudVM(ctx context.Context, userCred mcclient.
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, secgroup := range extraSecgroups {
|
||||
if _, err := GuestsecgroupManager.newGuestSecgroup(ctx, userCred, &guest, secgroup); err != nil {
|
||||
log.Errorf("failed to bind secgroup %s for guest %s error: %v", secgroup.Name, guest.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
if metaData != nil {
|
||||
meta := make(map[string]string, 0)
|
||||
if err := metaData.Unmarshal(meta); err != nil {
|
||||
@@ -2653,13 +2740,17 @@ func (self *SGuest) GetJsonDescAtHypervisor(ctx context.Context, host *SHost) *j
|
||||
desc.Add(jsonutils.NewString(secGrp.Name), "secgroup")
|
||||
}
|
||||
|
||||
if secgroups := self.getSecgroupJson(); len(secgroups) > 0 {
|
||||
desc.Add(jsonutils.NewArray(secgroups...), "secgroups")
|
||||
}
|
||||
|
||||
/*
|
||||
TODO
|
||||
srs := self.getSecurityRuleSet()
|
||||
if srs.estimatedSinglePortRuleCount() <= options.FirewallFlowCountLimit {
|
||||
*/
|
||||
|
||||
rules := self.getSecurityRules()
|
||||
rules := self.getSecurityGroupsRules()
|
||||
if len(rules) > 0 {
|
||||
desc.Add(jsonutils.NewString(rules), "security_rules")
|
||||
}
|
||||
@@ -2773,7 +2864,7 @@ func (self *SGuest) GetJsonDescAtBaremetal(ctx context.Context, host *SHost) *js
|
||||
desc.Add(jsonutils.NewStringArray(netRoles), "network_roles")
|
||||
}
|
||||
|
||||
rules := self.getSecurityRules()
|
||||
rules := self.getSecurityGroupsRules()
|
||||
if len(rules) > 0 {
|
||||
desc.Add(jsonutils.NewString(rules), "security_rules")
|
||||
}
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
)
|
||||
|
||||
type SGuestsecgroupManager struct {
|
||||
SGuestJointsManager
|
||||
}
|
||||
|
||||
var GuestsecgroupManager *SGuestsecgroupManager
|
||||
|
||||
func init() {
|
||||
db.InitManager(func() {
|
||||
GuestsecgroupManager = &SGuestsecgroupManager{
|
||||
SGuestJointsManager: NewGuestJointsManager(
|
||||
SGuestsecgroup{},
|
||||
"guestsecgroups_tbl",
|
||||
"guestsecgroup",
|
||||
"guestsecgroups",
|
||||
SecurityGroupManager,
|
||||
),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
type SGuestsecgroup struct {
|
||||
SGuestJointsBase
|
||||
|
||||
SecgroupId string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"required" key_index:"true"` // Column(VARCHAR(36, charset='ascii'), nullable=False)
|
||||
}
|
||||
|
||||
func (self *SGuestsecgroup) getSecgroup() *SSecurityGroup {
|
||||
secgrp, err := SecurityGroupManager.FetchById(self.SecgroupId)
|
||||
if err != nil {
|
||||
log.Errorf("failed to find secgroup %s", self.SecgroupId)
|
||||
return nil
|
||||
}
|
||||
secgroup := secgrp.(*SSecurityGroup)
|
||||
secgroup.SetModelManager(SecurityGroupManager)
|
||||
return secgroup
|
||||
}
|
||||
|
||||
func (manager *SGuestsecgroupManager) newGuestSecgroup(ctx context.Context, userCred mcclient.TokenCredential, guest *SGuest, secgroup *SSecurityGroup) (*SGuestsecgroup, error) {
|
||||
q := manager.Query()
|
||||
q = q.Equals("guest_id", guest.Id).Equals("secgroup_id", secgroup.Id)
|
||||
if count := q.Count(); count > 0 {
|
||||
return nil, fmt.Errorf("security group %s has already been assigned to guest %s", secgroup.Name, guest.Name)
|
||||
}
|
||||
|
||||
gs := SGuestsecgroup{SecgroupId: secgroup.Id}
|
||||
gs.SetModelManager(manager)
|
||||
gs.GuestId = guest.Id
|
||||
|
||||
lockman.LockObject(ctx, secgroup)
|
||||
defer lockman.ReleaseObject(ctx, secgroup)
|
||||
|
||||
return &gs, manager.TableSpec().Insert(&gs)
|
||||
}
|
||||
|
||||
func (manager *SGuestsecgroupManager) DeleteGuestSecgroup(ctx context.Context, userCred mcclient.TokenCredential, guest *SGuest, secgroup *SSecurityGroup) error {
|
||||
gss := []SGuestsecgroup{}
|
||||
q := manager.Query()
|
||||
q = q.Equals("guest_id", guest.Id).Equals("secgroup_id", secgroup.Id)
|
||||
if err := db.FetchModelObjects(manager, q, &gss); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, gs := range gss {
|
||||
if err := gs.Delete(ctx, userCred); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SGuestsecgroup) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
return db.DeleteModel(ctx, userCred, self)
|
||||
}
|
||||
@@ -51,8 +51,13 @@ type SSecurityGroup struct {
|
||||
|
||||
func (self *SSecurityGroup) GetGuestsQuery() *sqlchemy.SQuery {
|
||||
guests := GuestManager.Query().SubQuery()
|
||||
return guests.Query().Filter(sqlchemy.OR(sqlchemy.Equals(guests.Field("secgrp_id"), self.Id),
|
||||
sqlchemy.Equals(guests.Field("admin_secgrp_id"), self.Id)))
|
||||
return guests.Query().Filter(
|
||||
sqlchemy.OR(
|
||||
sqlchemy.Equals(guests.Field("secgrp_id"), self.Id),
|
||||
sqlchemy.Equals(guests.Field("admin_secgrp_id"), self.Id),
|
||||
sqlchemy.In(guests.Field("id"), GuestsecgroupManager.Query("guest_id").Equals("secgroup_id", self.Id).SubQuery()),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
func (self *SSecurityGroup) GetGuestsCount() int {
|
||||
@@ -60,7 +65,7 @@ func (self *SSecurityGroup) GetGuestsCount() int {
|
||||
}
|
||||
|
||||
func (self *SSecurityGroup) GetGuests() []SGuest {
|
||||
guests := make([]SGuest, 0)
|
||||
guests := []SGuest{}
|
||||
q := self.GetGuestsQuery()
|
||||
err := db.FetchModelObjects(GuestManager, q, &guests)
|
||||
if err != nil {
|
||||
@@ -70,6 +75,14 @@ func (self *SSecurityGroup) GetGuests() []SGuest {
|
||||
return guests
|
||||
}
|
||||
|
||||
func (self *SSecurityGroup) getDesc() jsonutils.JSONObject {
|
||||
desc := jsonutils.NewDict()
|
||||
desc.Add(jsonutils.NewString(self.Name), "name")
|
||||
desc.Add(jsonutils.NewString(self.Id), "id")
|
||||
desc.Add(jsonutils.NewString(self.getSecurityRuleString("")), "security_rules")
|
||||
return desc
|
||||
}
|
||||
|
||||
func (self *SSecurityGroup) GetExtraDetails(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) *jsonutils.JSONDict {
|
||||
extra := self.SSharableVirtualResourceBase.GetExtraDetails(ctx, userCred, query)
|
||||
extra.Add(jsonutils.NewInt(int64(len(self.GetGuests()))), "guest_cnt")
|
||||
@@ -121,7 +134,7 @@ func (self *SSecurityGroup) getSecurityRules(direction string) (rules []SSecurit
|
||||
return
|
||||
}
|
||||
|
||||
func (self *SSecurityGroup) getSecRules(direction string) []secrules.SecurityRule {
|
||||
func (self *SSecurityGroup) GetSecRules(direction string) []secrules.SecurityRule {
|
||||
rules := make([]secrules.SecurityRule, 0)
|
||||
for _, _rule := range self.getSecurityRules(direction) {
|
||||
//这里没必要拆分为单个单个的端口,到公有云那边适配
|
||||
|
||||
@@ -4,10 +4,10 @@ import (
|
||||
"context"
|
||||
"database/sql"
|
||||
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
|
||||
@@ -243,10 +243,11 @@ func (self *SStoragecache) StartImageCacheTask(ctx context.Context, userCred mcc
|
||||
|
||||
if image != nil {
|
||||
imgInfo := imagetools.NormalizeImageInfo(image.Name, image.Properties["os_arch"], image.Properties["os_type"],
|
||||
image.Properties["os_distribution"])
|
||||
image.Properties["os_distribution"], image.Properties["os_version"])
|
||||
data.Add(jsonutils.NewString(imgInfo.OsType), "os_type")
|
||||
data.Add(jsonutils.NewString(imgInfo.OsArch), "os_arch")
|
||||
data.Add(jsonutils.NewString(imgInfo.OsDistro), "os_distribution")
|
||||
data.Add(jsonutils.NewString(imgInfo.OsVersion), "os_version")
|
||||
}
|
||||
|
||||
if isForce {
|
||||
|
||||
@@ -61,8 +61,8 @@ func StartService() {
|
||||
cron.AddJob1("CleanPendingDeleteLoadbalancers", time.Duration(options.Options.LoadbalancerPendingDeleteCheckInterval)*time.Second, models.LoadbalancerAgentManager.CleanPendingDeleteLoadbalancers)
|
||||
cron.AddJob1("CleanPendingDeleteServers", time.Duration(options.Options.PrepaidExpireCheckSeconds)*time.Second, models.GuestManager.DeleteExpiredPrepaidServers)
|
||||
|
||||
cron.AddJob2("AutoDiskSnapshot", options.Options.AutoSnapshotDay, options.Options.AutoSnapshotHour, 0, 0, models.DiskManager.AutoDiskSnapshot)
|
||||
cron.AddJob2("SyncSkus", options.Options.SyncSkusDay, options.Options.SyncSkusHour, 0, 0, skus.SyncSkus)
|
||||
cron.AddJob2("AutoDiskSnapshot", options.Options.AutoSnapshotDay, options.Options.AutoSnapshotHour, 0, 0, models.DiskManager.AutoDiskSnapshot, false)
|
||||
cron.AddJob2("SyncSkus", options.Options.SyncSkusDay, options.Options.SyncSkusHour, 0, 0, skus.SyncSkus, true)
|
||||
|
||||
cron.Start()
|
||||
defer cron.Stop()
|
||||
|
||||
+53
-19
@@ -103,32 +103,41 @@ func processSkuData(ndata jsonutils.JSONObject) jsonutils.JSONObject {
|
||||
func (self *SkusZone) Init() error {
|
||||
s := auth.GetAdminSession(options.Options.Region, "")
|
||||
p, r, z := self.getExternalZone()
|
||||
|
||||
ret, e := modules.CloudmetaSkus.GetSkus(s, p, r, z)
|
||||
if e != nil {
|
||||
log.Debugf("SkusZone %s init failed, %s", z, e.Error())
|
||||
return e
|
||||
}
|
||||
limit := 1024
|
||||
offset := 0
|
||||
total := 1024
|
||||
|
||||
records := map[string]jsonutils.JSONObject{}
|
||||
for _, sku := range ret.Data {
|
||||
name, err := sku.GetString("name")
|
||||
if err != nil {
|
||||
log.Debugf("SkusZone sku name empty : %s", sku)
|
||||
return err
|
||||
for offset < total {
|
||||
ret, e := modules.CloudmetaSkus.GetSkus(s, p, r, z, limit, offset)
|
||||
if e != nil {
|
||||
log.Debugf("SkusZone %s init failed, %s", z, e.Error())
|
||||
return e
|
||||
}
|
||||
|
||||
if odata, exists := records[name]; exists {
|
||||
records[name] = mergeSkuData(odata, sku)
|
||||
} else {
|
||||
records[name] = processSkuData(sku)
|
||||
for _, sku := range ret.Data {
|
||||
name, err := sku.GetString("name")
|
||||
if err != nil {
|
||||
log.Debugf("SkusZone sku name empty : %s", sku)
|
||||
return err
|
||||
}
|
||||
|
||||
if odata, exists := records[name]; exists {
|
||||
records[name] = mergeSkuData(odata, sku)
|
||||
} else {
|
||||
records[name] = processSkuData(sku)
|
||||
}
|
||||
}
|
||||
|
||||
offset += limit
|
||||
total = ret.Total
|
||||
}
|
||||
|
||||
filtedData := []jsonutils.JSONObject{}
|
||||
for _, item := range records {
|
||||
filtedData = append(filtedData, item)
|
||||
}
|
||||
|
||||
self.total = len(records)
|
||||
self.skus = filtedData
|
||||
return nil
|
||||
@@ -208,6 +217,9 @@ func (self *SkusZone) getExternalZone() (string, string, string) {
|
||||
if len(parts) == 3 {
|
||||
// provider, region, zone
|
||||
return parts[0], parts[1], parts[2]
|
||||
} else if len(parts) == 2 && parts[0] == models.CLOUD_PROVIDER_AZURE {
|
||||
// azure 没有zone的概念
|
||||
return parts[0], parts[1], parts[1]
|
||||
}
|
||||
|
||||
log.Debugf("SkusZone invalid external zone id %s", self.ExternalZoneId)
|
||||
@@ -235,9 +247,17 @@ func (self *SkusZoneList) initData(provider string, region models.SCloudregion,
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SkusZoneList) Refresh() error {
|
||||
provideIds := cloudprovider.GetRegistedProviderIds()
|
||||
for _, p := range provideIds {
|
||||
func (self *SkusZoneList) Refresh(providerIds *[]string) error {
|
||||
self.Data = []*SkusZone{}
|
||||
|
||||
var pIds []string
|
||||
if providerIds == nil {
|
||||
pIds = cloudprovider.GetRegistedProviderIds()
|
||||
} else {
|
||||
pIds = *providerIds
|
||||
}
|
||||
|
||||
for _, p := range pIds {
|
||||
regions, e := models.CloudregionManager.GetRegionByProvider(p)
|
||||
if e != nil {
|
||||
return e
|
||||
@@ -288,7 +308,7 @@ func (self *SkusZoneList) SyncToLocalDB() error {
|
||||
|
||||
func SyncSkus(ctx context.Context, userCred mcclient.TokenCredential) {
|
||||
skus := SkusZoneList{}
|
||||
if e := skus.Refresh(); e != nil {
|
||||
if e := skus.Refresh(nil); e != nil {
|
||||
log.Errorf("SyncSkus refresh failed, %s", e.Error())
|
||||
}
|
||||
|
||||
@@ -296,3 +316,17 @@ func SyncSkus(ctx context.Context, userCred mcclient.TokenCredential) {
|
||||
log.Errorf("SyncSkus sync to local db failed, %s", e.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func SyncSkusByProviderIds(providerIds []string) error {
|
||||
skus := SkusZoneList{}
|
||||
log.Debugf("SyncSkusByProviderIds %s", providerIds)
|
||||
if e := skus.Refresh(&providerIds); e != nil {
|
||||
return fmt.Errorf("SyncSkus refresh failed, %s", e.Error())
|
||||
}
|
||||
|
||||
if e := skus.SyncToLocalDB(); e != nil {
|
||||
return fmt.Errorf("SyncSkus sync to local db failed, %s", e.Error())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"yunion.io/x/onecloud/pkg/compute/models"
|
||||
"yunion.io/x/onecloud/pkg/compute/skus"
|
||||
)
|
||||
|
||||
type CloudAccountSyncInfoTask struct {
|
||||
@@ -82,6 +83,11 @@ func (self *CloudAccountSyncInfoTask) OnCloudaccountSyncComplete(ctx context.Con
|
||||
if account != nil {
|
||||
account.SetStatus(self.UserCred, models.CLOUD_PROVIDER_CONNECTED, "")
|
||||
}
|
||||
|
||||
// sync skus
|
||||
if err := skus.SyncSkusByProviderIds([]string{cloudprovider.Provider}); err != nil {
|
||||
self.SetStageFailed(ctx, err.Error())
|
||||
}
|
||||
}
|
||||
self.SetStageComplete(ctx, nil)
|
||||
}
|
||||
|
||||
@@ -107,8 +107,9 @@ func (self *DiskResizeTask) OnDiskResizeComplete(ctx context.Context, disk *mode
|
||||
self.finalReleasePendingUsage(ctx)
|
||||
}
|
||||
|
||||
func (self *DiskResizeTask) OnDiskResizeCompleteFailed(ctx context.Context, disk *models.SDisk, reason jsonutils.JSONObject) {
|
||||
disk.SetDiskReady(ctx, self.GetUserCred(), reason.String())
|
||||
func (self *DiskResizeTask) OnDiskResizeCompleteFailed(ctx context.Context, disk *models.SDisk, data jsonutils.JSONObject) {
|
||||
disk.SetDiskReady(ctx, self.GetUserCred(), data.String())
|
||||
db.OpsLog.LogEvent(disk, db.ACT_RESIZE_FAIL, disk.GetShortDesc(), self.UserCred)
|
||||
logclient.AddActionLog(disk, logclient.ACT_RESIZE, reason.String(), self.UserCred, false)
|
||||
logclient.AddActionLog(disk, logclient.ACT_RESIZE, data.String(), self.UserCred, false)
|
||||
self.SetStageFailed(ctx, data.String())
|
||||
}
|
||||
|
||||
@@ -66,6 +66,7 @@ func (self *DiskSaveTask) StartBackupDisk(ctx context.Context, disk *models.SDis
|
||||
func (self *DiskSaveTask) OnDiskBackupCompleteFailed(ctx context.Context, disk *models.SDisk, data jsonutils.JSONObject) {
|
||||
disk.SetDiskReady(ctx, self.GetUserCred(), data.String())
|
||||
db.OpsLog.LogEvent(disk, db.ACT_SAVE_FAIL, data.String(), self.GetUserCred())
|
||||
self.SetStageFailed(ctx, data.String())
|
||||
}
|
||||
|
||||
func (self *DiskSaveTask) OnDiskBackupComplete(ctx context.Context, disk *models.SDisk, data *jsonutils.JSONDict) {
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/compute/models"
|
||||
)
|
||||
|
||||
@@ -38,13 +39,13 @@ func (self *EipDissociateTask) OnInit(ctx context.Context, obj db.IStandaloneMod
|
||||
}
|
||||
|
||||
extEip, err := eip.GetIEip()
|
||||
if err != nil {
|
||||
if err != nil && err != cloudprovider.ErrNotFound {
|
||||
msg := fmt.Sprintf("fail to find iEIP for eip %s", err)
|
||||
self.TaskFail(ctx, eip, msg, server)
|
||||
return
|
||||
}
|
||||
|
||||
if len(extEip.GetAssociationExternalId()) > 0 {
|
||||
if err == nil && len(extEip.GetAssociationExternalId()) > 0 {
|
||||
err = extEip.Dissociate()
|
||||
if err != nil {
|
||||
msg := fmt.Sprintf("fail to remote dissociate eip %s", err)
|
||||
|
||||
@@ -127,16 +127,25 @@ func (self *GuestDeployTask) OnDeployGuestComplete(ctx context.Context, obj db.I
|
||||
func (self *GuestDeployTask) OnDeployGuestCompleteFailed(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
|
||||
guest := obj.(*models.SGuest)
|
||||
guest.SetStatus(self.UserCred, models.VM_DEPLOY_FAILED, data.String())
|
||||
self.SetStageFailed(ctx, data.String())
|
||||
}
|
||||
|
||||
func (self *GuestDeployTask) OnDeployStartGuestComplete(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
|
||||
self.SetStageComplete(ctx, nil)
|
||||
}
|
||||
|
||||
func (self *GuestDeployTask) OnDeployStartGuestCompleteFailed(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
|
||||
self.SetStageFailed(ctx, data.String())
|
||||
}
|
||||
|
||||
func (self *GuestDeployTask) OnDeployGuestSyncstatusComplete(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
|
||||
self.SetStageComplete(ctx, nil)
|
||||
}
|
||||
|
||||
func (self *GuestDeployTask) OnDeployGuestSyncstatusCompleteFailed(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
|
||||
self.SetStageFailed(ctx, data.String())
|
||||
}
|
||||
|
||||
type GuestDeployBackupTask struct {
|
||||
GuestDeployTask
|
||||
}
|
||||
|
||||
@@ -111,6 +111,7 @@ func (self *GuestRebuildRootTask) OnRebuildRootDiskCompleteFailed(ctx context.Co
|
||||
db.OpsLog.LogEvent(guest, db.ACT_REBUILD_ROOT_FAIL, data, self.UserCred)
|
||||
guest.SetStatus(self.UserCred, models.VM_REBUILD_ROOT_FAIL, "")
|
||||
logclient.AddActionLog(guest, logclient.ACT_VM_REBUILD, data, self.UserCred, false)
|
||||
self.SetStageFailed(ctx, data.String())
|
||||
}
|
||||
|
||||
func (self *GuestRebuildRootTask) OnSyncStatusComplete(ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject) {
|
||||
|
||||
@@ -68,7 +68,7 @@ func (self *GuestStartTask) RequestStart(ctx context.Context, guest *models.SGue
|
||||
guest.SetStatus(self.UserCred, models.VM_STARTING, "")
|
||||
result, err := guest.GetDriver().RequestStartOnHost(ctx, guest, host, self.UserCred, self)
|
||||
if err != nil {
|
||||
self.onStartGuestFailed(ctx, guest, err)
|
||||
self.OnStartCompleteFailed(ctx, guest, jsonutils.NewString(err.Error()))
|
||||
} else {
|
||||
if result != nil && jsonutils.QueryBoolean(result, "is_running", false) {
|
||||
// guest.SetStatus(self.UserCred, models.VM_RUNNING, "start")
|
||||
@@ -84,7 +84,7 @@ func (self *GuestStartTask) RequestStartBacking(ctx context.Context, guest *mode
|
||||
guest.SetStatus(self.UserCred, models.VM_BACKUP_STARTING, "")
|
||||
result, err := guest.GetDriver().RequestStartOnHost(ctx, guest, host, self.UserCred, self)
|
||||
if err != nil {
|
||||
self.onStartGuestFailed(ctx, guest, err)
|
||||
self.OnStartCompleteFailed(ctx, guest, jsonutils.NewString(err.Error()))
|
||||
} else {
|
||||
if result != nil && jsonutils.QueryBoolean(result, "is_running", false) {
|
||||
self.OnStartBackupGuestComplete(ctx, guest, nil)
|
||||
@@ -100,13 +100,17 @@ func (self *GuestStartTask) OnStartBackupGuestComplete(ctx context.Context, gues
|
||||
nbdServerUri := fmt.Sprintf("nbd:%s:%d", backupHost.AccessIp, nbdServerPort)
|
||||
guest.SetMetadata(ctx, "backup_nbd_server_uri", nbdServerUri, self.UserCred)
|
||||
} else {
|
||||
self.onStartGuestFailed(ctx, guest, fmt.Errorf("Start backup guest result missing nbd_server_port"))
|
||||
self.OnStartCompleteFailed(ctx, guest, jsonutils.NewString("Start backup guest result missing nbd_server_port"))
|
||||
return
|
||||
}
|
||||
}
|
||||
self.RequestStart(ctx, guest)
|
||||
}
|
||||
|
||||
func (self *GuestStartTask) OnStartBackupGuestCompleteFailed(ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject) {
|
||||
self.OnStartCompleteFailed(ctx, guest, data)
|
||||
}
|
||||
|
||||
func (self *GuestStartTask) OnStartComplete(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
|
||||
guest := obj.(*models.SGuest)
|
||||
db.OpsLog.LogEvent(guest, db.ACT_START, guest.GetShortDesc(), self.UserCred)
|
||||
@@ -123,14 +127,10 @@ func (self *GuestStartTask) OnGuestSyncstatusAfterStart(ctx context.Context, obj
|
||||
|
||||
func (self *GuestStartTask) OnStartCompleteFailed(ctx context.Context, obj db.IStandaloneModel, err jsonutils.JSONObject) {
|
||||
guest := obj.(*models.SGuest)
|
||||
guest.SetStatus(self.UserCred, models.VM_START_FAILED, err.String())
|
||||
db.OpsLog.LogEvent(guest, db.ACT_START_FAIL, err, self.UserCred)
|
||||
}
|
||||
|
||||
func (self *GuestStartTask) onStartGuestFailed(ctx context.Context, guest *models.SGuest, err error) {
|
||||
guest.SetStatus(self.UserCred, models.VM_START_FAILED, err.Error())
|
||||
self.SetStageFailed(ctx, err.Error())
|
||||
self.OnStartCompleteFailed(ctx, guest, jsonutils.NewString(err.Error()))
|
||||
logclient.AddActionLog(guest, logclient.ACT_VM_START, err, self.UserCred, false)
|
||||
self.SetStageFailed(ctx, err.String())
|
||||
}
|
||||
|
||||
func (self *GuestStartTask) taskComplete(ctx context.Context, guest *models.SGuest) {
|
||||
|
||||
@@ -40,6 +40,7 @@ func (self *GuestSuspendTask) OnSuspendCompleteFailed(ctx context.Context, obj d
|
||||
guest := obj.(*models.SGuest)
|
||||
guest.SetStatus(self.UserCred, models.VM_RUNNING, "")
|
||||
db.OpsLog.LogEvent(guest, db.ACT_STOP_FAIL, err.String(), self.UserCred)
|
||||
self.SetStageFailed(ctx, err.String())
|
||||
}
|
||||
|
||||
func (self *GuestSuspendTask) OnSuspendGuestFail(guest *models.SGuest, reason string) {
|
||||
|
||||
@@ -37,11 +37,11 @@ func init() {
|
||||
registerCompute(&ServerSkus)
|
||||
}
|
||||
|
||||
func (self *SkusManager) GetSkus(s *mcclient.ClientSession, providerId, regionId, zoneId string) (*ListResult, error) {
|
||||
func (self *SkusManager) GetSkus(s *mcclient.ClientSession, providerId, regionId, zoneId string, limit, offset int) (*ListResult, error) {
|
||||
p := strings.ToLower(providerId)
|
||||
r := strings.ToLower(regionId)
|
||||
z := strings.ToLower(zoneId)
|
||||
url := fmt.Sprintf("/providers/%s/regions/%s/zones/%s/skus", p, r, z)
|
||||
url := fmt.Sprintf("/providers/%s/regions/%s/zones/%s/skus?limit=%d&offset=%d", p, r, z, limit, offset)
|
||||
ret, err := self._list(s, url, self.KeywordPlural)
|
||||
if err != nil {
|
||||
return &ListResult{}, err
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"yunion.io/x/pkg/utils"
|
||||
|
||||
"context"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/compute/models"
|
||||
"yunion.io/x/onecloud/pkg/util/billing"
|
||||
@@ -228,13 +229,11 @@ func (self *SInstance) GetMetadata() *jsonutils.JSONDict {
|
||||
data.Update(meta)
|
||||
}
|
||||
}
|
||||
secgroupIds := jsonutils.NewArray()
|
||||
for _, secgroupId := range self.SecurityGroupIds.SecurityGroupId {
|
||||
if len(secgroupId) > 0 {
|
||||
data.Add(jsonutils.NewString(secgroupId), "secgroupId")
|
||||
break
|
||||
}
|
||||
secgroupIds.Add(jsonutils.NewString(secgroupId))
|
||||
}
|
||||
|
||||
data.Add(secgroupIds, "secgroupIds")
|
||||
return data
|
||||
}
|
||||
|
||||
@@ -859,6 +858,10 @@ func (self *SInstance) AssignSecurityGroup(secgroupId string) error {
|
||||
return self.host.zone.region.AssignSecurityGroup(secgroupId, self.InstanceId)
|
||||
}
|
||||
|
||||
func (self *SInstance) AssignSecurityGroups(secgroupIds []string) error {
|
||||
return self.host.zone.region.AssignSecurityGroups(secgroupIds, self.InstanceId)
|
||||
}
|
||||
|
||||
func (self *SInstance) GetBillingType() string {
|
||||
switch self.InstanceChargeType {
|
||||
case PrePaidInstanceChargeType:
|
||||
|
||||
@@ -501,16 +501,23 @@ func (self *SRegion) syncSecgroupRules(secgroupId string, rules []secrules.Secur
|
||||
}
|
||||
|
||||
func (self *SRegion) AssignSecurityGroup(secgroupId, instanceId string) error {
|
||||
params := map[string]string{"InstanceId": instanceId, "SecurityGroupId": secgroupId}
|
||||
if _, err := self.ecsRequest("JoinSecurityGroup", params); err != nil {
|
||||
return err
|
||||
return self.AssignSecurityGroups([]string{secgroupId}, instanceId)
|
||||
}
|
||||
|
||||
func (self *SRegion) AssignSecurityGroups(secgroupIds []string, instanceId string) error {
|
||||
params := map[string]string{"InstanceId": instanceId}
|
||||
for _, secgroupId := range secgroupIds {
|
||||
params["SecurityGroupId"] = secgroupId
|
||||
if _, err := self.ecsRequest("JoinSecurityGroup", params); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
instance, err := self.GetInstance(instanceId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, _secgroupId := range instance.SecurityGroupIds.SecurityGroupId {
|
||||
if _secgroupId != secgroupId {
|
||||
if !utils.IsInStringArray(_secgroupId, secgroupIds) {
|
||||
if err := self.leaveSecurityGroup(_secgroupId, instanceId); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
+10
-3
@@ -87,7 +87,6 @@ func (self *SImage) GetStatus() string {
|
||||
}
|
||||
|
||||
func (self *SImage) Refresh() error {
|
||||
// todo: GetImage
|
||||
new, err := self.storageCache.region.GetImage(self.ImageId)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -173,7 +172,11 @@ func (self *SRegion) ExportImage(instanceId string, imageId string) (*ImageExpor
|
||||
}
|
||||
|
||||
func (self *SRegion) GetImage(imageId string) (*SImage, error) {
|
||||
images, _, err := self.GetImages("", ImageOwnerSelf, []string{imageId}, "", 0, 1)
|
||||
if len(imageId) == 0 {
|
||||
return nil, fmt.Errorf("image id should not be empty")
|
||||
}
|
||||
|
||||
images, _, err := self.GetImages("", ImageOwnerType(""), []string{imageId}, "", 0, 1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -184,7 +187,11 @@ func (self *SRegion) GetImage(imageId string) (*SImage, error) {
|
||||
}
|
||||
|
||||
func (self *SRegion) GetImageByName(name string) (*SImage, error) {
|
||||
images, _, err := self.GetImages("", ImageOwnerSelf, nil, name, 0, 1)
|
||||
if len(name) == 0 {
|
||||
return nil, fmt.Errorf("image name should not be empty")
|
||||
}
|
||||
|
||||
images, _, err := self.GetImages("", ImageOwnerType(""), nil, name, 0, 1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"time"
|
||||
|
||||
"context"
|
||||
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
@@ -172,13 +173,11 @@ func (self *SInstance) GetMetadata() *jsonutils.JSONDict {
|
||||
data.Update(meta)
|
||||
}
|
||||
}
|
||||
secgroupIds := jsonutils.NewArray()
|
||||
for _, secgroupId := range self.SecurityGroupIds.SecurityGroupId {
|
||||
if len(secgroupId) > 0 {
|
||||
data.Add(jsonutils.NewString(secgroupId), "secgroupId")
|
||||
break
|
||||
}
|
||||
secgroupIds.Add(jsonutils.NewString(secgroupId))
|
||||
}
|
||||
|
||||
data.Add(secgroupIds, "secgroupIds")
|
||||
return data
|
||||
}
|
||||
|
||||
@@ -281,7 +280,15 @@ func (self *SInstance) GetMachine() string {
|
||||
}
|
||||
|
||||
func (self *SInstance) AssignSecurityGroup(secgroupId string) error {
|
||||
return self.host.zone.region.assignSecurityGroup(secgroupId, self.InstanceId)
|
||||
return self.AssignSecurityGroups([]string{secgroupId})
|
||||
}
|
||||
|
||||
func (self *SInstance) AssignSecurityGroups(secgroupIds []string) error {
|
||||
ids := []*string{}
|
||||
for i := 0; i < len(secgroupIds); i++ {
|
||||
ids = append(ids, &secgroupIds[i])
|
||||
}
|
||||
return self.host.zone.region.assignSecurityGroups(ids, self.InstanceId)
|
||||
}
|
||||
|
||||
func (self *SInstance) GetHypervisor() string {
|
||||
|
||||
+5
-1
@@ -246,6 +246,10 @@ func (self *SRegion) revokeSecurityGroup(secgroupId, instanceId string, keep boo
|
||||
}
|
||||
|
||||
func (self *SRegion) assignSecurityGroup(secgroupId, instanceId string) error {
|
||||
return self.assignSecurityGroups([]*string{&secgroupId}, instanceId)
|
||||
}
|
||||
|
||||
func (self *SRegion) assignSecurityGroups(secgroupIds []*string, instanceId string) error {
|
||||
instance, err := self.GetInstance(instanceId)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -254,7 +258,7 @@ func (self *SRegion) assignSecurityGroup(secgroupId, instanceId string) error {
|
||||
for _, eth := range instance.NetworkInterfaces.NetworkInterface {
|
||||
params := &ec2.ModifyNetworkInterfaceAttributeInput{}
|
||||
params.SetNetworkInterfaceId(eth.NetworkInterfaceId)
|
||||
params.SetGroups([]*string{&secgroupId})
|
||||
params.SetGroups(secgroupIds)
|
||||
|
||||
_, err := self.ec2Client.ModifyNetworkInterfaceAttribute(params)
|
||||
if err != nil {
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"time"
|
||||
|
||||
"context"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
@@ -130,9 +131,12 @@ func (self *SClassicInstance) GetMetadata() *jsonutils.JSONDict {
|
||||
data := jsonutils.NewDict()
|
||||
priceKey := fmt.Sprintf("%s::%s", self.Properties.HardwareProfile.Size, self.host.zone.region.Name)
|
||||
data.Add(jsonutils.NewString(priceKey), "price_key")
|
||||
data.Add(jsonutils.NewString(self.host.zone.GetGlobalId()), "zone_ext_id")
|
||||
secgroupIds := jsonutils.NewArray()
|
||||
if self.Properties.NetworkProfile.NetworkSecurityGroup != nil {
|
||||
data.Add(jsonutils.NewString(self.Properties.NetworkProfile.NetworkSecurityGroup.ID), "secgroupId")
|
||||
secgroupIds.Add(jsonutils.NewString(self.Properties.NetworkProfile.NetworkSecurityGroup.ID))
|
||||
}
|
||||
data.Add(secgroupIds, "secgroupIds")
|
||||
return data
|
||||
}
|
||||
|
||||
@@ -483,6 +487,10 @@ type assignProperties struct {
|
||||
NetworkSecurityGroup SubResource `json:"networkSecurityGroup,omitempty"`
|
||||
}
|
||||
|
||||
func (self *SClassicInstance) AssignSecurityGroups(secgroupIds []string) error {
|
||||
return cloudprovider.ErrNotSupported
|
||||
}
|
||||
|
||||
func (self *SClassicInstance) AssignSecurityGroup(secgroupId string) error {
|
||||
if self.Properties.NetworkProfile.NetworkSecurityGroup != nil {
|
||||
if self.Properties.NetworkProfile.NetworkSecurityGroup.ID == secgroupId {
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"time"
|
||||
|
||||
"context"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
@@ -212,17 +213,18 @@ func (self *SInstance) GetMetadata() *jsonutils.JSONDict {
|
||||
data.Add(jsonutils.NewString(self.host.zone.GetGlobalId()), "zone_ext_id")
|
||||
priceKey := fmt.Sprintf("%s::%s", self.Properties.HardwareProfile.VMSize, self.host.zone.region.Name)
|
||||
data.Add(jsonutils.NewString(priceKey), "price_key")
|
||||
secgroupIds := jsonutils.NewArray()
|
||||
if nics, err := self.getNics(); err == nil {
|
||||
for _, nic := range nics {
|
||||
if nic.Properties.NetworkSecurityGroup != nil {
|
||||
if len(nic.Properties.NetworkSecurityGroup.ID) > 0 {
|
||||
data.Add(jsonutils.NewString(nic.Properties.NetworkSecurityGroup.ID), "secgroupId")
|
||||
secgroupIds.Add(jsonutils.NewString(nic.Properties.NetworkSecurityGroup.ID))
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data.Add(secgroupIds, "secgroupIds")
|
||||
return data
|
||||
}
|
||||
|
||||
@@ -1018,6 +1020,10 @@ func (self *SInstance) AssignSecurityGroup(secgroupId string) error {
|
||||
return self.host.zone.region.AssiginSecurityGroup(self.ID, secgroupId)
|
||||
}
|
||||
|
||||
func (self *SInstance) AssignSecurityGroups(secgroupIds []string) error {
|
||||
return cloudprovider.ErrNotSupported
|
||||
}
|
||||
|
||||
func (self *SInstance) GetBillingType() string {
|
||||
return models.BILLING_TYPE_POSTPAID
|
||||
}
|
||||
|
||||
@@ -514,6 +514,10 @@ func (dc *SVirtualMachine) ChangeConfig2(ctx context.Context, instanceType strin
|
||||
return cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SVirtualMachine) AssignSecurityGroups(secgroupIds []string) error {
|
||||
return cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SVirtualMachine) GetBillingType() string {
|
||||
return models.BILLING_TYPE_POSTPAID
|
||||
}
|
||||
|
||||
@@ -3,12 +3,12 @@ package imagetools
|
||||
import "testing"
|
||||
|
||||
func TestNormalizeImageInfo(t *testing.T) {
|
||||
info := NormalizeImageInfo("rhel67_20180816.qcow2", "", "", "")
|
||||
info := NormalizeImageInfo("rhel67_20180816.qcow2", "", "", "", "")
|
||||
t.Logf("%#v", info)
|
||||
|
||||
info = NormalizeImageInfo("Ubuntu_16.04.3_amd64_qingcloud_20180817.qcow2", "", "", "")
|
||||
info = NormalizeImageInfo("Ubuntu_16.04.3_amd64_qingcloud_20180817.qcow2", "", "", "", "")
|
||||
t.Logf("%#v", info)
|
||||
|
||||
info = NormalizeImageInfo("windows-server-2008-dc-cn-20180717", "", "", "")
|
||||
info = NormalizeImageInfo("windows-server-2008-dc-cn-20180717", "", "", "", "")
|
||||
t.Logf("%#v", info)
|
||||
}
|
||||
|
||||
@@ -38,21 +38,23 @@ func normalizeOsDistribution(osDist string, imageName string) string {
|
||||
osDist = imageName
|
||||
}
|
||||
osDist = strings.ToLower(osDist)
|
||||
if strings.HasPrefix(osDist, "centos") || strings.HasPrefix(osDist, "redhat") || strings.HasPrefix(osDist, "rhel") {
|
||||
if strings.Contains(osDist, "centos") || strings.Contains(osDist, "redhat") || strings.Contains(osDist, "rhel") {
|
||||
return "CentOS"
|
||||
} else if strings.HasPrefix(osDist, "ubuntu") {
|
||||
} else if strings.Contains(osDist, "ubuntu") {
|
||||
return "Ubuntu"
|
||||
} else if strings.HasPrefix(osDist, "suse") {
|
||||
} else if strings.Contains(osDist, "suse") {
|
||||
return "SUSE"
|
||||
} else if strings.HasPrefix(osDist, "opensuse") {
|
||||
} else if strings.Contains(osDist, "opensuse") {
|
||||
return "OpenSUSE"
|
||||
} else if strings.HasPrefix(osDist, "debian") {
|
||||
} else if strings.Contains(osDist, "debian") {
|
||||
return "Debian"
|
||||
} else if strings.HasPrefix(osDist, "coreos") {
|
||||
} else if strings.Contains(osDist, "coreos") {
|
||||
return "CoreOS"
|
||||
} else if strings.HasPrefix(osDist, "aliyun") {
|
||||
} else if strings.Contains(osDist, "aliyun") {
|
||||
return "Aliyun"
|
||||
} else if strings.HasPrefix(osDist, "windows") {
|
||||
} else if strings.Contains(osDist, "freebsd") {
|
||||
return "FreeBSD"
|
||||
} else if strings.Contains(osDist, "windows") {
|
||||
if strings.Contains(osDist, "2003") {
|
||||
return "Windows Server 2003"
|
||||
} else if strings.Contains(osDist, "2008") {
|
||||
@@ -69,18 +71,45 @@ func normalizeOsDistribution(osDist string, imageName string) string {
|
||||
}
|
||||
}
|
||||
|
||||
type ImageInfo struct {
|
||||
Name string
|
||||
OsArch string
|
||||
OsType string
|
||||
OsDistro string
|
||||
var imageVersions = map[string][]string{
|
||||
"CentOS": {"5", "6", "7"},
|
||||
"FreeBSD": {"10"},
|
||||
"Ubuntu": {"10", "12", "14", "16"},
|
||||
"OpenSUSE": {"11", "12"},
|
||||
"SUSE": {"10", "11", "12", "13"},
|
||||
"Debian": {"6", "7", "8", "9"},
|
||||
"CoreOS": {"7"},
|
||||
"Aliyun": {},
|
||||
}
|
||||
|
||||
func NormalizeImageInfo(imageName, osArch, osType, osDist string) ImageInfo {
|
||||
func normalizeOsVersion(imageName string, osDist string, osVersion string) string {
|
||||
if versions, ok := imageVersions[osDist]; ok {
|
||||
for _, version := range versions {
|
||||
if strings.HasPrefix(osVersion, version) {
|
||||
return version
|
||||
}
|
||||
}
|
||||
if len(versions) > 0 {
|
||||
return versions[0]
|
||||
}
|
||||
}
|
||||
return "-"
|
||||
}
|
||||
|
||||
type ImageInfo struct {
|
||||
Name string
|
||||
OsArch string
|
||||
OsType string
|
||||
OsDistro string
|
||||
OsVersion string
|
||||
}
|
||||
|
||||
func NormalizeImageInfo(imageName, osArch, osType, osDist, osVersion string) ImageInfo {
|
||||
info := ImageInfo{}
|
||||
info.Name = imageName
|
||||
info.OsDistro = normalizeOsDistribution(osDist, imageName)
|
||||
info.OsType = normalizeOsType(osType, info.OsDistro)
|
||||
info.OsArch = normalizeOsArch(osArch, info.OsType, info.OsDistro)
|
||||
info.OsVersion = normalizeOsVersion(imageName, info.OsDistro, osVersion)
|
||||
return info
|
||||
}
|
||||
|
||||
@@ -227,6 +227,9 @@ func (self *SRegion) GetImportImageParams(name string, osArch, osDist, osVersion
|
||||
}
|
||||
if !utils.IsInStringArray(osVersion, _imageSet.OsVersions) {
|
||||
osVersion = "-"
|
||||
if len(_imageSet.OsVersions) > 0 {
|
||||
osVersion = _imageSet.OsVersions[0]
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
@@ -146,7 +146,6 @@ func (self *SInstance) GetMetadata() *jsonutils.JSONDict {
|
||||
data.Add(jsonutils.NewString(self.host.zone.GetGlobalId()), "zone_ext_id")
|
||||
secgroupIds := jsonutils.NewArray()
|
||||
for _, secgroupId := range self.SecurityGroupIds {
|
||||
data.Add(jsonutils.NewString(secgroupId), "secgroupId")
|
||||
secgroupIds.Add(jsonutils.NewString(secgroupId))
|
||||
}
|
||||
data.Add(secgroupIds, "secgroupIds")
|
||||
@@ -731,6 +730,14 @@ func (self *SInstance) AssignSecurityGroup(secgroupId string) error {
|
||||
return self.host.zone.region.instanceOperation(self.InstanceId, "ModifyInstancesAttribute", params)
|
||||
}
|
||||
|
||||
func (self *SInstance) AssignSecurityGroups(secgroupIds []string) error {
|
||||
params := map[string]string{}
|
||||
for i := 0; i < len(secgroupIds); i++ {
|
||||
params[fmt.Sprintf("SecurityGroups.%d", i)] = secgroupIds[i]
|
||||
}
|
||||
return self.host.zone.region.instanceOperation(self.InstanceId, "ModifyInstancesAttribute", params)
|
||||
}
|
||||
|
||||
func (self *SInstance) GetIEIP() (cloudprovider.ICloudEIP, error) {
|
||||
eip, total, err := self.host.zone.region.GetEips("", self.InstanceId, 0, 1)
|
||||
if err != nil {
|
||||
|
||||
@@ -99,8 +99,8 @@ func _jsonRequest(client *common.Client, domain string, version string, apiName
|
||||
break
|
||||
}
|
||||
needRetry := false
|
||||
for _, msg := range []string{"EOF", "TLS handshake timeout", "Code=InternalError"} {
|
||||
if strings.Index(err.Error(), msg) > 0 {
|
||||
for _, msg := range []string{"EOF", "TLS handshake timeout", "Code=InternalError", "retry later", "Code=MutexOperation.TaskRunning"} {
|
||||
if strings.Contains(err.Error(), msg) {
|
||||
needRetry = true
|
||||
break
|
||||
}
|
||||
|
||||
-9
@@ -1,9 +0,0 @@
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2017 marvin + konsorten GmbH (open-source@konsorten.de)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
+1
-1
@@ -106,7 +106,7 @@ func GetOSProfileFromImageProperties(imgProp map[string]string, hypervisor strin
|
||||
}
|
||||
var imgHypers []string
|
||||
imgHyperStr, ok := imgProp["hypervisor"]
|
||||
if ok {
|
||||
if ok && len(imgHyperStr) > 0 {
|
||||
imgHypers = strings.Split(imgHyperStr, ",")
|
||||
} else {
|
||||
imgHypers = []string{}
|
||||
|
||||
Reference in New Issue
Block a user