yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/apsara/loadbalancerhttpslistener.go (about)

     1  // Copyright 2019 Yunion
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package apsara
    16  
    17  import (
    18  	"context"
    19  	"fmt"
    20  
    21  	"yunion.io/x/jsonutils"
    22  
    23  	api "yunion.io/x/cloudmux/pkg/apis/compute"
    24  	"yunion.io/x/cloudmux/pkg/cloudprovider"
    25  	"yunion.io/x/cloudmux/pkg/multicloud"
    26  )
    27  
    28  type SLoadbalancerHTTPSListener struct {
    29  	multicloud.SResourceBase
    30  	multicloud.SLoadbalancerRedirectBase
    31  	ApsaraTags
    32  	lb *SLoadbalancer
    33  
    34  	ListenerPort      int    //	负载均衡实例前端使用的端口。
    35  	BackendServerPort int    //	负载均衡实例后端使用的端口。
    36  	Bandwidth         int    //	监听的带宽峰值。
    37  	Status            string //	当前监听的状态。取值:starting | running | configuring | stopping | stopped
    38  	Description       string
    39  
    40  	XForwardedFor       string //	是否开启通过X-Forwarded-For头字段获取访者真实IP。
    41  	XForwardedFor_SLBIP string //	是否通过SLB-IP头字段获取客户端请求的真实IP。
    42  	XForwardedFor_SLBID string //	是否通过SLB-ID头字段获取负载均衡实例ID。
    43  	XForwardedFor_proto string //	是否通过X-Forwarded-Proto头字段获取负载均衡实例的监听协议。
    44  	Scheduler           string //	调度算法。
    45  	StickySession       string //	是否开启会话保持。
    46  	StickySessionType   string //	cookie的处理方式。
    47  	CookieTimeout       int    //	Cookie超时时间。
    48  	Cookie              string //	服务器上配置的cookie。
    49  	AclStatus           string //	是否开启访问控制功能。取值:on | off(默认值)
    50  
    51  	AclType string //	访问控制类型
    52  
    53  	AclId string //	监听绑定的访问策略组ID。当AclStatus参数的值为on时,该参数必选。
    54  
    55  	HealthCheck            string //	是否开启健康检查。
    56  	HealthCheckDomain      string //	用于健康检查的域名。
    57  	HealthCheckURI         string //	用于健康检查的URI。
    58  	HealthyThreshold       int    //	健康检查阈值。
    59  	UnhealthyThreshold     int    //	不健康检查阈值。
    60  	HealthCheckTimeout     int    //	每次健康检查响应的最大超时间,单位为秒。
    61  	HealthCheckInterval    int    //	健康检查的时间间隔,单位为秒。
    62  	HealthCheckHttpCode    string //	健康检查正常的HTTP状态码。
    63  	HealthCheckConnectPort int    //	健康检查的端口。
    64  	VServerGroupId         string //	绑定的服务器组ID。
    65  	ServerCertificateId    string //	服务器证书ID。
    66  	CACertificateId        string //	CA证书ID。
    67  	Gzip                   string //	是否开启Gzip压缩。
    68  	Rules                  Rules  //监听下的转发规则列表,具体请参见RuleList。
    69  	DomainExtensions       string //	域名扩展列表,具体请参见DomainExtensions。
    70  	EnableHttp2            string //	是否开启HTTP/2特性。取值:on(默认值)|off
    71  
    72  	TLSCipherPolicy string //
    73  	DepartmentInfo
    74  }
    75  
    76  func (listener *SLoadbalancerHTTPSListener) GetName() string {
    77  	if len(listener.Description) == 0 {
    78  		listener.Refresh()
    79  	}
    80  	if len(listener.Description) > 0 {
    81  		return listener.Description
    82  	}
    83  	return fmt.Sprintf("HTTPS:%d", listener.ListenerPort)
    84  }
    85  
    86  func (listerner *SLoadbalancerHTTPSListener) GetId() string {
    87  	return fmt.Sprintf("%s/%d", listerner.lb.LoadBalancerId, listerner.ListenerPort)
    88  }
    89  
    90  func (listerner *SLoadbalancerHTTPSListener) GetGlobalId() string {
    91  	return listerner.GetId()
    92  }
    93  
    94  func (listerner *SLoadbalancerHTTPSListener) GetStatus() string {
    95  	switch listerner.Status {
    96  	case "starting", "running":
    97  		return api.LB_STATUS_ENABLED
    98  	case "configuring", "stopping", "stopped":
    99  		return api.LB_STATUS_DISABLED
   100  	default:
   101  		return api.LB_STATUS_UNKNOWN
   102  	}
   103  }
   104  
   105  func (listerner *SLoadbalancerHTTPSListener) IsEmulated() bool {
   106  	return false
   107  }
   108  
   109  func (listerner *SLoadbalancerHTTPSListener) GetEgressMbps() int {
   110  	if listerner.Bandwidth < 1 {
   111  		return 0
   112  	}
   113  	return listerner.Bandwidth
   114  }
   115  
   116  func (listerner *SLoadbalancerHTTPSListener) Refresh() error {
   117  	lis, err := listerner.lb.region.GetLoadbalancerHTTPSListener(listerner.lb.LoadBalancerId, listerner.ListenerPort)
   118  	if err != nil {
   119  		return err
   120  	}
   121  	return jsonutils.Update(listerner, lis)
   122  }
   123  
   124  func (listerner *SLoadbalancerHTTPSListener) GetListenerType() string {
   125  	return "https"
   126  }
   127  
   128  func (listerner *SLoadbalancerHTTPSListener) GetListenerPort() int {
   129  	return listerner.ListenerPort
   130  }
   131  
   132  func (listerner *SLoadbalancerHTTPSListener) GetBackendGroupId() string {
   133  	if len(listerner.VServerGroupId) == 0 {
   134  		listerner.Refresh()
   135  	}
   136  	return listerner.VServerGroupId
   137  }
   138  
   139  func (listerner *SLoadbalancerHTTPSListener) GetBackendServerPort() int {
   140  	return listerner.BackendServerPort
   141  }
   142  
   143  func (listerner *SLoadbalancerHTTPSListener) GetScheduler() string {
   144  	return listerner.Scheduler
   145  }
   146  
   147  func (listerner *SLoadbalancerHTTPSListener) GetAclStatus() string {
   148  	return listerner.AclStatus
   149  }
   150  
   151  func (listerner *SLoadbalancerHTTPSListener) GetAclType() string {
   152  	return listerner.AclType
   153  }
   154  
   155  func (listerner *SLoadbalancerHTTPSListener) GetAclId() string {
   156  	return listerner.AclId
   157  }
   158  
   159  func (listerner *SLoadbalancerHTTPSListener) GetHealthCheck() string {
   160  	return listerner.HealthCheck
   161  }
   162  
   163  func (listerner *SLoadbalancerHTTPSListener) GetHealthCheckType() string {
   164  	return api.LB_HEALTH_CHECK_HTTP
   165  }
   166  
   167  func (listerner *SLoadbalancerHTTPSListener) GetHealthCheckDomain() string {
   168  	return listerner.HealthCheckDomain
   169  }
   170  
   171  func (listerner *SLoadbalancerHTTPSListener) GetHealthCheckURI() string {
   172  	return listerner.HealthCheckURI
   173  }
   174  
   175  func (listerner *SLoadbalancerHTTPSListener) GetHealthCheckCode() string {
   176  	return listerner.HealthCheckHttpCode
   177  }
   178  
   179  func (listerner *SLoadbalancerHTTPSListener) GetHealthCheckRise() int {
   180  	return listerner.HealthyThreshold
   181  }
   182  
   183  func (listerner *SLoadbalancerHTTPSListener) GetHealthCheckFail() int {
   184  	return listerner.UnhealthyThreshold
   185  }
   186  
   187  func (listerner *SLoadbalancerHTTPSListener) GetHealthCheckTimeout() int {
   188  	return listerner.HealthCheckTimeout
   189  }
   190  
   191  func (listerner *SLoadbalancerHTTPSListener) GetHealthCheckInterval() int {
   192  	return listerner.HealthCheckInterval
   193  }
   194  
   195  func (listerner *SLoadbalancerHTTPSListener) GetHealthCheckReq() string {
   196  	return ""
   197  }
   198  
   199  func (listerner *SLoadbalancerHTTPSListener) GetHealthCheckExp() string {
   200  	return ""
   201  }
   202  
   203  func (listerner *SLoadbalancerHTTPSListener) GetStickySession() string {
   204  	return listerner.StickySession
   205  }
   206  
   207  func (listerner *SLoadbalancerHTTPSListener) GetStickySessionType() string {
   208  	return listerner.StickySessionType
   209  }
   210  
   211  func (listerner *SLoadbalancerHTTPSListener) GetStickySessionCookie() string {
   212  	return listerner.Cookie
   213  }
   214  
   215  func (listerner *SLoadbalancerHTTPSListener) GetStickySessionCookieTimeout() int {
   216  	return listerner.CookieTimeout
   217  }
   218  
   219  func (listerner *SLoadbalancerHTTPSListener) XForwardedForEnabled() bool {
   220  	if listerner.XForwardedFor == "on" {
   221  		return true
   222  	}
   223  	return false
   224  }
   225  
   226  func (listerner *SLoadbalancerHTTPSListener) GzipEnabled() bool {
   227  	if listerner.Gzip == "on" {
   228  		return true
   229  	}
   230  	return false
   231  }
   232  
   233  func (listerner *SLoadbalancerHTTPSListener) GetCertificateId() string {
   234  	return listerner.ServerCertificateId
   235  }
   236  
   237  func (listerner *SLoadbalancerHTTPSListener) GetTLSCipherPolicy() string {
   238  	return listerner.TLSCipherPolicy
   239  }
   240  
   241  func (listerner *SLoadbalancerHTTPSListener) HTTP2Enabled() bool {
   242  	if listerner.EnableHttp2 == "on" {
   243  		return true
   244  	}
   245  	return false
   246  }
   247  
   248  func (listerner *SLoadbalancerHTTPSListener) GetILoadbalancerListenerRules() ([]cloudprovider.ICloudLoadbalancerListenerRule, error) {
   249  	rules, err := listerner.lb.region.GetLoadbalancerListenerRules(listerner.lb.LoadBalancerId, listerner.ListenerPort)
   250  	if err != nil {
   251  		return nil, err
   252  	}
   253  	iRules := []cloudprovider.ICloudLoadbalancerListenerRule{}
   254  	for i := 0; i < len(rules); i++ {
   255  		rules[i].httpsListener = listerner
   256  		iRules = append(iRules, &rules[i])
   257  	}
   258  	return iRules, nil
   259  }
   260  
   261  func (region *SRegion) GetLoadbalancerHTTPSListener(loadbalancerId string, listenerPort int) (*SLoadbalancerHTTPSListener, error) {
   262  	params := map[string]string{}
   263  	params["RegionId"] = region.RegionId
   264  	params["LoadBalancerId"] = loadbalancerId
   265  	params["ListenerPort"] = fmt.Sprintf("%d", listenerPort)
   266  	body, err := region.lbRequest("DescribeLoadBalancerHTTPSListenerAttribute", params)
   267  	if err != nil {
   268  		return nil, err
   269  	}
   270  	listener := SLoadbalancerHTTPSListener{}
   271  	return &listener, body.Unmarshal(&listener)
   272  }
   273  
   274  func (region *SRegion) constructHTTPCreateListenerParams(params map[string]string, listener *cloudprovider.SLoadbalancerListener) map[string]string {
   275  	params["HealthCheck"] = listener.HealthCheck
   276  	if listener.HealthCheck == "on" {
   277  		if len(listener.HealthCheckURI) == 0 {
   278  			params["HealthCheckURI"] = "/"
   279  		}
   280  		//The HealthCheckTimeout parameter is required.
   281  		if listener.HealthCheckTimeout < 1 || listener.HealthCheckTimeout > 300 {
   282  			listener.HealthCheckTimeout = 5
   283  		}
   284  		params["HealthCheckTimeout"] = fmt.Sprintf("%d", listener.HealthCheckTimeout)
   285  	}
   286  
   287  	if listener.ClientRequestTimeout < 1 || listener.ClientRequestTimeout > 180 {
   288  		listener.ClientRequestTimeout = 60
   289  	}
   290  	params["RequestTimeout"] = fmt.Sprintf("%d", listener.ClientRequestTimeout)
   291  
   292  	if listener.ClientIdleTimeout < 1 || listener.ClientIdleTimeout > 60 {
   293  		listener.ClientIdleTimeout = 15
   294  	}
   295  	params["IdleTimeout"] = fmt.Sprintf("%d", listener.ClientIdleTimeout)
   296  
   297  	params["StickySession"] = listener.StickySession
   298  	params["StickySessionType"] = listener.StickySessionType
   299  	params["Cookie"] = listener.StickySessionCookie
   300  	if listener.StickySessionCookieTimeout < 1 || listener.StickySessionCookieTimeout > 86400 {
   301  		listener.StickySessionCookieTimeout = 500
   302  	}
   303  	params["CookieTimeout"] = fmt.Sprintf("%d", listener.StickySessionCookieTimeout)
   304  	//params["ForwardPort"] = fmt.Sprintf("%d", listener.ForwardPort) //暂不支持
   305  	params["Gzip"] = "off"
   306  	if listener.Gzip {
   307  		params["Gzip"] = "on"
   308  	}
   309  	params["XForwardedFor"] = "off"
   310  	if listener.XForwardedFor {
   311  		params["XForwardedFor"] = "on"
   312  	}
   313  	return params
   314  }
   315  
   316  func (region *SRegion) CreateLoadbalancerHTTPSListener(lb *SLoadbalancer, listener *cloudprovider.SLoadbalancerListener) (cloudprovider.ICloudLoadbalancerListener, error) {
   317  	params := region.constructBaseCreateListenerParams(lb, listener)
   318  	params = region.constructHTTPCreateListenerParams(params, listener)
   319  	params["ServerCertificateId"] = listener.CertificateID
   320  	if listener.EnableHTTP2 {
   321  		params["EnableHttp2"] = "on"
   322  	} else {
   323  		params["EnableHttp2"] = "off"
   324  	}
   325  
   326  	if len(listener.TLSCipherPolicy) > 0 {
   327  		params["TLSCipherPolicy"] = listener.TLSCipherPolicy
   328  	}
   329  	_, err := region.lbRequest("CreateLoadBalancerHTTPSListener", params)
   330  	if err != nil {
   331  		return nil, err
   332  	}
   333  	iListener, err := region.GetLoadbalancerHTTPSListener(lb.LoadBalancerId, listener.ListenerPort)
   334  	if err != nil {
   335  		return nil, err
   336  	}
   337  	iListener.lb = lb
   338  	return iListener, nil
   339  }
   340  
   341  func (listerner *SLoadbalancerHTTPSListener) Delete(ctx context.Context) error {
   342  	return listerner.lb.region.DeleteLoadbalancerListener(listerner.lb.LoadBalancerId, listerner.ListenerPort)
   343  }
   344  
   345  func (listerner *SLoadbalancerHTTPSListener) CreateILoadBalancerListenerRule(rule *cloudprovider.SLoadbalancerListenerRule) (cloudprovider.ICloudLoadbalancerListenerRule, error) {
   346  	_rule := &SLoadbalancerListenerRule{
   347  		Domain:   rule.Domain,
   348  		Url:      rule.Path,
   349  		RuleName: rule.Name,
   350  	}
   351  	if len(rule.BackendGroupID) > 0 { //&& rule.BackendGroupType == api.LB_BACKENDGROUP_TYPE_NORMAL {
   352  		_rule.VServerGroupId = rule.BackendGroupID
   353  	}
   354  	listenerRule, err := listerner.lb.region.CreateLoadbalancerListenerRule(listerner.ListenerPort, listerner.lb.LoadBalancerId, _rule)
   355  	if err != nil {
   356  		return nil, err
   357  	}
   358  	listenerRule.httpsListener = listerner
   359  	return listenerRule, nil
   360  }
   361  
   362  func (listerner *SLoadbalancerHTTPSListener) GetILoadBalancerListenerRuleById(ruleId string) (cloudprovider.ICloudLoadbalancerListenerRule, error) {
   363  	rule, err := listerner.lb.region.GetLoadbalancerListenerRule(ruleId)
   364  	if err != nil {
   365  		return nil, err
   366  	}
   367  	rule.httpsListener = listerner
   368  	return rule, nil
   369  }
   370  
   371  func (listerner *SLoadbalancerHTTPSListener) Start() error {
   372  	return listerner.lb.region.startListener(listerner.ListenerPort, listerner.lb.LoadBalancerId)
   373  }
   374  
   375  func (listerner *SLoadbalancerHTTPSListener) Stop() error {
   376  	return listerner.lb.region.stopListener(listerner.ListenerPort, listerner.lb.LoadBalancerId)
   377  }
   378  
   379  func (region *SRegion) SyncLoadbalancerHTTPSListener(lb *SLoadbalancer, listener *cloudprovider.SLoadbalancerListener) error {
   380  	params := region.constructBaseCreateListenerParams(lb, listener)
   381  	params = region.constructHTTPCreateListenerParams(params, listener)
   382  	params["ServerCertificateId"] = listener.CertificateID
   383  	if listener.EnableHTTP2 {
   384  		params["EnableHttp2"] = "on"
   385  	} else {
   386  		params["EnableHttp2"] = "off"
   387  	}
   388  
   389  	if len(lb.LoadBalancerSpec) > 0 && len(listener.TLSCipherPolicy) > 0 {
   390  		params["TLSCipherPolicy"] = listener.TLSCipherPolicy
   391  	}
   392  	_, err := region.lbRequest("SetLoadBalancerHTTPSListenerAttribute", params)
   393  	return err
   394  }
   395  
   396  func (listerner *SLoadbalancerHTTPSListener) Sync(ctx context.Context, lblis *cloudprovider.SLoadbalancerListener) error {
   397  	return listerner.lb.region.SyncLoadbalancerHTTPSListener(listerner.lb, lblis)
   398  }
   399  
   400  func (listerner *SLoadbalancerHTTPSListener) GetClientIdleTimeout() int {
   401  	return 0
   402  }
   403  
   404  func (listerner *SLoadbalancerHTTPSListener) GetBackendConnectTimeout() int {
   405  	return 0
   406  }