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