synapse 0.13.1 → 0.13.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +13 -1
- data/lib/synapse/haproxy.rb +359 -39
- data/lib/synapse/service_watcher/dns.rb +1 -0
- data/lib/synapse/service_watcher/zookeeper_dns.rb +2 -2
- data/lib/synapse/version.rb +1 -1
- data/spec/lib/synapse/file_output_spec.rb +1 -1
- data/spec/lib/synapse/haproxy_spec.rb +192 -13
- data/spec/spec_helper.rb +4 -0
- data/spec/support/minimum.conf.yaml +8 -6
- data/synapse.gemspec +1 -0
- metadata +67 -31
- checksums.yaml +0 -7
data/README.md
CHANGED
@@ -149,9 +149,19 @@ Put these into the `discovery` section of the service hash, with these options:
|
|
149
149
|
##### Base #####
|
150
150
|
|
151
151
|
The base watcher is useful in situations where you only want to use the servers in the `default_servers` list.
|
152
|
-
It has
|
152
|
+
It has the following options:
|
153
153
|
|
154
154
|
* `method`: base
|
155
|
+
* `label_filter`: optional filter to be applied to discovered service nodes
|
156
|
+
|
157
|
+
###### Filtering service nodes ######
|
158
|
+
Synapse can be configured to only return service nodes that match a `label_filter` predicate. If provided, the `label_filter` hash should contain the following:
|
159
|
+
|
160
|
+
* `label`: The label for which the filter is applied
|
161
|
+
* `value`: The comparison value
|
162
|
+
* `condition` (one of ['`equals`']): The type of filter condition to be applied. Only `equals` is supported at present
|
163
|
+
|
164
|
+
Given a `label_filter`: `{ "label": "cluster", "value": "dev", "condition": "equals" }`, this will return only service nodes that contain the label value `{ "cluster": "dev" }`.
|
155
165
|
|
156
166
|
##### Zookeeper #####
|
157
167
|
|
@@ -175,6 +185,7 @@ Synapse attempts to decode the data in each of these nodes using JSON and you ca
|
|
175
185
|
* `endpoint_name` (default: nil): If using the `serverset` method, this controls which of the `additionalEndpoints` is chosen instead of the `serviceEndpoint` data. If not supplied the `serverset` method will use the host/port from the `serviceEndpoint` data.
|
176
186
|
|
177
187
|
If the `method` is `nerve`, then we expect to find nerve registrations with a `host` and a `port`.
|
188
|
+
Any additional metadata for the service node provided in the hash `labels` will be parsed. This information is used by `label_filter` configuration.
|
178
189
|
|
179
190
|
If the `method` is `serverset` then we expect to find Finagle ServerSet
|
180
191
|
(also used by [Aurora](https://github.com/apache/aurora/blob/master/docs/user-guide.md#service-discovery)) registrations with a `serviceEndpoint` and optionally one or more `additionalEndpoints`.
|
@@ -261,6 +272,7 @@ This section is its own hash, which should contain the following keys:
|
|
261
272
|
* `listen`: these lines will be parsed and placed in the correct `frontend`/`backend` section as applicable; you can put lines which are the same for the frontend and backend here.
|
262
273
|
* `backend_order`: optional: how backends should be ordered in the `backend` stanza. (default is shuffling). Setting to `asc` means sorting backends in ascending alphabetical order before generating stanza. `desc` means descending alphabetical order. `no_shuffle` means no shuffling or sorting.
|
263
274
|
* `shared_frontend`: optional: haproxy configuration directives for a shared http frontend (see below)
|
275
|
+
* `cookie_value_method`: optional: default value is `name`, it defines the way your backends receive a cookie value in http mode. If equal to `hash`, synapse hashes backend names on cookie value assignation of your discovered backends, useful when you want to use haproxy cookie feature but you do not want that your end users receive a Set-Cookie with your server name and ip readable in clear.
|
264
276
|
|
265
277
|
<a name="haproxy"/>
|
266
278
|
### Configuring HAProxy ###
|
data/lib/synapse/haproxy.rb
CHANGED
@@ -1,15 +1,17 @@
|
|
1
1
|
require 'fileutils'
|
2
2
|
require 'json'
|
3
3
|
require 'socket'
|
4
|
+
require 'digest/sha1'
|
4
5
|
|
5
6
|
module Synapse
|
6
7
|
class Haproxy
|
7
8
|
include Logging
|
8
|
-
attr_reader :opts
|
9
|
+
attr_reader :opts
|
9
10
|
|
10
|
-
# these come from the documentation for haproxy 1.5
|
11
|
+
# these come from the documentation for haproxy (1.5 and 1.6)
|
11
12
|
# http://haproxy.1wt.eu/download/1.5/doc/configuration.txt
|
12
|
-
|
13
|
+
# http://haproxy.1wt.eu/download/1.6/doc/configuration.txt
|
14
|
+
SECTION_FIELDS = {
|
13
15
|
"backend" => [
|
14
16
|
"acl",
|
15
17
|
"appsession",
|
@@ -23,6 +25,11 @@ module Synapse
|
|
23
25
|
"description",
|
24
26
|
"disabled",
|
25
27
|
"dispatch",
|
28
|
+
"email-alert from",
|
29
|
+
"email-alert level",
|
30
|
+
"email-alert mailers",
|
31
|
+
"email-alert myhostname",
|
32
|
+
"email-alert to",
|
26
33
|
"enabled",
|
27
34
|
"errorfile",
|
28
35
|
"errorloc",
|
@@ -37,10 +44,59 @@ module Synapse
|
|
37
44
|
"http-check send-state",
|
38
45
|
"http-request",
|
39
46
|
"http-response",
|
47
|
+
"http-send-name-header",
|
48
|
+
"http-reuse",
|
49
|
+
"http-send-name-header",
|
40
50
|
"id",
|
41
51
|
"ignore-persist",
|
52
|
+
"load-server-state-from-file",
|
42
53
|
"log",
|
54
|
+
"log-tag",
|
55
|
+
"max-keep-alive-queue",
|
43
56
|
"mode",
|
57
|
+
"no log",
|
58
|
+
"no option abortonclose",
|
59
|
+
"no option accept-invalid-http-response",
|
60
|
+
"no option allbackups",
|
61
|
+
"no option allredisp",
|
62
|
+
"no option checkcache",
|
63
|
+
"no option forceclose",
|
64
|
+
"no option forwardfor",
|
65
|
+
"no option http-buffer-request",
|
66
|
+
"no option http-keep-alive",
|
67
|
+
"no option http-no-delay",
|
68
|
+
"no option http-pretend-keepalive",
|
69
|
+
"no option http-server-close",
|
70
|
+
"no option http-tunnel",
|
71
|
+
"no option httpchk",
|
72
|
+
"no option httpclose",
|
73
|
+
"no option httplog",
|
74
|
+
"no option http_proxy",
|
75
|
+
"no option independent-streams",
|
76
|
+
"no option lb-agent-chk",
|
77
|
+
"no option ldap-check",
|
78
|
+
"no option external-check",
|
79
|
+
"no option log-health-checks",
|
80
|
+
"no option mysql-check",
|
81
|
+
"no option pgsql-check",
|
82
|
+
"no option nolinger",
|
83
|
+
"no option originalto",
|
84
|
+
"no option persist",
|
85
|
+
"no option pgsql-check",
|
86
|
+
"no option prefer-last-server",
|
87
|
+
"no option redispatch",
|
88
|
+
"no option redis-check",
|
89
|
+
"no option smtpchk",
|
90
|
+
"no option splice-auto",
|
91
|
+
"no option splice-request",
|
92
|
+
"no option splice-response",
|
93
|
+
"no option srvtcpka",
|
94
|
+
"no option ssl-hello-chk",
|
95
|
+
"no option tcp-check",
|
96
|
+
"no option tcp-smart-connect",
|
97
|
+
"no option tcpka",
|
98
|
+
"no option tcplog",
|
99
|
+
"no option transparent",
|
44
100
|
"option abortonclose",
|
45
101
|
"option accept-invalid-http-response",
|
46
102
|
"option allbackups",
|
@@ -48,9 +104,12 @@ module Synapse
|
|
48
104
|
"option checkcache",
|
49
105
|
"option forceclose",
|
50
106
|
"option forwardfor",
|
107
|
+
"option http-buffer-request",
|
108
|
+
"option http-keep-alive",
|
51
109
|
"option http-no-delay",
|
52
110
|
"option http-pretend-keepalive",
|
53
111
|
"option http-server-close",
|
112
|
+
"option http-tunnel",
|
54
113
|
"option httpchk",
|
55
114
|
"option httpclose",
|
56
115
|
"option httplog",
|
@@ -58,12 +117,15 @@ module Synapse
|
|
58
117
|
"option independent-streams",
|
59
118
|
"option lb-agent-chk",
|
60
119
|
"option ldap-check",
|
120
|
+
"option external-check",
|
61
121
|
"option log-health-checks",
|
62
122
|
"option mysql-check",
|
63
123
|
"option pgsql-check",
|
64
124
|
"option nolinger",
|
65
125
|
"option originalto",
|
66
126
|
"option persist",
|
127
|
+
"option pgsql-check",
|
128
|
+
"option prefer-last-server",
|
67
129
|
"option redispatch",
|
68
130
|
"option redis-check",
|
69
131
|
"option smtpchk",
|
@@ -77,6 +139,8 @@ module Synapse
|
|
77
139
|
"option tcpka",
|
78
140
|
"option tcplog",
|
79
141
|
"option transparent",
|
142
|
+
"external-check command",
|
143
|
+
"external-check path",
|
80
144
|
"persist rdp-cookie",
|
81
145
|
"redirect",
|
82
146
|
"redisp",
|
@@ -105,6 +169,7 @@ module Synapse
|
|
105
169
|
"rspirep",
|
106
170
|
"rsprep",
|
107
171
|
"server",
|
172
|
+
"server-state-file-name",
|
108
173
|
"source",
|
109
174
|
"srvtimeout",
|
110
175
|
"stats admin",
|
@@ -139,6 +204,7 @@ module Synapse
|
|
139
204
|
"timeout http-request",
|
140
205
|
"timeout queue",
|
141
206
|
"timeout server",
|
207
|
+
"timeout server-fin",
|
142
208
|
"timeout srvtimeout",
|
143
209
|
"timeout tarpit",
|
144
210
|
"timeout tunnel",
|
@@ -156,6 +222,11 @@ module Synapse
|
|
156
222
|
"default-server",
|
157
223
|
"default_backend",
|
158
224
|
"disabled",
|
225
|
+
"email-alert from",
|
226
|
+
"email-alert level",
|
227
|
+
"email-alert mailers",
|
228
|
+
"email-alert myhostname",
|
229
|
+
"email-alert to",
|
159
230
|
"enabled",
|
160
231
|
"errorfile",
|
161
232
|
"errorloc",
|
@@ -166,11 +237,71 @@ module Synapse
|
|
166
237
|
"hash-type",
|
167
238
|
"http-check disable-on-404",
|
168
239
|
"http-check send-state",
|
240
|
+
"http-reuse",
|
241
|
+
"load-server-state-from-file",
|
169
242
|
"log",
|
243
|
+
"log-format",
|
244
|
+
"log-format-sd",
|
245
|
+
"log-tag",
|
246
|
+
"max-keep-alive-queue",
|
170
247
|
"maxconn",
|
171
248
|
"mode",
|
172
249
|
"monitor-net",
|
173
250
|
"monitor-uri",
|
251
|
+
"no log",
|
252
|
+
"no option abortonclose",
|
253
|
+
"no option accept-invalid-http-request",
|
254
|
+
"no option accept-invalid-http-response",
|
255
|
+
"no option allbackups",
|
256
|
+
"no option allredisp",
|
257
|
+
"no option checkcache",
|
258
|
+
"no option clitcpka",
|
259
|
+
"no option contstats",
|
260
|
+
"no option dontlog-normal",
|
261
|
+
"no option dontlognull",
|
262
|
+
"no option forceclose",
|
263
|
+
"no option forwardfor",
|
264
|
+
"no option http-buffer-request",
|
265
|
+
"no option http-ignore-probes",
|
266
|
+
"no option http-keep-alive",
|
267
|
+
"no option http-no-delay",
|
268
|
+
"no option http-pretend-keepalive",
|
269
|
+
"no option http-server-close",
|
270
|
+
"no option http-tunnel",
|
271
|
+
"no option http-use-proxy-header",
|
272
|
+
"no option httpchk",
|
273
|
+
"no option httpclose",
|
274
|
+
"no option httplog",
|
275
|
+
"no option http_proxy",
|
276
|
+
"no option independent-streams",
|
277
|
+
"no option lb-agent-chk",
|
278
|
+
"no option ldap-check",
|
279
|
+
"no option external-check",
|
280
|
+
"no option log-health-checks",
|
281
|
+
"no option log-separate-errors",
|
282
|
+
"no option logasap",
|
283
|
+
"no option mysql-check",
|
284
|
+
"no option pgsql-check",
|
285
|
+
"no option nolinger",
|
286
|
+
"no option originalto",
|
287
|
+
"no option persist",
|
288
|
+
"no option pgsql-check",
|
289
|
+
"no option prefer-last-server",
|
290
|
+
"no option redispatch",
|
291
|
+
"no option redis-check",
|
292
|
+
"no option smtpchk",
|
293
|
+
"no option socket-stats",
|
294
|
+
"no option splice-auto",
|
295
|
+
"no option splice-request",
|
296
|
+
"no option splice-response",
|
297
|
+
"no option srvtcpka",
|
298
|
+
"no option ssl-hello-chk",
|
299
|
+
"no option tcp-check",
|
300
|
+
"no option tcp-smart-accept",
|
301
|
+
"no option tcp-smart-connect",
|
302
|
+
"no option tcpka",
|
303
|
+
"no option tcplog",
|
304
|
+
"no option transparent",
|
174
305
|
"option abortonclose",
|
175
306
|
"option accept-invalid-http-request",
|
176
307
|
"option accept-invalid-http-response",
|
@@ -183,9 +314,13 @@ module Synapse
|
|
183
314
|
"option dontlognull",
|
184
315
|
"option forceclose",
|
185
316
|
"option forwardfor",
|
317
|
+
"option http-buffer-request",
|
318
|
+
"option http-ignore-probes",
|
319
|
+
"option http-keep-alive",
|
186
320
|
"option http-no-delay",
|
187
321
|
"option http-pretend-keepalive",
|
188
322
|
"option http-server-close",
|
323
|
+
"option http-tunnel",
|
189
324
|
"option http-use-proxy-header",
|
190
325
|
"option httpchk",
|
191
326
|
"option httpclose",
|
@@ -194,6 +329,7 @@ module Synapse
|
|
194
329
|
"option independent-streams",
|
195
330
|
"option lb-agent-chk",
|
196
331
|
"option ldap-check",
|
332
|
+
"option external-check",
|
197
333
|
"option log-health-checks",
|
198
334
|
"option log-separate-errors",
|
199
335
|
"option logasap",
|
@@ -202,6 +338,8 @@ module Synapse
|
|
202
338
|
"option nolinger",
|
203
339
|
"option originalto",
|
204
340
|
"option persist",
|
341
|
+
"option pgsql-check",
|
342
|
+
"option prefer-last-server",
|
205
343
|
"option redispatch",
|
206
344
|
"option redis-check",
|
207
345
|
"option smtpchk",
|
@@ -217,11 +355,14 @@ module Synapse
|
|
217
355
|
"option tcpka",
|
218
356
|
"option tcplog",
|
219
357
|
"option transparent",
|
358
|
+
"external-check command",
|
359
|
+
"external-check path",
|
220
360
|
"persist rdp-cookie",
|
221
361
|
"rate-limit sessions",
|
222
362
|
"redisp",
|
223
363
|
"redispatch",
|
224
364
|
"retries",
|
365
|
+
"server-state-file-name",
|
225
366
|
"source",
|
226
367
|
"srvtimeout",
|
227
368
|
"stats auth",
|
@@ -236,6 +377,7 @@ module Synapse
|
|
236
377
|
"stats uri",
|
237
378
|
"timeout check",
|
238
379
|
"timeout client",
|
380
|
+
"timeout client-fin",
|
239
381
|
"timeout clitimeout",
|
240
382
|
"timeout connect",
|
241
383
|
"timeout contimeout",
|
@@ -243,6 +385,7 @@ module Synapse
|
|
243
385
|
"timeout http-request",
|
244
386
|
"timeout queue",
|
245
387
|
"timeout server",
|
388
|
+
"timeout server-fin",
|
246
389
|
"timeout srvtimeout",
|
247
390
|
"timeout tarpit",
|
248
391
|
"timeout tunnel",
|
@@ -261,9 +404,15 @@ module Synapse
|
|
261
404
|
"capture response header",
|
262
405
|
"clitimeout",
|
263
406
|
"compression",
|
407
|
+
"declare capture",
|
264
408
|
"default_backend",
|
265
409
|
"description",
|
266
410
|
"disabled",
|
411
|
+
"email-alert from",
|
412
|
+
"email-alert level",
|
413
|
+
"email-alert mailers",
|
414
|
+
"email-alert myhostname",
|
415
|
+
"email-alert to",
|
267
416
|
"enabled",
|
268
417
|
"errorfile",
|
269
418
|
"errorloc",
|
@@ -276,11 +425,45 @@ module Synapse
|
|
276
425
|
"id",
|
277
426
|
"ignore-persist",
|
278
427
|
"log",
|
428
|
+
"log-format",
|
429
|
+
"log-format-sd",
|
430
|
+
"log-tag",
|
279
431
|
"maxconn",
|
280
432
|
"mode",
|
281
433
|
"monitor fail",
|
282
434
|
"monitor-net",
|
283
435
|
"monitor-uri",
|
436
|
+
"no log",
|
437
|
+
"no option accept-invalid-http-request",
|
438
|
+
"no option clitcpka",
|
439
|
+
"no option contstats",
|
440
|
+
"no option dontlog-normal",
|
441
|
+
"no option dontlognull",
|
442
|
+
"no option forceclose",
|
443
|
+
"no option forwardfor",
|
444
|
+
"no option http-buffer-request",
|
445
|
+
"no option http-ignore-probes",
|
446
|
+
"no option http-keep-alive",
|
447
|
+
"no option http-no-delay",
|
448
|
+
"no option http-pretend-keepalive",
|
449
|
+
"no option http-server-close",
|
450
|
+
"no option http-tunnel",
|
451
|
+
"no option http-use-proxy-header",
|
452
|
+
"no option httpclose",
|
453
|
+
"no option httplog",
|
454
|
+
"no option http_proxy",
|
455
|
+
"no option independent-streams",
|
456
|
+
"no option log-separate-errors",
|
457
|
+
"no option logasap",
|
458
|
+
"no option nolinger",
|
459
|
+
"no option originalto",
|
460
|
+
"no option socket-stats",
|
461
|
+
"no option splice-auto",
|
462
|
+
"no option splice-request",
|
463
|
+
"no option splice-response",
|
464
|
+
"no option tcp-smart-accept",
|
465
|
+
"no option tcpka",
|
466
|
+
"no option tcplog",
|
284
467
|
"option accept-invalid-http-request",
|
285
468
|
"option clitcpka",
|
286
469
|
"option contstats",
|
@@ -288,9 +471,13 @@ module Synapse
|
|
288
471
|
"option dontlognull",
|
289
472
|
"option forceclose",
|
290
473
|
"option forwardfor",
|
474
|
+
"option http-buffer-request",
|
475
|
+
"option http-ignore-probes",
|
476
|
+
"option http-keep-alive",
|
291
477
|
"option http-no-delay",
|
292
478
|
"option http-pretend-keepalive",
|
293
479
|
"option http-server-close",
|
480
|
+
"option http-tunnel",
|
294
481
|
"option http-use-proxy-header",
|
295
482
|
"option httpclose",
|
296
483
|
"option httplog",
|
@@ -331,10 +518,23 @@ module Synapse
|
|
331
518
|
"rspideny",
|
332
519
|
"rspirep",
|
333
520
|
"rsprep",
|
521
|
+
"stats admin",
|
522
|
+
"stats auth",
|
523
|
+
"stats enable",
|
524
|
+
"stats hide-version",
|
525
|
+
"stats http-request",
|
526
|
+
"stats realm",
|
527
|
+
"stats refresh",
|
528
|
+
"stats scope",
|
529
|
+
"stats show-desc",
|
530
|
+
"stats show-legends",
|
531
|
+
"stats show-node",
|
532
|
+
"stats uri",
|
334
533
|
"tcp-request connection",
|
335
534
|
"tcp-request content",
|
336
535
|
"tcp-request inspect-delay",
|
337
536
|
"timeout client",
|
537
|
+
"timeout client-fin",
|
338
538
|
"timeout clitimeout",
|
339
539
|
"timeout http-keep-alive",
|
340
540
|
"timeout http-request",
|
@@ -358,11 +558,17 @@ module Synapse
|
|
358
558
|
"compression",
|
359
559
|
"contimeout",
|
360
560
|
"cookie",
|
561
|
+
"declare capture",
|
361
562
|
"default-server",
|
362
563
|
"default_backend",
|
363
564
|
"description",
|
364
565
|
"disabled",
|
365
566
|
"dispatch",
|
567
|
+
"email-alert from",
|
568
|
+
"email-alert level",
|
569
|
+
"email-alert mailers",
|
570
|
+
"email-alert myhostname",
|
571
|
+
"email-alert to",
|
366
572
|
"enabled",
|
367
573
|
"errorfile",
|
368
574
|
"errorloc",
|
@@ -377,14 +583,76 @@ module Synapse
|
|
377
583
|
"http-check send-state",
|
378
584
|
"http-request",
|
379
585
|
"http-response",
|
586
|
+
"http-send-name-header",
|
587
|
+
"http-reuse",
|
588
|
+
"http-send-name-header",
|
380
589
|
"id",
|
381
590
|
"ignore-persist",
|
591
|
+
"load-server-state-from-file",
|
382
592
|
"log",
|
593
|
+
"log-format",
|
594
|
+
"log-format-sd",
|
595
|
+
"log-tag",
|
596
|
+
"max-keep-alive-queue",
|
383
597
|
"maxconn",
|
384
598
|
"mode",
|
385
599
|
"monitor fail",
|
386
600
|
"monitor-net",
|
387
601
|
"monitor-uri",
|
602
|
+
"no log",
|
603
|
+
"no option abortonclose",
|
604
|
+
"no option accept-invalid-http-request",
|
605
|
+
"no option accept-invalid-http-response",
|
606
|
+
"no option allbackups",
|
607
|
+
"no option allredisp",
|
608
|
+
"no option checkcache",
|
609
|
+
"no option clitcpka",
|
610
|
+
"no option contstats",
|
611
|
+
"no option dontlog-normal",
|
612
|
+
"no option dontlognull",
|
613
|
+
"no option forceclose",
|
614
|
+
"no option forwardfor",
|
615
|
+
"no option http-buffer-request",
|
616
|
+
"no option http-ignore-probes",
|
617
|
+
"no option http-keep-alive",
|
618
|
+
"no option http-no-delay",
|
619
|
+
"no option http-pretend-keepalive",
|
620
|
+
"no option http-server-close",
|
621
|
+
"no option http-tunnel",
|
622
|
+
"no option http-use-proxy-header",
|
623
|
+
"no option httpchk",
|
624
|
+
"no option httpclose",
|
625
|
+
"no option httplog",
|
626
|
+
"no option http_proxy",
|
627
|
+
"no option independent-streams",
|
628
|
+
"no option lb-agent-chk",
|
629
|
+
"no option ldap-check",
|
630
|
+
"no option external-check",
|
631
|
+
"no option log-health-checks",
|
632
|
+
"no option log-separate-errors",
|
633
|
+
"no option logasap",
|
634
|
+
"no option mysql-check",
|
635
|
+
"no option pgsql-check",
|
636
|
+
"no option nolinger",
|
637
|
+
"no option originalto",
|
638
|
+
"no option persist",
|
639
|
+
"no option pgsql-check",
|
640
|
+
"no option prefer-last-server",
|
641
|
+
"no option redispatch",
|
642
|
+
"no option redis-check",
|
643
|
+
"no option smtpchk",
|
644
|
+
"no option socket-stats",
|
645
|
+
"no option splice-auto",
|
646
|
+
"no option splice-request",
|
647
|
+
"no option splice-response",
|
648
|
+
"no option srvtcpka",
|
649
|
+
"no option ssl-hello-chk",
|
650
|
+
"no option tcp-check",
|
651
|
+
"no option tcp-smart-accept",
|
652
|
+
"no option tcp-smart-connect",
|
653
|
+
"no option tcpka",
|
654
|
+
"no option tcplog",
|
655
|
+
"no option transparent",
|
388
656
|
"option abortonclose",
|
389
657
|
"option accept-invalid-http-request",
|
390
658
|
"option accept-invalid-http-response",
|
@@ -397,9 +665,13 @@ module Synapse
|
|
397
665
|
"option dontlognull",
|
398
666
|
"option forceclose",
|
399
667
|
"option forwardfor",
|
668
|
+
"option http-buffer-request",
|
669
|
+
"option http-ignore-probes",
|
670
|
+
"option http-keep-alive",
|
400
671
|
"option http-no-delay",
|
401
672
|
"option http-pretend-keepalive",
|
402
673
|
"option http-server-close",
|
674
|
+
"option http-tunnel",
|
403
675
|
"option http-use-proxy-header",
|
404
676
|
"option httpchk",
|
405
677
|
"option httpclose",
|
@@ -408,6 +680,7 @@ module Synapse
|
|
408
680
|
"option independent-streams",
|
409
681
|
"option lb-agent-chk",
|
410
682
|
"option ldap-check",
|
683
|
+
"option external-check",
|
411
684
|
"option log-health-checks",
|
412
685
|
"option log-separate-errors",
|
413
686
|
"option logasap",
|
@@ -416,6 +689,8 @@ module Synapse
|
|
416
689
|
"option nolinger",
|
417
690
|
"option originalto",
|
418
691
|
"option persist",
|
692
|
+
"option pgsql-check",
|
693
|
+
"option prefer-last-server",
|
419
694
|
"option redispatch",
|
420
695
|
"option redis-check",
|
421
696
|
"option smtpchk",
|
@@ -431,6 +706,8 @@ module Synapse
|
|
431
706
|
"option tcpka",
|
432
707
|
"option tcplog",
|
433
708
|
"option transparent",
|
709
|
+
"external-check command",
|
710
|
+
"external-check path",
|
434
711
|
"persist rdp-cookie",
|
435
712
|
"rate-limit sessions",
|
436
713
|
"redirect",
|
@@ -460,6 +737,7 @@ module Synapse
|
|
460
737
|
"rspirep",
|
461
738
|
"rsprep",
|
462
739
|
"server",
|
740
|
+
"server-state-file-name",
|
463
741
|
"source",
|
464
742
|
"srvtimeout",
|
465
743
|
"stats admin",
|
@@ -490,6 +768,7 @@ module Synapse
|
|
490
768
|
"tcp-response inspect-delay",
|
491
769
|
"timeout check",
|
492
770
|
"timeout client",
|
771
|
+
"timeout client-fin",
|
493
772
|
"timeout clitimeout",
|
494
773
|
"timeout connect",
|
495
774
|
"timeout contimeout",
|
@@ -497,6 +776,7 @@ module Synapse
|
|
497
776
|
"timeout http-request",
|
498
777
|
"timeout queue",
|
499
778
|
"timeout server",
|
779
|
+
"timeout server-fin",
|
500
780
|
"timeout srvtimeout",
|
501
781
|
"timeout tarpit",
|
502
782
|
"timeout tunnel",
|
@@ -506,7 +786,10 @@ module Synapse
|
|
506
786
|
"use_backend",
|
507
787
|
"use-server"
|
508
788
|
]
|
509
|
-
}
|
789
|
+
}.freeze
|
790
|
+
|
791
|
+
DEFAULT_STATE_FILE_TTL = (60 * 60 * 24).freeze # 24 hours
|
792
|
+
STATE_FILE_UPDATE_INTERVAL = 60.freeze # iterations; not a unit of time
|
510
793
|
|
511
794
|
def initialize(opts)
|
512
795
|
super()
|
@@ -527,7 +810,6 @@ module Synapse
|
|
527
810
|
end
|
528
811
|
|
529
812
|
@opts = opts
|
530
|
-
@name = 'haproxy'
|
531
813
|
|
532
814
|
@opts['do_writes'] = true unless @opts.key?('do_writes')
|
533
815
|
@opts['do_socket'] = true unless @opts.key?('do_socket')
|
@@ -546,20 +828,15 @@ module Synapse
|
|
546
828
|
@watcher_configs = {}
|
547
829
|
|
548
830
|
@state_file_path = @opts['state_file_path']
|
549
|
-
@state_file_ttl = @opts.fetch('state_file_ttl',
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
@seen = JSON.load(File.read(@state_file_path))
|
555
|
-
rescue StandardError => e
|
556
|
-
# It's ok if the state file doesn't exist
|
557
|
-
end
|
558
|
-
end
|
831
|
+
@state_file_ttl = @opts.fetch('state_file_ttl', DEFAULT_STATE_FILE_TTL).to_i
|
832
|
+
end
|
833
|
+
|
834
|
+
def name
|
835
|
+
'haproxy'
|
559
836
|
end
|
560
837
|
|
561
838
|
def tick(watchers)
|
562
|
-
if @time %
|
839
|
+
if (@time % STATE_FILE_UPDATE_INTERVAL) == 0
|
563
840
|
update_state_file(watchers)
|
564
841
|
end
|
565
842
|
|
@@ -654,7 +931,7 @@ module Synapse
|
|
654
931
|
config[section].concat(
|
655
932
|
watcher.haproxy['listen'].select {|setting|
|
656
933
|
parsed_setting = setting.strip.gsub(/\s+/, ' ').downcase
|
657
|
-
|
934
|
+
SECTION_FIELDS[section].any? {|field| parsed_setting.start_with?(field)}
|
658
935
|
})
|
659
936
|
|
660
937
|
# pick only those fields that are valid and warn about the invalid ones
|
@@ -667,7 +944,7 @@ module Synapse
|
|
667
944
|
def validate_haproxy_stanza(stanza, stanza_type, service_name)
|
668
945
|
return stanza.select {|setting|
|
669
946
|
parsed_setting = setting.strip.gsub(/\s+/, ' ').downcase
|
670
|
-
if
|
947
|
+
if SECTION_FIELDS[stanza_type].any? {|field| parsed_setting.start_with?(field)}
|
671
948
|
true
|
672
949
|
else
|
673
950
|
log.warn "synapse: service #{service_name} contains invalid #{stanza_type} setting: '#{setting}', discarding"
|
@@ -696,7 +973,7 @@ module Synapse
|
|
696
973
|
|
697
974
|
# The ordering here is important. First we add all the backends in the
|
698
975
|
# disabled state...
|
699
|
-
|
976
|
+
seen.fetch(watcher.name, []).each do |backend_name, backend|
|
700
977
|
backends[backend_name] = backend.merge('enabled' => false)
|
701
978
|
end
|
702
979
|
|
@@ -731,13 +1008,21 @@ module Synapse
|
|
731
1008
|
else
|
732
1009
|
backends.keys.shuffle
|
733
1010
|
end
|
1011
|
+
|
734
1012
|
stanza = [
|
735
1013
|
"\nbackend #{watcher.haproxy.fetch('backend_name', watcher.name)}",
|
736
1014
|
config.map {|c| "\t#{c}"},
|
737
1015
|
keys.map {|backend_name|
|
738
1016
|
backend = backends[backend_name]
|
739
1017
|
b = "\tserver #{backend_name} #{backend['host']}:#{backend['port']}"
|
740
|
-
|
1018
|
+
unless config.include?('mode tcp')
|
1019
|
+
b = case watcher.haproxy['cookie_value_method']
|
1020
|
+
when 'hash'
|
1021
|
+
b = "#{b} cookie #{Digest::SHA1.hexdigest(backend_name)}"
|
1022
|
+
else
|
1023
|
+
b = "#{b} cookie #{backend_name}"
|
1024
|
+
end
|
1025
|
+
end
|
741
1026
|
b = "#{b} #{watcher.haproxy['server_options']}" if watcher.haproxy['server_options']
|
742
1027
|
b = "#{b} #{backend['haproxy_server_options']}" if backend['haproxy_server_options']
|
743
1028
|
b = "#{b} disabled" unless backend['enabled']
|
@@ -745,16 +1030,24 @@ module Synapse
|
|
745
1030
|
]
|
746
1031
|
end
|
747
1032
|
|
1033
|
+
def haproxy_exec(command)
|
1034
|
+
s = UNIXSocket.new(@opts['socket_file_path'])
|
1035
|
+
s.write(command)
|
1036
|
+
s.read
|
1037
|
+
ensure
|
1038
|
+
s.close if s
|
1039
|
+
end
|
1040
|
+
|
748
1041
|
# tries to set active backends via haproxy's stats socket
|
749
1042
|
# because we can't add backends via the socket, we might still need to restart haproxy
|
750
1043
|
def update_backends(watchers)
|
751
1044
|
# first, get a list of existing servers for various backends
|
752
1045
|
begin
|
753
|
-
|
754
|
-
|
755
|
-
info = s.read()
|
1046
|
+
stat_command = "show stat\n"
|
1047
|
+
info = haproxy_exec(stat_command)
|
756
1048
|
rescue StandardError => e
|
757
|
-
log.warn "synapse:
|
1049
|
+
log.warn "synapse: restart required because socket command #{stat_command} failed "\
|
1050
|
+
"with error #{e.inspect}"
|
758
1051
|
@restart_required = true
|
759
1052
|
return
|
760
1053
|
end
|
@@ -805,15 +1098,15 @@ module Synapse
|
|
805
1098
|
|
806
1099
|
# actually write the command to the socket
|
807
1100
|
begin
|
808
|
-
|
809
|
-
s.write(command)
|
810
|
-
output = s.read()
|
1101
|
+
output = haproxy_exec(command)
|
811
1102
|
rescue StandardError => e
|
812
|
-
log.warn "synapse:
|
1103
|
+
log.warn "synapse: restart required because socket command #{command} failed with "\
|
1104
|
+
"error #{e.inspect}"
|
813
1105
|
@restart_required = true
|
814
1106
|
else
|
815
1107
|
unless output == "\n"
|
816
|
-
log.warn "synapse: socket command #{command} failed
|
1108
|
+
log.warn "synapse: restart required because socket command #{command} failed with "\
|
1109
|
+
"output #{output}"
|
817
1110
|
@restart_required = true
|
818
1111
|
end
|
819
1112
|
end
|
@@ -865,19 +1158,34 @@ module Synapse
|
|
865
1158
|
def construct_name(backend)
|
866
1159
|
name = "#{backend['host']}:#{backend['port']}"
|
867
1160
|
if backend['name'] && !backend['name'].empty?
|
868
|
-
name = "#{
|
1161
|
+
name = "#{backend['name']}_#{name}"
|
869
1162
|
end
|
870
1163
|
|
871
1164
|
return name
|
872
1165
|
end
|
873
1166
|
|
1167
|
+
######################################
|
1168
|
+
# methods for managing the state file
|
1169
|
+
######################################
|
1170
|
+
def seen
|
1171
|
+
# if we don't support the state file, return nothing
|
1172
|
+
return {} if @state_file_path.nil?
|
1173
|
+
|
1174
|
+
# if we've never needed the backends, now is the time to load them
|
1175
|
+
@seen = read_state_file if @seen.nil?
|
1176
|
+
|
1177
|
+
@seen
|
1178
|
+
end
|
1179
|
+
|
874
1180
|
def update_state_file(watchers)
|
875
|
-
|
1181
|
+
# if we don't support the state file, do nothing
|
1182
|
+
return if @state_file_path.nil?
|
876
1183
|
|
1184
|
+
log.info "synapse: writing state file"
|
877
1185
|
timestamp = Time.now.to_i
|
878
1186
|
|
879
1187
|
# Remove stale backends
|
880
|
-
|
1188
|
+
seen.each do |watcher_name, backends|
|
881
1189
|
backends.each do |backend_name, backend|
|
882
1190
|
ts = backend.fetch('timestamp', 0)
|
883
1191
|
delta = (timestamp - ts).abs
|
@@ -889,23 +1197,35 @@ module Synapse
|
|
889
1197
|
end
|
890
1198
|
|
891
1199
|
# Remove any services which no longer have any backends
|
892
|
-
|
1200
|
+
seen.reject!{|watcher_name, backends| backends.keys.length == 0}
|
893
1201
|
|
894
1202
|
# Add backends from watchers
|
895
1203
|
watchers.each do |watcher|
|
896
|
-
|
897
|
-
@seen[watcher.name] = {}
|
898
|
-
end
|
1204
|
+
seen[watcher.name] ||= {}
|
899
1205
|
|
900
1206
|
watcher.backends.each do |backend|
|
901
1207
|
backend_name = construct_name(backend)
|
902
|
-
|
1208
|
+
seen[watcher.name][backend_name] = backend.merge('timestamp' => timestamp)
|
903
1209
|
end
|
904
1210
|
end
|
905
1211
|
|
906
|
-
#
|
1212
|
+
# write the data!
|
1213
|
+
write_data_to_state_file(seen)
|
1214
|
+
end
|
1215
|
+
|
1216
|
+
def read_state_file
|
1217
|
+
# Some versions of JSON return nil on an empty file ...
|
1218
|
+
JSON.load(File.read(@state_file_path)) || {}
|
1219
|
+
rescue StandardError => e
|
1220
|
+
# It's ok if the state file doesn't exist or contains invalid data
|
1221
|
+
# The state file will be rebuilt automatically
|
1222
|
+
{}
|
1223
|
+
end
|
1224
|
+
|
1225
|
+
# we do this atomically so the state file is always consistent
|
1226
|
+
def write_data_to_state_file(data)
|
907
1227
|
tmp_state_file_path = @state_file_path + ".tmp"
|
908
|
-
File.write(tmp_state_file_path, JSON.pretty_generate(
|
1228
|
+
File.write(tmp_state_file_path, JSON.pretty_generate(data))
|
909
1229
|
FileUtils.mv(tmp_state_file_path, @state_file_path)
|
910
1230
|
end
|
911
1231
|
end
|