Merge pull request #10529 from ioito/hotfix/qx-qcloud-eip

fix: instance with eip charge type
This commit is contained in:
Zexi Li
2021-03-30 19:46:15 +08:00
committed by GitHub
7 changed files with 79 additions and 60 deletions
+1
View File
@@ -35,4 +35,5 @@ type AssociateConfig struct {
InstanceId string
AssociateType string
Bandwidth int
ChargeType string
}
+3
View File
@@ -524,6 +524,9 @@ func (manager *SElasticipManager) newFromCloudEip(ctx context.Context, userCred
eip.ManagerId = provider.Id
eip.CloudregionId = region.Id
eip.ChargeType = extEip.GetInternetChargeType()
if len(eip.ChargeType) == 0 {
eip.ChargeType = api.EIP_CHARGE_TYPE_BY_TRAFFIC
}
eip.Bandwidth = extEip.GetBandwidth()
if networkId := extEip.GetINetworkId(); len(networkId) > 0 {
network, err := db.FetchByExternalIdAndManagerId(NetworkManager, networkId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
@@ -3075,6 +3075,7 @@ func (self *SManagedVirtualizationRegionDriver) RequestAssociatEip(ctx context.C
InstanceId: input.InstanceExternalId,
Bandwidth: eip.Bandwidth,
AssociateType: input.InstanceType,
ChargeType: eip.ChargeType,
}
err = iEip.Associate(conf)
+3
View File
@@ -17,6 +17,7 @@ package tasks
import (
"context"
"fmt"
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
@@ -140,6 +141,8 @@ func (self *EipAllocateTask) OnInit(ctx context.Context, obj db.IStandaloneModel
return
}
cloudprovider.WaitStatus(extEip, api.EIP_STATUS_READY, time.Second*5, time.Minute*3)
if err := eip.SyncWithCloudEip(ctx, self.UserCred, eip.GetCloudprovider(), extEip, nil); err != nil {
msg := fmt.Sprintf("sync eip fail %s", err)
eip.SetStatus(self.UserCred, api.EIP_STATUS_ALLOCATE_FAIL, msg)
+59 -57
View File
@@ -21,6 +21,7 @@ import (
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
billing_api "yunion.io/x/onecloud/pkg/apis/billing"
api "yunion.io/x/onecloud/pkg/apis/compute"
@@ -28,13 +29,6 @@ import (
"yunion.io/x/onecloud/pkg/multicloud"
)
type TInternetChargeType string
const (
InternetChargeByTraffic = TInternetChargeType("PayByTraffic")
InternetChargeByBandwidth = TInternetChargeType("PayByBandwidth")
)
const (
EIP_STATUS_CREATING = "CREATING"
EIP_STATUS_BINDING = "BINDING"
@@ -209,7 +203,7 @@ func (self *SEipAddress) GetInternetChargeType() string {
}
}
}
return api.EIP_CHARGE_TYPE_BY_TRAFFIC
return ""
}
func (self *SEipAddress) Associate(conf *cloudprovider.AssociateConfig) error {
@@ -218,7 +212,7 @@ func (self *SEipAddress) Associate(conf *cloudprovider.AssociateConfig) error {
return err
}
if conf.Bandwidth > 0 && self.Bandwidth == 0 {
err = self.region.UpdateInstanceBandwidth(conf.InstanceId, conf.Bandwidth)
err = self.region.UpdateInstanceBandwidth(conf.InstanceId, conf.Bandwidth, conf.ChargeType)
if err != nil {
log.Warningf("failed to change instance %s bandwidth -> %d error: %v", conf.InstanceId, conf.Bandwidth, err)
}
@@ -235,8 +229,11 @@ func (self *SEipAddress) Dissociate() error {
}
func (self *SEipAddress) ChangeBandwidth(bw int) error {
if len(self.InstanceId) > 0 {
return self.region.UpdateInstanceBandwidth(self.InstanceId, bw)
if len(self.InstanceId) > 0 && len(self.InternetChargeType) > 0 && strings.HasSuffix(self.InstanceId, "ins-") {
return self.region.UpdateInstanceBandwidth(self.InstanceId, bw, "")
}
if len(self.InternetChargeType) > 0 {
return self.region.ChangeEipBindWidth(self.AddressId, bw, self.InternetChargeType)
}
return nil
}
@@ -289,52 +286,42 @@ func (region *SRegion) GetEip(eipId string) (*SEipAddress, error) {
return &eips[0], nil
}
func (region *SRegion) AllocateEIP(name string, bwMbps int, chargeType TInternetChargeType) (*SEipAddress, error) {
func (region *SRegion) AllocateEIP(name string, bwMbps int, chargeType string) (*SEipAddress, error) {
params := make(map[string]string)
params["AddressName"] = name
if bwMbps > 0 {
params["InternetMaxBandwidthOut"] = fmt.Sprintf("%d", bwMbps)
}
_, totalCount, err := region.GetBandwidthPackages([]string{}, 0, 50)
if err != nil {
return nil, errors.Wrapf(err, "GetBandwidthPackages")
}
if totalCount == 0 {
switch chargeType {
case api.EIP_CHARGE_TYPE_BY_TRAFFIC:
params["InternetChargeType"] = "TRAFFIC_POSTPAID_BY_HOUR"
case api.EIP_CHARGE_TYPE_BY_BANDWIDTH:
params["InternetChargeType"] = "BANDWIDTH_POSTPAID_BY_HOUR"
}
}
addRessSet := []string{}
body, err := region.vpcRequest("AllocateAddresses", params)
if err != nil {
return nil, err
return nil, errors.Wrapf(err, "AllocateAddresses")
}
err = body.Unmarshal(&addRessSet, "AddressSet")
if err != nil {
return nil, err
return nil, errors.Wrapf(err, "resp.Unmarshal")
}
if len(name) > 20 {
name = name[:20]
}
if len(addRessSet) > 0 {
params = map[string]string{}
params["AddressId"] = addRessSet[0]
params["AddressName"] = name
_, err = region.vpcRequest("ModifyAddressAttribute", params)
if err != nil {
return nil, err
}
eip, err := region.GetEip(addRessSet[0])
if err != nil {
return nil, err
}
return eip, cloudprovider.WaitStatus(eip, api.EIP_STATUS_READY, time.Second*5, time.Second*300)
}
return nil, cloudprovider.ErrNotFound
return region.GetEip(addRessSet[0])
}
// https://cloud.tencent.com/document/api/215/16699
// 腾讯云eip不支持指定项目
func (region *SRegion) CreateEIP(eip *cloudprovider.SEip) (cloudprovider.ICloudEIP, error) {
var ctype TInternetChargeType
switch eip.ChargeType {
case api.EIP_CHARGE_TYPE_BY_TRAFFIC:
ctype = InternetChargeByTraffic
case api.EIP_CHARGE_TYPE_BY_BANDWIDTH:
ctype = InternetChargeByBandwidth
}
return region.AllocateEIP(eip.Name, eip.BandwidthMbps, ctype)
return region.AllocateEIP(eip.Name, eip.BandwidthMbps, eip.ChargeType)
}
func (region *SRegion) DeallocateEIP(eipId string) error {
@@ -343,10 +330,7 @@ func (region *SRegion) DeallocateEIP(eipId string) error {
params["AddressIds.0"] = eipId
_, err := region.vpcRequest("ReleaseAddresses", params)
if err != nil {
log.Errorf("ReleaseAddresses fail %s", err)
}
return err
return errors.Wrapf(err, "ReleaseAddresses")
}
func (region *SRegion) AssociateEip(eipId string, instanceId string) error {
@@ -355,10 +339,7 @@ func (region *SRegion) AssociateEip(eipId string, instanceId string) error {
params["InstanceId"] = instanceId
_, err := region.vpcRequest("AssociateAddress", params)
if err != nil {
log.Errorf("AssociateAddress fail %s", err)
}
return err
return errors.Wrapf(err, "AssociateAddress")
}
func (region *SRegion) DissociateEip(eipId string) error {
@@ -367,20 +348,41 @@ func (region *SRegion) DissociateEip(eipId string) error {
params["AddressId"] = eipId
_, err := region.vpcRequest("DisassociateAddress", params)
if err != nil {
log.Errorf("UnassociateEipAddress fail %s", err)
}
return err
return errors.Wrapf(err, "DisassociateAddress")
}
func (region *SRegion) UpdateInstanceBandwidth(instanceId string, bw int) error {
func (region *SRegion) UpdateInstanceBandwidth(instanceId string, bw int, chargeType string) error {
params := make(map[string]string)
params["Region"] = region.Region
params["InstanceIds.0"] = instanceId
params["InstanceId"] = instanceId
params["InternetAccessible.InternetMaxBandwidthOut"] = fmt.Sprintf("%d", bw)
_, err := region.cvmRequest("ResetInstancesInternetMaxBandwidth", params, true)
return err
_, totalCount, err := region.GetBandwidthPackages([]string{}, 0, 50)
if err != nil {
return errors.Wrapf(err, "GetBandwidthPackages")
}
if totalCount == 0 {
switch chargeType {
case api.EIP_CHARGE_TYPE_BY_TRAFFIC:
params["InternetAccessible.InternetChargeType"] = "TRAFFIC_POSTPAID_BY_HOUR"
case api.EIP_CHARGE_TYPE_BY_BANDWIDTH:
params["InternetAccessible.InternetChargeType"] = "BANDWIDTH_POSTPAID_BY_HOUR"
}
}
_, err = region.cvmRequest("ModifyInstanceInternetChargeType", params, true)
return errors.Wrapf(err, "ModifyInstanceInternetChargeType")
}
func (self *SRegion) ChangeEipBindWidth(eipId string, bw int, chargeType string) error {
params := map[string]string{
"Region": self.Region,
"InternetMaxBandwidthOut": fmt.Sprintf("%d", bw),
"InternetChargeType": chargeType,
"AddressId": eipId,
}
_, err := self.vpcRequest("ModifyAddressInternetChargeType", params)
return errors.Wrapf(err, "ModifyAddressInternetChargeType")
}
func (self *SEipAddress) GetProjectId() string {
+3 -3
View File
@@ -36,9 +36,9 @@ func init() {
})
type EipAllocateOptions struct {
BANDWIDTH int `help:"EIP bandwoidth"`
NAME string `help:"EIP Name"`
ChargeType qcloud.TInternetChargeType `help:"EIP ChargeType"`
BANDWIDTH int `help:"EIP bandwoidth"`
NAME string `help:"EIP Name"`
ChargeType string `help:"EIP ChargeType" choices:"traffic|bandwidth"`
}
shellutils.R(&EipAllocateOptions{}, "eip-create", "Allocate an EIP", func(cli *qcloud.SRegion, args *EipAllocateOptions) error {
eip, err := cli.AllocateEIP(args.NAME, args.BANDWIDTH, args.ChargeType)
+9
View File
@@ -233,4 +233,13 @@ func init() {
return nil
})
type InstanceBandWidthOptions struct {
ID string `help:"Instance ID"`
BANDWIDTH int `help:"Bandwidth"`
InternetChargeType string `help:"InternetChargeType" default:"traffic" choices:"traffic|bandwidth"`
}
shellutils.R(&InstanceBandWidthOptions{}, "instance-change-bandwidth", "Change instance bandwidth", func(cli *qcloud.SRegion, args *InstanceBandWidthOptions) error {
return cli.UpdateInstanceBandwidth(args.ID, args.BANDWIDTH, args.InternetChargeType)
})
}