synapse 0.12.2 → 0.13.1

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 34b7877f7f8196407e10fafab1a72354e861121c
4
+ data.tar.gz: 154d642f85c7a1d1ab13078a8adb1a75d295d993
5
+ SHA512:
6
+ metadata.gz: 06e858b8cd8a0c316baad80264754206ee64615f7ca0f7958ebf7d38a5b07d67968d949d09367dd127b525e1f6710611d48813af224fe3371bd1e2c78c4da343
7
+ data.tar.gz: 41be259d76cd50f950b4d6e2e217f4c68134a8f71cfcc75bf69842f7d5edee95bac61996412ba8b9a00057ceb52e651aa4837e2146c3c57432929fbbbfb1f641
data/README.md CHANGED
@@ -97,6 +97,11 @@ install synapse with:
97
97
 
98
98
  ```bash
99
99
  $ mkdir -p /opt/smartstack/synapse
100
+
101
+ # If you want to install specific versions of dependencies such as an older
102
+ # version of the aws-sdk, the docker-api, etc, gem install that here *before*
103
+ # gem installing synapse
104
+
100
105
  # If you are on Ruby 2.X use --no-document instead of --no-ri --no-rdoc
101
106
  $ gem install synapse --install-dir /opt/smartstack/synapse --no-ri --no-rdoc
102
107
  ```
@@ -141,25 +146,39 @@ Each value in the services hash is also a hash, and should contain the following
141
146
  We've included a number of `watchers` which provide service discovery.
142
147
  Put these into the `discovery` section of the service hash, with these options:
143
148
 
144
- ##### Stub #####
149
+ ##### Base #####
145
150
 
146
- The stub watcher is useful in situations where you only want to use the servers in the `default_servers` list.
151
+ The base watcher is useful in situations where you only want to use the servers in the `default_servers` list.
147
152
  It has only one option:
148
153
 
149
- * `method`: stub
154
+ * `method`: base
150
155
 
151
156
  ##### Zookeeper #####
152
157
 
153
158
  This watcher retrieves a list of servers from zookeeper.
154
- It takes the following options:
159
+ It takes the following mandatory arguments:
155
160
 
156
161
  * `method`: zookeeper
157
162
  * `path`: the zookeeper path where ephemeral nodes will be created for each available service server
158
163
  * `hosts`: the list of zookeeper servers to query
159
164
 
160
165
  The watcher assumes that each node under `path` represents a service server.
161
- Synapse attempts to decode the data in each of these nodes using JSON and also using Thrift under the standard Twitter service encoding.
162
- We assume that the data contains a hostname and a port for service servers.
166
+
167
+ The following arguments are optional:
168
+
169
+ * `decode`: A hash containing configuration for how to decode the data found in zookeeper.
170
+
171
+ ###### Decoding service nodes ######
172
+ Synapse attempts to decode the data in each of these nodes using JSON and you can control how it is decoded with the `decode` argument. If provided, the `decode` hash should contain the following:
173
+
174
+ * `method` (one of ['`nerve`', '`serverset`'], default: '`nerve`'): The kind of data to expect to find in zookeeper nodes
175
+ * `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
+
177
+ If the `method` is `nerve`, then we expect to find nerve registrations with a `host` and a `port`.
178
+
179
+ If the `method` is `serverset` then we expect to find Finagle ServerSet
180
+ (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`.
181
+ The Synapse `name` will be automatically deduced from `shard` if present.
163
182
 
164
183
  ##### Docker #####
165
184
 
@@ -232,6 +251,7 @@ by unsetting `use_previous_backends`.
232
251
  This section is its own hash, which should contain the following keys:
233
252
 
234
253
  * `port`: the port (on localhost) where HAProxy will listen for connections to the service. If this is omitted, only a backend stanza (and no frontend stanza) will be generated for this service; you'll need to get traffic to your service yourself via the `shared_frontend` or manual frontends in `extra_sections`
254
+ * `bind_address`: force HAProxy to listen on this address ( default is localhost ). Setting `bind_address` on a per service basis overrides the global `bind_address` in the top level `haproxy`. Having HAProxy listen for connections on different addresses ( example: service1 listen on 127.0.0.2:443 and service2 listen on 127.0.0.3:443) allows /etc/hosts entries to point to services.
235
255
  * `server_port_override`: the port that discovered servers listen on; you should specify this if your discovery mechanism only discovers names or addresses (like the DNS watcher). If the discovery method discovers a port along with hostnames (like the zookeeper watcher) this option may be left out, but will be used in preference if given.
236
256
  * `server_options`: the haproxy options for each `server` line of the service in HAProxy config; it may be left out.
237
257
  * `frontend`: additional lines passed to the HAProxy config in the `frontend` stanza of this service
@@ -239,6 +259,7 @@ This section is its own hash, which should contain the following keys:
239
259
  * `backend_name`: The name of the generated HAProxy backend for this service
240
260
  (defaults to the service's key in the `services` section)
241
261
  * `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
+ * `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.
242
263
  * `shared_frontend`: optional: haproxy configuration directives for a shared http frontend (see below)
243
264
 
244
265
  <a name="haproxy"/>
@@ -259,11 +280,16 @@ The top level `haproxy` section of the config file has the following options:
259
280
  * `restart_interval`: number of seconds to wait between restarts of haproxy (default: 2)
260
281
  * `restart_jitter`: percentage, expressed as a float, of jitter to multiply the `restart_interval` by when determining the next
261
282
  restart time. Use this to help prevent healthcheck storms when HAProxy restarts. (default: 0.0)
262
- * `state_file_path`: full path on disk (e.g. /tmp/synapse/state.json) for caching haproxy state between reloads.
263
- If provided, synapse will store recently seen backends at this location and can "remember" backends across both synapse and
264
- HAProxy restarts. Any backends that are "down" in the reporter but listed in the cache will be put into HAProxy disabled (default: nil)
265
- * `state_file_ttl`: the number of seconds that backends should be kept in the state file cache.
266
- This only applies if `state_file_path` is provided (default: 86400)
283
+ * `state_file_path`: full path on disk (e.g. /tmp/synapse/state.json) for
284
+ caching haproxy state between reloads. If provided, synapse will store
285
+ recently seen backends at this location and can "remember" backends across
286
+ both synapse and HAProxy restarts. Any backends that are "down" in the
287
+ reporter but listed in the cache will be put into HAProxy disabled. Synapse
288
+ writes the state file every sixty seconds, so the file's age can be used to
289
+ monitor that Synapse is alive and making progress. (default: nil)
290
+ * `state_file_ttl`: the number of seconds that backends should be kept in the
291
+ state file cache. This only applies if `state_file_path` is provided.
292
+ (default: 86400)
267
293
 
268
294
  Note that a non-default `bind_address` can be dangerous.
269
295
  If you configure an `address:port` combination that is already in use on the system, haproxy will fail to start.
@@ -686,7 +686,7 @@ module Synapse
686
686
  stanza = [
687
687
  "\nfrontend #{watcher.name}",
688
688
  config.map {|c| "\t#{c}"},
689
- "\tbind #{@opts['bind_address'] || 'localhost'}:#{watcher.haproxy['port']}",
689
+ "\tbind #{ watcher.haproxy['bind_address'] || @opts['bind_address'] || 'localhost'}:#{watcher.haproxy['port']}",
690
690
  "\tdefault_backend #{watcher.haproxy.fetch('backend_name', watcher.name)}"
691
691
  ]
692
692
  end
@@ -721,10 +721,20 @@ module Synapse
721
721
  log.debug "synapse: no backends found for watcher #{watcher.name}"
722
722
  end
723
723
 
724
+ keys = case watcher.haproxy['backend_order']
725
+ when 'asc'
726
+ backends.keys.sort
727
+ when 'desc'
728
+ backends.keys.sort.reverse
729
+ when 'no_shuffle'
730
+ backends.keys
731
+ else
732
+ backends.keys.shuffle
733
+ end
724
734
  stanza = [
725
735
  "\nbackend #{watcher.haproxy.fetch('backend_name', watcher.name)}",
726
736
  config.map {|c| "\t#{c}"},
727
- backends.keys.shuffle.map {|backend_name|
737
+ keys.map {|backend_name|
728
738
  backend = backends[backend_name]
729
739
  b = "\tserver #{backend_name} #{backend['host']}:#{backend['port']}"
730
740
  b = "#{b} cookie #{backend_name}" unless config.include?('mode tcp')
@@ -21,6 +21,7 @@ class Synapse::ServiceWatcher
21
21
 
22
22
  @name = opts['name']
23
23
  @discovery = opts['discovery']
24
+ @label_filter = @discovery['label_filter'] || false
24
25
 
25
26
  @leader_election = opts['leader_election'] || false
26
27
  @leader_last_warn = Time.now - LEADER_WARN_INTERVAL
@@ -86,6 +87,8 @@ class Synapse::ServiceWatcher
86
87
 
87
88
  # if leader election fails, return no backends
88
89
  return []
90
+ elsif @label_filter
91
+ return filter_backends_by_label(@backends, @label_filter)
89
92
  end
90
93
 
91
94
  return @backends
@@ -99,6 +102,17 @@ class Synapse::ServiceWatcher
99
102
  log.warn "synapse: warning: a stub watcher with no default servers is pretty useless" if @default_servers.empty?
100
103
  end
101
104
 
105
+ def filter_backends_by_label(backends, label_filter)
106
+ filtered_backends = []
107
+ backends.each do |backend|
108
+ backend_labels = backend['labels'] || {}
109
+ if label_filter['condition'] == 'equals' and backend_labels[label_filter['label']] == label_filter['value']
110
+ filtered_backends << backend
111
+ end
112
+ end
113
+ return filtered_backends
114
+ end
115
+
102
116
  def set_backends(new_backends)
103
117
  # Aggregate and deduplicate all potential backend service instances.
104
118
  new_backends = (new_backends + @default_servers) if @keep_default_servers
@@ -11,6 +11,24 @@ class Synapse::ServiceWatcher
11
11
  @@zk_pool_count = {}
12
12
  @@zk_pool_lock = Mutex.new
13
13
 
14
+ def initialize(opts={}, synapse)
15
+ super(opts, synapse)
16
+
17
+ # Alternative deserialization support. By default we use nerve
18
+ # deserialization, but we also support serverset registries
19
+ @decode_method = self.method(:nerve_decode)
20
+ if @discovery['decode']
21
+ valid_methods = ['nerve', 'serverset']
22
+ decode_method = @discovery['decode']['method']
23
+ unless decode_method && valid_methods.include?(decode_method)
24
+ raise ArgumentError, "missing or invalid decode method #{decode_method}"
25
+ end
26
+ if decode_method == 'serverset'
27
+ @decode_method = self.method(:serverset_decode)
28
+ end
29
+ end
30
+ end
31
+
14
32
  def start
15
33
  @zk_hosts = @discovery['hosts'].sort.join(',')
16
34
 
@@ -43,6 +61,57 @@ class Synapse::ServiceWatcher
43
61
  unless @discovery['path']
44
62
  end
45
63
 
64
+ # Supported decode methods
65
+
66
+ # Airbnb nerve ZK node data looks like this:
67
+ #
68
+ # {
69
+ # "host": "somehostname",
70
+ # "port": 1234,
71
+ # }
72
+ def nerve_decode(data)
73
+ JSON.parse(data)
74
+ end
75
+
76
+ # Twitter serverset ZK node data looks like this:
77
+ #
78
+ # {
79
+ # "additionalEndpoints": {
80
+ # "serverset": {
81
+ # "host": "somehostname",
82
+ # "port": 31943
83
+ # },
84
+ # "http": {
85
+ # "host": "somehostname",
86
+ # "port": 31943
87
+ # },
88
+ # "otherport": {
89
+ # "host": "somehostname",
90
+ # "port": 31944
91
+ # }
92
+ # },
93
+ # "serviceEndpoint": {
94
+ # "host": "somehostname",
95
+ # "port": 31943
96
+ # },
97
+ # "shard": 0,
98
+ # "status": "ALIVE"
99
+ # }
100
+ def serverset_decode(data)
101
+ decoded = JSON.parse(data)
102
+ if @discovery['decode']['endpoint_name']
103
+ endpoint_name = @discovery['decode']['endpoint_name']
104
+ raise KeyError, "json data has no additionalEndpoint called #{endpoint_name}" \
105
+ unless decoded['additionalEndpoints'] && decoded['additionalEndpoints'][endpoint_name]
106
+ result = decoded['additionalEndpoints'][endpoint_name]
107
+ else
108
+ result = decoded['serviceEndpoint']
109
+ end
110
+ result['name'] = decoded['shard'] || nil
111
+ result['name'] = result['name'].to_s unless result['name'].nil?
112
+ result
113
+ end
114
+
46
115
  # helper method that ensures that the discovery path exists
47
116
  def create(path)
48
117
  log.debug "synapse: creating ZK path: #{path}"
@@ -62,11 +131,11 @@ class Synapse::ServiceWatcher
62
131
 
63
132
  begin
64
133
  # TODO: Do less munging, or refactor out this processing
65
- host, port, name, weight, haproxy_server_options = deserialize_service_instance(node.first)
134
+ host, port, name, weight, haproxy_server_options, labels = deserialize_service_instance(node.first)
66
135
  rescue StandardError => e
67
136
  log.error "synapse: invalid data in ZK node #{id} at #{@discovery['path']}: #{e}"
68
137
  else
69
- server_port = @server_port_override ? @server_port_override : port
138
+ server_port = @haproxy['server_port_override'] ? @haproxy['server_port_override'] : port
70
139
 
71
140
  # find the numberic id in the node name; used for leader elections if enabled
72
141
  numeric_id = id.split('_').last
@@ -76,7 +145,8 @@ class Synapse::ServiceWatcher
76
145
  new_backends << {
77
146
  'name' => name, 'host' => host, 'port' => server_port,
78
147
  'id' => numeric_id, 'weight' => weight,
79
- 'haproxy_server_options' => haproxy_server_options
148
+ 'haproxy_server_options' => haproxy_server_options,
149
+ 'labels' => labels
80
150
  }
81
151
  end
82
152
  end
@@ -173,15 +243,17 @@ class Synapse::ServiceWatcher
173
243
  # decode the data at a zookeeper endpoint
174
244
  def deserialize_service_instance(data)
175
245
  log.debug "synapse: deserializing process data"
176
- decoded = JSON.parse(data)
246
+ decoded = @decode_method.call(data)
177
247
 
178
- host = decoded['host'] || (raise ValueError, 'instance json data does not have host key')
179
- port = decoded['port'] || (raise ValueError, 'instance json data does not have port key')
248
+ host = decoded['host'] || (raise KeyError, 'instance json data does not have host key')
249
+ port = decoded['port'] || (raise KeyError, 'instance json data does not have port key')
180
250
  name = decoded['name'] || nil
181
251
  weight = decoded['weight'] || nil
182
252
  haproxy_server_options = decoded['haproxy_server_options'] || nil
253
+ labels = decoded['labels'] || nil
183
254
 
184
- return host, port, name, weight, haproxy_server_options
255
+ return host, port, name, weight, haproxy_server_options, labels
185
256
  end
186
257
  end
187
258
  end
259
+
@@ -1,3 +1,3 @@
1
1
  module Synapse
2
- VERSION = "0.12.2"
2
+ VERSION = "0.13.1"
3
3
  end
@@ -23,6 +23,21 @@ describe Synapse::Haproxy do
23
23
  mockWatcher
24
24
  end
25
25
 
26
+ let(:mockwatcher_frontend) do
27
+ mockWatcher = double(Synapse::ServiceWatcher)
28
+ allow(mockWatcher).to receive(:name).and_return('example_service')
29
+ allow(mockWatcher).to receive(:haproxy).and_return('port' => 2200)
30
+ mockWatcher
31
+ end
32
+
33
+ let(:mockwatcher_frontend_with_bind_address) do
34
+ mockWatcher = double(Synapse::ServiceWatcher)
35
+ allow(mockWatcher).to receive(:name).and_return('example_service')
36
+ allow(mockWatcher).to receive(:haproxy).and_return('port' => 2200, 'bind_address' => "127.0.0.3")
37
+ mockWatcher
38
+ end
39
+
40
+
26
41
  it 'updating the config' do
27
42
  expect(subject).to receive(:generate_config)
28
43
  subject.update_config([mockwatcher])
@@ -33,6 +48,34 @@ describe Synapse::Haproxy do
33
48
  expect(subject.generate_backend_stanza(mockwatcher, mockConfig)).to eql(["\nbackend example_service", [], ["\tserver somehost:5555 somehost:5555 cookie somehost:5555 check inter 2000 rise 3 fall 2"]])
34
49
  end
35
50
 
51
+ describe 'generate backend stanza in correct order' do
52
+ let(:multiple_backends_stanza_map) do
53
+ {
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"]]
57
+ }
58
+ end
59
+
60
+ let(:mockwatcher_with_multiple_backends) do
61
+ mockWatcher = double(Synapse::ServiceWatcher)
62
+ allow(mockWatcher).to receive(:name).and_return('example_service')
63
+ backends = [{ 'host' => 'somehost1', 'port' => 5555}, {'host' => 'somehost3', 'port' => 5555}, { 'host' => 'somehost2', 'port' => 5555}]
64
+ allow(mockWatcher).to receive(:backends).and_return(backends)
65
+ mockWatcher
66
+ end
67
+
68
+ ['asc', 'desc', 'no_shuffle'].each do |order_option|
69
+ context "when #{order_option} is specified for backend_order" do
70
+ it 'generates backend stanza in correct order' do
71
+ mockConfig = []
72
+ allow(mockwatcher_with_multiple_backends).to receive(:haproxy).and_return({'server_options' => "check inter 2000 rise 3 fall 2", 'backend_order' => order_option})
73
+ expect(subject.generate_backend_stanza(mockwatcher_with_multiple_backends, mockConfig)).to eql(multiple_backends_stanza_map[order_option])
74
+ end
75
+ end
76
+ end
77
+ end
78
+
36
79
  it 'generates backend stanza without cookies for tcp mode' do
37
80
  mockConfig = ['mode tcp']
38
81
  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"]])
@@ -42,4 +85,15 @@ describe Synapse::Haproxy do
42
85
  mockConfig = []
43
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"]])
44
87
  end
88
+
89
+ it 'generates frontend stanza ' do
90
+ mockConfig = []
91
+ expect(subject.generate_frontend_stanza(mockwatcher_frontend, mockConfig)).to eql(["\nfrontend example_service", [], "\tbind localhost:2200", "\tdefault_backend example_service"])
92
+ end
93
+
94
+ it 'respects frontend bind_address ' do
95
+ 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"])
97
+ end
98
+
45
99
  end
@@ -109,5 +109,31 @@ describe Synapse::ServiceWatcher::BaseWatcher do
109
109
  expect(subject.backends).to eq(backends + default_servers)
110
110
  end
111
111
  end
112
+
113
+ context 'with label_filter set' do
114
+ let(:matching_labeled_backends) { [
115
+ { 'name' => 'server1', 'host' => 'server1', 'port' => 1111, 'labels' => { 'az' => 'us-east-1a' } },
116
+ { 'name' => 'server2', 'host' => 'server2', 'port' => 2222, 'labels' => { 'az' => 'us-east-1a' } },
117
+ ] }
118
+ let(:non_matching_labeled_backends) { [
119
+ { 'name' => 'server3', 'host' => 'server3', 'port' => 3333, 'labels' => { 'az' => 'us-west-1c' } },
120
+ { 'name' => 'server4', 'host' => 'server4', 'port' => 4444, 'labels' => { 'az' => 'us-west-2a' } },
121
+ ] }
122
+ let(:non_labeled_backends) { [
123
+ { 'name' => 'server5', 'host' => 'server5', 'port' => 5555 },
124
+ ] }
125
+ let(:args) {
126
+ testargs.merge({ 'discovery' => {
127
+ 'method' => 'base',
128
+ 'label_filter' => { 'condition' => 'equals', 'label' => 'az', 'value' => 'us-east-1a' } }
129
+ })
130
+ }
131
+ it 'removes all backends that do not match the label_filter' do
132
+ expect(subject).to receive(:'reconfigure!').exactly(:once)
133
+ subject.send(:set_backends, matching_labeled_backends + non_matching_labeled_backends +
134
+ non_labeled_backends)
135
+ expect(subject.backends).to eq(matching_labeled_backends)
136
+ end
137
+ end
112
138
  end
113
139
  end
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+ require 'synapse/service_watcher/zookeeper'
3
+ require 'synapse/service_watcher/zookeeper_dns'
4
+
5
+ describe Synapse::ServiceWatcher::ZookeeperWatcher do
6
+ let(:mock_synapse) { double }
7
+ let(:config) do
8
+ {
9
+ 'name' => 'test',
10
+ 'haproxy' => {},
11
+ 'discovery' => discovery,
12
+ }
13
+ end
14
+
15
+ let(:service_data) do
16
+ {
17
+ 'host' => 'server',
18
+ 'port' => '8888',
19
+ 'name' => 'server',
20
+ 'weight' => '1',
21
+ 'haproxy_server_options' => 'backup',
22
+ 'labels' => { 'az' => 'us-east-1a' }
23
+ }
24
+ end
25
+ let(:service_data_string) { service_data.to_json }
26
+ let(:deserialized_service_data) {
27
+ [ service_data['host'], service_data['port'], service_data['name'], service_data['weight'],
28
+ service_data['haproxy_server_options'], service_data['labels'] ]
29
+ }
30
+
31
+ context 'ZookeeperWatcher' do
32
+ let(:discovery) { { 'method' => 'zookeeper', 'hosts' => 'somehost','path' => 'some/path' } }
33
+ subject { Synapse::ServiceWatcher::ZookeeperWatcher.new(config, mock_synapse) }
34
+ it 'decodes data correctly' do
35
+ expect(subject.send(:deserialize_service_instance, service_data_string)).to eql(deserialized_service_data)
36
+ end
37
+ end
38
+
39
+ context 'ZookeeperDnsWatcher' do
40
+ let(:discovery) { { 'method' => 'zookeeper_dns', 'hosts' => 'somehost','path' => 'some/path' } }
41
+ let(:message_queue) { [] }
42
+ subject { Synapse::ServiceWatcher::ZookeeperDnsWatcher::Zookeeper.new(config, mock_synapse, message_queue) }
43
+ it 'decodes data correctly' do
44
+ expect(subject.send(:deserialize_service_instance, service_data_string)).to eql(deserialized_service_data)
45
+ end
46
+ end
47
+ end
data/synapse.gemspec CHANGED
@@ -17,8 +17,9 @@ Gem::Specification.new do |gem|
17
17
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
18
 
19
19
  gem.add_runtime_dependency "aws-sdk", "~> 1.39"
20
- gem.add_runtime_dependency "docker-api", "~> 1.7.2"
20
+ gem.add_runtime_dependency "docker-api", "~> 1.7"
21
21
  gem.add_runtime_dependency "zk", "~> 1.9.4"
22
+ gem.add_runtime_dependency "logging", "~> 1.8"
22
23
 
23
24
  gem.add_development_dependency "rake"
24
25
  gem.add_development_dependency "rspec", "~> 3.1.0"
metadata CHANGED
@@ -1,145 +1,142 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: synapse
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.2
5
- prerelease:
4
+ version: 0.13.1
6
5
  platform: ruby
7
6
  authors:
8
7
  - Martin Rhoads
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2015-12-07 00:00:00.000000000 Z
11
+ date: 2016-02-18 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: aws-sdk
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ~>
17
+ - - "~>"
20
18
  - !ruby/object:Gem::Version
21
19
  version: '1.39'
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ~>
24
+ - - "~>"
28
25
  - !ruby/object:Gem::Version
29
26
  version: '1.39'
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: docker-api
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ~>
31
+ - - "~>"
36
32
  - !ruby/object:Gem::Version
37
- version: 1.7.2
33
+ version: '1.7'
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ~>
38
+ - - "~>"
44
39
  - !ruby/object:Gem::Version
45
- version: 1.7.2
40
+ version: '1.7'
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: zk
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
- - - ~>
45
+ - - "~>"
52
46
  - !ruby/object:Gem::Version
53
47
  version: 1.9.4
54
48
  type: :runtime
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
- - - ~>
52
+ - - "~>"
60
53
  - !ruby/object:Gem::Version
61
54
  version: 1.9.4
55
+ - !ruby/object:Gem::Dependency
56
+ name: logging
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.8'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.8'
62
69
  - !ruby/object:Gem::Dependency
63
70
  name: rake
64
71
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
72
  requirements:
67
- - - ! '>='
73
+ - - ">="
68
74
  - !ruby/object:Gem::Version
69
75
  version: '0'
70
76
  type: :development
71
77
  prerelease: false
72
78
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
79
  requirements:
75
- - - ! '>='
80
+ - - ">="
76
81
  - !ruby/object:Gem::Version
77
82
  version: '0'
78
83
  - !ruby/object:Gem::Dependency
79
84
  name: rspec
80
85
  requirement: !ruby/object:Gem::Requirement
81
- none: false
82
86
  requirements:
83
- - - ~>
87
+ - - "~>"
84
88
  - !ruby/object:Gem::Version
85
89
  version: 3.1.0
86
90
  type: :development
87
91
  prerelease: false
88
92
  version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
93
  requirements:
91
- - - ~>
94
+ - - "~>"
92
95
  - !ruby/object:Gem::Version
93
96
  version: 3.1.0
94
97
  - !ruby/object:Gem::Dependency
95
98
  name: pry
96
99
  requirement: !ruby/object:Gem::Requirement
97
- none: false
98
100
  requirements:
99
- - - ! '>='
101
+ - - ">="
100
102
  - !ruby/object:Gem::Version
101
103
  version: '0'
102
104
  type: :development
103
105
  prerelease: false
104
106
  version_requirements: !ruby/object:Gem::Requirement
105
- none: false
106
107
  requirements:
107
- - - ! '>='
108
+ - - ">="
108
109
  - !ruby/object:Gem::Version
109
110
  version: '0'
110
111
  - !ruby/object:Gem::Dependency
111
112
  name: pry-nav
112
113
  requirement: !ruby/object:Gem::Requirement
113
- none: false
114
114
  requirements:
115
- - - ! '>='
115
+ - - ">="
116
116
  - !ruby/object:Gem::Version
117
117
  version: '0'
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
- none: false
122
121
  requirements:
123
- - - ! '>='
122
+ - - ">="
124
123
  - !ruby/object:Gem::Version
125
124
  version: '0'
126
125
  - !ruby/object:Gem::Dependency
127
126
  name: webmock
128
127
  requirement: !ruby/object:Gem::Requirement
129
- none: false
130
128
  requirements:
131
- - - ! '>='
129
+ - - ">="
132
130
  - !ruby/object:Gem::Version
133
131
  version: '0'
134
132
  type: :development
135
133
  prerelease: false
136
134
  version_requirements: !ruby/object:Gem::Requirement
137
- none: false
138
135
  requirements:
139
- - - ! '>='
136
+ - - ">="
140
137
  - !ruby/object:Gem::Version
141
138
  version: '0'
142
- description: ': Write a gem description'
139
+ description: ": Write a gem description"
143
140
  email:
144
141
  - martin.rhoads@airbnb.com
145
142
  executables:
@@ -147,10 +144,10 @@ executables:
147
144
  extensions: []
148
145
  extra_rdoc_files: []
149
146
  files:
150
- - .gitignore
151
- - .mailmap
152
- - .rspec
153
- - .travis.yml
147
+ - ".gitignore"
148
+ - ".mailmap"
149
+ - ".rspec"
150
+ - ".travis.yml"
154
151
  - Gemfile
155
152
  - Gemfile.lock
156
153
  - LICENSE.txt
@@ -185,34 +182,34 @@ files:
185
182
  - spec/lib/synapse/service_watcher_ec2tags_spec.rb
186
183
  - spec/lib/synapse/service_watcher_marathon_spec.rb
187
184
  - spec/lib/synapse/service_watcher_spec.rb
185
+ - spec/lib/synapse/service_watcher_zookeeper_spec.rb
188
186
  - spec/spec_helper.rb
189
187
  - spec/support/configuration.rb
190
188
  - spec/support/minimum.conf.yaml
191
189
  - synapse.gemspec
192
190
  homepage: ''
193
191
  licenses: []
192
+ metadata: {}
194
193
  post_install_message:
195
194
  rdoc_options: []
196
195
  require_paths:
197
196
  - lib
198
197
  required_ruby_version: !ruby/object:Gem::Requirement
199
- none: false
200
198
  requirements:
201
- - - ! '>='
199
+ - - ">="
202
200
  - !ruby/object:Gem::Version
203
201
  version: '0'
204
202
  required_rubygems_version: !ruby/object:Gem::Requirement
205
- none: false
206
203
  requirements:
207
- - - ! '>='
204
+ - - ">="
208
205
  - !ruby/object:Gem::Version
209
206
  version: '0'
210
207
  requirements: []
211
208
  rubyforge_project:
212
- rubygems_version: 1.8.23.2
209
+ rubygems_version: 2.5.1
213
210
  signing_key:
214
- specification_version: 3
215
- summary: ': Write a gem summary'
211
+ specification_version: 4
212
+ summary: ": Write a gem summary"
216
213
  test_files:
217
214
  - spec/lib/synapse/file_output_spec.rb
218
215
  - spec/lib/synapse/haproxy_spec.rb
@@ -221,6 +218,7 @@ test_files:
221
218
  - spec/lib/synapse/service_watcher_ec2tags_spec.rb
222
219
  - spec/lib/synapse/service_watcher_marathon_spec.rb
223
220
  - spec/lib/synapse/service_watcher_spec.rb
221
+ - spec/lib/synapse/service_watcher_zookeeper_spec.rb
224
222
  - spec/spec_helper.rb
225
223
  - spec/support/configuration.rb
226
224
  - spec/support/minimum.conf.yaml