yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/apsara/loadbalancerhttplistener.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 SLoadbalancerHTTPListener 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 //white: 仅转发来自所选访问控制策略组中设置的IP地址或地址段的请求,白名单适用于应用只允许特定IP访问的场景。 53 //设置白名单存在一定业务风险。一旦设置白名单,就只有白名单中的IP可以访问负载均衡监听。如果开启了白名单访问,但访问策略组中没有添加任何IP,则负载均衡监听会转发全部请求。 54 55 //black: 来自所选访问控制策略组中设置的IP地址或地址段的所有请求都不会转发,黑名单适用于应用只限制某些特定IP访问的场景。 56 //如果开启了黑名单访问,但访问策略组中没有添加任何IP,则负载均衡监听会转发全部请求。 57 58 //当AclStatus参数的值为on时,该参数必选。 59 60 AclId string // 监听绑定的访问策略组ID。当AclStatus参数的值为on时,该参数必选。 61 62 HealthCheck string // 是否开启健康检查。 63 HealthCheckDomain string // 用于健康检查的域名。 64 HealthCheckURI string // 用于健康检查的URI。 65 HealthyThreshold int // 健康检查阈值。 66 UnhealthyThreshold int // 不健康检查阈值。 67 HealthCheckTimeout int // 每次健康检查响应的最大超时间,单位为秒。 68 HealthCheckInterval int // 健康检查的时间间隔,单位为秒。 69 HealthCheckHttpCode string // 健康检查正常的HTTP状态码。 70 HealthCheckConnectPort int // 健康检查的端口。 71 Gzip string // 是否开启Gzip压缩。 72 EnableHttp2 string // 是否开启HTTP/2特性。取值:on(默认值)|off 73 74 Rules Rules //监听下的转发规则列表,具体请参见RuleList。 75 ForwardPort int // HTTP至HTTPS的监听转发端口。暂时只支持将HTTP 80访问重定向转发至HTTPS 443。 说明 如果 ListenerForward的值为 off,该参数不显示。 76 ListenerForward string // 表示是否开启HTTP至HTTPS的监听转发。on:表示开启 off:表示未开启 77 VServerGroupId string // 绑定的服务器组ID 78 DepartmentInfo 79 } 80 81 func (listener *SLoadbalancerHTTPListener) GetName() string { 82 if len(listener.Description) == 0 { 83 listener.Refresh() 84 } 85 if len(listener.Description) > 0 { 86 return listener.Description 87 } 88 return fmt.Sprintf("HTTP:%d", listener.ListenerPort) 89 } 90 91 func (listerner *SLoadbalancerHTTPListener) GetId() string { 92 return fmt.Sprintf("%s/%d", listerner.lb.LoadBalancerId, listerner.ListenerPort) 93 } 94 95 func (listerner *SLoadbalancerHTTPListener) GetGlobalId() string { 96 return listerner.GetId() 97 } 98 99 func (listerner *SLoadbalancerHTTPListener) GetStatus() string { 100 switch listerner.Status { 101 case "starting", "running": 102 return api.LB_STATUS_ENABLED 103 case "configuring", "stopping", "stopped": 104 return api.LB_STATUS_DISABLED 105 default: 106 return api.LB_STATUS_UNKNOWN 107 } 108 } 109 110 func (listerner *SLoadbalancerHTTPListener) IsEmulated() bool { 111 return false 112 } 113 114 func (listerner *SLoadbalancerHTTPListener) GetEgressMbps() int { 115 if listerner.Bandwidth < 1 { 116 return 0 117 } 118 return listerner.Bandwidth 119 } 120 121 func (listerner *SLoadbalancerHTTPListener) Refresh() error { 122 lis, err := listerner.lb.region.GetLoadbalancerHTTPListener(listerner.lb.LoadBalancerId, listerner.ListenerPort) 123 if err != nil { 124 return err 125 } 126 return jsonutils.Update(listerner, lis) 127 } 128 129 func (listerner *SLoadbalancerHTTPListener) GetListenerType() string { 130 return "http" 131 } 132 133 func (listerner *SLoadbalancerHTTPListener) GetListenerPort() int { 134 return listerner.ListenerPort 135 } 136 137 func (listerner *SLoadbalancerHTTPListener) GetBackendGroupId() string { 138 if len(listerner.VServerGroupId) == 0 { 139 listerner.Refresh() 140 } 141 return listerner.VServerGroupId 142 } 143 144 func (listerner *SLoadbalancerHTTPListener) GetBackendServerPort() int { 145 return listerner.BackendServerPort 146 } 147 148 func (listerner *SLoadbalancerHTTPListener) GetScheduler() string { 149 return listerner.Scheduler 150 } 151 152 func (listerner *SLoadbalancerHTTPListener) GetAclStatus() string { 153 return listerner.AclStatus 154 } 155 156 func (listerner *SLoadbalancerHTTPListener) GetAclType() string { 157 return listerner.AclType 158 } 159 160 func (listerner *SLoadbalancerHTTPListener) GetAclId() string { 161 return listerner.AclId 162 } 163 164 func (listerner *SLoadbalancerHTTPListener) GetHealthCheck() string { 165 return listerner.HealthCheck 166 } 167 168 func (listerner *SLoadbalancerHTTPListener) GetHealthCheckType() string { 169 return api.LB_HEALTH_CHECK_HTTP 170 } 171 172 func (listerner *SLoadbalancerHTTPListener) GetHealthCheckDomain() string { 173 return listerner.HealthCheckDomain 174 } 175 176 func (listerner *SLoadbalancerHTTPListener) GetHealthCheckURI() string { 177 return listerner.HealthCheckURI 178 } 179 180 func (listerner *SLoadbalancerHTTPListener) GetHealthCheckCode() string { 181 return listerner.HealthCheckHttpCode 182 } 183 184 func (listerner *SLoadbalancerHTTPListener) GetHealthCheckRise() int { 185 return listerner.HealthyThreshold 186 } 187 188 func (listerner *SLoadbalancerHTTPListener) GetHealthCheckFail() int { 189 return listerner.UnhealthyThreshold 190 } 191 192 func (listerner *SLoadbalancerHTTPListener) GetHealthCheckTimeout() int { 193 return listerner.HealthCheckTimeout 194 } 195 196 func (listerner *SLoadbalancerHTTPListener) GetHealthCheckInterval() int { 197 return listerner.HealthCheckInterval 198 } 199 200 func (listerner *SLoadbalancerHTTPListener) GetHealthCheckReq() string { 201 return "" 202 } 203 204 func (listerner *SLoadbalancerHTTPListener) GetHealthCheckExp() string { 205 return "" 206 } 207 208 func (listerner *SLoadbalancerHTTPListener) GetStickySession() string { 209 return listerner.StickySession 210 } 211 212 func (listerner *SLoadbalancerHTTPListener) GetStickySessionType() string { 213 return listerner.StickySessionType 214 } 215 216 func (listerner *SLoadbalancerHTTPListener) GetStickySessionCookie() string { 217 return listerner.Cookie 218 } 219 220 func (listerner *SLoadbalancerHTTPListener) GetStickySessionCookieTimeout() int { 221 return listerner.CookieTimeout 222 } 223 224 func (listerner *SLoadbalancerHTTPListener) XForwardedForEnabled() bool { 225 if listerner.XForwardedFor == "on" { 226 return true 227 } 228 return false 229 } 230 231 func (listerner *SLoadbalancerHTTPListener) GzipEnabled() bool { 232 if listerner.Gzip == "on" { 233 return true 234 } 235 return false 236 } 237 238 func (listerner *SLoadbalancerHTTPListener) GetCertificateId() string { 239 return "" 240 } 241 242 func (listerner *SLoadbalancerHTTPListener) GetTLSCipherPolicy() string { 243 return "" 244 } 245 246 func (listerner *SLoadbalancerHTTPListener) HTTP2Enabled() bool { 247 if listerner.EnableHttp2 == "on" { 248 return true 249 } 250 return false 251 } 252 253 func (listerner *SLoadbalancerHTTPListener) GetILoadbalancerListenerRules() ([]cloudprovider.ICloudLoadbalancerListenerRule, error) { 254 rules, err := listerner.lb.region.GetLoadbalancerListenerRules(listerner.lb.LoadBalancerId, listerner.ListenerPort) 255 if err != nil { 256 return nil, err 257 } 258 iRules := []cloudprovider.ICloudLoadbalancerListenerRule{} 259 for i := 0; i < len(rules); i++ { 260 rules[i].httpListener = listerner 261 iRules = append(iRules, &rules[i]) 262 } 263 return iRules, nil 264 } 265 266 func (region *SRegion) GetLoadbalancerHTTPListener(loadbalancerId string, listenerPort int) (*SLoadbalancerHTTPListener, error) { 267 params := map[string]string{} 268 params["RegionId"] = region.RegionId 269 params["LoadBalancerId"] = loadbalancerId 270 params["ListenerPort"] = fmt.Sprintf("%d", listenerPort) 271 body, err := region.lbRequest("DescribeLoadBalancerHTTPListenerAttribute", params) 272 if err != nil { 273 return nil, err 274 } 275 listener := SLoadbalancerHTTPListener{} 276 return &listener, body.Unmarshal(&listener) 277 } 278 279 func (region *SRegion) DeleteLoadbalancerListener(loadbalancerId string, listenerPort int) error { 280 params := map[string]string{} 281 params["RegionId"] = region.RegionId 282 params["LoadBalancerId"] = loadbalancerId 283 params["ListenerPort"] = fmt.Sprintf("%d", listenerPort) 284 _, err := region.lbRequest("DeleteLoadBalancerListener", params) 285 return err 286 } 287 288 func (region *SRegion) CreateLoadbalancerHTTPListener(lb *SLoadbalancer, listener *cloudprovider.SLoadbalancerListener) (cloudprovider.ICloudLoadbalancerListener, error) { 289 params := region.constructBaseCreateListenerParams(lb, listener) 290 params = region.constructHTTPCreateListenerParams(params, listener) 291 _, err := region.lbRequest("CreateLoadBalancerHTTPListener", params) 292 if err != nil { 293 return nil, err 294 } 295 iListener, err := region.GetLoadbalancerHTTPListener(lb.LoadBalancerId, listener.ListenerPort) 296 if err != nil { 297 return nil, err 298 } 299 iListener.lb = lb 300 return iListener, nil 301 } 302 303 func (listerner *SLoadbalancerHTTPListener) Delete(ctx context.Context) error { 304 return listerner.lb.region.DeleteLoadbalancerListener(listerner.lb.LoadBalancerId, listerner.ListenerPort) 305 } 306 307 func (listerner *SLoadbalancerHTTPListener) CreateILoadBalancerListenerRule(rule *cloudprovider.SLoadbalancerListenerRule) (cloudprovider.ICloudLoadbalancerListenerRule, error) { 308 _rule := &SLoadbalancerListenerRule{ 309 Domain: rule.Domain, 310 Url: rule.Path, 311 RuleName: rule.Name, 312 } 313 if len(rule.BackendGroupID) > 0 { //&& rule.BackendGroupType == api.LB_BACKENDGROUP_TYPE_NORMAL { 314 _rule.VServerGroupId = rule.BackendGroupID 315 } 316 listenerRule, err := listerner.lb.region.CreateLoadbalancerListenerRule(listerner.ListenerPort, listerner.lb.LoadBalancerId, _rule) 317 if err != nil { 318 return nil, err 319 } 320 listenerRule.httpListener = listerner 321 return listenerRule, nil 322 } 323 324 func (listerner *SLoadbalancerHTTPListener) GetILoadBalancerListenerRuleById(ruleId string) (cloudprovider.ICloudLoadbalancerListenerRule, error) { 325 rule, err := listerner.lb.region.GetLoadbalancerListenerRule(ruleId) 326 if err != nil { 327 return nil, err 328 } 329 rule.httpListener = listerner 330 return rule, nil 331 } 332 333 func (region *SRegion) startListener(listenerPort int, loadbalancerId string) error { 334 params := map[string]string{} 335 params["RegionId"] = region.RegionId 336 params["LoadBalancerId"] = loadbalancerId 337 params["ListenerPort"] = fmt.Sprintf("%d", listenerPort) 338 _, err := region.lbRequest("StartLoadBalancerListener", params) 339 return err 340 } 341 342 func (region *SRegion) stopListener(listenerPort int, loadbalancerId string) error { 343 params := map[string]string{} 344 params["RegionId"] = region.RegionId 345 params["LoadBalancerId"] = loadbalancerId 346 params["ListenerPort"] = fmt.Sprintf("%d", listenerPort) 347 _, err := region.lbRequest("StopLoadBalancerListener", params) 348 return err 349 } 350 351 func (listerner *SLoadbalancerHTTPListener) Start() error { 352 return listerner.lb.region.startListener(listerner.ListenerPort, listerner.lb.LoadBalancerId) 353 } 354 355 func (listerner *SLoadbalancerHTTPListener) Stop() error { 356 return listerner.lb.region.stopListener(listerner.ListenerPort, listerner.lb.LoadBalancerId) 357 } 358 359 func (region *SRegion) SyncLoadbalancerHTTPListener(lb *SLoadbalancer, listener *cloudprovider.SLoadbalancerListener) error { 360 params := region.constructBaseCreateListenerParams(lb, listener) 361 params = region.constructHTTPCreateListenerParams(params, listener) 362 _, err := region.lbRequest("SetLoadBalancerHTTPListenerAttribute", params) 363 return err 364 } 365 366 func (listerner *SLoadbalancerHTTPListener) Sync(ctx context.Context, lblis *cloudprovider.SLoadbalancerListener) error { 367 return listerner.lb.region.SyncLoadbalancerHTTPListener(listerner.lb, lblis) 368 } 369 370 func (listerner *SLoadbalancerHTTPListener) GetClientIdleTimeout() int { 371 return 0 372 } 373 374 func (listerner *SLoadbalancerHTTPListener) GetBackendConnectTimeout() int { 375 return 0 376 }