diff --git a/pkg/apis/compute/loadbalancer_const.go b/pkg/apis/compute/loadbalancer_const.go index 1541607e5a..c736c33464 100644 --- a/pkg/apis/compute/loadbalancer_const.go +++ b/pkg/apis/compute/loadbalancer_const.go @@ -80,6 +80,29 @@ var LB_BACKENDGROUP_TYPE = choices.NewChoices( LB_BACKENDGROUP_TYPE_MASTER_SLAVE, ) +const ( + LB_ALIYUN_SPEC_S1_SMALL = "slb.s1.small" + LB_ALIYUN_SPEC_S2_SMALL = "slb.s2.small" + LB_ALIYUN_SPEC_S3_SMALL = "slb.s3.small" + LB_ALIYUN_SPEC_S2_MEDIUM = "slb.s2.medium" + LB_ALIYUN_SPEC_S3_MEDIUM = "slb.s3.medium" + LB_ALIYUN_SPEC_S3_LARGE = "slb.s3.large" +) + +const ( + LB_MbpsMin = 0 + LB_MbpsMax = 10000 +) + +var LB_ALIYUN_SPECS = choices.NewChoices( + LB_ALIYUN_SPEC_S1_SMALL, + LB_ALIYUN_SPEC_S2_SMALL, + LB_ALIYUN_SPEC_S3_SMALL, + LB_ALIYUN_SPEC_S2_MEDIUM, + LB_ALIYUN_SPEC_S3_MEDIUM, + LB_ALIYUN_SPEC_S3_LARGE, +) + // Load Balancer network type (vpc or classic) determines viable backend // servers (they should be from the same network type as the load balancer). // @@ -270,6 +293,12 @@ const ( LB_CHARGE_TYPE_BY_HOUR = "hour" ) +var LB_CHARGE_TYPES = choices.NewChoices( + LB_CHARGE_TYPE_BY_TRAFFIC, + LB_CHARGE_TYPE_BY_BANDWIDTH, + LB_CHARGE_TYPE_BY_HOUR, +) + const ( LB_HA_STATE_MASTER = "MASTER" LB_HA_STATE_BACKUP = "BACKUP" diff --git a/pkg/cloudprovider/loadbalancer.go b/pkg/cloudprovider/loadbalancer.go index ec7d01b75e..ee0014d78a 100644 --- a/pkg/cloudprovider/loadbalancer.go +++ b/pkg/cloudprovider/loadbalancer.go @@ -25,6 +25,6 @@ type SLoadbalancer struct { AddressType string LoadbalancerSpec string ChargeType string - Bandwidth int + EgressMbps int billingCycle *billing.SBillingCycle } diff --git a/pkg/cloudprovider/loadbalancerlistener.go b/pkg/cloudprovider/loadbalancerlistener.go index d95aeb2cce..0256567df5 100644 --- a/pkg/cloudprovider/loadbalancerlistener.go +++ b/pkg/cloudprovider/loadbalancerlistener.go @@ -27,7 +27,7 @@ type SLoadbalancerListener struct { AccessControlListID string EnableHTTP2 bool CertificateID string - Bandwidth int + EgressMbps int Description string EstablishedTimeout int diff --git a/pkg/cloudprovider/resources.go b/pkg/cloudprovider/resources.go index 34cde69908..80eca28a74 100644 --- a/pkg/cloudprovider/resources.go +++ b/pkg/cloudprovider/resources.go @@ -439,6 +439,7 @@ type ICloudLoadbalancer interface { GetZoneId() string GetLoadbalancerSpec() string GetChargeType() string + GetEgressMbps() int Delete() error @@ -466,6 +467,8 @@ type ICloudLoadbalancerListener interface { GetAclType() string GetAclId() string + GetEgressMbps() int + GetHealthCheck() string GetHealthCheckType() string GetHealthCheckTimeout() int diff --git a/pkg/compute/models/loadbalanceracls.go b/pkg/compute/models/loadbalanceracls.go index b37875a797..de45614cf0 100644 --- a/pkg/compute/models/loadbalanceracls.go +++ b/pkg/compute/models/loadbalanceracls.go @@ -147,6 +147,12 @@ func (man *SLoadbalancerAclManager) ValidateCreateData(ctx context.Context, user return nil, err } + managerIdV := validators.NewModelIdOrNameValidator("manager", "cloudprovider", "") + managerIdV.Optional(true) + if err := managerIdV.Validate(data); err != nil { + return nil, err + } + regionV := validators.NewModelIdOrNameValidator("cloudregion", "cloudregion", ownerProjId) regionV.Default("default") if err := regionV.Validate(data); err != nil { diff --git a/pkg/compute/models/loadbalancercertificates.go b/pkg/compute/models/loadbalancercertificates.go index a1738930fb..e58349c64f 100644 --- a/pkg/compute/models/loadbalancercertificates.go +++ b/pkg/compute/models/loadbalancercertificates.go @@ -146,6 +146,12 @@ func (man *SLoadbalancerCertificateManager) ValidateCreateData(ctx context.Conte return nil, err } + managerIdV := validators.NewModelIdOrNameValidator("manager", "cloudprovider", "") + managerIdV.Optional(true) + if err := managerIdV.Validate(data); err != nil { + return nil, err + } + regionV := validators.NewModelIdOrNameValidator("cloudregion", "cloudregion", ownerProjId) regionV.Default("default") if err := regionV.Validate(data); err != nil { diff --git a/pkg/compute/models/loadbalancerlisteners.go b/pkg/compute/models/loadbalancerlisteners.go index 98e980d4ae..29979a1e4e 100644 --- a/pkg/compute/models/loadbalancerlisteners.go +++ b/pkg/compute/models/loadbalancerlisteners.go @@ -58,6 +58,10 @@ type SLoadbalancerHTTPRateLimiter struct { HTTPRequestRatePerSrc int `nullable:"false" list:"user" create:"optional" update:"user"` } +type SLoadbalancerRateLimiter struct { + EgressMbps int `nullable:"false" list:"user" get:"user" create:"optional" update:"user"` +} + type SLoadbalancerHealthCheck struct { HealthCheck string `width:"16" charset:"ascii" nullable:"false" list:"user" create:"optional" update:"user"` HealthCheckType string `width:"16" charset:"ascii" nullable:"false" list:"user" create:"optional" update:"user"` @@ -123,6 +127,8 @@ type SLoadbalancerListener struct { AclType string `width:"16" charset:"ascii" nullable:"false" list:"user" create:"optional" update:"user"` AclId string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"optional" update:"user"` + SLoadbalancerRateLimiter + SLoadbalancerTCPListener SLoadbalancerUDPListener SLoadbalancerHTTPListener @@ -200,8 +206,8 @@ func (man *SLoadbalancerListenerManager) ValidateCreateData(ctx context.Context, "acl_type": aclTypeV.Optional(true), "acl": aclV.Optional(true), - "scheduler": validators.NewStringChoicesValidator("scheduler", api.LB_SCHEDULER_TYPES), - "bandwidth": validators.NewRangeValidator("bandwidth", 0, 10000).Optional(true), + "scheduler": validators.NewStringChoicesValidator("scheduler", api.LB_SCHEDULER_TYPES), + "egress_mbps": validators.NewRangeValidator("egress_mbps", api.LB_MbpsMin, api.LB_MbpsMax).Optional(true), "client_request_timeout": validators.NewRangeValidator("client_request_timeout", 0, 600).Default(10), "client_idle_timeout": validators.NewRangeValidator("client_idle_timeout", 0, 600).Default(90), @@ -407,8 +413,8 @@ func (lblis *SLoadbalancerListener) ValidateUpdateData(ctx context.Context, user "acl_type": aclTypeV, "acl": aclV, - "scheduler": validators.NewStringChoicesValidator("scheduler", api.LB_SCHEDULER_TYPES), - "bandwidth": validators.NewRangeValidator("bandwidth", 0, 10000), + "scheduler": validators.NewStringChoicesValidator("scheduler", api.LB_SCHEDULER_TYPES), + "egress_mbps": validators.NewRangeValidator("egress_mbps", api.LB_MbpsMin, api.LB_MbpsMax).Optional(true), "client_request_timeout": validators.NewRangeValidator("client_request_timeout", 0, 600), "client_idle_timeout": validators.NewRangeValidator("client_idle_timeout", 0, 600), @@ -599,7 +605,7 @@ func (lblis *SLoadbalancerListener) GetLoadbalancerListenerParams() (*cloudprovi ListenerPort: lblis.ListenerPort, Scheduler: lblis.Scheduler, EnableHTTP2: lblis.EnableHttp2, - Bandwidth: 0, + EgressMbps: lblis.EgressMbps, EstablishedTimeout: lblis.BackendConnectTimeout, HealthCheck: lblis.HealthCheck, @@ -761,6 +767,7 @@ func (lblis *SLoadbalancerListener) constructFieldsFromCloudListener(userCred mc lblis.ManagerId = lb.ManagerId // lblis.Name = extListener.GetName() lblis.ListenerType = extListener.GetListenerType() + lblis.EgressMbps = extListener.GetEgressMbps() lblis.ListenerPort = extListener.GetListenerPort() lblis.Scheduler = extListener.GetScheduler() lblis.Status = extListener.GetStatus() diff --git a/pkg/compute/models/loadbalancers.go b/pkg/compute/models/loadbalancers.go index c71e24e41b..0ba5e8a2f7 100644 --- a/pkg/compute/models/loadbalancers.go +++ b/pkg/compute/models/loadbalancers.go @@ -67,6 +67,7 @@ type SLoadbalancer struct { SManagedResourceBase SCloudregionResourceBase SZoneResourceBase + SLoadbalancerRateLimiter Address string `width:"16" charset:"ascii" nullable:"true" list:"user" create:"optional"` AddressType string `width:"16" charset:"ascii" nullable:"false" list:"user" create:"optional"` @@ -74,10 +75,11 @@ type SLoadbalancer struct { NetworkId string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"optional"` VpcId string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"optional"` - ChargeType string `list:"user" get:"user" create:"optional"` - LoadbalancerSpec string `list:"user" get:"user" create:"optional"` + ChargeType string `list:"user" get:"user" create:"optional" update:"user"` - BackendGroupId string `width:"36" charset:"ascii" nullable:"true" list:"user" update:"user" update:"user"` + LoadbalancerSpec string `list:"user" get:"user" list:"user" create:"optional"` + + BackendGroupId string `width:"36" charset:"ascii" nullable:"true" list:"user" update:"user"` LBInfo jsonutils.JSONObject `charset:"utf8" nullable:"true" list:"user" update:"admin" create:"admin_optional"` } @@ -109,7 +111,7 @@ func (man *SLoadbalancerManager) ValidateCreateData(ctx context.Context, userCre networkV := validators.NewModelIdOrNameValidator("network", "network", ownerProjId) addressType, _ := data.GetString("address_type") zoneV := validators.NewModelIdOrNameValidator("zone", "zone", "") - managerIdV := validators.NewModelIdOrNameValidator("manager_id", "cloudprovider", "") + managerIdV := validators.NewModelIdOrNameValidator("manager", "cloudprovider", "") if addressType == api.LB_ADDR_TYPE_INTERNET { networkV.Optional(true) } else { @@ -117,16 +119,19 @@ func (man *SLoadbalancerManager) ValidateCreateData(ctx context.Context, userCre managerIdV.Optional(true) } addressV := validators.NewIPv4AddrValidator("address") + chargeTypeV := validators.NewStringChoicesValidator("charge_type", api.LB_CHARGE_TYPES) + chargeTypeV.Default(api.LB_CHARGE_TYPE_BY_TRAFFIC) addressTypeV := validators.NewStringChoicesValidator("address_type", api.LB_ADDR_TYPES) { keyV := map[string]validators.IValidator{ "status": validators.NewStringChoicesValidator("status", api.LB_STATUS_SPEC).Default(api.LB_STATUS_ENABLED), + "charge_type": chargeTypeV, "address": addressV.Optional(true), "address_type": addressTypeV.Default(api.LB_ADDR_TYPE_INTRANET), "network": networkV, "zone": zoneV, - "manager_id": managerIdV, + "manager": managerIdV, } for _, v := range keyV { if err := v.Validate(data); err != nil { @@ -134,8 +139,13 @@ func (man *SLoadbalancerManager) ValidateCreateData(ctx context.Context, userCre } } } + var region *SCloudregion if addressTypeV.Value == api.LB_ADDR_TYPE_INTRANET { + if chargeTypeV.Value == api.LB_CHARGE_TYPE_BY_BANDWIDTH { + return nil, httperrors.NewUnsupportOperationError("intranet loadbalancer not support bandwidth charge type") + } + network := networkV.Model.(*SNetwork) if ipAddr := addressV.IP; ipAddr != nil { ipS := ipAddr.String() @@ -165,6 +175,9 @@ func (man *SLoadbalancerManager) ValidateCreateData(ctx context.Context, userCre } data.Set("vpc_id", jsonutils.NewString(vpc.Id)) if len(vpc.ManagerId) > 0 { + if managerIdV != nil && managerIdV.Model.GetId() != vpc.ManagerId { + return nil, httperrors.NewInputParameterError("Loadbalancer's manager (%s(%s)) does not match vpc's(%s(%s)) (%s)", managerIdV.Model.GetName(), managerIdV.Model.GetId(), vpc.GetName(), vpc.GetId(), vpc.ManagerId) + } data.Set("manager_id", jsonutils.NewString(vpc.ManagerId)) } zone := wire.GetZone() @@ -186,6 +199,13 @@ func (man *SLoadbalancerManager) ValidateCreateData(ctx context.Context, userCre if region == nil { return nil, fmt.Errorf("getting region failed") } + if chargeTypeV.Value == api.LB_CHARGE_TYPE_BY_BANDWIDTH { + egressMbpsV := validators.NewNonNegativeValidator("egress_mpbs") + if err := egressMbpsV.Validate(data); err != nil { + return nil, err + } + } + // 公网 lb 实例和vpc、network无关联 data.Set("vpc_id", jsonutils.NewString("")) data.Set("address", jsonutils.NewString("")) @@ -340,6 +360,9 @@ func (lb *SLoadbalancer) GetCreateLoadbalancerParams(iRegion cloudprovider.IClou } params.ZoneID = iZone.GetId() } + if lb.ChargeType == api.LB_CHARGE_TYPE_BY_BANDWIDTH { + lb.EgressMbps = lb.EgressMbps + } if lb.AddressType == api.LB_ADDR_TYPE_INTRANET { vpc := lb.GetVpc() if vpc == nil { @@ -444,6 +467,24 @@ func (lb *SLoadbalancer) CustomizeDelete(ctx context.Context, userCred mcclient. return lb.StartLoadBalancerDeleteTask(ctx, userCred, jsonutils.NewDict(), "") } +func (lb *SLoadbalancer) GetLoadbalancerListeners() ([]SLoadbalancerListener, error) { + listeners := []SLoadbalancerListener{} + q := LoadbalancerListenerManager.Query().Equals("loadbalancer_id", lb.Id).IsFalse("pending_deleted") + if err := db.FetchModelObjects(LoadbalancerListenerManager, q, &listeners); err != nil { + return nil, err + } + return listeners, nil +} + +func (lb *SLoadbalancer) GetLoadbalancerBackendgroups() ([]SLoadbalancerBackendGroup, error) { + lbbgs := []SLoadbalancerBackendGroup{} + q := LoadbalancerBackendGroupManager.Query().Equals("loadbalancer_id", lb.Id).IsFalse("pending_deleted") + if err := db.FetchModelObjects(LoadbalancerListenerManager, q, &lbbgs); err != nil { + return nil, err + } + return lbbgs, nil +} + func (lb *SLoadbalancer) LBPendingDelete(ctx context.Context, userCred mcclient.TokenCredential) { if len(lb.NetworkId) > 0 { req := &SLoadbalancerNetworkDeleteData{ @@ -559,6 +600,7 @@ func (man *SLoadbalancerManager) newFromCloudLoadbalancer(ctx context.Context, u lb.Status = extLb.GetStatus() lb.LoadbalancerSpec = extLb.GetLoadbalancerSpec() lb.ChargeType = extLb.GetChargeType() + lb.EgressMbps = extLb.GetEgressMbps() lb.ExternalId = extLb.GetGlobalId() if networkId := extLb.GetNetworkId(); len(networkId) > 0 { if network, err := NetworkManager.FetchByExternalId(networkId); err == nil && network != nil { @@ -629,6 +671,7 @@ func (lb *SLoadbalancer) SyncWithCloudLoadbalancer(ctx context.Context, userCred lb.Status = extLb.GetStatus() // lb.Name = extLb.GetName() lb.LoadbalancerSpec = extLb.GetLoadbalancerSpec() + lb.EgressMbps = extLb.GetEgressMbps() lb.ChargeType = extLb.GetChargeType() if extLb.GetMetadata() != nil { diff --git a/pkg/compute/regiondrivers/aliyun.go b/pkg/compute/regiondrivers/aliyun.go index 00e6faaeb0..fb44ad01c4 100644 --- a/pkg/compute/regiondrivers/aliyun.go +++ b/pkg/compute/regiondrivers/aliyun.go @@ -44,11 +44,26 @@ func (self *SAliyunRegionDriver) GetProvider() string { } func (self *SAliyunRegionDriver) ValidateCreateLoadbalancerData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { - loadbalancerSpec, _ := data.GetString("loadbalancer_spec") - if len(loadbalancerSpec) != 0 && !utils.IsInStringArray(loadbalancerSpec, []string{"slb.s1.small", "slb.s2.small", "slb.s2.mediu", "slb.s3.small", "slb.s3.mediu", "slb.s3.large"}) { - return nil, httperrors.NewInputParameterError("Unsupport loadbalancer_spec %s, support slb.s1.small、slb.s2.small、slb.s2.medium、slb.s3.small、slb.s3.medium、slb.s3.large", loadbalancerSpec) + loadbalancerSpecV := validators.NewStringChoicesValidator("loadbalancer_spec", api.LB_ALIYUN_SPECS) + loadbalancerSpecV.Default(api.LB_ALIYUN_SPEC_S1_SMALL) + if err := loadbalancerSpecV.Validate(data); err != nil { + return nil, err } - return data, nil + chargeType, _ := data.GetString("charge_type") + if len(chargeType) == 0 { + chargeType = api.LB_CHARGE_TYPE_BY_TRAFFIC + data.Set("charge_type", jsonutils.NewString(chargeType)) + } + if !utils.IsInStringArray(chargeType, []string{api.LB_CHARGE_TYPE_BY_BANDWIDTH, api.LB_CHARGE_TYPE_BY_TRAFFIC}) { + return nil, httperrors.NewInputParameterError("Unsupport charge type %s, only support traffic or bandwidth") + } + if chargeType == api.LB_CHARGE_TYPE_BY_BANDWIDTH { + egressMbps := validators.NewRangeValidator("egress_mbps", 1, 5000) + if err := egressMbps.Validate(data); err != nil { + return nil, err + } + } + return self.ValidateCreateLoadbalancerData(ctx, userCred, data) } func (self *SAliyunRegionDriver) ValidateUpdateLoadbalancerCertificateData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { @@ -158,8 +173,23 @@ func (self *SAliyunRegionDriver) ValidateCreateLoadbalancerListenerData(ctx cont return nil, httperrors.NewInputParameterError("health_check_domain must be in the range of 1 ~ 80") } + egressMbps := 5000 + if lb.ChargeType == api.LB_CHARGE_TYPE_BY_BANDWIDTH { + egressMbps = lb.EgressMbps + } + + listeners, err := lb.GetLoadbalancerListeners() + if err != nil { + return nil, err + } + for _, listener := range listeners { + if listener.EgressMbps > 0 { + egressMbps -= listener.EgressMbps + } + } + keyV := map[string]validators.IValidator{ - "bandwidth": validators.NewRangeValidator("bandwidth", 1, 5000), + "egress_mbps": validators.NewRangeValidator("egress_mbps", -1, int64(egressMbps)).Optional(true), "client_request_timeout": validators.NewRangeValidator("client_request_timeout", 1, 180), diff --git a/pkg/compute/regiondrivers/managedvirtual.go b/pkg/compute/regiondrivers/managedvirtual.go index edec721bd8..f65aa6c16b 100644 --- a/pkg/compute/regiondrivers/managedvirtual.go +++ b/pkg/compute/regiondrivers/managedvirtual.go @@ -16,7 +16,6 @@ package regiondrivers import ( "context" - "database/sql" "fmt" "yunion.io/x/jsonutils" @@ -37,22 +36,13 @@ type SManagedVirtualizationRegionDriver struct { } func (self *SManagedVirtualizationRegionDriver) ValidateCreateLoadbalancerData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { - return data, nil + return self.ValidateManagerId(ctx, userCred, data) } func (self *SManagedVirtualizationRegionDriver) ValidateManagerId(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { - managerID := jsonutils.GetAnyString(data, []string{"manager_id", "manager"}) - if len(managerID) == 0 { - return nil, httperrors.NewMissingParameterError("manager_id") + if managerId, _ := data.GetString("manager_id"); len(managerId) == 0 { + return nil, httperrors.NewMissingParameterError("manager") } - provider, err := models.CloudproviderManager.FetchByIdOrName(userCred, managerID) - if err != nil { - if err == sql.ErrNoRows { - return nil, httperrors.NewResourceNotFoundError("failed to find cloudprovider %s", managerID) - } - return nil, httperrors.NewGeneralError(err) - } - data.Set("manager_id", jsonutils.NewString(provider.GetId())) return data, nil } @@ -61,7 +51,7 @@ func (self *SManagedVirtualizationRegionDriver) ValidateCreateLoadbalancerAclDat } func (self *SManagedVirtualizationRegionDriver) ValidateCreateLoadbalancerCertificateData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { - return data, nil + return self.ValidateManagerId(ctx, userCred, data) } func (self *SManagedVirtualizationRegionDriver) ValidateUpdateLoadbalancerCertificateData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { diff --git a/pkg/mcclient/models/loadbalancers.go b/pkg/mcclient/models/loadbalancers.go index 2fd04718e3..07c70450d2 100644 --- a/pkg/mcclient/models/loadbalancers.go +++ b/pkg/mcclient/models/loadbalancers.go @@ -22,6 +22,7 @@ type Loadbalancer struct { VirtualResource ManagedResource + EgressMbps int Address string AddressType string NetworkType string @@ -68,6 +69,7 @@ type LoadbalancerListener struct { LoadbalancerId string ListenerType string ListenerPort int + EgressMbps int Scheduler string diff --git a/pkg/mcclient/modules/mod_loadbalancerlisteners.go b/pkg/mcclient/modules/mod_loadbalancerlisteners.go index 0eca1b4c79..da5565a48b 100644 --- a/pkg/mcclient/modules/mod_loadbalancerlisteners.go +++ b/pkg/mcclient/modules/mod_loadbalancerlisteners.go @@ -35,6 +35,7 @@ func init() { "listener_type", "listener_port", "backend_port", + "egress_mbps", "acl_status", "acl_type", }, diff --git a/pkg/mcclient/modules/mod_loadbalancers.go b/pkg/mcclient/modules/mod_loadbalancers.go index 5f17e0190e..ac91ecf8e8 100644 --- a/pkg/mcclient/modules/mod_loadbalancers.go +++ b/pkg/mcclient/modules/mod_loadbalancers.go @@ -35,6 +35,9 @@ func init() { "address", "network_type", "network_id", + "charge_type", + "egress_mbps", + "loadbalancer_spec", "cloudregion_id", }, []string{"tenant"}, diff --git a/pkg/mcclient/options/loadbalanceracls.go b/pkg/mcclient/options/loadbalanceracls.go index 30547c4966..42040d5a1e 100644 --- a/pkg/mcclient/options/loadbalanceracls.go +++ b/pkg/mcclient/options/loadbalanceracls.go @@ -70,10 +70,10 @@ func (entries AclEntries) String() string { } type LoadbalancerAclCreateOptions struct { - NAME string - AclEntry []string `help:"acl entry with cidr and comment separated by #, e.g. 10.9.0.0/16#no comment" json:"-"` - ManagerId string `json:"manager_id"` - Region string `json:"cloudregion"` + NAME string + AclEntry []string `help:"acl entry with cidr and comment separated by #, e.g. 10.9.0.0/16#no comment" json:"-"` + Manager string `json:"manager_id"` + Region string `json:"cloudregion"` } type LoadbalancerAclGetOptions struct { diff --git a/pkg/mcclient/options/loadbalancercertificates.go b/pkg/mcclient/options/loadbalancercertificates.go index 7570996cc3..e06571e20c 100644 --- a/pkg/mcclient/options/loadbalancercertificates.go +++ b/pkg/mcclient/options/loadbalancercertificates.go @@ -50,10 +50,10 @@ func loadbalancerCertificateLoadFiles(cert, pkey string, allowEmpty bool) (*json type LoadbalancerCertificateCreateOptions struct { NAME string - Cert string `required:"true" json:"-" help:"path to certificate file"` - Pkey string `required:"true" json:"-" help:"path to private key file"` - Region string `json:"cloudregion"` - ManagerId string + Cert string `required:"true" json:"-" help:"path to certificate file"` + Pkey string `required:"true" json:"-" help:"path to private key file"` + Region string `json:"cloudregion"` + Manager string } func (opts *LoadbalancerCertificateCreateOptions) Params() (*jsonutils.JSONDict, error) { diff --git a/pkg/mcclient/options/loadbalancerlisteners.go b/pkg/mcclient/options/loadbalancerlisteners.go index 31d82cd23a..41e0e5284e 100644 --- a/pkg/mcclient/options/loadbalancerlisteners.go +++ b/pkg/mcclient/options/loadbalancerlisteners.go @@ -34,6 +34,8 @@ type LoadbalancerListenerCreateOptions struct { AclType string `choices:"black|white"` Acl string + EgressMbps int + HealthCheck string `choices:"on|off"` HealthCheckType string `choices:"tcp|http"` diff --git a/pkg/mcclient/options/loadbalancers.go b/pkg/mcclient/options/loadbalancers.go index 0b48a1c758..7889be4a3e 100644 --- a/pkg/mcclient/options/loadbalancers.go +++ b/pkg/mcclient/options/loadbalancers.go @@ -21,8 +21,9 @@ type LoadbalancerCreateOptions struct { AddressType string `choices:"intranet|internet"` LoadbalancerSpec string `choices:"slb.s1.small|slb.s2.small|slb.s2.medium|slb.s3.small|slb.s3.medium|slb.s3.large"` ChargeType string `choices:"traffic|bandwidth"` + Bandwidth int Zone string - ManagerId string + Manager string } type LoadbalancerGetOptions struct { diff --git a/pkg/util/aliyun/loadbalancer.go b/pkg/util/aliyun/loadbalancer.go index d0ec7eae31..3b6c128ee3 100644 --- a/pkg/util/aliyun/loadbalancer.go +++ b/pkg/util/aliyun/loadbalancer.go @@ -259,6 +259,13 @@ func (lb *SLoadbalancer) GetChargeType() string { return "unknown" } +func (lb *SLoadbalancer) GetEgressMbps() int { + if lb.Bandwidth < 1 { + return 0 + } + return lb.Bandwidth +} + func (lb *SLoadbalancer) GetILoadBalancerBackendGroupById(groupId string) (cloudprovider.ICloudLoadbalancerBackendGroup, error) { groups, err := lb.GetILoadBalancerBackendGroups() if err != nil { diff --git a/pkg/util/aliyun/loadbalancerhttplistener.go b/pkg/util/aliyun/loadbalancerhttplistener.go index 8a766bbf8b..0b57847434 100644 --- a/pkg/util/aliyun/loadbalancerhttplistener.go +++ b/pkg/util/aliyun/loadbalancerhttplistener.go @@ -109,6 +109,13 @@ func (listerner *SLoadbalancerHTTPListener) IsEmulated() bool { return false } +func (listerner *SLoadbalancerHTTPListener) GetEgressMbps() int { + if listerner.Bandwidth < 1 { + return 0 + } + return listerner.Bandwidth +} + func (listerner *SLoadbalancerHTTPListener) Refresh() error { lis, err := listerner.lb.region.GetLoadbalancerHTTPListener(listerner.lb.LoadBalancerId, listerner.ListenerPort) if err != nil { diff --git a/pkg/util/aliyun/loadbalancerhttpslistener.go b/pkg/util/aliyun/loadbalancerhttpslistener.go index efc22c90a2..2c7bb83a52 100644 --- a/pkg/util/aliyun/loadbalancerhttpslistener.go +++ b/pkg/util/aliyun/loadbalancerhttpslistener.go @@ -104,6 +104,13 @@ func (listerner *SLoadbalancerHTTPSListener) IsEmulated() bool { return false } +func (listerner *SLoadbalancerHTTPSListener) GetEgressMbps() int { + if listerner.Bandwidth < 1 { + return 0 + } + return listerner.Bandwidth +} + func (listerner *SLoadbalancerHTTPSListener) Refresh() error { lis, err := listerner.lb.region.GetLoadbalancerHTTPSListener(listerner.lb.LoadBalancerId, listerner.ListenerPort) if err != nil { diff --git a/pkg/util/aliyun/loadbalancertcplistener.go b/pkg/util/aliyun/loadbalancertcplistener.go index c477a37495..58b1f74488 100644 --- a/pkg/util/aliyun/loadbalancertcplistener.go +++ b/pkg/util/aliyun/loadbalancertcplistener.go @@ -83,6 +83,13 @@ func (listerner *SLoadbalancerTCPListener) GetMetadata() *jsonutils.JSONDict { return nil } +func (listerner *SLoadbalancerTCPListener) GetEgressMbps() int { + if listerner.Bandwidth < 1 { + return 0 + } + return listerner.Bandwidth +} + func (listerner *SLoadbalancerTCPListener) IsEmulated() bool { return false } @@ -229,17 +236,10 @@ func (region *SRegion) GetLoadbalancerTCPListener(loadbalancerId string, listene func (region *SRegion) constructBaseCreateListenerParams(lb *SLoadbalancer, listener *cloudprovider.SLoadbalancerListener) map[string]string { params := map[string]string{} params["RegionId"] = region.RegionId - switch lb.InternetChargeType { - case "paybytraffic": - params["Bandwidth"] = "-1" - case "paybybandwidth": - if lb.Bandwidth > 5000 { - lb.Bandwidth = 5000 - } - params["Bandwidth"] = fmt.Sprintf("%d", lb.Bandwidth) - default: - params["Bandwidth"] = fmt.Sprintf("%d", listener.Bandwidth) + if listener.EgressMbps < 1 { + listener.EgressMbps = -1 } + params["Bandwidth"] = fmt.Sprintf("%d", listener.EgressMbps) params["ListenerPort"] = fmt.Sprintf("%d", listener.ListenerPort) params["LoadBalancerId"] = lb.LoadBalancerId if len(listener.AccessControlListID) > 0 { diff --git a/pkg/util/aliyun/loadbalancerudplistener.go b/pkg/util/aliyun/loadbalancerudplistener.go index 45a3df9562..a0747948dc 100644 --- a/pkg/util/aliyun/loadbalancerudplistener.go +++ b/pkg/util/aliyun/loadbalancerudplistener.go @@ -82,6 +82,13 @@ func (listerner *SLoadbalancerUDPListener) GetMetadata() *jsonutils.JSONDict { return nil } +func (listerner *SLoadbalancerUDPListener) GetEgressMbps() int { + if listerner.Bandwidth < 1 { + return 0 + } + return listerner.Bandwidth +} + func (listerner *SLoadbalancerUDPListener) IsEmulated() bool { return false } diff --git a/pkg/util/aliyun/region.go b/pkg/util/aliyun/region.go index 5db8289939..a08441dc38 100644 --- a/pkg/util/aliyun/region.go +++ b/pkg/util/aliyun/region.go @@ -846,8 +846,12 @@ func (region *SRegion) CreateILoadBalancer(loadbalancer *cloudprovider.SLoadbala params["LoadBalancerSpec"] = loadbalancer.LoadbalancerSpec } - if loadbalancer.Bandwidth > 0 { - params["Bandwidth"] = fmt.Sprintf("%d", loadbalancer.Bandwidth) + if len(loadbalancer.ChargeType) > 0 { + params["InternetChargeType"] = "payby" + loadbalancer.ChargeType + } + + if loadbalancer.ChargeType == api.LB_CHARGE_TYPE_BY_BANDWIDTH && loadbalancer.EgressMbps > 0 { + params["Bandwidth"] = fmt.Sprintf("%d", loadbalancer.EgressMbps) } body, err := region.lbRequest("CreateLoadBalancer", params) diff --git a/pkg/util/qcloud/loadbalancer.go b/pkg/util/qcloud/loadbalancer.go index 1b63f49aff..fe68cef093 100644 --- a/pkg/util/qcloud/loadbalancer.go +++ b/pkg/util/qcloud/loadbalancer.go @@ -75,6 +75,10 @@ func (self *SLoadbalancer) GetChargeType() string { return api.LB_CHARGE_TYPE_BY_HOUR } +func (self *SLoadbalancer) GetEgressMbps() int { + return 0 +} + // https://cloud.tencent.com/document/product/214/30689 func (self *SLoadbalancer) Delete() error { if self.Forward == LB_TYPE_APPLICATION { diff --git a/pkg/util/qcloud/loadbalancer_listener.go b/pkg/util/qcloud/loadbalancer_listener.go index 18f5427e47..5be6e0b472 100644 --- a/pkg/util/qcloud/loadbalancer_listener.go +++ b/pkg/util/qcloud/loadbalancer_listener.go @@ -253,6 +253,10 @@ func (self *SLBListener) IsEmulated() bool { return false } +func (self *SLBListener) GetEgressMbps() int { + return 0 +} + func (self *SLBListener) GetMetadata() *jsonutils.JSONDict { return nil }