synapse 0.13.1 → 0.13.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
@@ -129,11 +129,11 @@ class Synapse::ServiceWatcher
|
|
129
129
|
|
130
130
|
def start
|
131
131
|
dns_discovery_opts = @discovery.select do |k,_|
|
132
|
-
k == 'nameserver'
|
132
|
+
k == 'nameserver' || k == 'label_filter'
|
133
133
|
end
|
134
134
|
|
135
135
|
zookeeper_discovery_opts = @discovery.select do |k,_|
|
136
|
-
k == 'hosts' || k == 'path'
|
136
|
+
k == 'hosts' || k == 'path' || k == 'label_filter'
|
137
137
|
end
|
138
138
|
|
139
139
|
@check_interval = @discovery['check_interval'] || 30.0
|
data/lib/synapse/version.rb
CHANGED
@@ -35,7 +35,7 @@ describe Synapse::FileOutput do
|
|
35
35
|
it 'manages correct files' do
|
36
36
|
subject.update_config([mockwatcher_1, mockwatcher_2])
|
37
37
|
FileUtils.cd(config['file_output']['output_directory']) do
|
38
|
-
expect(Dir.glob('*.json')).to eql(['example_service.json', 'foobar_service.json'])
|
38
|
+
expect(Dir.glob('*.json').sort).to eql(['example_service.json', 'foobar_service.json'])
|
39
39
|
end
|
40
40
|
# Should clean up after itself
|
41
41
|
subject.update_config([mockwatcher_1])
|
@@ -16,31 +16,182 @@ describe Synapse::Haproxy do
|
|
16
16
|
|
17
17
|
let(:mockwatcher_with_server_options) do
|
18
18
|
mockWatcher = double(Synapse::ServiceWatcher)
|
19
|
-
allow(mockWatcher).to receive(:name).and_return('
|
19
|
+
allow(mockWatcher).to receive(:name).and_return('example_service2')
|
20
20
|
backends = [{ 'host' => 'somehost', 'port' => 5555, 'haproxy_server_options' => 'backup'}]
|
21
21
|
allow(mockWatcher).to receive(:backends).and_return(backends)
|
22
22
|
allow(mockWatcher).to receive(:haproxy).and_return({'server_options' => "check inter 2000 rise 3 fall 2"})
|
23
23
|
mockWatcher
|
24
24
|
end
|
25
25
|
|
26
|
+
let(:mockwatcher_with_cookie_value_method_hash) do
|
27
|
+
mockWatcher = double(Synapse::ServiceWatcher)
|
28
|
+
allow(mockWatcher).to receive(:name).and_return('example_service3')
|
29
|
+
backends = [{ 'host' => 'somehost', 'port' => 5555}]
|
30
|
+
allow(mockWatcher).to receive(:backends).and_return(backends)
|
31
|
+
allow(mockWatcher).to receive(:haproxy).and_return({'server_options' => "check inter 2000 rise 3 fall 2", 'cookie_value_method' => 'hash'})
|
32
|
+
mockWatcher
|
33
|
+
end
|
34
|
+
|
26
35
|
let(:mockwatcher_frontend) do
|
27
36
|
mockWatcher = double(Synapse::ServiceWatcher)
|
28
|
-
allow(mockWatcher).to receive(:name).and_return('
|
37
|
+
allow(mockWatcher).to receive(:name).and_return('example_service4')
|
29
38
|
allow(mockWatcher).to receive(:haproxy).and_return('port' => 2200)
|
30
39
|
mockWatcher
|
31
40
|
end
|
32
41
|
|
33
42
|
let(:mockwatcher_frontend_with_bind_address) do
|
34
43
|
mockWatcher = double(Synapse::ServiceWatcher)
|
35
|
-
allow(mockWatcher).to receive(:name).and_return('
|
44
|
+
allow(mockWatcher).to receive(:name).and_return('example_service5')
|
36
45
|
allow(mockWatcher).to receive(:haproxy).and_return('port' => 2200, 'bind_address' => "127.0.0.3")
|
37
46
|
mockWatcher
|
38
47
|
end
|
39
48
|
|
49
|
+
describe '#name' do
|
50
|
+
it 'returns haproxy' do
|
51
|
+
expect(subject.name).to eq('haproxy')
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe '#update_config' do
|
56
|
+
let(:watchers) { [mockwatcher_frontend, mockwatcher_frontend_with_bind_address] }
|
57
|
+
|
58
|
+
shared_context 'generate_config is stubbed out' do
|
59
|
+
let(:new_config) { 'this is a new config!' }
|
60
|
+
before { expect(subject).to receive(:generate_config).and_return(new_config) }
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'always updates the config' do
|
64
|
+
expect(subject).to receive(:generate_config).with(watchers)
|
65
|
+
subject.update_config(watchers)
|
66
|
+
end
|
67
|
+
|
68
|
+
context 'when we support socket updates' do
|
69
|
+
include_context 'generate_config is stubbed out'
|
70
|
+
before do
|
71
|
+
config['haproxy']['do_socket'] = true
|
72
|
+
config['haproxy']['socket_file_path'] = 'socket_file_path'
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'updates backends via the socket' do
|
76
|
+
expect(subject).to receive(:update_backends).with(watchers)
|
77
|
+
subject.update_config(watchers)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context 'when we do not support socket updates' do
|
82
|
+
include_context 'generate_config is stubbed out'
|
83
|
+
before { config['haproxy']['do_socket'] = false }
|
84
|
+
|
85
|
+
it 'does not update the backends' do
|
86
|
+
expect(subject).to_not receive(:update_backends)
|
87
|
+
subject.update_config(watchers)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
context 'if we support config writes' do
|
92
|
+
include_context 'generate_config is stubbed out'
|
93
|
+
before { config['haproxy']['do_writes'] = true }
|
94
|
+
|
95
|
+
it 'writes the new config' do
|
96
|
+
expect(subject).to receive(:write_config).with(new_config)
|
97
|
+
subject.update_config(watchers)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
context 'if we do not support config writes' do
|
102
|
+
include_context 'generate_config is stubbed out'
|
103
|
+
before { config['haproxy']['do_writes'] = false }
|
104
|
+
|
105
|
+
it 'does not write the config' do
|
106
|
+
expect(subject).to_not receive(:write_config)
|
107
|
+
subject.update_config(watchers)
|
108
|
+
end
|
109
|
+
end
|
40
110
|
|
41
|
-
|
42
|
-
|
43
|
-
|
111
|
+
context 'when we support config writes and reloads but not socket updates' do
|
112
|
+
include_context 'generate_config is stubbed out'
|
113
|
+
|
114
|
+
before do
|
115
|
+
config['haproxy']['do_writes'] = true
|
116
|
+
config['haproxy']['do_reloads'] = true
|
117
|
+
config['haproxy']['do_socket'] = false
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'always does a reload' do
|
121
|
+
expect(subject).to receive(:write_config).with(new_config)
|
122
|
+
expect(subject).to receive(:restart)
|
123
|
+
subject.update_config(watchers)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
describe '#tick' do
|
129
|
+
it 'updates the state file at regular intervals' do
|
130
|
+
expect(subject).to receive(:update_state_file).twice
|
131
|
+
(described_class::STATE_FILE_UPDATE_INTERVAL + 1).times do
|
132
|
+
subject.tick({})
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
describe '#update_state_file' do
|
138
|
+
let(:watchers) { [mockwatcher, mockwatcher_with_server_options] }
|
139
|
+
let(:state_file_ttl) { 60 } # seconds
|
140
|
+
|
141
|
+
before do
|
142
|
+
config['haproxy']['state_file_path'] = '/statefile'
|
143
|
+
config['haproxy']['state_file_ttl'] = state_file_ttl
|
144
|
+
allow(subject).to receive(:write_data_to_state_file)
|
145
|
+
end
|
146
|
+
|
147
|
+
it 'adds backends along with timestamps' do
|
148
|
+
subject.update_state_file(watchers)
|
149
|
+
data = subject.send(:seen)
|
150
|
+
|
151
|
+
watcher_names = watchers.map{ |w| w.name }
|
152
|
+
expect(data.keys).to contain_exactly(*watcher_names)
|
153
|
+
|
154
|
+
watchers.each do |watcher|
|
155
|
+
backend_names = watcher.backends.map{ |b| subject.construct_name(b) }
|
156
|
+
expect(data[watcher.name].keys).to contain_exactly(*backend_names)
|
157
|
+
|
158
|
+
backend_names.each do |backend_name|
|
159
|
+
expect(data[watcher.name][backend_name]).to include('timestamp')
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
context 'when the state file contains backends not in the watcher' do
|
165
|
+
it 'keeps them in the config' do
|
166
|
+
subject.update_state_file(watchers)
|
167
|
+
|
168
|
+
expect do
|
169
|
+
watchers.each do |watcher|
|
170
|
+
allow(watcher).to receive(:backends).and_return([])
|
171
|
+
end
|
172
|
+
subject.update_state_file(watchers)
|
173
|
+
end.to_not change { subject.send(:seen) }
|
174
|
+
end
|
175
|
+
|
176
|
+
context 'if those backends are stale' do
|
177
|
+
it 'removes those backends' do
|
178
|
+
subject.update_state_file(watchers)
|
179
|
+
|
180
|
+
watchers.each do |watcher|
|
181
|
+
allow(watcher).to receive(:backends).and_return([])
|
182
|
+
end
|
183
|
+
|
184
|
+
# the final +1 puts us over the expiry limit
|
185
|
+
Timecop.travel(Time.now + state_file_ttl + 1) do
|
186
|
+
subject.update_state_file(watchers)
|
187
|
+
data = subject.send(:seen)
|
188
|
+
watchers.each do |watcher|
|
189
|
+
expect(data[watcher.name]).to be_empty
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
44
195
|
end
|
45
196
|
|
46
197
|
it 'generates backend stanza' do
|
@@ -51,16 +202,39 @@ describe Synapse::Haproxy do
|
|
51
202
|
describe 'generate backend stanza in correct order' do
|
52
203
|
let(:multiple_backends_stanza_map) do
|
53
204
|
{
|
54
|
-
'asc' => [
|
55
|
-
|
56
|
-
|
205
|
+
'asc' => [
|
206
|
+
"\nbackend example_service",
|
207
|
+
[],
|
208
|
+
["\tserver somehost1_10.11.11.11:5555 10.11.11.11:5555 cookie somehost1_10.11.11.11:5555 check inter 2000 rise 3 fall 2",
|
209
|
+
"\tserver somehost2_10.10.10.10:5555 10.10.10.10:5555 cookie somehost2_10.10.10.10:5555 check inter 2000 rise 3 fall 2",
|
210
|
+
"\tserver somehost3_10.22.22.22:5555 10.22.22.22:5555 cookie somehost3_10.22.22.22:5555 check inter 2000 rise 3 fall 2"
|
211
|
+
]
|
212
|
+
],
|
213
|
+
'desc' => [
|
214
|
+
"\nbackend example_service",
|
215
|
+
[],
|
216
|
+
["\tserver somehost3_10.22.22.22:5555 10.22.22.22:5555 cookie somehost3_10.22.22.22:5555 check inter 2000 rise 3 fall 2",
|
217
|
+
"\tserver somehost2_10.10.10.10:5555 10.10.10.10:5555 cookie somehost2_10.10.10.10:5555 check inter 2000 rise 3 fall 2",
|
218
|
+
"\tserver somehost1_10.11.11.11:5555 10.11.11.11:5555 cookie somehost1_10.11.11.11:5555 check inter 2000 rise 3 fall 2"
|
219
|
+
]
|
220
|
+
],
|
221
|
+
'no_shuffle' => [
|
222
|
+
"\nbackend example_service",
|
223
|
+
[],
|
224
|
+
["\tserver somehost1_10.11.11.11:5555 10.11.11.11:5555 cookie somehost1_10.11.11.11:5555 check inter 2000 rise 3 fall 2",
|
225
|
+
"\tserver somehost3_10.22.22.22:5555 10.22.22.22:5555 cookie somehost3_10.22.22.22:5555 check inter 2000 rise 3 fall 2",
|
226
|
+
"\tserver somehost2_10.10.10.10:5555 10.10.10.10:5555 cookie somehost2_10.10.10.10:5555 check inter 2000 rise 3 fall 2"
|
227
|
+
]
|
228
|
+
]
|
57
229
|
}
|
58
230
|
end
|
59
231
|
|
60
232
|
let(:mockwatcher_with_multiple_backends) do
|
61
233
|
mockWatcher = double(Synapse::ServiceWatcher)
|
62
234
|
allow(mockWatcher).to receive(:name).and_return('example_service')
|
63
|
-
backends = [{ 'host' => '
|
235
|
+
backends = [{ 'host' => '10.11.11.11', 'port' => 5555, 'name' => 'somehost1'},
|
236
|
+
{ 'host' => '10.22.22.22', 'port' => 5555, 'name' => 'somehost3'},
|
237
|
+
{ 'host' => '10.10.10.10', 'port' => 5555, 'name' => 'somehost2'}]
|
64
238
|
allow(mockWatcher).to receive(:backends).and_return(backends)
|
65
239
|
mockWatcher
|
66
240
|
end
|
@@ -76,6 +250,11 @@ describe Synapse::Haproxy do
|
|
76
250
|
end
|
77
251
|
end
|
78
252
|
|
253
|
+
it 'hashes backend name as cookie value' do
|
254
|
+
mockConfig = []
|
255
|
+
expect(subject.generate_backend_stanza(mockwatcher_with_cookie_value_method_hash, mockConfig)).to eql(["\nbackend example_service3", [], ["\tserver somehost:5555 somehost:5555 cookie 9e736eef2f5a1d441e34ade3d2a8eb1e3abb1c92 check inter 2000 rise 3 fall 2"]])
|
256
|
+
end
|
257
|
+
|
79
258
|
it 'generates backend stanza without cookies for tcp mode' do
|
80
259
|
mockConfig = ['mode tcp']
|
81
260
|
expect(subject.generate_backend_stanza(mockwatcher, mockConfig)).to eql(["\nbackend example_service", ["\tmode tcp"], ["\tserver somehost:5555 somehost:5555 check inter 2000 rise 3 fall 2"]])
|
@@ -83,17 +262,17 @@ describe Synapse::Haproxy do
|
|
83
262
|
|
84
263
|
it 'respects haproxy_server_options' do
|
85
264
|
mockConfig = []
|
86
|
-
expect(subject.generate_backend_stanza(mockwatcher_with_server_options, mockConfig)).to eql(["\nbackend
|
265
|
+
expect(subject.generate_backend_stanza(mockwatcher_with_server_options, mockConfig)).to eql(["\nbackend example_service2", [], ["\tserver somehost:5555 somehost:5555 cookie somehost:5555 check inter 2000 rise 3 fall 2 backup"]])
|
87
266
|
end
|
88
267
|
|
89
268
|
it 'generates frontend stanza ' do
|
90
269
|
mockConfig = []
|
91
|
-
expect(subject.generate_frontend_stanza(mockwatcher_frontend, mockConfig)).to eql(["\nfrontend
|
270
|
+
expect(subject.generate_frontend_stanza(mockwatcher_frontend, mockConfig)).to eql(["\nfrontend example_service4", [], "\tbind localhost:2200", "\tdefault_backend example_service4"])
|
92
271
|
end
|
93
272
|
|
94
273
|
it 'respects frontend bind_address ' do
|
95
274
|
mockConfig = []
|
96
|
-
expect(subject.generate_frontend_stanza(mockwatcher_frontend_with_bind_address, mockConfig)).to eql(["\nfrontend
|
275
|
+
expect(subject.generate_frontend_stanza(mockwatcher_frontend_with_bind_address, mockConfig)).to eql(["\nfrontend example_service5", [], "\tbind 127.0.0.3:2200", "\tdefault_backend example_service5"])
|
97
276
|
end
|
98
277
|
|
99
278
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -9,6 +9,10 @@ require 'pry'
|
|
9
9
|
require 'support/configuration'
|
10
10
|
require 'webmock/rspec'
|
11
11
|
|
12
|
+
# configure timecop
|
13
|
+
require 'timecop'
|
14
|
+
Timecop.safe_mode = true
|
15
|
+
|
12
16
|
RSpec.configure do |config|
|
13
17
|
config.run_all_when_everything_filtered = true
|
14
18
|
config.filter_run :focus
|
@@ -1,8 +1,6 @@
|
|
1
1
|
# list the services to connect
|
2
2
|
services:
|
3
|
-
|
4
|
-
local_port: 3210
|
5
|
-
server_options: test_option
|
3
|
+
test:
|
6
4
|
default_servers:
|
7
5
|
- { name: default1, host: localhost, port: 8080}
|
8
6
|
discovery:
|
@@ -10,9 +8,13 @@ services:
|
|
10
8
|
path: /airbnb/service/logging/event_collector
|
11
9
|
hosts:
|
12
10
|
- localhost:2181
|
13
|
-
|
14
|
-
|
15
|
-
|
11
|
+
haproxy:
|
12
|
+
port: 3219
|
13
|
+
bind_address: 'localhost'
|
14
|
+
server_options:
|
15
|
+
- some_haproxy_server_option
|
16
|
+
listen:
|
17
|
+
- some_haproxy_listen_option
|
16
18
|
|
17
19
|
# settings for haproxy including the global config
|
18
20
|
haproxy:
|
data/synapse.gemspec
CHANGED
metadata
CHANGED
@@ -1,142 +1,177 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: synapse
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.13.
|
4
|
+
version: 0.13.5
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
7
|
authors:
|
7
8
|
- Martin Rhoads
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date: 2016-
|
12
|
+
date: 2016-06-08 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: aws-sdk
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
16
18
|
requirements:
|
17
|
-
- -
|
19
|
+
- - ~>
|
18
20
|
- !ruby/object:Gem::Version
|
19
21
|
version: '1.39'
|
20
22
|
type: :runtime
|
21
23
|
prerelease: false
|
22
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
23
26
|
requirements:
|
24
|
-
- -
|
27
|
+
- - ~>
|
25
28
|
- !ruby/object:Gem::Version
|
26
29
|
version: '1.39'
|
27
30
|
- !ruby/object:Gem::Dependency
|
28
31
|
name: docker-api
|
29
32
|
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
30
34
|
requirements:
|
31
|
-
- -
|
35
|
+
- - ~>
|
32
36
|
- !ruby/object:Gem::Version
|
33
37
|
version: '1.7'
|
34
38
|
type: :runtime
|
35
39
|
prerelease: false
|
36
40
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
37
42
|
requirements:
|
38
|
-
- -
|
43
|
+
- - ~>
|
39
44
|
- !ruby/object:Gem::Version
|
40
45
|
version: '1.7'
|
41
46
|
- !ruby/object:Gem::Dependency
|
42
47
|
name: zk
|
43
48
|
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
44
50
|
requirements:
|
45
|
-
- -
|
51
|
+
- - ~>
|
46
52
|
- !ruby/object:Gem::Version
|
47
53
|
version: 1.9.4
|
48
54
|
type: :runtime
|
49
55
|
prerelease: false
|
50
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
51
58
|
requirements:
|
52
|
-
- -
|
59
|
+
- - ~>
|
53
60
|
- !ruby/object:Gem::Version
|
54
61
|
version: 1.9.4
|
55
62
|
- !ruby/object:Gem::Dependency
|
56
63
|
name: logging
|
57
64
|
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
58
66
|
requirements:
|
59
|
-
- -
|
67
|
+
- - ~>
|
60
68
|
- !ruby/object:Gem::Version
|
61
69
|
version: '1.8'
|
62
70
|
type: :runtime
|
63
71
|
prerelease: false
|
64
72
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
65
74
|
requirements:
|
66
|
-
- -
|
75
|
+
- - ~>
|
67
76
|
- !ruby/object:Gem::Version
|
68
77
|
version: '1.8'
|
69
78
|
- !ruby/object:Gem::Dependency
|
70
79
|
name: rake
|
71
80
|
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
72
82
|
requirements:
|
73
|
-
- -
|
83
|
+
- - ! '>='
|
74
84
|
- !ruby/object:Gem::Version
|
75
85
|
version: '0'
|
76
86
|
type: :development
|
77
87
|
prerelease: false
|
78
88
|
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
79
90
|
requirements:
|
80
|
-
- -
|
91
|
+
- - ! '>='
|
81
92
|
- !ruby/object:Gem::Version
|
82
93
|
version: '0'
|
83
94
|
- !ruby/object:Gem::Dependency
|
84
95
|
name: rspec
|
85
96
|
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
86
98
|
requirements:
|
87
|
-
- -
|
99
|
+
- - ~>
|
88
100
|
- !ruby/object:Gem::Version
|
89
101
|
version: 3.1.0
|
90
102
|
type: :development
|
91
103
|
prerelease: false
|
92
104
|
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
93
106
|
requirements:
|
94
|
-
- -
|
107
|
+
- - ~>
|
95
108
|
- !ruby/object:Gem::Version
|
96
109
|
version: 3.1.0
|
97
110
|
- !ruby/object:Gem::Dependency
|
98
111
|
name: pry
|
99
112
|
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
100
114
|
requirements:
|
101
|
-
- -
|
115
|
+
- - ! '>='
|
102
116
|
- !ruby/object:Gem::Version
|
103
117
|
version: '0'
|
104
118
|
type: :development
|
105
119
|
prerelease: false
|
106
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
107
122
|
requirements:
|
108
|
-
- -
|
123
|
+
- - ! '>='
|
109
124
|
- !ruby/object:Gem::Version
|
110
125
|
version: '0'
|
111
126
|
- !ruby/object:Gem::Dependency
|
112
127
|
name: pry-nav
|
113
128
|
requirement: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
114
130
|
requirements:
|
115
|
-
- -
|
131
|
+
- - ! '>='
|
116
132
|
- !ruby/object:Gem::Version
|
117
133
|
version: '0'
|
118
134
|
type: :development
|
119
135
|
prerelease: false
|
120
136
|
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
121
138
|
requirements:
|
122
|
-
- -
|
139
|
+
- - ! '>='
|
123
140
|
- !ruby/object:Gem::Version
|
124
141
|
version: '0'
|
125
142
|
- !ruby/object:Gem::Dependency
|
126
143
|
name: webmock
|
127
144
|
requirement: !ruby/object:Gem::Requirement
|
145
|
+
none: false
|
128
146
|
requirements:
|
129
|
-
- -
|
147
|
+
- - ! '>='
|
130
148
|
- !ruby/object:Gem::Version
|
131
149
|
version: '0'
|
132
150
|
type: :development
|
133
151
|
prerelease: false
|
134
152
|
version_requirements: !ruby/object:Gem::Requirement
|
153
|
+
none: false
|
135
154
|
requirements:
|
136
|
-
- -
|
155
|
+
- - ! '>='
|
137
156
|
- !ruby/object:Gem::Version
|
138
157
|
version: '0'
|
139
|
-
|
158
|
+
- !ruby/object:Gem::Dependency
|
159
|
+
name: timecop
|
160
|
+
requirement: !ruby/object:Gem::Requirement
|
161
|
+
none: false
|
162
|
+
requirements:
|
163
|
+
- - ! '>='
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '0'
|
166
|
+
type: :development
|
167
|
+
prerelease: false
|
168
|
+
version_requirements: !ruby/object:Gem::Requirement
|
169
|
+
none: false
|
170
|
+
requirements:
|
171
|
+
- - ! '>='
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
description: ': Write a gem description'
|
140
175
|
email:
|
141
176
|
- martin.rhoads@airbnb.com
|
142
177
|
executables:
|
@@ -144,10 +179,10 @@ executables:
|
|
144
179
|
extensions: []
|
145
180
|
extra_rdoc_files: []
|
146
181
|
files:
|
147
|
-
-
|
148
|
-
-
|
149
|
-
-
|
150
|
-
-
|
182
|
+
- .gitignore
|
183
|
+
- .mailmap
|
184
|
+
- .rspec
|
185
|
+
- .travis.yml
|
151
186
|
- Gemfile
|
152
187
|
- Gemfile.lock
|
153
188
|
- LICENSE.txt
|
@@ -189,27 +224,28 @@ files:
|
|
189
224
|
- synapse.gemspec
|
190
225
|
homepage: ''
|
191
226
|
licenses: []
|
192
|
-
metadata: {}
|
193
227
|
post_install_message:
|
194
228
|
rdoc_options: []
|
195
229
|
require_paths:
|
196
230
|
- lib
|
197
231
|
required_ruby_version: !ruby/object:Gem::Requirement
|
232
|
+
none: false
|
198
233
|
requirements:
|
199
|
-
- -
|
234
|
+
- - ! '>='
|
200
235
|
- !ruby/object:Gem::Version
|
201
236
|
version: '0'
|
202
237
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
238
|
+
none: false
|
203
239
|
requirements:
|
204
|
-
- -
|
240
|
+
- - ! '>='
|
205
241
|
- !ruby/object:Gem::Version
|
206
242
|
version: '0'
|
207
243
|
requirements: []
|
208
244
|
rubyforge_project:
|
209
|
-
rubygems_version:
|
245
|
+
rubygems_version: 1.8.23.2
|
210
246
|
signing_key:
|
211
|
-
specification_version:
|
212
|
-
summary:
|
247
|
+
specification_version: 3
|
248
|
+
summary: ': Write a gem summary'
|
213
249
|
test_files:
|
214
250
|
- spec/lib/synapse/file_output_spec.rb
|
215
251
|
- spec/lib/synapse/haproxy_spec.rb
|