From de34764cada243c949152aa49f0232c5a7444237 Mon Sep 17 00:00:00 2001 From: wanyaoqi Date: Sat, 18 Jan 2020 19:02:22 +0800 Subject: [PATCH] support attach multi network --- cmd/climc/shell/servernetworks.go | 17 +++++---- pkg/apis/compute/api.go | 6 ++++ pkg/compute/models/guest_actions.go | 53 ++++++++++++++++++----------- 3 files changed, 50 insertions(+), 26 deletions(-) diff --git a/cmd/climc/shell/servernetworks.go b/cmd/climc/shell/servernetworks.go index a02f782290..c430ae3fef 100644 --- a/cmd/climc/shell/servernetworks.go +++ b/cmd/climc/shell/servernetworks.go @@ -21,6 +21,7 @@ import ( "yunion.io/x/jsonutils" "yunion.io/x/pkg/util/regutils" + "yunion.io/x/onecloud/pkg/apis/compute" "yunion.io/x/onecloud/pkg/cloudcommon/cmdline" "yunion.io/x/onecloud/pkg/mcclient" "yunion.io/x/onecloud/pkg/mcclient/modulebase" @@ -150,15 +151,19 @@ func init() { }) type ServerAttachNetworkOptions struct { - SERVER string `help:"ID or Name of server"` - NETDESC string `help:"Network description"` + SERVER string `help:"ID or Name of server"` + NETDESC []string `help:"Network description"` } R(&ServerAttachNetworkOptions{}, "server-attach-network", "Attach a server to a virtual network", func(s *mcclient.ClientSession, args *ServerAttachNetworkOptions) error { - conf, err := cmdline.ParseNetworkConfig(args.NETDESC, -1) - if err != nil { - return err + input := compute.AttachNetworkInput{[]*compute.NetworkConfig{}} + for i := 0; i < len(args.NETDESC); i++ { + conf, err := cmdline.ParseNetworkConfig(args.NETDESC[i], -1) + if err != nil { + return err + } + input.Nets = append(input.Nets, conf) } - params := jsonutils.Marshal(conf) + params := jsonutils.Marshal(input) srv, err := modules.Servers.PerformAction(s, args.SERVER, "attachnetwork", params) if err != nil { return err diff --git a/pkg/apis/compute/api.go b/pkg/apis/compute/api.go index 64fa468c11..376ff95e20 100644 --- a/pkg/apis/compute/api.go +++ b/pkg/apis/compute/api.go @@ -84,6 +84,12 @@ type NetworkConfig struct { Schedtags []*SchedtagConfig `json:"schedtags"` } +type AttachNetworkInput struct { + // 添加的网卡的配置 + // required: true + Nets []*NetworkConfig `json:"nets"` +} + type DiskConfig struct { apis.Meta diff --git a/pkg/compute/models/guest_actions.go b/pkg/compute/models/guest_actions.go index bc3b506ffd..b00b020c8e 100644 --- a/pkg/compute/models/guest_actions.go +++ b/pkg/compute/models/guest_actions.go @@ -2070,20 +2070,29 @@ func (self *SGuest) AllowPerformAttachnetwork(ctx context.Context, userCred mccl return self.IsOwner(userCred) || db.IsAdminAllowPerform(userCred, self, "attachnetwork") } -func (self *SGuest) PerformAttachnetwork(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input *api.NetworkConfig) (*api.SGuest, error) { - - err := isValidNetworkInfo(userCred, input) - if err != nil { - return nil, err +func (self *SGuest) PerformAttachnetwork(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input *api.AttachNetworkInput) (*api.SGuest, error) { + if !utils.IsInStringArray(self.Status, []string{api.VM_READY, api.VM_RUNNING}) { + return nil, httperrors.NewBadRequestError("Cannot attach network in status %s", self.Status) + } + count := len(input.Nets) + if count == 0 { + return nil, httperrors.NewMissingParameterError("nets") } var inicCnt, enicCnt int - if IsExitNetworkInfo(input) { - enicCnt = 1 - // ebw = input.BwLimit - } else { - inicCnt = 1 - // ibw = input.BwLimit + for i := 0; i < count; i++ { + err := isValidNetworkInfo(userCred, input.Nets[i]) + if err != nil { + return nil, err + } + if IsExitNetworkInfo(input.Nets[i]) { + enicCnt = count + // ebw = input.BwLimit + } else { + inicCnt = count + // ibw = input.BwLimit + } } + pendingUsage := &SRegionQuota{ Port: inicCnt, Eport: enicCnt, @@ -2100,20 +2109,24 @@ func (self *SGuest) PerformAttachnetwork(ctx context.Context, userCred mcclient. return nil, httperrors.NewOutOfQuotaError(err.Error()) } host := self.GetHost() - _, err = self.attach2NetworkDesc(ctx, userCred, host, input, pendingUsage, nil) - if err != nil { - quotas.CancelPendingUsage(ctx, userCred, pendingUsage, pendingUsage) - return nil, httperrors.NewBadRequestError(err.Error()) + defer host.ClearSchedDescCache() + for i := 0; i < count; i++ { + _, err = self.attach2NetworkDesc(ctx, userCred, host, input.Nets[i], pendingUsage, nil) + if err != nil { + quotas.CancelPendingUsage(ctx, userCred, pendingUsage, pendingUsage) + return nil, httperrors.NewBadRequestError(err.Error()) + } } - host.ClearSchedDescCache() + if self.Status == api.VM_READY { err = self.StartGuestDeployTask(ctx, userCred, nil, "deploy", "") - return nil, err - } else if self.Status == api.VM_RUNNING { + } else { err = self.StartSyncTask(ctx, userCred, false, "") - return nil, err } - return nil, httperrors.NewBadRequestError("Cannot attach network in status %s", self.Status) + if err != nil { + quotas.CancelPendingUsage(ctx, userCred, pendingUsage, pendingUsage) + } + return nil, err } func (self *SGuest) AllowPerformChangeBandwidth(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {