yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/aliyun/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 aliyun
    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  	AliyunTags
    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  }
    74  
    75  func (listener *SLoadbalancerHTTPSListener) GetName() string {
    76  	if len(listener.Description) == 0 {
    77  		listener.Refresh()
    78  	}
    79  	if len(listener.Description) > 0 {
    80  		return listener.Description
    81  	}
    82  	return fmt.Sprintf("HTTPS:%d", listener.ListenerPort)
    83  }
    84  
    85  func (listerner *SLoadbalancerHTTPSListener) GetId() string {
    86  	return fmt.Sprintf("%s/%d", listerner.lb.LoadBalancerId, listerner.ListenerPort)
    87  }
    88  
    89  func (listerner *SLoadbalancerHTTPSListener) GetGlobalId() string {
    90  	return listerner.GetId()
    91  }
    92  
    93  func (listerner *SLoadbalancerHTTPSListener) GetStatus() string {
    94  	switch listerner.Status {
    95  	case "starting", "running":
    96  		return api.LB_STATUS_ENABLED
    97  	case "configuring", "stopping", "stopped":
    98  		return api.LB_STATUS_DISABLED
    99  	default:
   100  		return api.LB_STATUS_UNKNOWN
   101  	}
   102  }
   103  
   104  func (listerner *SLoadbalancerHTTPSListener) IsEmulated() bool {
   105  	return false
   106  }
   107  
   108  func (listerner *SLoadbalancerHTTPSListener) GetEgressMbps() int {
   109  	if listerner.Bandwidth < 1 {
   110  		return 0
   111  	}
   112  	return listerner.Bandwidth
   113  }
   114  
   115  func (listerner *SLoadbalancerHTTPSListener) Refresh() error {
   116  	lis, err := listerner.lb.region.GetLoadbalancerHTTPSListener(listerner.lb.LoadBalancerId, listerner.ListenerPort)
   117  	if err != nil {
   118  		return err
   119  	}
   120  	return jsonutils.Update(listerner, lis)
   121  }
   122  
   123  func (listerner *SLoadbalancerHTTPSListener) GetListenerType() string {
   124  	return "https"
   125  }
   126  
   127  func (listerner *SLoadbalancerHTTPSListener) GetListenerPort() int {
   128  	return listerner.ListenerPort
   129  }
   130  
   131  func (listerner *SLoadbalancerHTTPSListener) GetBackendGroupId() string {
   132  	if len(listerner.VServerGroupId) == 0 {
   133  		listerner.Refresh()
   134  	}
   135  	return listerner.VServerGroupId
   136  }
   137  
   138  func (listerner *SLoadbalancerHTTPSListener) GetBackendServerPort() int {
   139  	return listerner.BackendServerPort
   140  }
   141  
   142  func (listerner *SLoadbalancerHTTPSListener) GetScheduler() string {
   143  	return listerner.Scheduler
   144  }
   145  
   146  func (listerner *SLoadbalancerHTTPSListener) GetAclStatus() string {
   147  	return listerner.AclStatus
   148  }
   149  
   150  func (listerner *SLoadbalancerHTTPSListener) GetAclType() string {
   151  	return listerner.AclType
   152  }
   153  
   154  func (listerner *SLoadbalancerHTTPSListener) GetAclId() string {
   155  	return listerner.AclId
   156  }
   157  
   158  func (listerner *SLoadbalancerHTTPSListener) GetHealthCheck() string {
   159  	return listerner.HealthCheck
   160  }
   161  
   162  func (listerner *SLoadbalancerHTTPSListener) GetHealthCheckType() string {
   163  	return api.LB_HEALTH_CHECK_HTTP
   164  }
   165  
   166  func (listerner *SLoadbalancerHTTPSListener) GetHealthCheckDomain() string {
   167  	return listerner.HealthCheckDomain
   168  }
   169  
   170  func (listerner *SLoadbalancerHTTPSListener) GetHealthCheckURI() string {
   171  	return listerner.HealthCheckURI
   172  }
   173  
   174  func (listerner *SLoadbalancerHTTPSListener) GetHealthCheckCode() string {
   175  	return listerner.HealthCheckHttpCode
   176  }
   177  
   178  func (listerner *SLoadbalancerHTTPSListener) GetHealthCheckRise() int {
   179  	return listerner.HealthyThreshold
   180  }
   181  
   182  func (listerner *SLoadbalancerHTTPSListener) GetHealthCheckFail() int {
   183  	return listerner.UnhealthyThreshold
   184  }
   185  
   186  func (listerner *SLoadbalancerHTTPSListener) GetHealthCheckTimeout() int {
   187  	return listerner.HealthCheckTimeout
   188  }
   189  
   190  func (listerner *SLoadbalancerHTTPSListener) GetHealthCheckInterval() int {
   191  	return listerner.HealthCheckInterval
   192  }
   193  
   194  func (listerner *SLoadbalancerHTTPSListener) GetHealthCheckReq() string {
   195  	return ""
   196  }
   197  
   198  func (listerner *SLoadbalancerHTTPSListener) GetHealthCheckExp() string {
   199  	return ""
   200  }
   201  
   202  func (listerner *SLoadbalancerHTTPSListener) GetStickySession() string {
   203  	return listerner.StickySession
   204  }
   205  
   206  func (listerner *SLoadbalancerHTTPSListener) GetStickySessionType() string {
   207  	return listerner.StickySessionType
   208  }
   209  
   210  func (listerner *SLoadbalancerHTTPSListener) GetStickySessionCookie() string {
   211  	return listerner.Cookie
   212  }
   213  
   214  func (listerner *SLoadbalancerHTTPSListener) GetStickySessionCookieTimeout() int {
   215  	return listerner.CookieTimeout
   216  }
   217  
   218  func (listerner *SLoadbalancerHTTPSListener) XForwardedForEnabled() bool {
   219  	if listerner.XForwardedFor == "on" {
   220  		return true
   221  	}
   222  	return false
   223  }
   224  
   225  func (listerner *SLoadbalancerHTTPSListener) GzipEnabled() bool {
   226  	if listerner.Gzip == "on" {
   227  		return true
   228  	}
   229  	return false
   230  }
   231  
   232  func (listerner *SLoadbalancerHTTPSListener) GetCertificateId() string {
   233  	return listerner.ServerCertificateId
   234  }
   235  
   236  func (listerner *SLoadbalancerHTTPSListener) GetTLSCipherPolicy() string {
   237  	return listerner.TLSCipherPolicy
   238  }
   239  
   240  func (listerner *SLoadbalancerHTTPSListener) HTTP2Enabled() bool {
   241  	if listerner.EnableHttp2 == "on" {
   242  		return true
   243  	}
   244  	return false
   245  }
   246  
   247  func (listerner *SLoadbalancerHTTPSListener) GetILoadbalancerListenerRules() ([]cloudprovider.ICloudLoadbalancerListenerRule, error) {
   248  	rules, err := listerner.lb.region.GetLoadbalancerListenerRules(listerner.lb.LoadBalancerId, listerner.ListenerPort)
   249  	if err != nil {
   250  		return nil, err
   251  	}
   252  	iRules := []cloudprovider.ICloudLoadbalancerListenerRule{}
   253  	for i := 0; i < len(rules); i++ {
   254  		rules[i].httpsListener = listerner
   255  		iRules = append(iRules, &rules[i])
   256  	}
   257  	return iRules, nil
   258  }
   259  
   260  func (region *SRegion) GetLoadbalancerHTTPSListener(loadbalancerId string, listenerPort int) (*SLoadbalancerHTTPSListener, error) {
   261  	params := map[string]string{}
   262  	params["RegionId"] = region.RegionId
   263  	params["LoadBalancerId"] = loadbalancerId
   264  	params["ListenerPort"] = fmt.Sprintf("%d", listenerPort)
   265  	body, err := region.lbRequest("DescribeLoadBalancerHTTPSListenerAttribute", params)
   266  	if err != nil {
   267  		return nil, err
   268  	}
   269  	listener := SLoadbalancerHTTPSListener{}
   270  	return &listener, body.Unmarshal(&listener)
   271  }
   272  
   273  func (region *SRegion) constructHTTPCreateListenerParams(params map[string]string, listener *cloudprovider.SLoadbalancerListener) map[string]string {
   274  	params["HealthCheck"] = listener.HealthCheck
   275  	if listener.HealthCheck == "on" {
   276  		if len(listener.HealthCheckURI) == 0 {
   277  			params["HealthCheckURI"] = "/"
   278  		}
   279  		//The HealthCheckTimeout parameter is required.
   280  		if listener.HealthCheckTimeout < 1 || listener.HealthCheckTimeout > 300 {
   281  			listener.HealthCheckTimeout = 5
   282  		}
   283  		params["HealthCheckTimeout"] = fmt.Sprintf("%d", listener.HealthCheckTimeout)
   284  	}
   285  
   286  	if listener.ClientRequestTimeout < 1 || listener.ClientRequestTimeout > 180 {
   287  		listener.ClientRequestTimeout = 60
   288  	}
   289  	params["RequestTimeout"] = fmt.Sprintf("%d", listener.ClientRequestTimeout)
   290  
   291  	if listener.ClientIdleTimeout < 1 || listener.ClientIdleTimeout > 60 {
   292  		listener.ClientIdleTimeout = 15
   293  	}
   294  	params["IdleTimeout"] = fmt.Sprintf("%d", listener.ClientIdleTimeout)
   295  
   296  	params["StickySession"] = listener.StickySession
   297  	params["StickySessionType"] = listener.StickySessionType
   298  	params["Cookie"] = listener.StickySessionCookie
   299  	if listener.StickySessionCookieTimeout < 1 || listener.StickySessionCookieTimeout > 86400 {
   300  		listener.StickySessionCookieTimeout = 500
   301  	}
   302  	params["CookieTimeout"] = fmt.Sprintf("%d", listener.StickySessionCookieTimeout)
   303  	//params["ForwardPort"] = fmt.Sprintf("%d", listener.ForwardPort) //暂不支持
   304  	params["Gzip"] = "off"
   305  	if listener.Gzip {
   306  		params["Gzip"] = "on"
   307  	}
   308  	params["XForwardedFor"] = "off"
   309  	if listener.XForwardedFor {
   310  		params["XForwardedFor"] = "on"
   311  	}
   312  	return params
   313  }
   314  
   315  func (region *SRegion) CreateLoadbalancerHTTPSListener(lb *SLoadbalancer, listener *cloudprovider.SLoadbalancerListener) (cloudprovider.ICloudLoadbalancerListener, error) {
   316  	params := region.constructBaseCreateListenerParams(lb, listener)
   317  	params = region.constructHTTPCreateListenerParams(params, listener)
   318  	params["ServerCertificateId"] = listener.CertificateID
   319  	if listener.EnableHTTP2 {
   320  		params["EnableHttp2"] = "on"
   321  	} else {
   322  		params["EnableHttp2"] = "off"
   323  	}
   324  
   325  	if len(listener.TLSCipherPolicy) > 0 {
   326  		params["TLSCipherPolicy"] = listener.TLSCipherPolicy
   327  	}
   328  	_, err := region.lbRequest("CreateLoadBalancerHTTPSListener", params)
   329  	if err != nil {
   330  		return nil, err
   331  	}
   332  	iListener, err := region.GetLoadbalancerHTTPSListener(lb.LoadBalancerId, listener.ListenerPort)
   333  	if err != nil {
   334  		return nil, err
   335  	}
   336  	iListener.lb = lb
   337  	return iListener, nil
   338  }
   339  
   340  func (listerner *SLoadbalancerHTTPSListener) Delete(ctx context.Context) error {
   341  	return listerner.lb.region.DeleteLoadbalancerListener(listerner.lb.LoadBalancerId, listerner.ListenerPort)
   342  }
   343  
   344  func (listerner *SLoadbalancerHTTPSListener) CreateILoadBalancerListenerRule(rule *cloudprovider.SLoadbalancerListenerRule) (cloudprovider.ICloudLoadbalancerListenerRule, error) {
   345  	_rule := &SLoadbalancerListenerRule{
   346  		Domain:   rule.Domain,
   347  		Url:      rule.Path,
   348  		RuleName: rule.Name,
   349  	}
   350  	if len(rule.BackendGroupID) > 0 { //&& rule.BackendGroupType == api.LB_BACKENDGROUP_TYPE_NORMAL {
   351  		_rule.VServerGroupId = rule.BackendGroupID
   352  	}
   353  	listenerRule, err := listerner.lb.region.CreateLoadbalancerListenerRule(listerner.ListenerPort, listerner.lb.LoadBalancerId, _rule)
   354  	if err != nil {
   355  		return nil, err
   356  	}
   357  	listenerRule.httpsListener = listerner
   358  	return listenerRule, nil
   359  }
   360  
   361  func (listerner *SLoadbalancerHTTPSListener) GetILoadBalancerListenerRuleById(ruleId string) (cloudprovider.ICloudLoadbalancerListenerRule, error) {
   362  	rule, err := listerner.lb.region.GetLoadbalancerListenerRule(ruleId)
   363  	if err != nil {
   364  		return nil, err
   365  	}
   366  	rule.httpsListener = listerner
   367  	return rule, nil
   368  }
   369  
   370  func (listerner *SLoadbalancerHTTPSListener) Start() error {
   371  	return listerner.lb.region.startListener(listerner.ListenerPort, listerner.lb.LoadBalancerId)
   372  }
   373  
   374  func (listerner *SLoadbalancerHTTPSListener) Stop() error {
   375  	return listerner.lb.region.stopListener(listerner.ListenerPort, listerner.lb.LoadBalancerId)
   376  }
   377  
   378  func (region *SRegion) SyncLoadbalancerHTTPSListener(lb *SLoadbalancer, listener *cloudprovider.SLoadbalancerListener) error {
   379  	params := region.constructBaseCreateListenerParams(lb, listener)
   380  	params = region.constructHTTPCreateListenerParams(params, listener)
   381  	params["ServerCertificateId"] = listener.CertificateID
   382  	if listener.EnableHTTP2 {
   383  		params["EnableHttp2"] = "on"
   384  	} else {
   385  		params["EnableHttp2"] = "off"
   386  	}
   387  
   388  	if len(lb.LoadBalancerSpec) > 0 && len(listener.TLSCipherPolicy) > 0 {
   389  		params["TLSCipherPolicy"] = listener.TLSCipherPolicy
   390  	}
   391  	_, err := region.lbRequest("SetLoadBalancerHTTPSListenerAttribute", params)
   392  	return err
   393  }
   394  
   395  func (listerner *SLoadbalancerHTTPSListener) Sync(ctx context.Context, lblis *cloudprovider.SLoadbalancerListener) error {
   396  	return listerner.lb.region.SyncLoadbalancerHTTPSListener(listerner.lb, lblis)
   397  }
   398  
   399  func (listerner *SLoadbalancerHTTPSListener) GetProjectId() string {
   400  	return listerner.lb.GetProjectId()
   401  }
   402  
   403  func (listerner *SLoadbalancerHTTPSListener) GetClientIdleTimeout() int {
   404  	return 0
   405  }
   406  
   407  func (listerner *SLoadbalancerHTTPSListener) GetBackendConnectTimeout() int {
   408  	return 0
   409  }