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 }