Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion cmd/climc/shell/compute/servernetworks.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,10 @@ func init() {
type ServerNetworkBWOptions struct {
SERVER string `help:"ID or Name of server"`
MACORIP string `help:"IP, Mac, or Index of NIC"`
BW int64 `help:"Bandwidth in Mbps"`

BW int64 `help:"Bandwidth in Mbps"`
Tx int64 `help:"Tx bandwidth in Mbps"`
Rx int64 `help:"Rx bandwidth in Mbps"`
}
R(&ServerNetworkBWOptions{}, "server-change-bandwidth", "Change server network bandwidth in Mbps", func(s *mcclient.ClientSession, args *ServerNetworkBWOptions) error {
params := jsonutils.NewDict()
Expand All @@ -156,6 +159,8 @@ func init() {
return fmt.Errorf("Please specify Ip or Mac")
}
params.Add(jsonutils.NewInt(args.BW), "bandwidth")
params.Add(jsonutils.NewInt(args.Tx), "tx_bw_limit")
params.Add(jsonutils.NewInt(args.Rx), "rx_bw_limit")
server, err := modules.Servers.PerformAction(s, args.SERVER, "change-bandwidth", params)
if err != nil {
return err
Expand Down
2 changes: 2 additions & 0 deletions cmd/climc/shell/compute/servers.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,8 @@ func init() {
params.Eip = opts.Eip
params.EipChargeType = opts.EipChargeType
params.EipBw = opts.EipBw
params.EipTxBw = opts.EipTxBw
params.EipRxBw = opts.EipRxBw

server, err := modules.Servers.Create(s, params.JSON(params))
if err != nil {
Expand Down
6 changes: 6 additions & 0 deletions pkg/apis/compute/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ type NetworkConfig struct {
// 若指定镜像的网络驱动方式,此参数会被覆盖
Driver string `json:"driver"`
BwLimit int `json:"bw_limit"`
TxBwLimit int `json:"tx_bw_limit"`
RxBwLimit int `json:"rx_bw_limit"`
Vip bool `json:"vip"`
Reserved bool `json:"reserved"`
NumQueues int `json:"num_queues"`
Expand Down Expand Up @@ -592,6 +594,10 @@ type ServerCreateInput struct {
// 指定此参数后会创建新的弹性公网IP并绑定到新建的虚拟机
// 此参数优先级低于public_ip
EipBw int `json:"eip_bw,omitzero"`
// 弹性公网IP上行带宽
EipTxBw int `json:"eip_tx_bw,omitzero"`
// 弹性公网IP下行带宽
EipRxBw int `json:"eip_rx_bw,omitzero"`
// 弹性公网IP线路类型
EipBgpType string `json:"eip_bgp_type,omitzero"`
// 弹性公网IP计费类型
Expand Down
25 changes: 25 additions & 0 deletions pkg/apis/compute/elasticip.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
package compute

import (
"errors"

"yunion.io/x/onecloud/pkg/apis"
)

Expand Down Expand Up @@ -148,3 +150,26 @@ type ElasticipRemoteUpdateInput struct {
// 是否覆盖替换所有标签
ReplaceTags *bool `json:"replace_tags" help:"replace all remote tags"`
}

type ElasticipChangeBandwidthInput struct {
// 带宽限制,单位mbps
// swagger:ignore
// Deprecated
Bandwidth int64 `json:"bandwidth" yunion-deprecated-by:"bandwidth_mb"`
// 带宽限制,单位mbps
BandwidthMb int64 `json:"bandwidth_mb"`
// 下行带宽限制,单位mbps
RxBwLimitMb int64 `json:"rx_bw_limit_mb"`
// 上行带宽限制,单位mbps
TxBwLimitMb int64 `json:"tx_bw_limit_mb"`
}

func (input ElasticipChangeBandwidthInput) Validate() error {
if input.BandwidthMb <= 0 && input.RxBwLimitMb <= 0 {
return errors.New("bandwidth_mb or rx_bw_limit_mb must be greater than 0")
}
if input.BandwidthMb <= 0 && input.TxBwLimitMb <= 0 {
return errors.New("bandwidth_mb or tx_bw_limit_mb must be greater than 0")
}
return nil
}
2 changes: 2 additions & 0 deletions pkg/apis/compute/guestnetwork.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ type GuestnetworkBaseDesc struct {
Masklen int8 `json:"masklen"`
Vlan int `json:"vlan"`
Bw int `json:"bw"`
RxBwLimit int `json:"rx_bw_limit"`
TxBwLimit int `json:"tx_bw_limit"`
Mtu int16 `json:"mtu"`
Index int `json:"index"`
RxTrafficLimit int64 `json:"rx_traffic_limit"`
Expand Down
3 changes: 3 additions & 0 deletions pkg/apis/compute/guests.go
Original file line number Diff line number Diff line change
Expand Up @@ -1325,6 +1325,9 @@ type ServerChangeBandwidthInput struct {

Bandwidth int `json:"bandwidth"`

TxBwLimit int `json:"tx_bw_limit"`
RxBwLimit int `json:"rx_bw_limit"`

NoSync *bool `json:"no_sync"`
}

Expand Down
2 changes: 2 additions & 0 deletions pkg/apis/compute/host_tap.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
package compute

const (
TapConfigFileName = "tap-config.json"

HostVpcBridge = "__vpc_bridge__"
HostTapBridge = "__tap_bridge__"
)
Expand Down
12 changes: 12 additions & 0 deletions pkg/cloudcommon/cmdline/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,18 @@ func ParseNetworkConfig(desc string, idx int) (*compute.NetworkConfig, error) {
return nil, err
}
netConfig.BwLimit = bw
} else if strings.HasPrefix(p, "rx-bw=") {
bw, err := fileutils.GetSizeMb(p[len("rx-bw="):], 'M', 1000)
if err != nil {
return nil, err
}
netConfig.RxBwLimit = bw
} else if strings.HasPrefix(p, "tx-bw=") {
bw, err := fileutils.GetSizeMb(p[len("tx-bw="):], 'M', 1000)
if err != nil {
return nil, err
}
netConfig.TxBwLimit = bw
} else if p == "vip" {
netConfig.Vip = true
} else if strings.HasPrefix(p, "sriov-nic-id=") {
Expand Down
2 changes: 2 additions & 0 deletions pkg/compute/guestdrivers/baremetals.go
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,8 @@ func (self *SBaremetalGuestDriver) Attach2RandomNetwork(guest *models.SGuest, ct
IpAddr: address,
NicDriver: netConfig.Driver,
BwLimit: netConfig.BwLimit,
RxBwLimit: netConfig.RxBwLimit,
TxBwLimit: netConfig.TxBwLimit,
Virtual: netConfig.Vip,
TryReserved: false,
AllocDir: api.IPAllocationStepup,
Expand Down
2 changes: 2 additions & 0 deletions pkg/compute/guestdrivers/cloudpods-baremetals.go
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,8 @@ func (self *SCloudpodsBaremetalGuestDriver) Attach2RandomNetwork(guest *models.S
IpAddr: address,
NicDriver: netConfig.Driver,
BwLimit: netConfig.BwLimit,
RxBwLimit: netConfig.RxBwLimit,
TxBwLimit: netConfig.TxBwLimit,
Virtual: netConfig.Vip,
TryReserved: false,
AllocDir: api.IPAllocationStepup,
Expand Down
2 changes: 2 additions & 0 deletions pkg/compute/guestdrivers/virtualization.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,8 @@ func (self *SVirtualizedGuestDriver) Attach2RandomNetwork(guest *models.SGuest,
Ip6Addr: netConfig.Address6,
NicDriver: netConfig.Driver,
BwLimit: netConfig.BwLimit,
RxBwLimit: netConfig.RxBwLimit,
TxBwLimit: netConfig.TxBwLimit,
Virtual: netConfig.Vip,
TryReserved: netConfig.Reserved,
AllocDir: api.IPAllocationDefault,
Expand Down
67 changes: 48 additions & 19 deletions pkg/compute/models/elasticips.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import (
"yunion.io/x/onecloud/pkg/compute/options"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/logclient"
"yunion.io/x/onecloud/pkg/util/rbacutils"
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
Expand Down Expand Up @@ -117,6 +118,11 @@ type SElasticip struct {

// 区域Id
// CloudregionId string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"required"`

// 下行带宽限制,单位mbps
RxBwLimit int `nullable:"false" default:"0" list:"user"`
// 上行带宽限制,单位mbps
TxBwLimit int `nullable:"false" default:"0" list:"user"`
}

// 弹性公网IP列表
Expand Down Expand Up @@ -387,6 +393,8 @@ func (self *SElasticip) GetShortDesc(ctx context.Context) *jsonutils.JSONDict {
// desc.Add(jsonutils.NewString(self.ChargeType), "charge_type")

desc.Add(jsonutils.NewInt(int64(self.Bandwidth)), "bandwidth")
desc.Add(jsonutils.NewInt(int64(self.RxBwLimit)), "rx_bw_limit")
desc.Add(jsonutils.NewInt(int64(self.TxBwLimit)), "tx_bw_limit")
desc.Add(jsonutils.NewString(self.Mode), "mode")
desc.Add(jsonutils.NewString(self.IpAddr), "ip_addr")
desc.Add(jsonutils.NewString(self.BgpType), "bgp_type")
Expand Down Expand Up @@ -589,6 +597,8 @@ func (self *SElasticip) SyncWithCloudEip(ctx context.Context, userCred mcclient.
}
if bandwidth := ext.GetBandwidth(); bandwidth != 0 {
self.Bandwidth = bandwidth
self.RxBwLimit = bandwidth
self.TxBwLimit = bandwidth
}
self.IpAddr = ext.GetIpAddr()
self.Mode = ext.GetMode()
Expand Down Expand Up @@ -672,6 +682,8 @@ func (manager *SElasticipManager) newFromCloudEip(ctx context.Context, userCred
eip.ChargeType = api.EIP_CHARGE_TYPE_BY_TRAFFIC
}
eip.Bandwidth = extEip.GetBandwidth()
eip.RxBwLimit = extEip.GetBandwidth()
eip.TxBwLimit = extEip.GetBandwidth()
if networkId := extEip.GetINetworkId(); len(networkId) > 0 {
network, err := db.FetchByExternalIdAndManagerId(NetworkManager, networkId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
wire := WireManager.Query().SubQuery()
Expand Down Expand Up @@ -1598,6 +1610,8 @@ func (a SEipNetworks) Less(i, j int) bool {

type NewEipForVMOnHostArgs struct {
Bandwidth int
RxBwLimit int
TxBwLimit int
BgpType string
ChargeType string
AutoDellocate bool
Expand All @@ -1613,7 +1627,6 @@ type NewEipForVMOnHostArgs struct {

func (manager *SElasticipManager) NewEipForVMOnHost(ctx context.Context, userCred mcclient.TokenCredential, args *NewEipForVMOnHostArgs) (*SElasticip, error) {
var (
bw = args.Bandwidth
bgpType = args.BgpType
chargeType = args.ChargeType
autoDellocate = args.AutoDellocate
Expand Down Expand Up @@ -1655,7 +1668,10 @@ func (manager *SElasticipManager) NewEipForVMOnHost(ctx context.Context, userCre
eip.Mode = api.EIP_MODE_STANDALONE_EIP
// do not implicitly auto dellocate EIP, should be set by user explicitly
// eip.AutoDellocate = tristate.True
eip.Bandwidth = bw
eip.Bandwidth = args.Bandwidth
eip.RxBwLimit = args.RxBwLimit
eip.TxBwLimit = args.TxBwLimit

eip.ChargeType = chargeType
eip.BgpType = args.BgpType
eip.AutoDellocate = tristate.NewFromBool(autoDellocate)
Expand Down Expand Up @@ -1818,14 +1834,13 @@ func (eip *SElasticip) AllocateAndAssociateInstance(ctx context.Context, userCre
return eip.startEipAllocateTask(ctx, userCred, params, parentTaskId)
}

func (self *SElasticip) PerformChangeBandwidth(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
if self.Status != api.EIP_STATUS_READY {
return nil, httperrors.NewInvalidStatusError("cannot change bandwidth in status %s", self.Status)
func (self *SElasticip) PerformChangeBandwidth(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.ElasticipChangeBandwidthInput) (jsonutils.JSONObject, error) {
if err := input.Validate(); err != nil {
return nil, httperrors.NewInputParameterError("%v", err)
}

bandwidth, err := data.Int("bandwidth")
if err != nil || bandwidth <= 0 {
return nil, httperrors.NewInputParameterError("Invalid bandwidth")
if self.Status != api.EIP_STATUS_READY {
return nil, httperrors.NewInvalidStatusError("cannot change bandwidth in status %s", self.Status)
}

if self.IsManaged() {
Expand All @@ -1834,24 +1849,23 @@ func (self *SElasticip) PerformChangeBandwidth(ctx context.Context, userCred mcc
return nil, err
}

if err := factory.ValidateChangeBandwidth(self.AssociateId, bandwidth); err != nil {
if err := factory.ValidateChangeBandwidth(self.AssociateId, input.BandwidthMb); err != nil {
return nil, httperrors.NewInputParameterError("%v", err)
}
}

err = self.StartEipChangeBandwidthTask(ctx, userCred, bandwidth)
err := self.StartEipChangeBandwidthTask(ctx, userCred, input)
if err != nil {
return nil, httperrors.NewGeneralError(err)
}
return nil, nil
}

func (self *SElasticip) StartEipChangeBandwidthTask(ctx context.Context, userCred mcclient.TokenCredential, bandwidth int64) error {
func (self *SElasticip) StartEipChangeBandwidthTask(ctx context.Context, userCred mcclient.TokenCredential, input api.ElasticipChangeBandwidthInput) error {

self.SetStatus(ctx, userCred, api.EIP_STATUS_CHANGE_BANDWIDTH, "change bandwidth")

params := jsonutils.NewDict()
params.Add(jsonutils.NewInt(bandwidth), "bandwidth")
params := jsonutils.Marshal(input).(*jsonutils.JSONDict)

task, err := taskman.TaskManager.NewTask(ctx, "EipChangeBandwidthTask", self, userCred, params, "", "", nil)
if err != nil {
Expand All @@ -1862,24 +1876,35 @@ func (self *SElasticip) StartEipChangeBandwidthTask(ctx context.Context, userCre
return nil
}

func (self *SElasticip) DoChangeBandwidth(ctx context.Context, userCred mcclient.TokenCredential, bandwidth int) error {
func (self *SElasticip) DoChangeBandwidth(ctx context.Context, userCred mcclient.TokenCredential, input api.ElasticipChangeBandwidthInput) error {
changes := jsonutils.NewDict()
obw := api.ElasticipChangeBandwidthInput{
BandwidthMb: int64(self.Bandwidth),
RxBwLimitMb: int64(self.RxBwLimit),
TxBwLimitMb: int64(self.TxBwLimit),
}
changes.Add(jsonutils.NewInt(int64(self.Bandwidth)), "obw")
changes.Add(jsonutils.Marshal(obw), "obw_details")

_, err := db.Update(self, func() error {
self.Bandwidth = bandwidth
self.Bandwidth = int(input.BandwidthMb)
self.RxBwLimit = int(input.RxBwLimitMb)
self.TxBwLimit = int(input.TxBwLimitMb)
return nil
})

self.SetStatus(ctx, userCred, api.EIP_STATUS_READY, "finish change bandwidth")

if err != nil {
self.SetStatus(ctx, userCred, api.EIP_STATUS_READY, "change bandwidth failed")
logclient.AddActionLogWithContext(ctx, self, logclient.ACT_CHANGE_BANDWIDTH, changes, userCred, false)
log.Errorf("DoChangeBandwidth update fail %s", err)
return err
}

changes.Add(jsonutils.NewInt(int64(bandwidth)), "nbw")
self.SetStatus(ctx, userCred, api.EIP_STATUS_READY, "finish change bandwidth")

changes.Add(jsonutils.NewInt(int64(input.BandwidthMb)), "nbw")
changes.Add(jsonutils.Marshal(input), "nbw_details")
db.OpsLog.LogEvent(self, db.ACT_CHANGE_BANDWIDTH, changes, userCred)
logclient.AddActionLogWithContext(ctx, self, logclient.ACT_CHANGE_BANDWIDTH, changes, userCred, true)

return nil
}
Expand All @@ -1889,6 +1914,8 @@ type EipUsage struct {
PublicIpBandwidth int
EIPCount int
EipBandwidth int
EipRxBwLimit int
EipTxBwLimit int
EIPUsedCount int
}

Expand Down Expand Up @@ -1935,6 +1962,8 @@ func (manager *SElasticipManager) TotalCount(
q2 := q2sq.Query(
sqlchemy.COUNT("eip_count", q2sq.Field("id")),
sqlchemy.SUM("eip_bandwidth", q2sq.Field("bandwidth")),
sqlchemy.SUM("eip_rx_bw_limit", q2sq.Field("rx_bw_limit")),
sqlchemy.SUM("eip_tx_bw_limit", q2sq.Field("tx_bw_limit")),
).Equals("mode", api.EIP_MODE_STANDALONE_EIP)
q2 = manager.usageQ(ctx, scope, ownerId, q2, rangeObjs, providers, brands, cloudEnv, policyResult)
q3sq := manager.Query().SubQuery()
Expand Down
19 changes: 14 additions & 5 deletions pkg/compute/models/guest_actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -746,6 +746,8 @@ func (self *SGuest) PerformClone(ctx context.Context, userCred mcclient.TokenCre
createInput.AutoStart = cloneInput.AutoStart

createInput.EipBw = cloneInput.EipBw
createInput.EipTxBw = cloneInput.EipTxBw
createInput.EipRxBw = cloneInput.EipRxBw
createInput.Eip = cloneInput.Eip
createInput.EipChargeType = cloneInput.EipChargeType
if err := GuestManager.validateEip(ctx, userCred, createInput, createInput.PreferRegion, createInput.PreferManager); err != nil {
Expand Down Expand Up @@ -2758,6 +2760,12 @@ func (self *SGuest) PerformChangeIpaddr(
if conf.BwLimit == 0 {
conf.BwLimit = gn.BwLimit
}
if conf.TxBwLimit == 0 {
conf.TxBwLimit = gn.TxBwLimit
}
if conf.RxBwLimit == 0 {
conf.RxBwLimit = gn.RxBwLimit
}
if conf.Index == 0 {
conf.Index = int(gn.Index)
}
Expand Down Expand Up @@ -3241,19 +3249,20 @@ func (guest *SGuest) PerformChangeBandwidth(
return nil, httperrors.NewBadRequestError("Cannot change bandwidth in status %s", guest.Status)
}

bandwidth := input.Bandwidth
if bandwidth < 0 {
return nil, httperrors.NewBadRequestError("Bandwidth must be non-negative")
if input.Bandwidth < 0 && input.TxBwLimit < 0 && input.RxBwLimit < 0 {
return nil, httperrors.NewBadRequestError("Bandwidth, tx_bw_limit and rx_bw_limit must be non-negative")
}

guestnic, err := guest.findGuestnetworkByInfo(input.ServerNetworkInfo)
if err != nil {
return nil, errors.Wrap(err, "findGuestnetworkByInfo")
}

if guestnic.BwLimit != int(bandwidth) {
if guestnic.BwLimit != int(input.Bandwidth) || guestnic.TxBwLimit != int(input.TxBwLimit) || guestnic.RxBwLimit != int(input.RxBwLimit) {
diff, err := db.Update(guestnic, func() error {
guestnic.BwLimit = int(bandwidth)
guestnic.BwLimit = int(input.Bandwidth)
guestnic.TxBwLimit = int(input.TxBwLimit)
guestnic.RxBwLimit = int(input.RxBwLimit)
return nil
})
if err != nil {
Expand Down
Loading
Loading