synapse 0.13.1 → 0.13.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -85,6 +85,7 @@ class Synapse::ServiceWatcher
85
85
  'host' => address,
86
86
  'port' => server['port'],
87
87
  'name' => server['name'],
88
+ 'labels' => server['labels'],
88
89
  }
89
90
  end
90
91
  end
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Synapse
2
- VERSION = "0.13.1"
2
+ VERSION = "0.13.5"
3
3
  end
@@ -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('example_service')
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('example_service')
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('example_service')
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
- it 'updating the config' do
42
- expect(subject).to receive(:generate_config)
43
- subject.update_config([mockwatcher])
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' => ["\nbackend example_service", [], ["\tserver somehost1:5555 somehost1:5555 cookie somehost1:5555 check inter 2000 rise 3 fall 2", "\tserver somehost2:5555 somehost2:5555 cookie somehost2:5555 check inter 2000 rise 3 fall 2", "\tserver somehost3:5555 somehost3:5555 cookie somehost3:5555 check inter 2000 rise 3 fall 2"]],
55
- 'desc' => ["\nbackend example_service", [], ["\tserver somehost3:5555 somehost3:5555 cookie somehost3:5555 check inter 2000 rise 3 fall 2", "\tserver somehost2:5555 somehost2:5555 cookie somehost2:5555 check inter 2000 rise 3 fall 2", "\tserver somehost1:5555 somehost1:5555 cookie somehost1:5555 check inter 2000 rise 3 fall 2"]],
56
- 'no_shuffle' => ["\nbackend example_service", [], ["\tserver somehost1:5555 somehost1:5555 cookie somehost1:5555 check inter 2000 rise 3 fall 2", "\tserver somehost3:5555 somehost3:5555 cookie somehost3:5555 check inter 2000 rise 3 fall 2", "\tserver somehost2:5555 somehost2:5555 cookie somehost2:5555 check inter 2000 rise 3 fall 2"]]
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' => 'somehost1', 'port' => 5555}, {'host' => 'somehost3', 'port' => 5555}, { 'host' => 'somehost2', 'port' => 5555}]
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 example_service", [], ["\tserver somehost:5555 somehost:5555 cookie somehost:5555 check inter 2000 rise 3 fall 2 backup"]])
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 example_service", [], "\tbind localhost:2200", "\tdefault_backend example_service"])
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 example_service", [], "\tbind 127.0.0.3:2200", "\tdefault_backend example_service"])
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
- - name: test
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
- listen:
14
- - test_option
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
@@ -26,4 +26,5 @@ Gem::Specification.new do |gem|
26
26
  gem.add_development_dependency "pry"
27
27
  gem.add_development_dependency "pry-nav"
28
28
  gem.add_development_dependency "webmock"
29
+ gem.add_development_dependency "timecop"
29
30
  end
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.1
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-02-18 00:00:00.000000000 Z
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
- description: ": Write a gem description"
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
- - ".gitignore"
148
- - ".mailmap"
149
- - ".rspec"
150
- - ".travis.yml"
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: 2.5.1
245
+ rubygems_version: 1.8.23.2
210
246
  signing_key:
211
- specification_version: 4
212
- summary: ": Write a gem 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