diff --git a/pkg/apis/compute/loadbalancer_const.go b/pkg/apis/compute/loadbalancer_const.go index 6593dacedd..080e1f0367 100644 --- a/pkg/apis/compute/loadbalancer_const.go +++ b/pkg/apis/compute/loadbalancer_const.go @@ -267,6 +267,22 @@ var LB_SCHEDULER_TYPES = choices.NewChoices( LB_SCHEDULER_TCH, ) +const ( + LB_SENDPROXY_OFF = "off" + LB_SENDPROXY_V1 = "v1" + LB_SENDPROXY_V2 = "v2" + LB_SENDPROXY_V2_SSL = "v2-ssl" + LB_SENDPROXY_V2_SSL_CN = "v2-ssl-cn" +) + +var LB_SENDPROXY_CHOICES = choices.NewChoices( + LB_SENDPROXY_OFF, + LB_SENDPROXY_V1, + LB_SENDPROXY_V2, + LB_SENDPROXY_V2_SSL, + LB_SENDPROXY_V2_SSL_CN, +) + var LB_ALIYUN_UDP_SCHEDULER_TYPES = choices.NewChoices( LB_SCHEDULER_RR, LB_SCHEDULER_WRR, diff --git a/pkg/compute/models/loadbalancerbackends.go b/pkg/compute/models/loadbalancerbackends.go index f3651c5052..d2f0c7f3f9 100644 --- a/pkg/compute/models/loadbalancerbackends.go +++ b/pkg/compute/models/loadbalancerbackends.go @@ -64,6 +64,8 @@ type SLoadbalancerBackend struct { Weight int `width:"36" charset:"ascii" nullable:"false" list:"user" create:"optional" update:"user"` Address string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"optional"` Port int `nullable:"false" list:"user" create:"required" update:"user"` + + SendProxy string `width:"16" charset:"ascii" nullable:"false" list:"user" create:"optional" update:"user" default:"off"` } func (man *SLoadbalancerBackendManager) pendingDeleteSubs(ctx context.Context, userCred mcclient.TokenCredential, q *sqlchemy.SQuery) { @@ -144,6 +146,7 @@ func (man *SLoadbalancerBackendManager) ValidateCreateData(ctx context.Context, "backend_type": backendTypeV, "weight": validators.NewRangeValidator("weight", 1, 256).Default(1), "port": validators.NewPortValidator("port"), + "send_proxy": validators.NewStringChoicesValidator("send_proxy", api.LB_SENDPROXY_CHOICES).Default(api.LB_SENDPROXY_OFF), } for _, v := range keyV { if err := v.Validate(data); err != nil { @@ -274,8 +277,9 @@ func (man *SLoadbalancerBackendManager) GetGuestAddress(guest *SGuest) (string, func (lbb *SLoadbalancerBackend) ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { keyV := map[string]validators.IValidator{ - "weight": validators.NewRangeValidator("weight", 1, 256), - "port": validators.NewPortValidator("port"), + "weight": validators.NewRangeValidator("weight", 1, 256), + "port": validators.NewPortValidator("port"), + "send_proxy": validators.NewStringChoicesValidator("send_proxy", api.LB_SENDPROXY_CHOICES), } for _, v := range keyV { v.Optional(true) diff --git a/pkg/compute/models/loadbalancerlisteners.go b/pkg/compute/models/loadbalancerlisteners.go index 75769c3f94..60239d30c6 100644 --- a/pkg/compute/models/loadbalancerlisteners.go +++ b/pkg/compute/models/loadbalancerlisteners.go @@ -118,6 +118,8 @@ type SLoadbalancerListener struct { Scheduler string `width:"16" charset:"ascii" nullable:"false" list:"user" create:"required" update:"user"` + SendProxy string `width:"16" charset:"ascii" nullable:"false" list:"user" create:"optional" update:"user" default:"off"` + ClientRequestTimeout int `nullable:"false" list:"user" create:"optional" update:"user"` ClientIdleTimeout int `nullable:"false" list:"user" create:"optional" update:"user"` BackendConnectTimeout int `nullable:"false" list:"user" create:"optional" update:"user"` @@ -204,6 +206,8 @@ func (man *SLoadbalancerListenerManager) ValidateCreateData(ctx context.Context, "listener_port": listenerPortV, "backend_group": backendGroupV.Optional(true), + "send_proxy": validators.NewStringChoicesValidator("send_proxy", api.LB_SENDPROXY_CHOICES).Default(api.LB_SENDPROXY_OFF), + "acl_status": aclStatusV.Default(api.LB_BOOL_OFF), "acl_type": aclTypeV.Optional(true), "acl": aclV.Optional(true), @@ -420,6 +424,8 @@ func (lblis *SLoadbalancerListener) ValidateUpdateData(ctx context.Context, user keyV := map[string]validators.IValidator{ "backend_group": backendGroupV, + "send_proxy": validators.NewStringChoicesValidator("send_proxy", api.LB_SENDPROXY_CHOICES), + "acl_status": aclStatusV, "acl_type": aclTypeV, "acl": aclV, diff --git a/pkg/lbagent/models/haproxy.go b/pkg/lbagent/models/haproxy.go index 5f38ec256d..35e615a01e 100644 --- a/pkg/lbagent/models/haproxy.go +++ b/pkg/lbagent/models/haproxy.go @@ -289,6 +289,10 @@ func (b *LoadbalancerCorpus) genHaproxyConfigBackend(data map[string]interface{} } } { + listenerSendProxy, err := agentutils.HaproxySendProxy(listener.SendProxy) + if err != nil { + return fmt.Errorf("listener %s(%s): %v", listener.Name, listener.Id, err) + } serverLines := []string{} for _, backend := range backendGroup.backends { serverLine := fmt.Sprintf("server %s %s:%d", backend.Id, backend.Address, backend.Port) @@ -304,6 +308,15 @@ func (b *LoadbalancerCorpus) genHaproxyConfigBackend(data map[string]interface{} if stickySessionEnable { serverLine += fmt.Sprintf(" cookie %q", backend.Id) } + if listenerSendProxy != "" { + serverLine += " " + listenerSendProxy + } else if sendProxy, err := agentutils.HaproxySendProxy(backend.SendProxy); err != nil { + return fmt.Errorf("backend %s(%s): %v", backend.Name, backend.Id, err) + } else if sendProxy != "" { + serverLine += " " + sendProxy + } else { + // nothing to do + } serverLines = append(serverLines, serverLine) } data["servers"] = serverLines diff --git a/pkg/lbagent/utils/haproxy.go b/pkg/lbagent/utils/haproxy.go index 98040676d1..a3d119b39e 100644 --- a/pkg/lbagent/utils/haproxy.go +++ b/pkg/lbagent/utils/haproxy.go @@ -17,6 +17,8 @@ package utils import ( "fmt" "strings" + + "yunion.io/x/onecloud/pkg/apis/compute" ) const HaproxyCfgExt = "cfg" @@ -83,3 +85,20 @@ func HaproxyConfigHttpCheckExpect(s string) string { s = fmt.Sprintf("http-check expect rstatus %s", s) return s } + +func HaproxySendProxy(s string) (r string, err error) { + switch s { + case compute.LB_SENDPROXY_OFF, "": + case compute.LB_SENDPROXY_V1: + r = "send-proxy" + case compute.LB_SENDPROXY_V2: + r = "send-proxy-v2" + case compute.LB_SENDPROXY_V2_SSL: + r = "send-proxy-v2-ssl" + case compute.LB_SENDPROXY_V2_SSL_CN: + r = "send-proxy-v2-ssl-cn" + default: + err = fmt.Errorf("unknown SendProxy: %s", s) + } + return +} diff --git a/pkg/mcclient/models/loadbalancers.go b/pkg/mcclient/models/loadbalancers.go index 07c70450d2..c968787c80 100644 --- a/pkg/mcclient/models/loadbalancers.go +++ b/pkg/mcclient/models/loadbalancers.go @@ -73,6 +73,8 @@ type LoadbalancerListener struct { Scheduler string + SendProxy string + ClientRequestTimeout int ClientIdleTimeout int BackendConnectTimeout int @@ -143,6 +145,8 @@ type LoadbalancerBackend struct { Weight int Address string Port int + + SendProxy string } type LoadbalancerAclEntry struct { diff --git a/pkg/mcclient/options/loadbalancerbackends.go b/pkg/mcclient/options/loadbalancerbackends.go index 20cbc145db..46785594a7 100644 --- a/pkg/mcclient/options/loadbalancerbackends.go +++ b/pkg/mcclient/options/loadbalancerbackends.go @@ -20,6 +20,8 @@ type LoadbalancerBackendCreateOptions struct { BackendType string `default:"guest"` Port *int `required:"true"` Weight *int `default:"1"` + + SendProxy string `choices:"off|v1|v2|v2-ssl|v2-ssl-on"` } type LoadbalancerBackendListOptions struct { @@ -30,6 +32,8 @@ type LoadbalancerBackendListOptions struct { Weight *int Address string Port *int + + SendProxy string `choices:"off|v1|v2|v2-ssl|v2-ssl-on"` } type LoadbalancerBackendUpdateOptions struct { @@ -38,6 +42,8 @@ type LoadbalancerBackendUpdateOptions struct { Weight *int Port *int + + SendProxy string `choices:"off|v1|v2|v2-ssl|v2-ssl-on"` } type LoadbalancerBackendGetOptions struct { diff --git a/pkg/mcclient/options/loadbalancerlisteners.go b/pkg/mcclient/options/loadbalancerlisteners.go index 4b840daef0..93ce2322a5 100644 --- a/pkg/mcclient/options/loadbalancerlisteners.go +++ b/pkg/mcclient/options/loadbalancerlisteners.go @@ -25,6 +25,8 @@ type LoadbalancerListenerCreateOptions struct { Scheduler string `required:"true" choices:"rr|wrr|wlc|sch|tch"` + SendProxy string `choices:"off|v1|v2|v2-ssl|v2-ssl-cn"` + ClientRequestTimeout *int ClientIdleTimeout *int BackendConnectTimeout *int @@ -77,6 +79,8 @@ type LoadbalancerListenerListOptions struct { Scheduler string `choices:"rr|wrr|wlc|sch|tch"` + SendProxy string `choices:"off|v1|v2|v2-ssl|v2-ssl-cn"` + ClientRequestTimeout *int ClientIdleTimeout *int BackendConnectTimeout *int @@ -125,6 +129,8 @@ type LoadbalancerListenerUpdateOptions struct { Scheduler string `choices:"rr|wrr|wlc|sch|tch"` + SendProxy string `choices:"off|v1|v2|v2-ssl|v2-ssl-cn"` + ClientRequestTimeout *int ClientIdleTimeout *int BackendConnectTimeout *int