synapse 0.0.1 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/.rspec +2 -0
- data/Gemfile.lock +45 -0
- data/README.md +185 -4
- data/Vagrantfile +112 -0
- data/bin/synapse +54 -0
- data/chef/converge +4 -0
- data/chef/cookbooks/lxc/recipes/default.rb +2 -0
- data/chef/cookbooks/synapse/attributes/default.rb +1 -0
- data/chef/cookbooks/synapse/recipes/default.rb +6 -0
- data/chef/run.json +8 -0
- data/chef/run.rb +2 -0
- data/client/.RData +0 -0
- data/client/.Rhistory +294 -0
- data/client/bench_rewrite_config.dat +2013 -0
- data/client/benchmark-client.iml +20 -0
- data/client/pom.xml +45 -0
- data/client/src/main/java/ClientArsch.java +68 -0
- data/client/src/main/java/META-INF/MANIFEST.MF +3 -0
- data/config/synapse.conf.json +96 -0
- data/haproxy.pid +1 -0
- data/lib/gen-rb/endpoint_types.rb +65 -0
- data/lib/gen-rb/thrift.rb +65 -0
- data/lib/synapse/base.rb +5 -0
- data/lib/synapse/haproxy.rb +200 -0
- data/lib/synapse/service_watcher/base.rb +44 -0
- data/lib/synapse/service_watcher/dns.rb +98 -0
- data/lib/synapse/service_watcher/ec2tag.rb +26 -0
- data/lib/synapse/service_watcher/zookeeper.rb +138 -0
- data/lib/synapse/service_watcher.rb +28 -0
- data/lib/synapse/version.rb +1 -1
- data/lib/synapse.rb +61 -2
- data/spec/lib/synapse/haproxy_spec.rb +14 -0
- data/spec/spec_helper.rb +22 -0
- data/spec/support/config.rb +9 -0
- data/spec/support/minimum.conf.yaml +27 -0
- data/synapse.gemspec +7 -0
- data/test.sh +3 -0
- metadata +123 -5
@@ -0,0 +1,98 @@
|
|
1
|
+
require_relative "./base"
|
2
|
+
|
3
|
+
require 'thread'
|
4
|
+
require 'resolv'
|
5
|
+
|
6
|
+
module Synapse
|
7
|
+
class DnsWatcher < BaseWatcher
|
8
|
+
def start
|
9
|
+
@check_interval = @discovery['check_interval'] || 30.0
|
10
|
+
@nameserver = @discovery['nameserver']
|
11
|
+
|
12
|
+
watch
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
def validate_discovery_opts
|
17
|
+
raise ArgumentError, "invalid discovery method #{@discovery['method']}" \
|
18
|
+
unless @discovery['method'] == 'dns'
|
19
|
+
raise ArgumentError, "a non-empty list of servers is required" \
|
20
|
+
if @discovery['servers'].empty?
|
21
|
+
end
|
22
|
+
|
23
|
+
def watch
|
24
|
+
@watcher = Thread.new do
|
25
|
+
last_resolution = resolve_servers
|
26
|
+
configure_backends(last_resolution)
|
27
|
+
while true
|
28
|
+
begin
|
29
|
+
start = Time.now
|
30
|
+
current_resolution = resolve_servers
|
31
|
+
unless last_resolution == current_resolution
|
32
|
+
last_resolution = current_resolution
|
33
|
+
configure_backends(last_resolution)
|
34
|
+
end
|
35
|
+
|
36
|
+
sleep_until_next_check(start)
|
37
|
+
rescue => e
|
38
|
+
log.warn "Error in watcher thread: #{e.inspect}"
|
39
|
+
log.warn e.backtrace
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def sleep_until_next_check(start_time)
|
46
|
+
sleep_time = @check_interval - (Time.now - start_time)
|
47
|
+
if sleep_time > 0.0
|
48
|
+
sleep(sleep_time)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def resolve_servers
|
53
|
+
resolver.tap do |dns|
|
54
|
+
resolution = @discovery['servers'].map do |server|
|
55
|
+
addresses = dns.getaddresses(server['host']).map(&:to_s)
|
56
|
+
[server, addresses.sort]
|
57
|
+
end
|
58
|
+
|
59
|
+
return resolution
|
60
|
+
end
|
61
|
+
rescue => e
|
62
|
+
log.warn "Error while resolving host names: #{e.inspect}"
|
63
|
+
[]
|
64
|
+
end
|
65
|
+
|
66
|
+
def resolver
|
67
|
+
args = [{:nameserver => @nameserver}] if @nameserver
|
68
|
+
Resolv::DNS.open(*args)
|
69
|
+
end
|
70
|
+
|
71
|
+
def configure_backends(servers)
|
72
|
+
new_backends = servers.flat_map do |(server, addresses)|
|
73
|
+
addresses.map do |address|
|
74
|
+
{
|
75
|
+
'name' => "#{server['name']}-#{[address, server['port']].hash}",
|
76
|
+
'host' => address,
|
77
|
+
'port' => server['port']
|
78
|
+
}
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
if new_backends.empty?
|
83
|
+
if @default_servers.empty?
|
84
|
+
log.warn "synapse: no backends and no default servers for service #{@name};" \
|
85
|
+
" using previous backends: #{@backends.inspect}"
|
86
|
+
else
|
87
|
+
log.warn "synapse: no backends for service #{@name};" \
|
88
|
+
" using default servers: #{@default_servers.inspect}"
|
89
|
+
@backends = @default_servers
|
90
|
+
end
|
91
|
+
else
|
92
|
+
log.info "synapse: discovered #{new_backends.length} backends for service #{@name}"
|
93
|
+
@backends = new_backends
|
94
|
+
end
|
95
|
+
@synapse.configure
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require_relative "./base"
|
2
|
+
|
3
|
+
module Synapse
|
4
|
+
class EC2Watcher < BaseWatcher
|
5
|
+
def start
|
6
|
+
# connect to ec2
|
7
|
+
# find all servers whose @discovery['tag_name'] matches @discovery['tag_value']
|
8
|
+
# call @synapse.configure
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
def validate_discovery_opts
|
13
|
+
raise ArgumentError, "invalid discovery method #{@discovery['method']}" \
|
14
|
+
unless @discovery['method'] == 'ec2tag'
|
15
|
+
raise ArgumentError, "a `server_port_override` option is required for ec2tag watchers" \
|
16
|
+
unless @server_port_override
|
17
|
+
raise ArgumentError, "missing aws credentials for service #{@name}" \
|
18
|
+
unless (@discovery['aws_key'] && @discovery['aws_secret'])
|
19
|
+
raise ArgumentError, "aws tag name is required for service #{@name}" \
|
20
|
+
unless @discovery['tag_name']
|
21
|
+
raise ArgumentError, "aws tag value required for service #{@name}" \
|
22
|
+
unless @discovery['tag_value']
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
@@ -0,0 +1,138 @@
|
|
1
|
+
require_relative "./base"
|
2
|
+
|
3
|
+
require_relative "../../gen-rb/endpoint_types"
|
4
|
+
require_relative "../../gen-rb/thrift"
|
5
|
+
require 'zk'
|
6
|
+
|
7
|
+
module Synapse
|
8
|
+
class ZookeeperWatcher < BaseWatcher
|
9
|
+
def start
|
10
|
+
zk_hosts = @discovery['hosts'].shuffle.join(',')
|
11
|
+
|
12
|
+
log.info "synapse: starting ZK watcher #{@name} @ hosts: #{zk_hosts}, path: #{@discovery['path']}"
|
13
|
+
@zk = ZK.new(zk_hosts)
|
14
|
+
|
15
|
+
@deserializer = Thrift::Deserializer.new
|
16
|
+
|
17
|
+
watch
|
18
|
+
discover
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
def validate_discovery_opts
|
23
|
+
raise ArgumentError, "invalid discovery method #{@discovery['method']}" \
|
24
|
+
unless @discovery['method'] == 'zookeeper'
|
25
|
+
raise ArgumentError, "missing or invalid zookeeper host for service #{@name}" \
|
26
|
+
unless @discovery['hosts']
|
27
|
+
raise ArgumentError, "invalid zookeeper path for service #{@name}" \
|
28
|
+
unless @discovery['path']
|
29
|
+
end
|
30
|
+
|
31
|
+
# helper method that ensures that the discovery path exists
|
32
|
+
def create(path)
|
33
|
+
log.debug "synapse: creating ZK path: #{path}"
|
34
|
+
# recurse if the parent node does not exist
|
35
|
+
create File.dirname(path) unless @zk.exists? File.dirname(path)
|
36
|
+
@zk.create(path, ignore: :node_exists)
|
37
|
+
end
|
38
|
+
|
39
|
+
# find the current backends at the discovery path; sets @backends
|
40
|
+
def discover
|
41
|
+
log.info "synapse: discovering backends for service #{@name}"
|
42
|
+
|
43
|
+
new_backends = []
|
44
|
+
begin
|
45
|
+
@zk.children(@discovery['path'], :watch => true).map do |name|
|
46
|
+
node = @zk.get("#{@discovery['path']}/#{name}")
|
47
|
+
|
48
|
+
begin
|
49
|
+
host, port = deserialize_service_instance(node.first)
|
50
|
+
rescue
|
51
|
+
log.error "synapse: invalid data in ZK node #{name} at #{@discovery['path']}"
|
52
|
+
else
|
53
|
+
server_port = @server_port_override ? @server_port_override : port
|
54
|
+
backend_name = "#{name}-#{[host, server_port].hash}"
|
55
|
+
|
56
|
+
log.debug "synapse: discovered backend #{backend_name} at #{host}:#{server_port} for service #{@name}"
|
57
|
+
new_backends << { 'name' => backend_name, 'host' => host, 'port' => server_port}
|
58
|
+
end
|
59
|
+
end
|
60
|
+
rescue ZK::Exceptions::NoNode
|
61
|
+
# the path must exist, otherwise watch callbacks will not work
|
62
|
+
create(@discovery['path'])
|
63
|
+
retry
|
64
|
+
end
|
65
|
+
|
66
|
+
if new_backends.empty?
|
67
|
+
if @default_servers.empty?
|
68
|
+
log.warn "synapse: no backends and no default servers for service #{@name}; using previous backends: #{@backends.inspect}"
|
69
|
+
else
|
70
|
+
log.warn "synapse: no backends for service #{@name}; using default servers: #{@default_servers.inspect}"
|
71
|
+
@backends = @default_servers
|
72
|
+
end
|
73
|
+
else
|
74
|
+
log.info "synapse: discovered #{new_backends.length} backends for service #{@name}"
|
75
|
+
@backends = new_backends
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# sets up zookeeper callbacks if the data at the discovery path changes
|
80
|
+
def watch
|
81
|
+
@watcher.unsubscribe if defined? @watcher
|
82
|
+
@watcher = @zk.register(@discovery['path'], &watcher_callback)
|
83
|
+
end
|
84
|
+
|
85
|
+
# handles the event that a watched path has changed in zookeeper
|
86
|
+
def watcher_callback
|
87
|
+
Proc.new do |event|
|
88
|
+
# Set new watcher
|
89
|
+
watch
|
90
|
+
# Rediscover
|
91
|
+
discover
|
92
|
+
# send a message to calling class to reconfigure
|
93
|
+
@synapse.configure
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# tries to extract host/port from a json hash
|
98
|
+
def parse_json(data)
|
99
|
+
begin
|
100
|
+
json = JSON.parse data
|
101
|
+
rescue Object => o
|
102
|
+
return false
|
103
|
+
end
|
104
|
+
raise 'instance json data does not have host key' unless json.has_key?('host')
|
105
|
+
raise 'instance json data does not have port key' unless json.has_key?('port')
|
106
|
+
return json['host'], json['port']
|
107
|
+
end
|
108
|
+
|
109
|
+
# tries to extract a host/port from twitter thrift data
|
110
|
+
def parse_thrift(data)
|
111
|
+
begin
|
112
|
+
service = Twitter::Thrift::ServiceInstance.new
|
113
|
+
@deserializer.deserialize(service, data)
|
114
|
+
rescue Object => o
|
115
|
+
return false
|
116
|
+
end
|
117
|
+
raise "instance thrift data does not have host" if service.serviceEndpoint.host.nil?
|
118
|
+
raise "instance thrift data does not have port" if service.serviceEndpoint.port.nil?
|
119
|
+
return service.serviceEndpoint.host, service.serviceEndpoint.port
|
120
|
+
end
|
121
|
+
|
122
|
+
# decode the data at a zookeeper endpoint
|
123
|
+
def deserialize_service_instance(data)
|
124
|
+
log.debug "synapse: deserializing process data"
|
125
|
+
|
126
|
+
# first, lets try parsing this as thrift
|
127
|
+
host, port = parse_thrift(data)
|
128
|
+
return host, port if host
|
129
|
+
|
130
|
+
# if that does not work, try json
|
131
|
+
host, port = parse_json(data)
|
132
|
+
return host, port if host
|
133
|
+
|
134
|
+
# if we got this far, then we have a problem
|
135
|
+
raise "could not decode this data:\n#{data}"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require_relative "./service_watcher/base"
|
2
|
+
require_relative "./service_watcher/zookeeper"
|
3
|
+
require_relative "./service_watcher/ec2tag"
|
4
|
+
require_relative "./service_watcher/dns"
|
5
|
+
|
6
|
+
module Synapse
|
7
|
+
class ServiceWatcher
|
8
|
+
|
9
|
+
@watchers = {
|
10
|
+
'base'=>BaseWatcher,
|
11
|
+
'zookeeper'=>ZookeeperWatcher,
|
12
|
+
'ec2tag'=>EC2Watcher,
|
13
|
+
'dns' => DnsWatcher
|
14
|
+
}
|
15
|
+
|
16
|
+
# the method which actually dispatches watcher creation requests
|
17
|
+
def self.create(opts, synapse)
|
18
|
+
raise ArgumentError, "Missing discovery method when trying to create watcher" \
|
19
|
+
unless opts.has_key?('discovery') && opts['discovery'].has_key?('method')
|
20
|
+
|
21
|
+
discovery_method = opts['discovery']['method']
|
22
|
+
raise ArgumentError, "Invalid discovery method #{discovery_method}" \
|
23
|
+
unless @watchers.has_key?(discovery_method)
|
24
|
+
|
25
|
+
return @watchers[discovery_method].new(opts, synapse)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/synapse/version.rb
CHANGED
data/lib/synapse.rb
CHANGED
@@ -1,5 +1,64 @@
|
|
1
|
-
|
1
|
+
require_relative "synapse/version"
|
2
|
+
require_relative "synapse/base"
|
3
|
+
require_relative "synapse/haproxy"
|
4
|
+
require_relative "synapse/service_watcher"
|
5
|
+
|
6
|
+
require 'logger'
|
7
|
+
require 'json'
|
8
|
+
|
9
|
+
include Synapse
|
2
10
|
|
3
11
|
module Synapse
|
4
|
-
|
12
|
+
class Synapse
|
13
|
+
def initialize(opts={})
|
14
|
+
# disable configuration until this is started
|
15
|
+
@configure_enabled = false
|
16
|
+
|
17
|
+
# create the service watchers for all our services
|
18
|
+
raise "specify a list of services to connect in the config" unless opts.has_key?('services')
|
19
|
+
@service_watchers = create_service_watchers(opts['services'])
|
20
|
+
|
21
|
+
# create the haproxy object
|
22
|
+
raise "haproxy config section is missing" unless opts.has_key?('haproxy')
|
23
|
+
@haproxy = Haproxy.new(opts['haproxy'])
|
24
|
+
end
|
25
|
+
|
26
|
+
# start all the watchers and enable haproxy configuration
|
27
|
+
def run
|
28
|
+
log.info "synapse: starting..."
|
29
|
+
|
30
|
+
@service_watchers.map { |watcher| watcher.start }
|
31
|
+
@configure_enabled = true
|
32
|
+
configure
|
33
|
+
|
34
|
+
# loop forever
|
35
|
+
loops = 0
|
36
|
+
loop do
|
37
|
+
sleep 1
|
38
|
+
loops += 1
|
39
|
+
log.debug "synapse: still running at #{Time.now}" if (loops % 60) == 0
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# reconfigure haproxy based on our watchers
|
44
|
+
def configure
|
45
|
+
if @configure_enabled
|
46
|
+
log.info "synapse: regenerating haproxy config"
|
47
|
+
@haproxy.update_config(@service_watchers)
|
48
|
+
else
|
49
|
+
log.info "synapse: reconfigure requested, but it's not yet enabled"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
def create_service_watchers(services={})
|
55
|
+
service_watchers =[]
|
56
|
+
services.each do |service_config|
|
57
|
+
service_watchers << ServiceWatcher.create(service_config, self)
|
58
|
+
end
|
59
|
+
|
60
|
+
return service_watchers
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
5
64
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class MockWatcher; end;
|
4
|
+
|
5
|
+
describe Synapse::Haproxy do
|
6
|
+
subject { Synapse::Haproxy.new(config['haproxy']) }
|
7
|
+
|
8
|
+
it 'updating the config' do
|
9
|
+
mockWatcher = mock(Synapse::ServiceWatcher)
|
10
|
+
binding.pry
|
11
|
+
subject.should_receive(:generate_config)
|
12
|
+
subject.update_config([mockWatcher])
|
13
|
+
end
|
14
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
|
+
# Require this file using `require "spec_helper"` to ensure that it is only
|
4
|
+
# loaded once.
|
5
|
+
#
|
6
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
7
|
+
require_relative '../lib/synapse'
|
8
|
+
require 'pry'
|
9
|
+
require_relative 'support/config'
|
10
|
+
|
11
|
+
RSpec.configure do |config|
|
12
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
13
|
+
config.run_all_when_everything_filtered = true
|
14
|
+
config.filter_run :focus
|
15
|
+
config.include Config
|
16
|
+
|
17
|
+
# Run specs in random order to surface order dependencies. If you find an
|
18
|
+
# order dependency and want to debug it, you can fix the order by providing
|
19
|
+
# the seed, which is printed after each run.
|
20
|
+
# --seed 1234
|
21
|
+
config.order = 'random'
|
22
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# list the services to connect
|
2
|
+
services:
|
3
|
+
- name: test
|
4
|
+
local_port: 3210
|
5
|
+
server_options: test_option
|
6
|
+
default_servers:
|
7
|
+
- { name: default1, host: localhost, port: 8080}
|
8
|
+
discovery:
|
9
|
+
method: zookeeper
|
10
|
+
path: /airbnb/service/logging/event_collector
|
11
|
+
hosts:
|
12
|
+
- localhost:2181
|
13
|
+
listen:
|
14
|
+
- test_option
|
15
|
+
|
16
|
+
|
17
|
+
# settings for haproxy including the global config
|
18
|
+
haproxy:
|
19
|
+
reload_command: "sudo service haproxy reload"
|
20
|
+
config_file_path: "/etc/haproxy/haproxy.cfg"
|
21
|
+
do_writes: false
|
22
|
+
do_reloads: false
|
23
|
+
global:
|
24
|
+
- global_test_option
|
25
|
+
|
26
|
+
defaults:
|
27
|
+
- default_test_option
|
data/synapse.gemspec
CHANGED
@@ -16,4 +16,11 @@ Gem::Specification.new do |gem|
|
|
16
16
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
17
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
18
|
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.add_runtime_dependency "zk", "~> 1.7.4"
|
21
|
+
gem.add_runtime_dependency "thrift", "~> 0.9.0"
|
22
|
+
|
23
|
+
gem.add_development_dependency "rspec"
|
24
|
+
gem.add_development_dependency "pry"
|
25
|
+
gem.add_development_dependency "pry-nav"
|
19
26
|
end
|
data/test.sh
ADDED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: synapse
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,23 +9,137 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
13
|
-
dependencies:
|
12
|
+
date: 2013-10-24 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: zk
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 1.7.4
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 1.7.4
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: thrift
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 0.9.0
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 0.9.0
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rspec
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: pry
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: pry-nav
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
14
94
|
description: ': Write a gem description'
|
15
95
|
email:
|
16
96
|
- martin.rhoads@airbnb.com
|
17
|
-
executables:
|
97
|
+
executables:
|
98
|
+
- synapse
|
18
99
|
extensions: []
|
19
100
|
extra_rdoc_files: []
|
20
101
|
files:
|
21
102
|
- .gitignore
|
103
|
+
- .rspec
|
22
104
|
- Gemfile
|
105
|
+
- Gemfile.lock
|
23
106
|
- LICENSE.txt
|
24
107
|
- README.md
|
25
108
|
- Rakefile
|
109
|
+
- Vagrantfile
|
110
|
+
- bin/synapse
|
111
|
+
- chef/converge
|
112
|
+
- chef/cookbooks/lxc/recipes/default.rb
|
113
|
+
- chef/cookbooks/synapse/attributes/default.rb
|
114
|
+
- chef/cookbooks/synapse/recipes/default.rb
|
115
|
+
- chef/run.json
|
116
|
+
- chef/run.rb
|
117
|
+
- client/.RData
|
118
|
+
- client/.Rhistory
|
119
|
+
- client/bench_rewrite_config.dat
|
120
|
+
- client/benchmark-client.iml
|
121
|
+
- client/pom.xml
|
122
|
+
- client/src/main/java/ClientArsch.java
|
123
|
+
- client/src/main/java/META-INF/MANIFEST.MF
|
124
|
+
- config/synapse.conf.json
|
125
|
+
- haproxy.pid
|
126
|
+
- lib/gen-rb/endpoint_types.rb
|
127
|
+
- lib/gen-rb/thrift.rb
|
26
128
|
- lib/synapse.rb
|
129
|
+
- lib/synapse/base.rb
|
130
|
+
- lib/synapse/haproxy.rb
|
131
|
+
- lib/synapse/service_watcher.rb
|
132
|
+
- lib/synapse/service_watcher/base.rb
|
133
|
+
- lib/synapse/service_watcher/dns.rb
|
134
|
+
- lib/synapse/service_watcher/ec2tag.rb
|
135
|
+
- lib/synapse/service_watcher/zookeeper.rb
|
27
136
|
- lib/synapse/version.rb
|
137
|
+
- spec/lib/synapse/haproxy_spec.rb
|
138
|
+
- spec/spec_helper.rb
|
139
|
+
- spec/support/config.rb
|
140
|
+
- spec/support/minimum.conf.yaml
|
28
141
|
- synapse.gemspec
|
142
|
+
- test.sh
|
29
143
|
homepage: ''
|
30
144
|
licenses: []
|
31
145
|
post_install_message:
|
@@ -50,4 +164,8 @@ rubygems_version: 1.8.23
|
|
50
164
|
signing_key:
|
51
165
|
specification_version: 3
|
52
166
|
summary: ': Write a gem summary'
|
53
|
-
test_files:
|
167
|
+
test_files:
|
168
|
+
- spec/lib/synapse/haproxy_spec.rb
|
169
|
+
- spec/spec_helper.rb
|
170
|
+
- spec/support/config.rb
|
171
|
+
- spec/support/minimum.conf.yaml
|