Merge pull request #15692 from ioito/hotfix/qx-aws-lb

fix(region): aws lb optimized
This commit is contained in:
Zexi Li
2023-01-03 18:37:26 +08:00
committed by GitHub
23 changed files with 609 additions and 1039 deletions
+1 -1
View File
@@ -81,7 +81,7 @@ require (
k8s.io/client-go v0.19.3
k8s.io/cluster-bootstrap v0.19.3
moul.io/http2curl/v2 v2.3.0
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20221230080227-1e5aa8c05d5e
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20230103095152-d51258a2c88d
yunion.io/x/executor v0.0.0-20211018100936-39a2cd966656
yunion.io/x/jsonutils v1.0.1-0.20220819091305-3bab322ab4fd
yunion.io/x/log v1.0.0
+2 -2
View File
@@ -1158,8 +1158,8 @@ sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20221230080227-1e5aa8c05d5e h1:LoD6Z+y3n4Rg2v38uOOqMx7aAEzkpM0wNLYq+AXsMrg=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20221230080227-1e5aa8c05d5e/go.mod h1:yEMFtIKPyIdIfPzsw7oTcH41JXc8G5StUAQw3ZoGj5I=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20230103095152-d51258a2c88d h1:5QoHFEN4LJ5yXYWRN4L8/HOc+T13VvxivgE/WonNexI=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20230103095152-d51258a2c88d/go.mod h1:yEMFtIKPyIdIfPzsw7oTcH41JXc8G5StUAQw3ZoGj5I=
yunion.io/x/executor v0.0.0-20211018100936-39a2cd966656 h1:0zlZD5uhZoIHgLVAWCz2aHaYk2ZrNsACCYD7R6EIBII=
yunion.io/x/executor v0.0.0-20211018100936-39a2cd966656/go.mod h1:Uxuou9WQIeJXNpy7t2fPLL0BYLvLiMvGQwY7Qc6aSws=
yunion.io/x/jsonutils v0.0.0-20190625054549-a964e1e8a051/go.mod h1:4N0/RVzsYL3kH3WE/H1BjUQdFiWu50JGCFQuuy+Z634=
+2
View File
@@ -335,6 +335,7 @@ const (
LB_SCHEDULER_TCH = compute.LB_SCHEDULER_TCH // 4-tuple-based consistent hash
LB_SCHEDULER_QCH = compute.LB_SCHEDULER_QCH
LB_SCHEDULER_MH = compute.LB_SCHEDULER_MH // maglev consistent hash
LB_SCHEDULER_NOP = "nop" // aws noop
)
var LB_SCHEDULER_TYPES = []string{
@@ -343,6 +344,7 @@ var LB_SCHEDULER_TYPES = []string{
LB_SCHEDULER_WLC,
LB_SCHEDULER_SCH,
LB_SCHEDULER_TCH,
LB_SCHEDULER_NOP,
}
const (
+1 -1
View File
@@ -191,7 +191,7 @@ func (self *LoadbalancerListenerCreateInput) Validate() error {
return httperrors.NewInputParameterError("invalid send_proxy %s", self.SendProxy)
}
if !utils.IsInStringArray(self.Scheduler, LB_SCHEDULER_TYPES) {
return httperrors.NewInputParameterError("invalid sechduler %s", self.Scheduler)
return httperrors.NewInputParameterError("invalid scheduler %s", self.Scheduler)
}
if len(self.StickySession) == 0 {
self.StickySession = LB_BOOL_OFF
+7 -4
View File
@@ -333,6 +333,13 @@ func (man *SLoadbalancerListenerManager) ValidateCreateData(ctx context.Context,
if lbbg.LoadbalancerId != lb.Id {
return nil, httperrors.NewConflictError("backendgroup_id not same with listener's loadbalancer")
}
region, err := lb.GetRegion()
if err != nil {
return nil, errors.Wrapf(err, "GetRegion")
}
if region.Provider == api.CLOUD_PROVIDER_AWS {
input.Scheduler = api.LB_SCHEDULER_NOP
}
err = input.Validate()
if err != nil {
return nil, err
@@ -358,10 +365,6 @@ func (man *SLoadbalancerListenerManager) ValidateCreateData(ctx context.Context,
return nil, err
}
}
region, err := lb.GetRegion()
if err != nil {
return nil, errors.Wrapf(err, "GetRegion")
}
input, err = region.GetDriver().ValidateCreateLoadbalancerListenerData(ctx, userCred, ownerId, input, lb, lbbg)
if err != nil {
return nil, err
-1
View File
@@ -54,7 +54,6 @@ type IRegionDriver interface {
RequestSyncLoadbalancerAcl(ctx context.Context, userCred mcclient.TokenCredential, lbacl *SCachedLoadbalancerAcl, task taskman.ITask) error
IsCertificateBelongToRegion() bool
ValidateCreateLoadbalancerCertificateData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error)
RequestCreateLoadbalancerCertificate(ctx context.Context, userCred mcclient.TokenCredential, lbcert *SCachedLoadbalancerCertificate, task taskman.ITask) error
RequestDeleteLoadbalancerCertificate(ctx context.Context, userCred mcclient.TokenCredential, lbcert *SCachedLoadbalancerCertificate, task taskman.ITask) error
+107 -47
View File
@@ -159,10 +159,6 @@ func (self *SAwsRegionDriver) ValidateCreateLoadbalancerListenerData(ctx context
return input, nil
}
func (self *SAwsRegionDriver) ValidateCreateLoadbalancerCertificateData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
return nil, httperrors.NewNotImplementedError("%s does not currently support creating loadbalancer certificate", self.GetProvider())
}
func (self *SAwsRegionDriver) ValidateUpdateLoadbalancerListenerData(ctx context.Context, userCred mcclient.TokenCredential,
lblis *models.SLoadbalancerListener, input *api.LoadbalancerListenerUpdateInput) (*api.LoadbalancerListenerUpdateInput, error) {
return input, nil
@@ -207,57 +203,121 @@ func (self *SAwsRegionDriver) ValidateUpdateLoadbalancerBackendData(ctx context.
return input, nil
}
func (self *SAwsRegionDriver) RequestCreateLoadbalancerBackend(ctx context.Context, userCred mcclient.TokenCredential, lbb *models.SLoadbalancerBackend, task taskman.ITask) error {
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
return nil, cloudprovider.ErrNotImplemented
})
return nil
}
func (self *SAwsRegionDriver) RequestDeleteLoadbalancerBackend(ctx context.Context, userCred mcclient.TokenCredential, lbb *models.SLoadbalancerBackend, task taskman.ITask) error {
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
return nil, cloudprovider.ErrNotImplemented
})
return nil
}
func (self *SAwsRegionDriver) RequestCreateLoadbalancerListener(ctx context.Context, userCred mcclient.TokenCredential, lblis *models.SLoadbalancerListener, task taskman.ITask) error {
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
return nil, cloudprovider.ErrNotImplemented
lbbg, err := lblis.GetLoadbalancerBackendGroup()
if err != nil {
return nil, errors.Wrapf(err, "GetLoadbalancerBackendGroup")
}
lb, err := lblis.GetLoadbalancer()
if err != nil {
return nil, errors.Wrapf(err, "GetLoadbalancer")
}
iLb, err := lb.GetILoadbalancer(ctx)
if err != nil {
return nil, errors.Wrapf(err, "GetILoadbalancer")
}
if len(lbbg.ExternalId) == 0 {
vpc, err := lb.GetVpc()
if err != nil {
return nil, errors.Wrapf(err, "GetVpc")
}
lbbgOpts := &cloudprovider.SLoadbalancerBackendGroup{
Name: lbbg.Name,
Scheduler: lblis.Scheduler,
Protocol: lblis.ListenerType,
ListenPort: lblis.ListenerPort,
VpcId: vpc.ExternalId,
}
iLbbg, err := iLb.CreateILoadBalancerBackendGroup(lbbgOpts)
if err != nil {
return nil, errors.Wrapf(err, "CreateILoadBalancerBackendGroup")
}
err = db.SetExternalId(lbbg, userCred, iLbbg.GetGlobalId())
if err != nil {
return nil, errors.Wrapf(err, "db.SetExternalId")
}
}
opts := &cloudprovider.SLoadbalancerListenerCreateOptions{
Name: lblis.Name,
Description: lblis.Description,
ListenerType: lblis.ListenerType,
ListenerPort: lblis.ListenerPort,
Scheduler: lblis.Scheduler,
EnableHTTP2: lblis.EnableHttp2,
EgressMbps: lblis.EgressMbps,
EstablishedTimeout: lblis.BackendConnectTimeout,
AccessControlListStatus: lblis.AclStatus,
BackendGroupId: lbbg.ExternalId,
ClientRequestTimeout: lblis.ClientRequestTimeout,
ClientIdleTimeout: lblis.ClientIdleTimeout,
BackendIdleTimeout: lblis.BackendIdleTimeout,
BackendConnectTimeout: lblis.BackendConnectTimeout,
HealthCheckReq: lblis.HealthCheckReq,
HealthCheckExp: lblis.HealthCheckExp,
HealthCheck: lblis.HealthCheck,
HealthCheckType: lblis.HealthCheckType,
HealthCheckTimeout: lblis.HealthCheckTimeout,
HealthCheckDomain: lblis.HealthCheckDomain,
HealthCheckHttpCode: lblis.HealthCheckHttpCode,
HealthCheckURI: lblis.HealthCheckURI,
HealthCheckInterval: lblis.HealthCheckInterval,
HealthCheckRise: lblis.HealthCheckRise,
HealthCheckFail: lblis.HealthCheckFall,
StickySession: lblis.StickySession,
StickySessionType: lblis.StickySessionType,
StickySessionCookie: lblis.StickySessionCookie,
StickySessionCookieTimeout: lblis.StickySessionCookieTimeout,
BackendServerPort: lblis.BackendServerPort,
XForwardedFor: lblis.XForwardedFor,
TLSCipherPolicy: lblis.TLSCipherPolicy,
Gzip: lblis.Gzip,
}
iLis, err := iLb.CreateILoadBalancerListener(ctx, opts)
if err != nil {
return nil, errors.Wrapf(err, "CreateILoadBalancerListener")
}
err = db.SetExternalId(lblis, userCred, iLis.GetGlobalId())
if err != nil {
return nil, errors.Wrapf(err, "lblis.SetExternalId")
}
backends, err := lbbg.GetBackends()
if err != nil {
return nil, errors.Wrapf(err, "GetBackends")
}
if len(backends) == 0 {
return nil, nil
}
iLbbg, err := lbbg.GetICloudLoadbalancerBackendGroup(ctx)
if err != nil {
return nil, errors.Wrapf(err, "GetICloudLoadbalancerBackendGroup")
}
for i := range backends {
_, err := iLbbg.AddBackendServer(backends[i].ExternalId, backends[i].Port, backends[i].Weight)
if err != nil {
return nil, errors.Wrapf(err, "AddBackendServer")
}
}
return nil, nil
})
return nil
}
func (self *SAwsRegionDriver) RequestCreateLoadbalancerListenerRule(ctx context.Context, userCred mcclient.TokenCredential, lbr *models.SLoadbalancerListenerRule, task taskman.ITask) error {
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
return nil, cloudprovider.ErrNotImplemented
})
return nil
func (self *SAwsRegionDriver) RequestStartLoadbalancerListener(ctx context.Context, userCred mcclient.TokenCredential, lblis *models.SLoadbalancerListener, task taskman.ITask) error {
return task.ScheduleRun(nil)
}
func (self *SAwsRegionDriver) RequestDeleteLoadbalancerBackendGroup(ctx context.Context, userCred mcclient.TokenCredential, lbbg *models.SLoadbalancerBackendGroup, task taskman.ITask) error {
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
return nil, cloudprovider.ErrNotImplemented
})
return nil
}
func (self *SAwsRegionDriver) RequestDeleteLoadbalancer(ctx context.Context, userCred mcclient.TokenCredential, lb *models.SLoadbalancer, task taskman.ITask) error {
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
return nil, cloudprovider.ErrNotImplemented
})
return nil
}
func (self *SAwsRegionDriver) RequestSyncLoadbalancerListener(ctx context.Context, userCred mcclient.TokenCredential, lblis *models.SLoadbalancerListener, task taskman.ITask) error {
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
return nil, cloudprovider.ErrNotImplemented
})
return nil
}
func (self *SAwsRegionDriver) RequestSyncLoadbalancerBackendGroup(ctx context.Context, userCred mcclient.TokenCredential, lblis *models.SLoadbalancerListener, task taskman.ITask) error {
return cloudprovider.ErrNotImplemented
func (self *SAwsRegionDriver) RequestCreateLoadbalancerBackendGroup(ctx context.Context, userCred mcclient.TokenCredential, lbbg *models.SLoadbalancerBackendGroup, task taskman.ITask) error {
return task.ScheduleRun(nil)
}
func (self *SAwsRegionDriver) IsSecurityGroupBelongVpc() bool {
-4
View File
@@ -50,10 +50,6 @@ func (self *SAzureRegionDriver) GenerateSecurityGroupName(name string) string {
return pinyinutils.Text2Pinyin(name)
}
func (self *SAzureRegionDriver) ValidateCreateLoadbalancerCertificateData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
return nil, httperrors.NewNotImplementedError("%s does not currently support creating loadbalancer certificate", self.GetProvider())
}
func (self *SAzureRegionDriver) IsSupportClassicSecurityGroup() bool {
return true
}
-6
View File
@@ -20,12 +20,10 @@ import (
"strings"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/util/secrules"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
)
@@ -65,10 +63,6 @@ func (self *SBingoCloudRegionDriver) GetDefaultSecurityGroupOutRule() cloudprovi
return cloudprovider.SecurityRule{SecurityRule: *secrules.MustParseSecurityRule("out:deny any")}
}
func (self *SBingoCloudRegionDriver) ValidateCreateLoadbalancerCertificateData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
return nil, httperrors.NewNotImplementedError("%s does not support creating loadbalancer certificate", self.GetProvider())
}
func (self *SBingoCloudRegionDriver) ValidateCreateSnapshotData(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, storage *models.SStorage, input *api.SnapshotCreateInput) error {
return fmt.Errorf("%s does not support creating snapshot", self.GetProvider())
}
-5
View File
@@ -25,7 +25,6 @@ import (
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
)
@@ -42,10 +41,6 @@ func (self *SEsxiRegionDriver) GetProvider() string {
return api.CLOUD_PROVIDER_VMWARE
}
func (self *SEsxiRegionDriver) ValidateCreateLoadbalancerCertificateData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
return nil, httperrors.NewNotImplementedError("%s does not support creating loadbalancer certificate", self.GetProvider())
}
func (self *SEsxiRegionDriver) ValidateCreateSnapshotData(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, storage *models.SStorage, input *api.SnapshotCreateInput) error {
return fmt.Errorf("%s does not support creating snapshot", self.GetProvider())
}
-4
View File
@@ -184,10 +184,6 @@ func (self *SKVMRegionDriver) ValidateCreateLoadbalancerData(ctx context.Context
return input, nil
}
func (self *SKVMRegionDriver) ValidateCreateLoadbalancerCertificateData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
return data, nil
}
func (self *SKVMRegionDriver) ValidateCreateLoadbalancerBackendGroupData(ctx context.Context, userCred mcclient.TokenCredential, lb *models.SLoadbalancer, input *api.LoadbalancerBackendGroupCreateInput) (*api.LoadbalancerBackendGroupCreateInput, error) {
return input, nil
}
-7
View File
@@ -18,11 +18,8 @@ import (
"context"
"fmt"
"yunion.io/x/jsonutils"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
)
@@ -39,10 +36,6 @@ func (self *SNutanixRegionDriver) GetProvider() string {
return api.CLOUD_PROVIDER_NUTANIX
}
func (self *SNutanixRegionDriver) ValidateCreateLoadbalancerCertificateData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
return nil, httperrors.NewNotImplementedError("%s does not support creating loadbalancer certificate", self.GetProvider())
}
func (self *SNutanixRegionDriver) ValidateCreateSnapshotData(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, storage *models.SStorage, input *api.SnapshotCreateInput) error {
return fmt.Errorf("%s does not support creating snapshot", self.GetProvider())
}
-4
View File
@@ -99,10 +99,6 @@ func (self *SOpenStackRegionDriver) RequestCreateLoadbalancerAcl(ctx context.Con
return nil
}
func (self *SOpenStackRegionDriver) ValidateCreateLoadbalancerCertificateData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
return nil, httperrors.NewNotImplementedError("%s does not currently support creating loadbalancer certificate", self.GetProvider())
}
func (self *SOpenStackRegionDriver) ValidateCreateEipData(ctx context.Context, userCred mcclient.TokenCredential, input *api.SElasticipCreateInput) error {
if len(input.NetworkId) == 0 {
return httperrors.NewMissingParameterError("network_id")
-4
View File
@@ -65,10 +65,6 @@ func (self *SUcloudRegionDriver) GetProvider() string {
return api.CLOUD_PROVIDER_UCLOUD
}
func (self *SUcloudRegionDriver) ValidateCreateLoadbalancerCertificateData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
return nil, httperrors.NewNotImplementedError("%s does not currently support creating loadbalancer certificate", self.GetProvider())
}
func (self *SUcloudRegionDriver) ValidateCreateVpcData(ctx context.Context, userCred mcclient.TokenCredential, input api.VpcCreateInput) (api.VpcCreateInput, error) {
var cidrV = validators.NewIPv4PrefixValidator("cidr_block")
if err := cidrV.Validate(jsonutils.Marshal(input).(*jsonutils.JSONDict)); err != nil {
-5
View File
@@ -19,7 +19,6 @@ import (
"database/sql"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/util/secrules"
api "yunion.io/x/onecloud/pkg/apis/compute"
@@ -69,10 +68,6 @@ func (self *SZStackRegionDriver) GetProvider() string {
return api.CLOUD_PROVIDER_ZSTACK
}
func (self *SZStackRegionDriver) ValidateCreateLoadbalancerCertificateData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
return nil, httperrors.NewNotImplementedError("%s does not currently support creating loadbalancer certificate", self.GetProvider())
}
func (self *SZStackRegionDriver) ValidateCreateEipData(ctx context.Context, userCred mcclient.TokenCredential, input *api.SElasticipCreateInput) error {
if len(input.NetworkId) == 0 {
return httperrors.NewMissingParameterError("network_id")
+1 -1
View File
@@ -1439,7 +1439,7 @@ sigs.k8s.io/structured-merge-diff/v4/value
# sigs.k8s.io/yaml v1.2.0
## explicit; go 1.12
sigs.k8s.io/yaml
# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20221230080227-1e5aa8c05d5e
# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20230103095152-d51258a2c88d
## explicit; go 1.18
yunion.io/x/cloudmux/pkg/apis
yunion.io/x/cloudmux/pkg/apis/billing
+5
View File
@@ -58,6 +58,11 @@ const (
LB_BACKENDGROUP_TYPE_MASTER_SLAVE = "master_slave"
)
const (
LB_AWS_SPEC_APPLICATION = "application"
LB_AWS_SPEC_NETWORK = "network"
)
// Load Balancer network type (vpc or classic) determines viable backend
// servers (they should be from the same network type as the load balancer).
//
+182 -182
View File
@@ -21,8 +21,6 @@ import (
"strconv"
"strings"
"github.com/aws/aws-sdk-go/service/elbv2"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
@@ -37,37 +35,42 @@ import (
https://docs.aws.amazon.com/elasticloadbalancing/latest/APIReference/Welcome.html
*/
type SElbs struct {
LoadBalancers []SElb `xml:"LoadBalancers>member"`
NextMarker string `xml:"NextMarker"`
}
type SElb struct {
multicloud.SResourceBase
multicloud.SVirtualResourceBase
region *SRegion
Type string `json:"Type"`
Scheme string `json:"Scheme"`
IPAddressType string `json:"IpAddressType"`
VpcID string `json:"VpcId"`
AvailabilityZones []AvailabilityZone `json:"AvailabilityZones"`
CreatedTime string `json:"CreatedTime"`
CanonicalHostedZoneID string `json:"CanonicalHostedZoneId"`
DNSName string `json:"DNSName"`
SecurityGroups []string `json:"SecurityGroups"`
LoadBalancerName string `json:"LoadBalancerName"`
State State `json:"State"`
LoadBalancerArn string `json:"LoadBalancerArn"`
Type string `xml:"Type"`
Scheme string `xml:"Scheme"`
IPAddressType string `xml:"IpAddressType"`
VpcId string `xml:"VpcId"`
AvailabilityZones []AvailabilityZone `xml:"AvailabilityZones>member"`
CreatedTime string `xml:"CreatedTime"`
CanonicalHostedZoneID string `xml:"CanonicalHostedZoneId"`
DNSName string `xml:"DNSName"`
SecurityGroups []string `xml:"SecurityGroups>member"`
LoadBalancerName string `xml:"LoadBalancerName"`
State State `xml:"State"`
LoadBalancerArn string `xml:"LoadBalancerArn"`
}
type AvailabilityZone struct {
LoadBalancerAddresses []LoadBalancerAddress `json:"LoadBalancerAddresses"`
ZoneName string `json:"ZoneName"`
SubnetID string `json:"SubnetId"`
LoadBalancerAddresses []LoadBalancerAddress `xml:"LoadBalancerAddresses"`
ZoneName string `xml:"ZoneName"`
SubnetId string `xml:"SubnetId"`
}
type LoadBalancerAddress struct {
IPAddress string `json:"IpAddress"`
AllocationID string `json:"AllocationId"`
IPAddress string `xml:"IpAddress"`
AllocationID string `xml:"AllocationId"`
}
type State struct {
Code string `json:"Code"`
Code string `xml:"Code"`
}
func (self *SElb) GetId() string {
@@ -96,29 +99,18 @@ func (self *SElb) GetStatus() string {
}
func (self *SElb) Refresh() error {
ielb, err := self.region.GetILoadBalancerById(self.GetId())
lb, err := self.region.GetLoadBalancer(self.GetId())
if err != nil {
return err
}
err = jsonutils.Update(self, ielb)
if err != nil {
return err
}
return nil
}
func (self *SElb) IsEmulated() bool {
return false
return jsonutils.Update(self, lb)
}
func (self *SElb) GetSysTags() map[string]string {
data := map[string]string{}
data["loadbalance_type"] = self.Type
attrs, err := self.region.getElbAttributesById(self.GetId())
attrs, err := self.region.GetElbAttributes(self.GetId())
if err != nil {
log.Errorf("SElb GetSysTags %s", err)
return data
}
@@ -129,15 +121,7 @@ func (self *SElb) GetSysTags() map[string]string {
}
func (self *SElb) GetTags() (map[string]string, error) {
tags, err := self.region.FetchElbTags(self.LoadBalancerArn)
if err != nil {
return nil, errors.Wrap(err, "self.region.FetchElbTags")
}
return tags, nil
}
func (self *SElb) GetProjectId() string {
return ""
return self.region.FetchElbTags(self.LoadBalancerArn)
}
func (self *SElb) GetAddress() string {
@@ -162,14 +146,14 @@ func (self *SElb) GetNetworkType() string {
func (self *SElb) GetNetworkIds() []string {
ret := []string{}
for i := range self.AvailabilityZones {
ret = append(ret, self.AvailabilityZones[i].SubnetID)
ret = append(ret, self.AvailabilityZones[i].SubnetId)
}
return ret
}
func (self *SElb) GetVpcId() string {
return self.VpcID
return self.VpcId
}
func (self *SElb) GetZoneId() string {
@@ -221,33 +205,41 @@ func (self *SElb) Stop() error {
}
func (self *SElb) GetILoadBalancerListeners() ([]cloudprovider.ICloudLoadbalancerListener, error) {
listeners, err := self.region.GetElbListeners(self.GetId())
if err != nil {
return nil, errors.Wrap(err, "GetElbListeners")
ret := []cloudprovider.ICloudLoadbalancerListener{}
marker := ""
for {
part, marker, err := self.region.GetElbListeners(self.LoadBalancerArn, "", marker)
if err != nil {
return nil, err
}
for i := range part {
part[i].lb = self
ret = append(ret, &part[i])
}
if len(marker) == 0 || len(part) == 0 {
break
}
}
ret := make([]cloudprovider.ICloudLoadbalancerListener, len(listeners))
for i := range listeners {
listeners[i].lb = self
ret[i] = &listeners[i]
}
return ret, nil
}
func (self *SElb) GetILoadBalancerBackendGroups() ([]cloudprovider.ICloudLoadbalancerBackendGroup, error) {
backendgroups, err := self.region.GetElbBackendgroups(self.GetId(), nil)
if err != nil {
return nil, errors.Wrap(err, "GetElbBackendgroups")
ret := []cloudprovider.ICloudLoadbalancerBackendGroup{}
marker := ""
for {
part, marker, err := self.region.GetElbBackendgroups(self.LoadBalancerArn, "", marker)
if err != nil {
return nil, errors.Wrapf(err, "GetElbBackendgroups")
}
for i := range part {
part[i].lb = self
ret = append(ret, &part[i])
}
if len(marker) == 0 || len(part) == 0 {
break
}
}
ibackendgroups := make([]cloudprovider.ICloudLoadbalancerBackendGroup, len(backendgroups))
for i := range backendgroups {
backendgroups[i].lb = self
ibackendgroups[i] = &backendgroups[i]
}
return ibackendgroups, nil
return ret, nil
}
func (self *SElb) CreateILoadBalancerBackendGroup(group *cloudprovider.SLoadbalancerBackendGroup) (cloudprovider.ICloudLoadbalancerBackendGroup, error) {
@@ -261,7 +253,12 @@ func (self *SElb) CreateILoadBalancerBackendGroup(group *cloudprovider.SLoadbala
}
func (self *SElb) GetILoadBalancerBackendGroupById(groupId string) (cloudprovider.ICloudLoadbalancerBackendGroup, error) {
return self.region.GetElbBackendgroup(groupId)
lbbg, err := self.region.GetElbBackendgroup(groupId)
if err != nil {
return nil, err
}
lbbg.lb = self
return lbbg, nil
}
func (self *SElb) CreateILoadBalancerListener(ctx context.Context, listener *cloudprovider.SLoadbalancerListenerCreateOptions) (cloudprovider.ICloudLoadbalancerListener, error) {
@@ -275,100 +272,53 @@ func (self *SElb) CreateILoadBalancerListener(ctx context.Context, listener *clo
}
func (self *SElb) GetILoadBalancerListenerById(listenerId string) (cloudprovider.ICloudLoadbalancerListener, error) {
if listenerId == "" {
return nil, errors.Wrap(cloudprovider.ErrNotFound, "GetILoadBalancerListenerById")
lis, err := self.region.GetElbListener(listenerId)
if err != nil {
return nil, err
}
return self.region.GetElbListener(listenerId)
lis.lb = self
return lis, nil
}
func (self *SElb) GetIEIP() (cloudprovider.ICloudEIP, error) {
return nil, nil
}
func (self *SRegion) DeleteElb(elbId string) error {
client, err := self.GetElbV2Client()
if err != nil {
return errors.Wrap(err, "GetElbV2Client")
}
params := &elbv2.DeleteLoadBalancerInput{}
params.SetLoadBalancerArn(elbId)
_, err = client.DeleteLoadBalancer(params)
if err != nil {
return errors.Wrap(err, "DeleteLoadBalancer")
}
return nil
func (self *SRegion) DeleteElb(id string) error {
params := map[string]string{"LoadBalancerArn": id}
return self.elbRequest("DeleteLoadBalancer", params, nil)
}
func (self *SRegion) GetElbBackendgroups(elbId string, backendgroupIds []string) ([]SElbBackendGroup, error) {
client, err := self.GetElbV2Client()
if err != nil {
return nil, errors.Wrap(err, "GetElbV2Client")
}
params := &elbv2.DescribeTargetGroupsInput{}
func (self *SRegion) GetElbBackendgroups(elbId, id, marker string) ([]SElbBackendGroup, string, error) {
params := map[string]string{}
if len(elbId) > 0 {
params.SetLoadBalancerArn(elbId)
params["LoadBalancerArn"] = elbId
}
if len(backendgroupIds) > 0 {
v := make([]*string, len(backendgroupIds))
for i := range backendgroupIds {
v[i] = &backendgroupIds[i]
}
params.SetTargetGroupArns(v)
if len(marker) > 0 {
params["Marker"] = marker
}
ret, err := client.DescribeTargetGroups(params)
if len(id) > 0 {
params["TargetGroupArns.member.1"] = id
}
ret := &SElbBackendGroups{}
err := self.elbRequest("DescribeTargetGroups", params, ret)
if err != nil {
return nil, errors.Wrap(err, "DescribeTargetGroups")
return nil, "", errors.Wrapf(err, "DescribeTargetGroups")
}
backendgroups := []SElbBackendGroup{}
err = unmarshalAwsOutput(ret, "TargetGroups", &backendgroups)
if err != nil {
return nil, errors.Wrap(err, "unmarshalAwsOutput.TargetGroups")
}
for i := range backendgroups {
backendgroups[i].region = self
}
return backendgroups, nil
return ret.TargetGroups, ret.NextMarker, nil
}
func (self *SRegion) GetElbBackendgroup(backendgroupId string) (*SElbBackendGroup, error) {
client, err := self.GetElbV2Client()
func (self *SRegion) GetElbBackendgroup(id string) (*SElbBackendGroup, error) {
groups, _, err := self.GetElbBackendgroups("", id, "")
if err != nil {
return nil, errors.Wrap(err, "GetElbV2Client")
return nil, err
}
params := &elbv2.DescribeTargetGroupsInput{}
params.SetTargetGroupArns([]*string{&backendgroupId})
ret, err := client.DescribeTargetGroups(params)
if err != nil {
if strings.Contains(err.Error(), "TargetGroupNotFound") {
return nil, cloudprovider.ErrNotFound
for i := range groups {
if groups[i].TargetGroupArn == id {
return &groups[i], nil
}
return nil, errors.Wrap(err, "DescribeTargetGroups")
}
backendgroups := []SElbBackendGroup{}
err = unmarshalAwsOutput(ret, "TargetGroups", &backendgroups)
if err != nil {
return nil, errors.Wrap(err, "unmarshalAwsOutput.TargetGroups")
}
if len(backendgroups) == 1 {
backendgroups[0].region = self
return &backendgroups[0], nil
}
return nil, errors.Wrap(cloudprovider.ErrNotFound, "GetElbBackendgroup")
return nil, errors.Wrapf(cloudprovider.ErrNotFound, id)
}
func ToAwsHealthCode(s string) string {
@@ -422,35 +372,22 @@ func ToOnecloudHealthCode(s string) string {
// 目前只支持target type :instance
func (self *SRegion) CreateElbBackendgroup(opts *cloudprovider.SLoadbalancerBackendGroup) (*SElbBackendGroup, error) {
params := &elbv2.CreateTargetGroupInput{}
params.SetProtocol(strings.ToUpper(opts.Protocol))
params.SetPort(int64(opts.ListenPort))
params.SetVpcId(opts.VpcId)
params.SetName(opts.Name)
params.SetTargetType("instance")
client, err := self.GetElbV2Client()
params := map[string]string{
"Protocol": strings.ToUpper(opts.Protocol),
"Name": opts.Name,
"Port": fmt.Sprintf("%d", opts.ListenPort),
"TargetType": "instance",
"VpcId": opts.VpcId,
}
ret := &SElbBackendGroups{}
err := self.elbRequest("CreateTargetGroup", params, ret)
if err != nil {
return nil, errors.Wrap(err, "GetElbV2Client")
return nil, err
}
ret, err := client.CreateTargetGroup(params)
if err != nil {
return nil, errors.Wrap(err, "CreateTargetGroup")
for i := range ret.TargetGroups {
return &ret.TargetGroups[i], nil
}
backendgroups := []SElbBackendGroup{}
err = unmarshalAwsOutput(ret, "TargetGroups", &backendgroups)
if err != nil {
return nil, errors.Wrap(err, "unmarshalAwsOutput.TargetGroups")
}
if len(backendgroups) == 1 {
backendgroups[0].region = self
return &backendgroups[0], nil
}
return nil, fmt.Errorf("CreateElbBackendgroup error: %#v", backendgroups)
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "after created")
}
func (self *SElb) SetTags(tags map[string]string, replace bool) error {
@@ -466,26 +403,89 @@ func (self *SElb) SetTags(tags map[string]string, replace bool) error {
}
func (self *SRegion) FetchElbTags(arn string) (map[string]string, error) {
client, err := self.GetElbV2Client()
ret := struct {
TagDescriptions []struct {
ResourceArn string `xml:"ResourceArn"`
Tags []struct {
Key string
Value string
} `xml:"Tags>member"`
} `xml:"TagDescriptions>member"`
}{}
err := self.elbRequest("DescribeTags", map[string]string{"ResourceArns.member.1": arn}, &ret)
if err != nil {
return nil, errors.Wrap(err, "GetElbV2Client")
}
params := elbv2.DescribeTagsInput{}
params.SetResourceArns([]*string{&arn})
output, err := client.DescribeTags(&params)
if err != nil {
return nil, errors.Wrapf(err, "client.DescribeTags(%s)", jsonutils.Marshal(params).String())
return nil, errors.Wrapf(err, "DescribeTags")
}
result := map[string]string{}
for i := range output.TagDescriptions {
if output.TagDescriptions[i].ResourceArn != nil && *output.TagDescriptions[i].ResourceArn == arn {
for j := range output.TagDescriptions[i].Tags {
if output.TagDescriptions[i].Tags[j].Key != nil && output.TagDescriptions[i].Tags[j].Value != nil {
result[*output.TagDescriptions[i].Tags[j].Key] = *output.TagDescriptions[i].Tags[j].Value
}
for _, res := range ret.TagDescriptions {
if res.ResourceArn == arn {
for _, tag := range res.Tags {
result[tag.Key] = tag.Value
}
return result, nil
}
}
return nil, cloudprovider.ErrNotFound
}
func (self *SRegion) GetLoadbalancers(id, marker string) ([]SElb, string, error) {
ret := &SElbs{}
params := map[string]string{}
if len(id) > 0 {
params["LoadBalancerArns.member.1"] = id
}
if len(marker) > 0 {
params["Marker"] = marker
}
err := self.elbRequest("DescribeLoadBalancers", params, ret)
if err != nil {
return nil, "", errors.Wrapf(err, "DescribeLoadBalancers")
}
return ret.LoadBalancers, ret.NextMarker, nil
}
func (self *SRegion) CreateLoadbalancer(opts *cloudprovider.SLoadbalancerCreateOptions) (*SElb, error) {
ret := &SElbs{}
params := map[string]string{
"Name": opts.Name,
"Type": opts.LoadbalancerSpec,
"Scheme": "internal",
"IpAddressType": "ipv4",
}
if opts.AddressType == api.LB_ADDR_TYPE_INTERNET {
params["Scheme"] = "internet-facing"
}
if opts.LoadbalancerSpec == api.LB_AWS_SPEC_APPLICATION && len(opts.NetworkIds) == 1 {
nets, err := self.GetNetwroks(nil, opts.VpcId)
if err != nil {
return nil, errors.Wrapf(err, "GetNetworks(%s)", opts.VpcId)
}
for i := range nets {
if !utils.IsInStringArray(nets[i].NetworkId, opts.NetworkIds) && nets[i].ZoneId != opts.ZoneId {
opts.NetworkIds = append(opts.NetworkIds, nets[i].NetworkId)
break
}
}
}
for i, net := range opts.NetworkIds {
params[fmt.Sprintf("Subnets.member.%d", i+1)] = net
}
idx := 1
for k, v := range opts.Tags {
params[fmt.Sprintf("Tags.member.%d.Key", idx)] = k
params[fmt.Sprintf("Tags.member.%d.Value", idx)] = v
idx++
}
err := self.elbRequest("CreateLoadBalancer", params, ret)
if err != nil {
return nil, errors.Wrapf(err, "CreateLoadBalancer")
}
for i := range ret.LoadBalancers {
ret.LoadBalancers[i].region = self
return &ret.LoadBalancers[i], nil
}
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "after created")
}
+6 -3
View File
@@ -22,11 +22,14 @@ import (
"yunion.io/x/cloudmux/pkg/multicloud"
)
type SElbBackends struct {
TargetHealthDescriptions []SElbBackend `xml:"TargetHealthDescriptions>member"`
}
type SElbBackend struct {
multicloud.SResourceBase
AwsTags
region *SRegion
group *SElbBackendGroup
group *SElbBackendGroup
Target Target `json:"Target"`
TargetHealth TargetHealth `json:"TargetHealth"`
@@ -92,7 +95,7 @@ func (self *SElbBackend) GetBackendId() string {
}
func (self *SElbBackend) SyncConf(ctx context.Context, port, weight int) error {
return self.region.SyncElbBackend(self.GetId(), self.GetBackendId(), self.Target.Port, port)
return self.group.lb.region.SyncElbBackend(self.GetId(), self.GetBackendId(), self.Target.Port, port)
}
func (self *SElbBackend) GetIpAddress() string {
+86 -265
View File
@@ -20,47 +20,39 @@ import (
"strconv"
"strings"
"github.com/aws/aws-sdk-go/service/elbv2"
"github.com/pkg/errors"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/utils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/cloudmux/pkg/apis/compute"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/cloudmux/pkg/multicloud"
)
type SElbBackendGroups struct {
NextMarker string
TargetGroups []SElbBackendGroup `xml:"TargetGroups>member"`
}
type SElbBackendGroup struct {
multicloud.SResourceBase
AwsTags
region *SRegion
lb *SElb
lb *SElb
TargetGroupName string `json:"TargetGroupName"`
Protocol string `json:"Protocol"`
Port int64 `json:"Port"`
VpcID string `json:"VpcId"`
TargetType string `json:"TargetType"`
HealthyThresholdCount int `json:"HealthyThresholdCount"`
Matcher Matcher `json:"Matcher"`
UnhealthyThresholdCount int `json:"UnhealthyThresholdCount"`
HealthCheckPath string `json:"HealthCheckPath"`
HealthCheckProtocol string `json:"HealthCheckProtocol"`
HealthCheckPort string `json:"HealthCheckPort"`
HealthCheckIntervalSeconds int `json:"HealthCheckIntervalSeconds"`
HealthCheckTimeoutSeconds int `json:"HealthCheckTimeoutSeconds"`
TargetGroupArn string `json:"TargetGroupArn"`
LoadBalancerArns []string `json:"LoadBalancerArns"`
}
func (self *SElbBackendGroup) GetLoadbalancerId() string {
if len(self.LoadBalancerArns) > 0 {
return self.LoadBalancerArns[0]
}
return ""
TargetGroupName string `xml:"TargetGroupName"`
Protocol string `xml:"Protocol"`
Port int64 `xml:"Port"`
VpcID string `xml:"VpcId"`
TargetType string `xml:"TargetType"`
HealthyThresholdCount int `xml:"HealthyThresholdCount"`
Matcher Matcher `xml:"Matcher"`
UnhealthyThresholdCount int `xml:"UnhealthyThresholdCount"`
HealthCheckPath string `xml:"HealthCheckPath"`
HealthCheckProtocol string `xml:"HealthCheckProtocol"`
HealthCheckPort string `xml:"HealthCheckPort"`
HealthCheckIntervalSeconds int `xml:"HealthCheckIntervalSeconds"`
HealthCheckTimeoutSeconds int `xml:"HealthCheckTimeoutSeconds"`
TargetGroupArn string `xml:"TargetGroupArn"`
LoadBalancerArns []string `xml:"LoadBalancerArns>member"`
}
func (self *SElbBackendGroup) GetILoadbalancer() cloudprovider.ICloudLoadbalancer {
@@ -88,21 +80,11 @@ func (self *SElbBackendGroup) GetStatus() string {
}
func (self *SElbBackendGroup) Refresh() error {
lbbg, err := self.region.GetElbBackendgroup(self.GetId())
lbbg, err := self.lb.region.GetElbBackendgroup(self.GetId())
if err != nil {
return err
}
err = jsonutils.Update(self, lbbg)
if err != nil {
return err
}
return nil
}
func (self *SElbBackendGroup) IsEmulated() bool {
return false
return jsonutils.Update(self, lbbg)
}
func (self *SElbBackendGroup) GetSysTags() map[string]string {
@@ -127,14 +109,13 @@ func (self *SElbBackendGroup) GetType() string {
}
func (self *SElbBackendGroup) GetILoadbalancerBackends() ([]cloudprovider.ICloudLoadbalancerBackend, error) {
backends, err := self.region.GetELbBackends(self.GetId())
backends, err := self.lb.region.GetELbBackends(self.GetId())
if err != nil {
return nil, errors.Wrap(err, "GetELbBackends")
}
ibackends := make([]cloudprovider.ICloudLoadbalancerBackend, len(backends))
for i := range backends {
backends[i].region = self.region
backends[i].group = self
ibackends[i] = &backends[i]
}
@@ -143,7 +124,7 @@ func (self *SElbBackendGroup) GetILoadbalancerBackends() ([]cloudprovider.ICloud
}
func (self *SElbBackendGroup) GetILoadbalancerBackendById(backendId string) (cloudprovider.ICloudLoadbalancerBackend, error) {
backend, err := self.region.GetELbBackend(backendId)
backend, err := self.lb.region.GetELbBackend(backendId)
if err != nil {
return nil, errors.Wrap(err, "GetELbBackend")
}
@@ -187,9 +168,9 @@ func (self *SElbBackendGroup) GetHealthCheck() (*cloudprovider.SLoadbalancerHeal
}
func (self *SElbBackendGroup) GetStickySession() (*cloudprovider.SLoadbalancerStickySession, error) {
attrs, err := self.region.GetElbBackendgroupAttributesById(self.GetId())
attrs, err := self.lb.region.GetElbBackendgroupAttributes(self.GetId())
if err != nil {
return nil, errors.Wrap(err, "GetElbBackendgroupAttributesById")
return nil, errors.Wrap(err, "GetElbBackendgroupAttributes")
}
cookieTime := 0
@@ -208,22 +189,21 @@ func (self *SElbBackendGroup) GetStickySession() (*cloudprovider.SLoadbalancerSt
}
func (self *SElbBackendGroup) AddBackendServer(serverId string, weight int, port int) (cloudprovider.ICloudLoadbalancerBackend, error) {
backend, err := self.region.AddElbBackend(self.GetId(), serverId, weight, port)
backend, err := self.lb.region.AddElbBackend(self.GetId(), serverId, weight, port)
if err != nil {
return nil, errors.Wrap(err, "AddElbBackend")
}
backend.region = self.region
backend.group = self
return backend, nil
}
func (self *SElbBackendGroup) RemoveBackendServer(serverId string, weight int, port int) error {
return self.region.RemoveElbBackend(self.GetId(), serverId, weight, port)
return self.lb.region.RemoveElbBackend(self.GetId(), serverId, weight, port)
}
func (self *SElbBackendGroup) Delete(ctx context.Context) error {
return self.region.DeleteElbBackendGroup(self.GetId())
return self.lb.region.DeleteElbBackendGroup(self.GetId())
}
func (self *SElbBackendGroup) Sync(ctx context.Context, group *cloudprovider.SLoadbalancerBackendGroup) error {
@@ -231,76 +211,38 @@ func (self *SElbBackendGroup) Sync(ctx context.Context, group *cloudprovider.SLo
}
func (self *SRegion) GetELbBackends(backendgroupId string) ([]SElbBackend, error) {
client, err := self.GetElbV2Client()
params := map[string]string{
"TargetGroupArn": backendgroupId,
}
ret := &SElbBackends{}
err := self.elbRequest("DescribeTargetHealth", params, ret)
if err != nil {
return nil, errors.Wrap(err, "GetElbV2Client")
return nil, err
}
group, err := self.GetElbBackendgroup(backendgroupId)
if err != nil {
return nil, errors.Wrap(err, "GetElbBackendgroup")
}
params := &elbv2.DescribeTargetHealthInput{}
params.SetTargetGroupArn(backendgroupId)
output, err := client.DescribeTargetHealth(params)
if err != nil {
return nil, errors.Wrap(err, "DescribeTargetHealth")
}
backends := []SElbBackend{}
err = unmarshalAwsOutput(output, "TargetHealthDescriptions", &backends)
if err != nil {
return nil, errors.Wrap(err, "unmarshalAwsOutput.TargetHealthDescriptions")
}
ret := []SElbBackend{}
for i := range backends {
if !utils.IsInStringArray(backends[i].TargetHealth.Reason, []string{"Target.InvalidState", "Target.NotInUse", "Target.DeregistrationInProgress"}) {
backends[i].region = self
backends[i].group = group
ret = append(ret, backends[i])
}
}
return ret, nil
return ret.TargetHealthDescriptions, nil
}
func (self *SRegion) GetELbBackend(backendId string) (*SElbBackend, error) {
client, err := self.GetElbV2Client()
if err != nil {
return nil, errors.Wrap(err, "GetElbV2Client")
}
groupId, instanceId, port, err := parseElbBackendId(backendId)
if err != nil {
log.Errorf("parseElbBackendId %s: %s", backendId, err)
return nil, errors.Wrap(err, "parseElbBackendId")
}
params := &elbv2.DescribeTargetHealthInput{}
desc := &elbv2.TargetDescription{}
desc.SetPort(int64(port))
desc.SetId(instanceId)
params.SetTargets([]*elbv2.TargetDescription{desc})
params.SetTargetGroupArn(groupId)
ret, err := client.DescribeTargetHealth(params)
params := map[string]string{
"TargetGroupArn": groupId,
"Targets.member.1.Id": instanceId,
"Targets.member.1.Port": fmt.Sprintf("%d", port),
}
ret := &SElbBackends{}
err = self.elbRequest("DescribeTargetHealth", params, ret)
if err != nil {
return nil, errors.Wrap(err, "DescribeTargetHealth")
return nil, errors.Wrapf(err, "DescribeTargetHealth")
}
backends := []SElbBackend{}
err = unmarshalAwsOutput(ret, "TargetHealthDescriptions", &backends)
if err != nil {
return nil, errors.Wrap(err, "unmarshalAwsOutput.TargetHealthDescriptions")
for i := range ret.TargetHealthDescriptions {
if ret.TargetHealthDescriptions[i].GetGlobalId() == backendId {
return &ret.TargetHealthDescriptions[i], nil
}
}
if len(backends) == 1 {
backends[0].region = self
return &backends[0], nil
}
return nil, errors.Wrap(cloudprovider.ErrNotFound, "GetELbBackend")
return nil, errors.Wrapf(cloudprovider.ErrNotFound, backendId)
}
func parseElbBackendId(id string) (string, string, int, error) {
@@ -322,102 +264,32 @@ func genElbBackendId(backendgroupId string, serverId string, port int) string {
}
func (self *SRegion) AddElbBackend(backendgroupId, serverId string, weight int, port int) (*SElbBackend, error) {
client, err := self.GetElbV2Client()
if err != nil {
return nil, errors.Wrap(err, "GetElbV2Client")
params := map[string]string{
"TargetGroupArn": backendgroupId,
"Targets.member.1.Id": serverId,
"Targets.member.1.Port": fmt.Sprintf("%d", port),
}
params := &elbv2.RegisterTargetsInput{}
params.SetTargetGroupArn(backendgroupId)
desc := &elbv2.TargetDescription{}
desc.SetId(serverId)
desc.SetPort(int64(port))
params.SetTargets([]*elbv2.TargetDescription{desc})
_, err = client.RegisterTargets(params)
err := self.elbRequest("RegisterTargets", params, nil)
if err != nil {
return nil, errors.Wrap(err, "RegisterTargets")
return nil, errors.Wrapf(err, "RegisterTargets")
}
return self.GetELbBackend(genElbBackendId(backendgroupId, serverId, port))
}
func (self *SRegion) RemoveElbBackend(backendgroupId, serverId string, weight int, port int) error {
client, err := self.GetElbV2Client()
if err != nil {
return errors.Wrap(err, "GetElbV2Client")
params := map[string]string{
"TargetGroupArn": backendgroupId,
"Targets.member.1.Id": serverId,
"Targets.member.1.Port": fmt.Sprintf("%d", port),
}
params := &elbv2.DeregisterTargetsInput{}
params.SetTargetGroupArn(backendgroupId)
desc := &elbv2.TargetDescription{}
desc.SetId(serverId)
desc.SetPort(int64(port))
params.SetTargets([]*elbv2.TargetDescription{desc})
_, err = client.DeregisterTargets(params)
if err != nil {
return errors.Wrap(err, "DeregisterTargets")
}
return nil
return self.elbRequest("DeregisterTargets", params, nil)
}
func (self *SRegion) DeleteElbBackendGroup(backendgroupId string) error {
client, err := self.GetElbV2Client()
if err != nil {
return errors.Wrap(err, "GetElbV2Client")
}
params := &elbv2.DeleteTargetGroupInput{}
params.SetTargetGroupArn(backendgroupId)
_, err = client.DeleteTargetGroup(params)
if err != nil {
return errors.Wrap(err, "DeleteTargetGroup")
}
return nil
}
func (self *SRegion) modifyELbBackendGroup(backendgroupId string, healthCheck *cloudprovider.SLoadbalancerHealthCheck) error {
client, err := self.GetElbV2Client()
if err != nil {
return err
}
params := &elbv2.ModifyTargetGroupInput{}
params.SetTargetGroupArn(backendgroupId)
params.SetHealthCheckProtocol(strings.ToUpper(healthCheck.HealthCheckType))
params.SetHealthyThresholdCount(int64(healthCheck.HealthCheckRise))
if utils.IsInStringArray(healthCheck.HealthCheckType, []string{api.LB_HEALTH_CHECK_HTTP, api.LB_LISTENER_TYPE_HTTPS}) {
params.SetUnhealthyThresholdCount(int64(healthCheck.HealthCheckFail))
params.SetHealthCheckTimeoutSeconds(int64(healthCheck.HealthCheckTimeout))
params.SetHealthCheckIntervalSeconds(int64(healthCheck.HealthCheckInterval))
if len(healthCheck.HealthCheckURI) > 0 {
params.SetHealthCheckPath(healthCheck.HealthCheckURI)
}
codes := ToAwsHealthCode(healthCheck.HealthCheckHttpCode)
if len(codes) > 0 {
matcher := &elbv2.Matcher{}
matcher.SetHttpCode(codes)
params.SetMatcher(matcher)
}
}
_, err = client.ModifyTargetGroup(params)
if err != nil {
return errors.Wrap(err, "ModifyTargetGroup")
}
return nil
func (self *SRegion) DeleteElbBackendGroup(id string) error {
return self.elbRequest("DeleteTargetGroup", map[string]string{"TargetGroupArn": id}, nil)
}
func (self *SRegion) RemoveElbBackends(backendgroupId string) error {
client, err := self.GetElbV2Client()
if err != nil {
return err
}
backends, err := self.GetELbBackends(backendgroupId)
if err != nil {
return errors.Wrap(err, "GetELbBackends")
@@ -426,81 +298,30 @@ func (self *SRegion) RemoveElbBackends(backendgroupId string) error {
if len(backends) == 0 {
return nil
}
targets := []*elbv2.TargetDescription{}
for i := range backends {
target := &elbv2.TargetDescription{}
target.SetId(backends[i].GetBackendId())
target.SetPort(int64(backends[i].GetPort()))
targets = append(targets, target)
}
params := &elbv2.DeregisterTargetsInput{}
params.SetTargetGroupArn(backendgroupId)
params.SetTargets(targets)
_, err = client.DeregisterTargets(params)
if err != nil {
return errors.Wrap(err, "DeregisterTargets")
}
return nil
}
func (self *SRegion) AddElbBackends(backendgroupId string, backends []cloudprovider.SLoadbalancerBackend) error {
client, err := self.GetElbV2Client()
if err != nil {
return err
}
if len(backends) == 0 {
return nil
}
params := &elbv2.RegisterTargetsInput{}
params.SetTargetGroupArn(backendgroupId)
targets := []*elbv2.TargetDescription{}
for i := range backends {
desc := &elbv2.TargetDescription{}
desc.SetId(backends[i].ExternalID)
desc.SetPort(int64(backends[i].Port))
targets = append(targets, desc)
}
params.SetTargets(targets)
_, err = client.RegisterTargets(params)
if err != nil {
return errors.Wrap(err, "RegisterTargets")
}
return nil
}
func (self *SRegion) GetElbBackendgroupAttributesById(backendgroupId string) (map[string]string, error) {
client, err := self.GetElbV2Client()
if err != nil {
return nil, errors.Wrap(err, "GetElbV2Client")
}
params := &elbv2.DescribeTargetGroupAttributesInput{}
params.SetTargetGroupArn(backendgroupId)
output, err := client.DescribeTargetGroupAttributes(params)
if err != nil {
return nil, errors.Wrap(err, "DescribeTargetGroupAttributes")
}
attrs := []map[string]string{}
err = unmarshalAwsOutput(output, "Attributes", &attrs)
if err != nil {
return nil, errors.Wrap(err, "unmarshalAwsOutput.Attributes")
}
ret := map[string]string{}
for i := range attrs {
for k, v := range attrs[i] {
ret[k] = v
err := self.RemoveElbBackend(backendgroupId, backends[i].GetBackendId(), 0, backends[i].GetPort())
if err != nil {
return err
}
}
return nil
}
return ret, nil
func (self *SRegion) GetElbBackendgroupAttributes(id string) (map[string]string, error) {
ret := struct {
Attributes []struct {
Key string
Value string
} `xml:"Attributes>member"`
}{}
err := self.elbRequest("DescribeTargetGroupAttributes", map[string]string{"TargetGroupArn": id}, &ret)
if err != nil {
return nil, err
}
result := map[string]string{}
for _, attr := range ret.Attributes {
result[attr.Key] = attr.Value
}
return result, nil
}
+115 -274
View File
@@ -18,28 +18,28 @@ import (
"context"
"encoding/json"
"fmt"
"strconv"
"strings"
"time"
"github.com/aws/aws-sdk-go/service/elbv2"
"github.com/pkg/errors"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
api "yunion.io/x/cloudmux/pkg/apis/compute"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/cloudmux/pkg/multicloud"
)
type SElbListeners struct {
NextMarker string
Listeners []SElbListener `xml:"Listeners>member"`
}
type SElbListener struct {
multicloud.SResourceBase
multicloud.SLoadbalancerRedirectBase
AwsTags
region *SRegion
lb *SElb
group *SElbBackendGroup
lb *SElb
group *SElbBackendGroup
Port int `json:"Port"`
Protocol string `json:"Protocol"`
@@ -77,7 +77,7 @@ func (self *SElbListener) GetStatus() string {
}
func (self *SElbListener) Refresh() error {
listener, err := self.region.GetElbListener(self.GetId())
listener, err := self.lb.region.GetElbListener(self.GetId())
if err != nil {
return err
}
@@ -161,7 +161,7 @@ func (self *SElbListener) getBackendGroup() (*SElbBackendGroup, error) {
return self.group, nil
}
lbbg, err := self.region.GetElbBackendgroup(self.DefaultActions[0].TargetGroupArn)
lbbg, err := self.lb.region.GetElbBackendgroup(self.DefaultActions[0].TargetGroupArn)
if err != nil {
return nil, errors.Wrap(err, "GetElbBackendgroup")
}
@@ -323,44 +323,46 @@ func (self *SElbListener) CreateILoadBalancerListenerRule(rule *cloudprovider.SL
if err != nil {
return nil, errors.Wrap(err, "GetILoadbalancerListenerRules")
} else {
if err := self.region.UpdateRulesPriority(rules); err != nil {
if err := self.lb.region.UpdateRulesPriority(rules); err != nil {
return nil, errors.Wrap(err, "UpdateRulesPriority")
}
}
ret, err := self.region.CreateElbListenerRule(self.GetId(), rule)
ret, err := self.lb.region.CreateElbListenerRule(self.GetId(), rule)
if err != nil {
return nil, errors.Wrap(err, "CreateElbListenerRule")
}
ret.listener = self
ret.region = self.region
return ret, nil
}
func (self *SElbListener) GetILoadBalancerListenerRuleById(ruleId string) (cloudprovider.ICloudLoadbalancerListenerRule, error) {
rule, err := self.region.GetElbListenerRuleById(ruleId)
rule, err := self.lb.region.GetElbListenerRule(ruleId)
if err != nil {
return nil, errors.Wrap(err, "GetElbListenerRuleById")
return nil, errors.Wrap(err, "GetElbListenerRule")
}
rule.listener = self
return rule, nil
}
func (self *SElbListener) GetILoadbalancerListenerRules() ([]cloudprovider.ICloudLoadbalancerListenerRule, error) {
rules, err := self.region.GetElbListenerRules(self.GetId(), "")
if err != nil {
return nil, errors.Wrap(err, "GetElbListenerRules")
ret := []cloudprovider.ICloudLoadbalancerListenerRule{}
marker := ""
for {
part, marker, err := self.lb.region.GetElbListenerRules(self.ListenerArn, "", marker)
if err != nil {
return nil, err
}
for i := range part {
part[i].listener = self
ret = append(ret, &part[i])
}
if len(marker) == 0 || len(part) == 0 {
break
}
}
irules := make([]cloudprovider.ICloudLoadbalancerListenerRule, len(rules))
for i := range rules {
rules[i].listener = self
irules[i] = &rules[i]
}
return irules, nil
return ret, nil
}
func (self *SElbListener) GetStickySession() string {
@@ -460,37 +462,30 @@ func (self *SElbListener) Stop() error {
}
func (self *SElbListener) Sync(ctx context.Context, listener *cloudprovider.SLoadbalancerListenerCreateOptions) error {
return self.region.SyncElbListener(self, listener)
return self.lb.region.SyncElbListener(self, listener)
}
func (self *SElbListener) Delete(ctx context.Context) error {
return self.region.DeleteElbListener(self.GetId())
return self.lb.region.DeleteElbListener(self.GetId())
}
func (self *SRegion) GetElbListeners(elbId string) ([]SElbListener, error) {
client, err := self.GetElbV2Client()
func (self *SRegion) GetElbListeners(elbId, lisId, marker string) ([]SElbListener, string, error) {
ret := &SElbListeners{}
params := map[string]string{}
if len(elbId) > 0 {
params["LoadBalancerArn"] = elbId
}
if len(lisId) > 0 {
params["ListenerArns.member.1"] = lisId
}
if len(marker) > 0 {
params["Marker"] = marker
}
err := self.elbRequest("DescribeListeners", params, ret)
if err != nil {
return nil, errors.Wrap(err, "GetElbV2Client")
return nil, "", err
}
params := &elbv2.DescribeListenersInput{}
params.SetLoadBalancerArn(elbId)
ret, err := client.DescribeListeners(params)
if err != nil {
return nil, errors.Wrap(err, "DescribeListeners")
}
listeners := []SElbListener{}
err = unmarshalAwsOutput(ret, "Listeners", &listeners)
if err != nil {
return nil, errors.Wrap(err, "unmarshalAwsOutput.Listeners")
}
for i := range listeners {
listeners[i].region = self
}
return listeners, nil
return ret.Listeners, ret.NextMarker, nil
}
func unmarshalAwsOutput(output interface{}, respKey string, result interface{}) error {
@@ -520,249 +515,95 @@ func unmarshalAwsOutput(output interface{}, respKey string, result interface{})
}
func (self *SRegion) GetElbListener(listenerId string) (*SElbListener, error) {
client, err := self.GetElbV2Client()
ret, _, err := self.GetElbListeners("", listenerId, "")
if err != nil {
return nil, errors.Wrap(err, "GetElbV2Client")
return nil, errors.Wrapf(err, "GetElbListeners")
}
params := &elbv2.DescribeListenersInput{}
params.SetListenerArns([]*string{&listenerId})
ret, err := client.DescribeListeners(params)
if err != nil {
return nil, errors.Wrap(err, "DescribeListeners")
for i := range ret {
if ret[i].ListenerArn == listenerId {
return &ret[i], nil
}
}
listeners := []SElbListener{}
err = unmarshalAwsOutput(ret, "Listeners", &listeners)
if err != nil {
return nil, errors.Wrap(err, "unmarshalAwsOutput.Listeners")
}
if len(listeners) == 1 {
listeners[0].region = self
return &listeners[0], nil
}
return nil, errors.Wrap(cloudprovider.ErrNotFound, "GetElbListener")
return nil, errors.Wrapf(cloudprovider.ErrNotFound, listenerId)
}
func (self *SRegion) CreateElbListener(lbId string, listener *cloudprovider.SLoadbalancerListenerCreateOptions) (*SElbListener, error) {
client, err := self.GetElbV2Client()
if err != nil {
return nil, errors.Wrap(err, "GetElbV2Client")
func (self *SRegion) CreateElbListener(lbId string, opts *cloudprovider.SLoadbalancerListenerCreateOptions) (*SElbListener, error) {
params := map[string]string{
"LoadBalancerArn": lbId,
"Port": fmt.Sprintf("%d", opts.ListenerPort),
"Protocol": strings.ToUpper(opts.ListenerType),
"DefaultActions.member.1.Type": "forward",
"DefaultActions.member.1.TargetGroupArn": opts.BackendGroupId,
}
listenerType := strings.ToUpper(listener.ListenerType)
params := &elbv2.CreateListenerInput{}
params.SetLoadBalancerArn(lbId)
params.SetPort(int64(listener.ListenerPort))
params.SetProtocol(listenerType)
action := &elbv2.Action{}
action.SetType("forward")
action.SetTargetGroupArn(listener.BackendGroupId)
params.SetDefaultActions([]*elbv2.Action{action})
if listenerType == "HTTPS" {
cert := &elbv2.Certificate{
CertificateArn: &listener.CertificateId,
}
params.SetCertificates([]*elbv2.Certificate{cert})
params.SetSslPolicy("ELBSecurityPolicy-2016-08")
if opts.ListenerType == api.LB_LISTENER_TYPE_HTTPS {
params["Certificates.member.1.CertificateArn"] = opts.CertificateId
params["SslPolicy"] = "ELBSecurityPolicy-2016-08"
}
ret, err := client.CreateListener(params)
ret := &SElbListeners{}
err := self.elbRequest("CreateListener", params, ret)
if err != nil {
// aws 比较诡异,证书能查询到,但是如果立即创建会报错,这里只能等待一会重试
time.Sleep(10 * time.Second)
if strings.Contains(err.Error(), "CertificateNotFound") {
ret, err = client.CreateListener(params)
if err != nil {
return nil, errors.Wrap(err, "Region.CreateElbListener.Retry")
return nil, errors.Wrapf(err, "CreateListener")
}
for i := range ret.Listeners {
return &ret.Listeners[i], nil
}
/*
if err != nil {
// aws 比较诡异,证书能查询到,但是如果立即创建会报错,这里只能等待一会重试
time.Sleep(10 * time.Second)
if strings.Contains(err.Error(), "CertificateNotFound") {
ret, err = client.CreateListener(params)
if err != nil {
return nil, errors.Wrap(err, "Region.CreateElbListener.Retry")
}
} else {
return nil, errors.Wrap(err, "Region.CreateElbListener")
}
} else {
return nil, errors.Wrap(err, "Region.CreateElbListener")
}
*/
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "after created")
}
func (self *SRegion) GetElbListenerRules(listenerId string, ruleId, marker string) ([]SElbListenerRule, string, error) {
params := map[string]string{}
if len(listenerId) > 0 {
params["ListenerArn"] = listenerId
}
if len(ruleId) > 0 {
params["RuleArns.member.1"] = ruleId
}
if len(marker) > 0 {
params["Marker"] = marker
}
ret := &SElbListenerRules{}
err := self.elbRequest("DescribeRules", params, ret)
if err != nil {
return nil, "", errors.Wrapf(err, "DescribeRules")
}
return ret.Rules, ret.NextMarker, nil
}
func (self *SRegion) GetElbListenerRule(id string) (*SElbListenerRule, error) {
rules, _, err := self.GetElbListenerRules("", id, "")
if err != nil {
return nil, errors.Wrapf(err, "GetElbListenerRules")
}
for i := range rules {
if rules[i].RuleArn == id {
return &rules[i], nil
}
}
listeners := []SElbListener{}
err = unmarshalAwsOutput(ret, "Listeners", &listeners)
if err != nil {
return nil, errors.Wrap(err, "unmarshalAwsOutput.Listeners")
}
if len(listeners) == 1 {
listeners[0].region = self
return &listeners[0], nil
}
return nil, fmt.Errorf("CreateElbListener err %#v", listeners)
return nil, errors.Wrapf(cloudprovider.ErrNotFound, id)
}
func (self *SRegion) GetElbListenerRules(listenerId string, ruleId string) ([]SElbListenerRule, error) {
client, err := self.GetElbV2Client()
if err != nil {
return nil, errors.Wrap(err, "GetElbV2Client")
}
params := &elbv2.DescribeRulesInput{}
if len(listenerId) > 0 {
params.SetListenerArn(listenerId)
}
if len(ruleId) > 0 {
params.SetRuleArns([]*string{&ruleId})
}
ret, err := client.DescribeRules(params)
if err != nil {
return nil, errors.Wrap(err, "DescribeRules")
}
rules := []SElbListenerRule{}
err = unmarshalAwsOutput(ret, "Rules", &rules)
if err != nil {
return nil, errors.Wrap(err, "unmarshalAwsOutput.Rules")
}
for i := range rules {
rules[i].region = self
}
return rules, nil
}
func (self *SRegion) GetElbListenerRuleById(ruleId string) (*SElbListenerRule, error) {
client, err := self.GetElbV2Client()
if err != nil {
return nil, errors.Wrap(err, "GetElbV2Client")
}
params := &elbv2.DescribeRulesInput{}
if len(ruleId) > 0 {
params.SetRuleArns([]*string{&ruleId})
}
ret, err := client.DescribeRules(params)
if err != nil {
return nil, errors.Wrap(err, "DescribeRules")
}
rules := []SElbListenerRule{}
err = unmarshalAwsOutput(ret, "Rules", &rules)
if err != nil {
return nil, errors.Wrap(err, "unmarshalAwsOutput.Rules")
}
if len(rules) == 1 {
rules[0].region = self
return &rules[0], nil
} else {
log.Errorf("GetElbListenerRuleById %s %d found", ruleId, len(rules))
return nil, errors.Wrap(cloudprovider.ErrNotFound, "GetElbListenerRuleById")
}
}
func (self *SRegion) DeleteElbListener(listenerId string) error {
client, err := self.GetElbV2Client()
if err != nil {
return err
}
params := &elbv2.DeleteListenerInput{}
params.SetListenerArn(listenerId)
_, err = client.DeleteListener(params)
if err != nil {
return err
}
return nil
func (self *SRegion) DeleteElbListener(id string) error {
return self.elbRequest("DeleteListener", map[string]string{"ListenerArn": id}, nil)
}
func (self *SRegion) SyncElbListener(listener *SElbListener, config *cloudprovider.SLoadbalancerListenerCreateOptions) error {
client, err := self.GetElbV2Client()
if err != nil {
return err
}
params := &elbv2.ModifyListenerInput{}
params.SetListenerArn(listener.GetId())
params.SetPort(int64(config.ListenerPort))
params.SetProtocol(strings.ToUpper(config.ListenerType))
action := &elbv2.Action{}
action.SetType("forward")
action.SetTargetGroupArn(config.BackendGroupId)
params.SetDefaultActions([]*elbv2.Action{action})
if config.ListenerType == api.LB_LISTENER_TYPE_HTTPS {
cert := &elbv2.Certificate{}
cert.SetCertificateArn(config.CertificateId)
params.SetCertificates([]*elbv2.Certificate{cert})
}
_, err = client.ModifyListener(params)
if err != nil {
if strings.Contains(err.Error(), "CertificateNotFound") {
// aws 比较诡异,证书能查询到,但是如果立即创建会报错,这里只能等待一会重试
time.Sleep(10 * time.Second)
_, err = client.ModifyListener(params)
if err != nil {
return errors.Wrap(err, "SRegion.SyncElbListener.ModifyListener.Retry")
}
}
return errors.Wrap(err, "SRegion.SyncElbListener.ModifyListener")
}
hc := &cloudprovider.SLoadbalancerHealthCheck{
HealthCheckType: config.HealthCheckType,
HealthCheckReq: config.HealthCheckReq,
HealthCheckExp: config.HealthCheckExp,
HealthCheck: config.HealthCheck,
HealthCheckTimeout: config.HealthCheckTimeout,
HealthCheckDomain: config.HealthCheckDomain,
HealthCheckHttpCode: config.HealthCheckHttpCode,
HealthCheckURI: config.HealthCheckURI,
HealthCheckInterval: config.HealthCheckInterval,
HealthCheckRise: config.HealthCheckRise,
HealthCheckFail: config.HealthCheckFail,
}
err = self.modifyELbBackendGroup(config.BackendGroupId, hc)
if err != nil {
return errors.Wrap(err, "region.SyncElbListener.updateELbBackendGroup")
}
return nil
}
func (self *SRegion) UpdateRulesPriority(rules []cloudprovider.ICloudLoadbalancerListenerRule) error {
client, err := self.GetElbV2Client()
if err != nil {
return err
}
ps := []*elbv2.RulePriorityPair{}
for i := range rules {
rule := rules[i].(*SElbListenerRule)
if !rule.IsDefaultRule {
v, _ := strconv.Atoi(rule.Priority)
p := &elbv2.RulePriorityPair{}
p.SetRuleArn(rules[i].GetId())
p.SetPriority(int64(v + 1))
ps = append(ps, p)
}
}
if len(ps) == 0 {
return nil
}
params := &elbv2.SetRulePrioritiesInput{}
params.SetRulePriorities(ps)
_, err = client.SetRulePriorities(params)
if err != nil {
return err
}
return nil
}
+30 -58
View File
@@ -31,6 +31,11 @@ import (
"yunion.io/x/cloudmux/pkg/multicloud"
)
type SElbListenerRules struct {
Rules []SElbListenerRule `xml:"Rules>member"`
NextMarker string
}
type SElbListenerRule struct {
multicloud.SResourceBase
multicloud.SLoadbalancerRedirectBase
@@ -97,17 +102,11 @@ func (self *SElbListenerRule) GetStatus() string {
}
func (self *SElbListenerRule) Refresh() error {
rule, err := self.region.GetElbListenerRuleById(self.GetId())
rule, err := self.region.GetElbListenerRule(self.RuleArn)
if err != nil {
return err
}
err = jsonutils.Update(self, rule)
if err != nil {
return err
}
return nil
return jsonutils.Update(self, rule)
}
func (self *SElbListenerRule) IsDefault() bool {
@@ -166,61 +165,34 @@ func (self *SElbListenerRule) Delete(ctx context.Context) error {
return self.region.DeleteElbListenerRule(self.GetId())
}
func (self *SRegion) DeleteElbListenerRule(ruleId string) error {
client, err := self.GetElbV2Client()
if err != nil {
return err
}
params := &elbv2.DeleteRuleInput{}
params.SetRuleArn(ruleId)
_, err = client.DeleteRule(params)
if err != nil {
return err
}
return nil
func (self *SRegion) DeleteElbListenerRule(id string) error {
return self.elbRequest("DeleteRule", map[string]string{"RuleArn": id}, nil)
}
func (self *SRegion) CreateElbListenerRule(listenerId string, config *cloudprovider.SLoadbalancerListenerRule) (*SElbListenerRule, error) {
client, err := self.GetElbV2Client()
func (self *SRegion) CreateElbListenerRule(listenerId string, opts *cloudprovider.SLoadbalancerListenerRule) (*SElbListenerRule, error) {
params := map[string]string{
"ListenerArn": listenerId,
"Actions.member.1.Type": "forward",
"Actions.member.1.TargetGroupArn": opts.BackendGroupId,
"Priority": "1",
}
// TODO
//condtions, err := parseConditions(config.Condition)
//if err != nil {
// return nil, errors.Wrap(err, "parseConditions")
//}
//params.SetConditions(condtions)
ret := &SElbListenerRules{}
err := self.elbRequest("CreateRule", params, ret)
if err != nil {
return nil, errors.Wrap(err, "GetElbV2Client")
return nil, err
}
forward := "forward"
action := &elbv2.Action{
TargetGroupArn: &config.BackendGroupId,
Type: &forward,
for i := range ret.Rules {
return &ret.Rules[i], nil
}
condtions, err := parseConditions(config.Condition)
if err != nil {
return nil, errors.Wrap(err, "parseConditions")
}
params := &elbv2.CreateRuleInput{}
params.SetListenerArn(listenerId)
params.SetActions([]*elbv2.Action{action})
params.SetConditions(condtions)
params.SetPriority(int64(1))
ret, err := client.CreateRule(params)
if err != nil {
return nil, errors.Wrap(err, "CreateRule")
}
if len(ret.Rules) == 0 {
return nil, errors.Wrap(fmt.Errorf("empty rules"), "Region.CreateElbListenerRule.len")
}
rule := SElbListenerRule{}
err = unmarshalAwsOutput(ret.Rules[0], "", &rule)
if err != nil {
return nil, errors.Wrap(err, "unmarshalAwsOutput.rule")
}
rule.region = self
return &rule, nil
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "after created")
}
func parseConditions(conditions string) ([]*elbv2.RuleCondition, error) {
+64 -161
View File
@@ -24,7 +24,6 @@ import (
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/acm"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go/service/elbv2"
"github.com/aws/aws-sdk-go/service/iam"
"github.com/aws/aws-sdk-go/service/organizations"
"github.com/aws/aws-sdk-go/service/resourcegroupstaggingapi"
@@ -123,6 +122,9 @@ const (
ROUTE53_SERVICE_NAME = "route53"
ELASTICACHE_SERVICE_NAME = "elasticache"
ELB_SERVICE_NAME = "elasticloadbalancing"
ELB_SERVICE_ID = "Elastic Load Balancing v2"
)
type SRegion struct {
@@ -132,7 +134,6 @@ type SRegion struct {
ec2Client *ec2.EC2
iamClient *iam.IAM
s3Client *s3.S3
elbv2Client *elbv2.ELBV2
acmClient *acm.ACM
wafClient *wafv2.WAFV2
organizationClient *organizations.Organizations
@@ -232,6 +233,10 @@ func (self *SRegion) getResourceGroupTagClient() (*resourcegroupstaggingapi.Reso
return self.resourceGroupTagClient, nil
}
func (self *SRegion) elbRequest(apiName string, params map[string]string, retval interface{}) error {
return self.client.request(self.RegionId, ELB_SERVICE_NAME, ELB_SERVICE_ID, "2015-12-01", apiName, params, retval, true)
}
func (self *SRegion) rdsRequest(apiName string, params map[string]string, retval interface{}) error {
return self.client.request(self.RegionId, RDS_SERVICE_NAME, RDS_SERVICE_ID, "2014-10-31", apiName, params, retval, true)
}
@@ -244,20 +249,6 @@ func (self *SAwsClient) monitorRequest(regionId, apiName string, params map[stri
return self.request(regionId, CLOUDWATCH_SERVICE_NAME, CLOUDWATCH_SERVICE_ID, "2010-08-01", apiName, params, retval, true)
}
func (self *SRegion) GetElbV2Client() (*elbv2.ELBV2, error) {
if self.elbv2Client == nil {
s, err := self.getAwsSession()
if err != nil {
return nil, errors.Wrap(err, "getAwsSession")
}
self.elbv2Client = elbv2.New(s)
}
return self.elbv2Client, nil
}
/////////////////////////////////////////////////////////////////////////////
func (self *SRegion) fetchZones() error {
ec2Client, err := self.getEc2Client()
@@ -647,92 +638,65 @@ func (self *SRegion) CreateInstanceSimple(name string, imgId string, cpu int, me
}
func (self *SRegion) GetILoadBalancers() ([]cloudprovider.ICloudLoadbalancer, error) {
client, err := self.GetElbV2Client()
if err != nil {
return nil, errors.Wrap(err, "GetElbV2Client")
}
params := &elbv2.DescribeLoadBalancersInput{}
ret, err := client.DescribeLoadBalancers(params)
if err != nil {
return nil, errors.Wrap(err, "DescribeLoadBalancers")
}
result := make([]SElb, 0)
err = unmarshalAwsOutput(ret, "LoadBalancers", &result)
if err != nil {
return nil, errors.Wrap(err, "unmarshalAwsOutput.LoadBalancers")
}
ielbs := make([]cloudprovider.ICloudLoadbalancer, len(result))
for i := range result {
result[i].region = self
ielbs[i] = &result[i]
}
return ielbs, nil
}
func (self *SRegion) GetILoadBalancerById(loadbalancerId string) (cloudprovider.ICloudLoadbalancer, error) {
client, err := self.GetElbV2Client()
if err != nil {
return nil, errors.Wrap(err, "GetElbV2Client")
}
params := &elbv2.DescribeLoadBalancersInput{}
params.SetLoadBalancerArns([]*string{&loadbalancerId})
ret, err := client.DescribeLoadBalancers(params)
if err != nil {
if strings.Contains(err.Error(), "LoadBalancerNotFound") {
return nil, cloudprovider.ErrNotFound
ret := []cloudprovider.ICloudLoadbalancer{}
marker := ""
for {
part, marker, err := self.GetLoadbalancers("", marker)
if err != nil {
return nil, errors.Wrapf(err, "GetLoadbalancers")
}
return nil, errors.Wrap(err, "DescribeLoadBalancers")
}
elbs := []SElb{}
err = unmarshalAwsOutput(ret, "LoadBalancers", &elbs)
if err != nil {
return nil, errors.Wrap(err, "unmarshalAwsOutput.LoadBalancers")
}
if len(elbs) == 1 {
elbs[0].region = self
return &elbs[0], nil
}
return nil, errors.Wrap(cloudprovider.ErrNotFound, "GetILoadBalancerById")
}
func (self *SRegion) getElbAttributesById(loadbalancerId string) (map[string]string, error) {
client, err := self.GetElbV2Client()
if err != nil {
return nil, errors.Wrap(err, "GetElbV2Client")
}
params := &elbv2.DescribeLoadBalancerAttributesInput{}
params.SetLoadBalancerArn(loadbalancerId)
output, err := client.DescribeLoadBalancerAttributes(params)
if err != nil {
return nil, errors.Wrap(err, "DescribeLoadBalancerAttributes")
}
attrs := []map[string]string{}
err = unmarshalAwsOutput(output, "Attributes", &attrs)
if err != nil {
return nil, errors.Wrap(err, "unmarshalAwsOutput.Attributes")
}
ret := map[string]string{}
for i := range attrs {
for k, v := range attrs[i] {
ret[k] = v
for i := range part {
part[i].region = self
ret = append(ret, &part[i])
}
if len(marker) == 0 || len(part) == 0 {
break
}
}
return ret, nil
}
func (self *SRegion) GetLoadBalancer(id string) (*SElb, error) {
part, _, err := self.GetLoadbalancers(id, "")
if err != nil {
return nil, errors.Wrapf(err, "GetLoadbalancers")
}
for i := range part {
if part[i].GetGlobalId() == id {
part[i].region = self
return &part[i], nil
}
}
return nil, errors.Wrap(cloudprovider.ErrNotFound, id)
}
func (self *SRegion) GetILoadBalancerById(id string) (cloudprovider.ICloudLoadbalancer, error) {
lb, err := self.GetLoadBalancer(id)
if err != nil {
return nil, err
}
return lb, nil
}
func (self *SRegion) GetElbAttributes(id string) (map[string]string, error) {
ret := struct {
Attributes []struct {
Key string
Value string
} `xml:"Attributes>member"`
}{}
params := map[string]string{"LoadBalancerArn": id}
err := self.elbRequest("DescribeLoadBalancerAttributes", params, &ret)
if err != nil {
return nil, err
}
result := map[string]string{}
for _, attr := range ret.Attributes {
result[attr.Key] = attr.Value
}
return result, nil
}
func (self *SRegion) GetILoadBalancerAclById(aclId string) (cloudprovider.ICloudLoadbalancerAcl, error) {
return nil, cloudprovider.ErrNotSupported
}
@@ -818,59 +782,12 @@ func (self *SRegion) GetILoadBalancerCertificates() ([]cloudprovider.ICloudLoadb
return icerts, nil
}
func (self *SRegion) CreateILoadBalancer(loadbalancer *cloudprovider.SLoadbalancerCreateOptions) (cloudprovider.ICloudLoadbalancer, error) {
client, err := self.GetElbV2Client()
func (self *SRegion) CreateILoadBalancer(opts *cloudprovider.SLoadbalancerCreateOptions) (cloudprovider.ICloudLoadbalancer, error) {
lb, err := self.CreateLoadbalancer(opts)
if err != nil {
return nil, errors.Wrap(err, "GetElbV2Client")
return nil, errors.Wrapf(err, "CreateLoadbalancer")
}
params := &elbv2.CreateLoadBalancerInput{}
params.SetName(loadbalancer.Name)
params.SetType(loadbalancer.LoadbalancerSpec)
params.SetIpAddressType("ipv4")
if loadbalancer.AddressType == api.LB_ADDR_TYPE_INTERNET {
params.SetScheme("internet-facing")
} else {
params.SetScheme("internal")
}
// params.SetSecurityGroups()
params.SetSubnets(ConvertedList(loadbalancer.NetworkIds))
tagInput := []*elbv2.Tag{}
keys := []string{}
values := []string{}
for k, v := range loadbalancer.Tags {
keys = append(keys, k)
values = append(values, v)
}
for i := range keys {
tagInput = append(tagInput, &elbv2.Tag{
Key: &keys[i],
Value: &values[i],
})
}
if len(loadbalancer.Tags) > 0 {
params.SetTags(tagInput)
}
ret, err := client.CreateLoadBalancer(params)
if err != nil {
return nil, errors.Wrap(err, "CreateLoadBalancer")
}
elbs := []SElb{}
err = unmarshalAwsOutput(ret, "LoadBalancers", &elbs)
if err != nil {
return nil, errors.Wrap(err, "unmarshalAwsOutput.LoadBalancers")
}
if len(elbs) == 1 {
elbs[0].region = self
return &elbs[0], nil
}
return nil, fmt.Errorf("CreateILoadBalancer error %#v", elbs)
return lb, nil
}
func (region *SRegion) GetIBuckets() ([]cloudprovider.ICloudBucket, error) {
@@ -995,20 +912,6 @@ func (self *SRegion) GetSkus(zoneId string) ([]cloudprovider.ICloudSku, error) {
return nil, cloudprovider.ErrNotImplemented
}
func (self *SRegion) GetILoadBalancerBackendGroups() ([]cloudprovider.ICloudLoadbalancerBackendGroup, error) {
backendgroups, err := self.GetElbBackendgroups("", nil)
if err != nil {
return nil, errors.Wrap(err, "GetElbBackendgroups")
}
ret := make([]cloudprovider.ICloudLoadbalancerBackendGroup, len(backendgroups))
for i := range backendgroups {
ret[i] = &backendgroups[i]
}
return ret, nil
}
func (self *SRegion) GetISecurityGroupById(secgroupId string) (cloudprovider.ICloudSecurityGroup, error) {
secgroups, total, err := self.GetSecurityGroups("", "", secgroupId, 0, 1)
if err != nil {