diff --git a/pkg/cloudprovider/eip.go b/pkg/cloudprovider/eip.go index 4a47c67b4e..b0faa84556 100644 --- a/pkg/cloudprovider/eip.go +++ b/pkg/cloudprovider/eip.go @@ -22,3 +22,9 @@ type SEip struct { NetworkExternalId string IP string } + +type AssociateConfig struct { + InstanceId string + AssociateType string + Bandwidth int +} diff --git a/pkg/cloudprovider/resources.go b/pkg/cloudprovider/resources.go index 07cfbfeee8..169c2f781a 100644 --- a/pkg/cloudprovider/resources.go +++ b/pkg/cloudprovider/resources.go @@ -328,7 +328,7 @@ type ICloudEIP interface { Delete() error - Associate(instanceId string) error + Associate(conf *AssociateConfig) error Dissociate() error ChangeBandwidth(bw int) error diff --git a/pkg/compute/guestdrivers/aws.go b/pkg/compute/guestdrivers/aws.go index e78073fd0e..f516f5a8ee 100644 --- a/pkg/compute/guestdrivers/aws.go +++ b/pkg/compute/guestdrivers/aws.go @@ -202,7 +202,13 @@ func (self *SAwsGuestDriver) RequestAssociateEip(ctx context.Context, userCred m return nil, fmt.Errorf("SAwsGuestDriver.RequestAssociateEip fail to find iEIP for eip %s", err) } - err = extEip.Associate(server.ExternalId) + conf := &cloudprovider.AssociateConfig{ + InstanceId: server.ExternalId, + Bandwidth: eip.Bandwidth, + AssociateType: api.EIP_ASSOCIATE_TYPE_SERVER, + } + + err = extEip.Associate(conf) if err != nil { return nil, fmt.Errorf("SAwsGuestDriver.RequestAssociateEip fail to remote associate EIP %s", err) } diff --git a/pkg/compute/guestdrivers/managedvirtual.go b/pkg/compute/guestdrivers/managedvirtual.go index 7f99dcf8f0..9b1580b001 100644 --- a/pkg/compute/guestdrivers/managedvirtual.go +++ b/pkg/compute/guestdrivers/managedvirtual.go @@ -1010,7 +1010,13 @@ func (self *SManagedVirtualizedGuestDriver) RequestAssociateEip(ctx context.Cont return nil, fmt.Errorf("ManagedVirtualizedGuestDriver.RequestAssociateEip fail to find iEIP for eip %s", err) } - err = extEip.Associate(server.ExternalId) + conf := &cloudprovider.AssociateConfig{ + InstanceId: server.ExternalId, + Bandwidth: eip.Bandwidth, + AssociateType: api.EIP_ASSOCIATE_TYPE_SERVER, + } + + err = extEip.Associate(conf) if err != nil { return nil, fmt.Errorf("ManagedVirtualizedGuestDriver.RequestAssociateEip fail to remote associate EIP %s", err) } diff --git a/pkg/compute/guestdrivers/openstack.go b/pkg/compute/guestdrivers/openstack.go index c1f91ad85a..c289d85180 100644 --- a/pkg/compute/guestdrivers/openstack.go +++ b/pkg/compute/guestdrivers/openstack.go @@ -237,7 +237,11 @@ func (self *SOpenStackGuestDriver) RemoteDeployGuestForRebuildRoot(ctx context.C if err != nil { return "", errors.Wrap(err, "ieip.Dissociate") } - defer ieip.Associate(instanceId) + conf := &cloudprovider.AssociateConfig{ + InstanceId: instanceId, + AssociateType: api.EIP_ASSOCIATE_TYPE_SERVER, + } + defer ieip.Associate(conf) } err = iVM.DeleteVM(ctx) if err != nil { diff --git a/pkg/compute/models/elasticips.go b/pkg/compute/models/elasticips.go index e2b3594050..51ac3f74cd 100644 --- a/pkg/compute/models/elasticips.go +++ b/pkg/compute/models/elasticips.go @@ -343,7 +343,9 @@ func (self *SElasticip) SyncWithCloudEip(ctx context.Context, userCred mcclient. diff, err := db.UpdateWithLock(ctx, self, func() error { // self.Name = ext.GetName() - self.Bandwidth = ext.GetBandwidth() + if bandwidth := ext.GetBandwidth(); bandwidth != 0 { + self.Bandwidth = bandwidth + } self.IpAddr = ext.GetIpAddr() self.Mode = ext.GetMode() self.Status = ext.GetStatus() diff --git a/pkg/compute/regiondrivers/aliyun.go b/pkg/compute/regiondrivers/aliyun.go index 8f1a191a26..0efb696752 100644 --- a/pkg/compute/regiondrivers/aliyun.go +++ b/pkg/compute/regiondrivers/aliyun.go @@ -888,7 +888,12 @@ func (self *SAliyunRegionDriver) RequestBindIPToNatgateway(ctx context.Context, if err != nil { return nil, errors.Wrap(err, "fetch eip failed") } - err = ieip.Associate(natgateway.GetExternalId()) + conf := &cloudprovider.AssociateConfig{ + InstanceId: natgateway.GetExternalId(), + Bandwidth: eip.Bandwidth, + AssociateType: api.EIP_ASSOCIATE_TYPE_NAT_GATEWAY, + } + err = ieip.Associate(conf) if err != nil { return nil, errors.Wrap(err, "fail to bind eip to natgateway") } diff --git a/pkg/compute/regiondrivers/huawei.go b/pkg/compute/regiondrivers/huawei.go index 870f773ce3..510762156b 100644 --- a/pkg/compute/regiondrivers/huawei.go +++ b/pkg/compute/regiondrivers/huawei.go @@ -1870,7 +1870,12 @@ func (self *SHuaWeiRegionDriver) RequestCreateLoadbalancer(ctx context.Context, return nil, err } - err = ieip.Associate(iLoadbalancer.GetGlobalId()) + conf := &cloudprovider.AssociateConfig{ + InstanceId: iLoadbalancer.GetGlobalId(), + AssociateType: api.EIP_ASSOCIATE_TYPE_LOADBALANCER, + } + + err = ieip.Associate(conf) if err != nil { return nil, err } diff --git a/pkg/multicloud/aliyun/eip.go b/pkg/multicloud/aliyun/eip.go index c45d9446eb..48c1dde523 100644 --- a/pkg/multicloud/aliyun/eip.go +++ b/pkg/multicloud/aliyun/eip.go @@ -203,9 +203,9 @@ func (self *SEipAddress) GetInternetChargeType() string { } } -func (self *SEipAddress) Associate(instanceId string) error { +func (self *SEipAddress) Associate(conf *cloudprovider.AssociateConfig) error { err := cloudprovider.Wait(20*time.Second, 60*time.Second, func() (bool, error) { - err := self.region.AssociateEip(self.AllocationId, instanceId) + err := self.region.AssociateEip(self.AllocationId, conf.InstanceId) if err != nil { if isError(err, "IncorrectInstanceStatus") { return false, nil diff --git a/pkg/multicloud/aws/eip.go b/pkg/multicloud/aws/eip.go index 4a5ed9b736..ce19cbf0e5 100644 --- a/pkg/multicloud/aws/eip.go +++ b/pkg/multicloud/aws/eip.go @@ -137,8 +137,8 @@ func (self *SEipAddress) Delete() error { return self.region.DeallocateEIP(self.AllocationId) } -func (self *SEipAddress) Associate(instanceId string) error { - err := self.region.AssociateEip(self.AllocationId, instanceId) +func (self *SEipAddress) Associate(conf *cloudprovider.AssociateConfig) error { + err := self.region.AssociateEip(self.AllocationId, conf.InstanceId) if err != nil { return err } diff --git a/pkg/multicloud/azure/classic_eip.go b/pkg/multicloud/azure/classic_eip.go index 3596da76f9..971254e8e4 100644 --- a/pkg/multicloud/azure/classic_eip.go +++ b/pkg/multicloud/azure/classic_eip.go @@ -45,7 +45,7 @@ type SClassicEipAddress struct { Type string } -func (self *SClassicEipAddress) Associate(instanceId string) error { +func (self *SClassicEipAddress) Associate(conf *cloudprovider.AssociateConfig) error { return cloudprovider.ErrNotImplemented } diff --git a/pkg/multicloud/azure/eip.go b/pkg/multicloud/azure/eip.go index 0c6d1fd4d4..fe5ba06f2c 100644 --- a/pkg/multicloud/azure/eip.go +++ b/pkg/multicloud/azure/eip.go @@ -86,8 +86,8 @@ func (region *SRegion) GetEip(eipId string) (*SEipAddress, error) { return &eip, region.client.Get(eipId, []string{}, &eip) } -func (self *SEipAddress) Associate(instanceId string) error { - return self.region.AssociateEip(self.ID, instanceId) +func (self *SEipAddress) Associate(conf *cloudprovider.AssociateConfig) error { + return self.region.AssociateEip(self.ID, conf.InstanceId) } func (region *SRegion) AssociateEip(eipId string, instanceId string) error { diff --git a/pkg/multicloud/ctyun/eip.go b/pkg/multicloud/ctyun/eip.go index 3eb9a1727b..65cbbafacb 100644 --- a/pkg/multicloud/ctyun/eip.go +++ b/pkg/multicloud/ctyun/eip.go @@ -190,8 +190,8 @@ func (self *SEip) Delete() error { return self.region.DeleteEip(self.GetId()) } -func (self *SEip) Associate(instanceId string) error { - nics, err := self.region.GetNics(instanceId) +func (self *SEip) Associate(conf *cloudprovider.AssociateConfig) error { + nics, err := self.region.GetNics(conf.InstanceId) if err != nil { return errors.Wrap(err, "Eip.Associate.GetNics") } diff --git a/pkg/multicloud/google/eip.go b/pkg/multicloud/google/eip.go index e838d460a6..7877a73de2 100644 --- a/pkg/multicloud/google/eip.go +++ b/pkg/multicloud/google/eip.go @@ -149,8 +149,8 @@ func (addr *SAddress) Delete() error { return addr.region.Delete(addr.SelfLink) } -func (addr *SAddress) Associate(instanceId string) error { - return addr.region.AssociateInstanceEip(instanceId, addr.Address) +func (addr *SAddress) Associate(conf *cloudprovider.AssociateConfig) error { + return addr.region.AssociateInstanceEip(conf.InstanceId, addr.Address) } func (addr *SAddress) Dissociate() error { diff --git a/pkg/multicloud/huawei/eip.go b/pkg/multicloud/huawei/eip.go index 876b2f0256..bd7b4abdfb 100644 --- a/pkg/multicloud/huawei/eip.go +++ b/pkg/multicloud/huawei/eip.go @@ -229,8 +229,8 @@ func (self *SEipAddress) Delete() error { return self.region.DeallocateEIP(self.ID) } -func (self *SEipAddress) Associate(instanceId string) error { - portId, err := self.region.GetInstancePortId(instanceId) +func (self *SEipAddress) Associate(conf *cloudprovider.AssociateConfig) error { + portId, err := self.region.GetInstancePortId(conf.InstanceId) if err != nil { return err } diff --git a/pkg/multicloud/openstack/eip.go b/pkg/multicloud/openstack/eip.go index 2ca482d217..8fb8d257aa 100644 --- a/pkg/multicloud/openstack/eip.go +++ b/pkg/multicloud/openstack/eip.go @@ -232,8 +232,8 @@ func (eip *SEipAddress) GetInternetChargeType() string { return api.EIP_CHARGE_TYPE_BY_TRAFFIC } -func (eip *SEipAddress) Associate(instanceId string) error { - return eip.region.AssociateEip(instanceId, eip.ID) +func (eip *SEipAddress) Associate(conf *cloudprovider.AssociateConfig) error { + return eip.region.AssociateEip(conf.InstanceId, eip.ID) } func (eip *SEipAddress) Dissociate() error { diff --git a/pkg/multicloud/qcloud/eip.go b/pkg/multicloud/qcloud/eip.go index fa70c82294..3a0e306042 100644 --- a/pkg/multicloud/qcloud/eip.go +++ b/pkg/multicloud/qcloud/eip.go @@ -203,12 +203,18 @@ func (self *SEipAddress) GetInternetChargeType() string { return api.EIP_CHARGE_TYPE_BY_TRAFFIC } -func (self *SEipAddress) Associate(instanceId string) error { - err := self.region.AssociateEip(self.AddressId, instanceId) +func (self *SEipAddress) Associate(conf *cloudprovider.AssociateConfig) error { + err := self.region.AssociateEip(self.AddressId, conf.InstanceId) if err != nil { return err } - return cloudprovider.WaitStatus(self, api.EIP_STATUS_READY, 10*time.Second, 180*time.Second) + if conf.Bandwidth > 0 { + err = self.region.UpdateInstanceBandwidth(conf.InstanceId, conf.Bandwidth) + if err != nil { + log.Warningf("failed to change instance %s bandwidth -> %d error: %v", conf.InstanceId, conf.Bandwidth, err) + } + } + return cloudprovider.WaitStatusWithDelay(self, api.EIP_STATUS_READY, 5*time.Second, 10*time.Second, 180*time.Second) } func (self *SEipAddress) Dissociate() error { @@ -216,16 +222,14 @@ func (self *SEipAddress) Dissociate() error { if err != nil { return err } - return cloudprovider.WaitStatus(self, api.EIP_STATUS_READY, 10*time.Second, 180*time.Second) + return cloudprovider.WaitStatusWithDelay(self, api.EIP_STATUS_READY, 5*time.Second, 10*time.Second, 180*time.Second) } func (self *SEipAddress) ChangeBandwidth(bw int) error { - if self.GetInternetChargeType() == api.EIP_CHARGE_TYPE_BY_TRAFFIC { - if len(self.InstanceId) > 0 { - return self.region.UpdateInstanceBandwidth(self.InstanceId, bw) - } + if len(self.InstanceId) > 0 { + return self.region.UpdateInstanceBandwidth(self.InstanceId, bw) } - return cloudprovider.ErrNotSupported + return nil } func (region *SRegion) GetEips(eipId string, instanceId string, offset int, limit int) ([]SEipAddress, int, error) { diff --git a/pkg/multicloud/qcloud/instance.go b/pkg/multicloud/qcloud/instance.go index 871084bf53..b96b3cfbd2 100644 --- a/pkg/multicloud/qcloud/instance.go +++ b/pkg/multicloud/qcloud/instance.go @@ -504,6 +504,7 @@ func (self *SRegion) CreateInstance(name string, imageId string, instanceType st params["Placement.Zone"] = zoneId params["InstanceName"] = name + params["InternetAccessible.InternetMaxBandwidthOut"] = "1" params["InternetAccessible.PublicIpAssigned"] = "FALSE" //params["HostName"] = name if len(keypair) > 0 { diff --git a/pkg/multicloud/ucloud/eip.go b/pkg/multicloud/ucloud/eip.go index 5c6a43afb1..72ecce916d 100644 --- a/pkg/multicloud/ucloud/eip.go +++ b/pkg/multicloud/ucloud/eip.go @@ -196,8 +196,8 @@ func (self *SEip) Delete() error { return self.region.DeallocateEIP(self.GetId()) } -func (self *SEip) Associate(instanceId string) error { - return self.region.AssociateEip(self.GetId(), instanceId) +func (self *SEip) Associate(conf *cloudprovider.AssociateConfig) error { + return self.region.AssociateEip(self.GetId(), conf.InstanceId) } func (self *SEip) Dissociate() error { diff --git a/pkg/multicloud/zstack/eip.go b/pkg/multicloud/zstack/eip.go index 66126842ba..96c73588bf 100644 --- a/pkg/multicloud/zstack/eip.go +++ b/pkg/multicloud/zstack/eip.go @@ -147,8 +147,8 @@ func (eip *SEipAddress) GetInternetChargeType() string { return api.EIP_CHARGE_TYPE_BY_TRAFFIC } -func (eip *SEipAddress) Associate(instanceId string) error { - return eip.region.AssociateEip(instanceId, eip.UUID) +func (eip *SEipAddress) Associate(conf *cloudprovider.AssociateConfig) error { + return eip.region.AssociateEip(conf.InstanceId, eip.UUID) } func (eip *SEipAddress) Dissociate() error {