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 }