etcd 0.2.4 → 0.3.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 608958d15011133cdba9f60d48ed79e880e0de67
4
- data.tar.gz: 2c4ad5c83169f006a7fdd04ca4817d8ebedd8c52
3
+ metadata.gz: 22603e3722f2b94cc4b1b11b4b656328a43df33a
4
+ data.tar.gz: 13ecd4b92dc77af3540a61aa0237fbec51eb8b68
5
5
  SHA512:
6
- metadata.gz: 119aca839b983863c895be6b7ab86f73b4301a8ad816b104652b0e3a1d10f9c5c0ebb49a315b858e8cfa5be7c07fc79523a3bfd02157d67052145d0409b6a39b
7
- data.tar.gz: d1e5bd3393d11a19eb647db761571c55597b8884f3e1eb393dd9536727da340a28a6e87b4d7c1b49af3a2711518a7878ec7ffd900c65afd3e57d3f3d14e7b259
6
+ metadata.gz: ce218a334fd115475efb1e2aa4424de2a6c61c8b9d16ba3aceacecea6d2c4aa7fbeb980700cc6889e305f3297723a45837cdc022cd7e72fe4c880f25facb0033
7
+ data.tar.gz: ac82296d320989aa83c1852287a1b956709edb578e5215efbb9ad2318ad30e0641e37b3e7a70f7ea5efb127909cd404cbfe2fcee39c54ba4769d18795084706d
data/.rspec CHANGED
@@ -1,3 +1,2 @@
1
1
  -c
2
2
  -fd
3
- --fail-fast
@@ -1,9 +1,9 @@
1
1
  AllCops:
2
- Includes:
2
+ Include:
3
3
  - Gemfile
4
- - lib/**
5
- Excludes:
6
- - spec/**
4
+ - lib/**/*
5
+ Exclude:
6
+ - spec/**/*
7
7
 
8
8
  Encoding:
9
9
  Enabled: false
@@ -1,11 +1,13 @@
1
1
  before_install:
2
- - bash build_etcd
3
- - bundle install --path .bundle
2
+ - wget -c https://github.com/coreos/etcd/releases/download/v2.0.0-rc.1/etcd-v2.0.0-rc.1-linux-amd64.tar.gz
3
+ - tar -zxf etcd-v2.0.0-rc.1-linux-amd64.tar.gz
4
+ - bundle install
5
+
4
6
  rvm:
5
7
  - 1.9.3
6
- - 2.0.0
7
8
  - 2.1.0
9
+ - 2.2.0
8
10
  branches:
9
11
  only:
10
12
  - master
11
- script: "ETCD_BIN=./etcd/bin/etcd bundle exec rake spec"
13
+ script: "ETCD_BIN=./etcd-v2.0.0-rc.1-linux-amd64/etcd bundle exec rake spec"
data/Gemfile CHANGED
@@ -7,5 +7,6 @@ gem 'coco'
7
7
  gem 'rubocop'
8
8
  gem 'guard'
9
9
  gem 'guard-rake'
10
+ gem 'json'
10
11
  # uuid gem isn't pulling in systemu
11
12
  gem 'systemu'
data/README.md CHANGED
@@ -25,6 +25,31 @@ client = Etcd.client(host: '127.0.0.1', port: 4003)
25
25
  client = Etcd.client(:user_name => 'test', :password => 'pwd') # populates the authentication header for basic HTTP auth with user name and password (useful for proxied connections)
26
26
  client = Etcd.client(host: '127.0.0.1', port: 4003, allow_redirect: false) # wont let you run sensitive commands on non-leader machines, default is true
27
27
  ```
28
+
29
+ ### Create a client object to connect to a SSL etcd instance
30
+
31
+ See [Etcd config](https://github.com/coreos/etcd/blob/master/Documentation/configuration.md) to setup `etcd` in SSL mode.
32
+
33
+ Assuming you have these:
34
+ * `myca.crt` - Your internal CAs certificate
35
+ * `my-cert.crt` - The "client" cert
36
+ * `my-cert.key` - The key corresponding to `my-cert.crt`
37
+
38
+ If you were using self signed Certs and have your own CA, You would have set `-ca-file` in your etcd config also to use `myca.crt`.
39
+
40
+ ```ruby
41
+ client=Etcd.client(
42
+ :host => "your-etcd-host",
43
+ :port => 443,
44
+ :use_ssl => true,
45
+ :ca_file => "/pathto/myca.crt",
46
+ :ssl_cert => OpenSSL::X509::Certificate.new( File.read("/pathto/my-cert.crt") ),
47
+ :ssl_key => OpenSSL::PKey::RSA.new("/etc/ssl/my-cert.key",passphrase)
48
+ )
49
+ #Omit passphrase if not set on your key.
50
+ ```
51
+
52
+
28
53
  ### Set a key
29
54
  ```ruby
30
55
  client.set('/nodes/n1', value: 1)
@@ -18,10 +18,12 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
- spec.add_dependency "mixlib-log"
21
+ spec.required_ruby_version = '>= 1.9'
22
22
 
23
+ spec.add_dependency "mixlib-log"
23
24
  spec.add_development_dependency "uuid"
24
25
  spec.add_development_dependency "bundler"
25
26
  spec.add_development_dependency "rake"
27
+ spec.add_development_dependency "rdoc"
26
28
  spec.add_development_dependency "rspec"
27
29
  end
@@ -16,7 +16,6 @@ module Etcd
16
16
  # etcd api, like Etcd::Client#lock and Etcd::Client#eternal_watch, they
17
17
  # are defined in separate modules and included in this class
18
18
  class Client
19
-
20
19
  extend Forwardable
21
20
 
22
21
  HTTP_REDIRECT = ->(r) { r.is_a? Net::HTTPRedirection }
@@ -26,12 +25,19 @@ module Etcd
26
25
  include Stats
27
26
  include Keys
28
27
 
29
- Config = Struct.new(:use_ssl, :verify_mode, :read_timeout, :ssl_key, :ca_file,
30
- :user_name, :password, :allow_redirect, :ssl_cert)
28
+ Config = Struct.new(
29
+ :use_ssl,
30
+ :verify_mode,
31
+ :read_timeout,
32
+ :ssl_key,
33
+ :ca_file,
34
+ :user_name,
35
+ :password,
36
+ :ssl_cert
37
+ )
31
38
 
32
39
  def_delegators :@config, :use_ssl, :verify_mode, :read_timeout
33
- def_delegators :@config, :user_name, :password, :allow_redirect
34
-
40
+ def_delegators :@config, :user_name, :password
35
41
 
36
42
  attr_reader :host, :port, :http, :config
37
43
 
@@ -48,12 +54,15 @@ module Etcd
48
54
  @port = opts[:port] || 4001
49
55
  @config = Config.new
50
56
  @config.read_timeout = opts[:read_timeout] || 60
51
- @config.allow_redirect = opts.key?(:allow_redirect) ? opts[:allow_redirect] : true
52
57
  @config.use_ssl = opts[:use_ssl] || false
53
58
  @config.verify_mode = opts.key?(:verify_mode) ? opts[:verify_mode] : OpenSSL::SSL::VERIFY_PEER
54
59
  @config.user_name = opts[:user_name] || nil
55
60
  @config.password = opts[:password] || nil
56
- @config.allow_redirect = opts.key?(:allow_redirect) ? opts[:allow_redirect] : true
61
+ @config.ca_file = opts.key?(:ca_file) ? opts[:ca_file] : nil
62
+ # Provide a OpenSSL X509 cert here and not the path. See README
63
+ @config.ssl_cert = opts.key?(:ssl_cert) ? opts[:ssl_cert] : nil
64
+ # Provide the key (content) and not just the filename here.
65
+ @config.ssl_key = opts.key?(:ssl_key) ? opts[:ssl_key] : nil
57
66
  yield @config if block_given?
58
67
  end
59
68
  # rubocop:enable CyclomaticComplexity
@@ -68,14 +77,9 @@ module Etcd
68
77
  api_execute('/version', :get).body
69
78
  end
70
79
 
71
- # Returns array of all machines in the cluster
72
- def machines
73
- api_execute(version_prefix + '/machines', :get).body.split(',').map(&:strip)
74
- end
75
-
76
80
  # Get the current leader
77
81
  def leader
78
- api_execute(version_prefix + '/leader', :get).body.strip
82
+ api_execute(version_prefix + '/stats/leader', :get).body.strip
79
83
  end
80
84
 
81
85
  # This method sends api request to etcd server.
@@ -99,51 +103,40 @@ module Etcd
99
103
  else
100
104
  fail "Unknown http action: #{method}"
101
105
  end
102
- timeout = options[:timeout] || @read_timeout
103
106
  http = Net::HTTP.new(host, port)
104
- http.read_timeout = timeout
107
+ http.read_timeout = options[:timeout] || read_timeout
105
108
  setup_https(http)
106
109
  req.basic_auth(user_name, password) if [user_name, password].all?
107
110
  Log.debug("Invoking: '#{req.class}' against '#{path}")
108
111
  res = http.request(req)
109
112
  Log.debug("Response code: #{res.code}")
110
- process_http_request(res, req, params)
113
+ Log.debug("Response body: #{res.body}")
114
+ process_http_request(res)
111
115
  end
112
116
 
113
117
  def setup_https(http)
114
118
  http.use_ssl = use_ssl
115
119
  http.verify_mode = verify_mode
116
- unless config.ssl_cert.nil?
120
+ if config.ssl_cert
117
121
  Log.debug('Setting up ssl cert')
118
122
  http.cert = config.ssl_cert
119
123
  end
120
- unless config.ssl_key.nil?
124
+ if config.ssl_key
121
125
  Log.debug('Setting up ssl key')
122
126
  http.key = config.ssl_key
123
127
  end
124
- unless config.ca_file.nil?
128
+ if config.ca_file
125
129
  Log.debug('Setting up ssl ca file to :' + config.ca_file)
126
130
  http.ca_file = config.ca_file
127
131
  end
128
132
  end
129
133
 
130
- # need to ahve original request to process the response when it redirects
131
- def process_http_request(res, req = nil, params = nil)
134
+ # need to have original request to process the response when it redirects
135
+ def process_http_request(res)
132
136
  case res
133
137
  when HTTP_SUCCESS
134
138
  Log.debug('Http success')
135
139
  res
136
- when HTTP_REDIRECT
137
- if allow_redirect
138
- uri = URI(res['location'])
139
- @host = uri.host
140
- @port = uri.port
141
- Log.debug("Http redirect, setting new host to: #{@host}:#{@port}, and retrying")
142
- api_execute(uri.path, req.method.downcase.to_sym, params: params)
143
- else
144
- Log.debug('Http redirect not allowed')
145
- res.error!
146
- end
147
140
  when HTTP_CLIENT_ERROR
148
141
  fail Error.from_http_response(res)
149
142
  else
@@ -78,8 +78,12 @@ module Etcd
78
78
  params[:consistent] = opts[:consistent] if opts.key?(:consistent)
79
79
  params[:recursive] = opts[:recursive] if opts.key?(:recursive)
80
80
 
81
- response = api_execute(key_endpoint + key, :get,
82
- timeout: timeout, params: params)
81
+ response = api_execute(
82
+ key_endpoint + key,
83
+ :get,
84
+ timeout: timeout,
85
+ params: params
86
+ )
83
87
  Response.from_http_response(response)
84
88
  end
85
89
 
@@ -19,7 +19,7 @@ module Etcd
19
19
  @expiration = opts['expiration']
20
20
  @dir = opts['dir']
21
21
 
22
- if opts['dir'] && (!!opts['nodes'])
22
+ if opts['dir'] && opts['nodes']
23
23
  opts['nodes'].each do |data|
24
24
  children << Node.new(data)
25
25
  end
@@ -39,7 +39,7 @@ module Etcd
39
39
  end
40
40
 
41
41
  def directory?
42
- !! @dir
42
+ ! @dir.nil?
43
43
  end
44
44
  end
45
45
  end
@@ -1,5 +1,5 @@
1
1
  # Encoding: utf-8
2
2
  # Version const
3
3
  module Etcd
4
- VERSION = '0.2.4'
4
+ VERSION = '0.3.0'
5
5
  end
@@ -3,14 +3,6 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  describe 'Etcd basic auth client' do
6
-
7
- before(:all) do
8
- start_daemon(2)
9
- end
10
- after(:all) do
11
- stop_daemon
12
- end
13
-
14
6
  let(:client) do
15
7
  Etcd.client(host: 'localhost') do |config|
16
8
  config.user_name = 'test'
@@ -25,13 +17,4 @@ describe 'Etcd basic auth client' do
25
17
  it '#password' do
26
18
  expect(client.password).to eq('pwd')
27
19
  end
28
-
29
- it 'should set basic auth' do
30
- Net::HTTPRequest.any_instance.should_receive(:basic_auth).with('test', 'pwd')
31
- key = random_key
32
- value = uuid.generate
33
- client.set(key, value: value)
34
- sleep 1
35
- expect(read_only_client.get(key).value).to eq(value)
36
- end
37
20
  end
@@ -1,29 +1,12 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Etcd::Client do
4
-
5
- before(:all) do
6
- start_daemon(3)
7
- end
8
-
9
- after(:all) do
10
- stop_daemon
11
- end
12
-
13
4
  let(:client) do
14
5
  etcd_client
15
6
  end
16
7
 
17
- it 'should return the leader address' do
18
- expect(client.leader).to_not be_nil
19
- end
20
-
21
- it '#machines' do
22
- expect(client.machines).to include('http://127.0.0.1:4001')
23
- end
24
-
25
- it '#version' do
26
- expect(client.version).to match(/^etcd v?0\.\d+\.\d+(\+git)?/)
8
+ it '#version' do #etcd 2.0.0-rc.1
9
+ expect(client.version).to match(/^etcd v?\d+\.\d+\.\d+.*$/)
27
10
  end
28
11
 
29
12
  it '#version_prefix' do
@@ -36,15 +19,6 @@ describe Etcd::Client do
36
19
  client.api_execute('/v2/keys/x', :do)
37
20
  end.to raise_error
38
21
  end
39
-
40
- it 'should redirect api request when allow_redirect is set' do
41
- key = random_key
42
- value = uuid.generate
43
- resp = client.set(key, value: value)
44
- resp.node.key.should eql key
45
- resp.node.value.should eql value
46
- client.get(key).value.should eql resp.value
47
- end
48
22
  end
49
23
 
50
24
  context '#http header based metadata' do
@@ -1,9 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Etcd::Keys do
4
-
5
4
  shared_examples 'basic key operation' do
6
-
7
5
  it '#set/#get' do
8
6
  key = random_key
9
7
  value = uuid.generate
@@ -65,43 +63,10 @@ describe Etcd::Keys do
65
63
  end
66
64
  end
67
65
  end
68
-
69
66
  context 'without ssl' do
70
- before(:all) do
71
- start_daemon
72
- end
73
- after(:all) do
74
- stop_daemon
75
- end
76
67
  let(:client) do
77
68
  etcd_client
78
69
  end
79
70
  it_should_behave_like 'basic key operation'
80
71
  end
81
-
82
- context 'with ssl' do
83
- before(:all) do
84
- start_daemon(1, use_ssl: true)
85
- end
86
- after(:all) do
87
- stop_daemon
88
- end
89
- let(:client) do
90
- etcd_ssl_client
91
- end
92
- it_should_behave_like 'basic key operation'
93
- end
94
-
95
- context 'with ssl and client certificate' do
96
- before(:all) do
97
- start_daemon(1, use_ssl: true, check_client_cert: true )
98
- end
99
- after(:all) do
100
- stop_daemon
101
- end
102
- let(:client) do
103
- etcd_ssl_client_with_cert
104
- end
105
- it_should_behave_like 'basic key operation'
106
- end
107
72
  end
@@ -1,15 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Etcd::Node do
4
-
5
- before(:all) do
6
- start_daemon
7
- end
8
-
9
- after(:all) do
10
- stop_daemon
11
- end
12
-
13
4
  let(:client) do
14
5
  etcd_client
15
6
  end
@@ -3,17 +3,8 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  describe 'Etcd specs for the main etcd README examples' do
6
-
7
- before(:all) do
8
- start_daemon
9
- end
10
-
11
- after(:all) do
12
- stop_daemon
13
- end
14
-
15
6
  let(:client) do
16
- Etcd.client
7
+ etcd_client
17
8
  end
18
9
 
19
10
  shared_examples 'response with valid node data' do |action|
@@ -307,7 +298,6 @@ describe 'Etcd specs for the main etcd README examples' do
307
298
  end
308
299
 
309
300
  context 'hidden nodes' do
310
-
311
301
  before(:all) do
312
302
  etcd_client.set('/_message', value: 'Hello Hidden World')
313
303
  etcd_client.set('/message', value: 'Hello World')
@@ -3,19 +3,14 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  describe Etcd::Stats do
6
-
7
- before(:all) do
8
- start_daemon(5)
9
- end
10
-
11
- after(:all) do
12
- stop_daemon
13
- end
14
-
15
6
  let(:client) do
16
7
  etcd_client
17
8
  end
18
9
 
10
+ let(:leader) do
11
+ etcd_leader
12
+ end
13
+
19
14
  describe 'of leader' do
20
15
 
21
16
  let(:stats) do
@@ -23,11 +18,7 @@ describe Etcd::Stats do
23
18
  end
24
19
 
25
20
  it 'should contain a key for leader' do
26
- expect(stats['leader']).to_not be_nil
27
- end
28
-
29
- it 'should have 4 followers (since we spawn 5 node etcd cluster)' do
30
- expect(stats['followers'].keys.size).to eq(4)
21
+ expect(leader.stats(:leader)).to_not be_nil
31
22
  end
32
23
  end
33
24
 
@@ -3,15 +3,6 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  describe 'Etcd test_and_set' do
6
-
7
- before(:all) do
8
- start_daemon
9
- end
10
-
11
- after(:all) do
12
- stop_daemon
13
- end
14
-
15
6
  let(:client) do
16
7
  etcd_client
17
8
  end
@@ -21,7 +12,7 @@ describe 'Etcd test_and_set' do
21
12
  old_value = uuid.generate
22
13
  new_value = uuid.generate
23
14
  resp = client.set(key, value: old_value)
24
- resp.node.value.should eql old_value
15
+ expect(resp.node.value).to eq(old_value)
25
16
  client.test_and_set(key, value: new_value, prevValue: old_value)
26
17
  expect(client.get(key).value).to eq(new_value)
27
18
  end
@@ -3,19 +3,9 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  describe 'Etcd watch' do
6
-
7
- before(:all) do
8
- start_daemon
9
- end
10
-
11
- after(:all) do
12
- stop_daemon
13
- end
14
-
15
6
  let(:client) do
16
7
  etcd_client
17
8
  end
18
-
19
9
  it 'without index, returns the value at a particular index' do
20
10
  key = random_key(4)
21
11
  value1 = uuid.generate
@@ -20,32 +20,31 @@ module Etcd
20
20
  @ca_cert = File.expand_path('../data/ca.crt', __FILE__)
21
21
  end
22
22
 
23
- def etcd_servers
24
- @pids.size.times.inject([]){|servers, n| servers << "http://127.0.0.1:700#{n}" }
23
+ def etcd_ports
24
+ @pids.size.times.inject([]){|servers, n| servers << 4000 + n + 1 }
25
25
  end
26
26
 
27
- def start(numbers = 1, opts={})
27
+ def start(numbers = 1)
28
28
  raise "Already running etcd servers(#{@pids.inspect})" unless @pids.empty?
29
29
  @tmpdir = Dir.mktmpdir
30
- ssl_args = ""
31
- ssl_args << " -cert-file=#{@cert_file} -key-file=#{@key_file}" if opts[:use_ssl]
32
- ssl_args << " -ca-file=#{@ca_cert}" if opts[:check_client_cert]
33
- @pids << daemonize(@tmpdir, ssl_args)
34
- (numbers - 1).times do |n|
35
- @pids << daemonize(@tmpdir, ssl_args)
30
+ (1..numbers).each do |n|
31
+ @pids << daemonize(n, @tmpdir + n.to_s , numbers)
36
32
  end
33
+ sleep 5
37
34
  end
38
35
 
39
- def daemonize(dir, ssl_args)
40
- client_port = 4001 + @pids.size
41
- server_port = 7001 + @pids.size
42
- leader = '127.0.0.1:7001'
43
- args = " -addr 127.0.0.1:#{client_port} -peer-addr 127.0.0.1:#{server_port}"
44
- args << " -data-dir #{dir + client_port.to_s} -name node_#{client_port}"
45
- command = etcd_binary + args + ssl_args
46
- command << " -peers #{leader}" unless @pids.empty? # if pids are not empty, theres a daemon already
47
- pid = spawn(command, out: '/dev/null')
48
- sleep 1
36
+ def daemonize(index, dir, total)
37
+ ad_url = "http://localhost:#{7000 + index}"
38
+ client_url = "http://localhost:#{4000 + index}"
39
+ cluster_urls = (1..total).map{|n| "node_#{n}=http://localhost:#{7000 + n}"}.join(",")
40
+ flags = " -name node_#{index} -initial-advertise-peer-urls #{ad_url}"
41
+ flags << " -listen-peer-urls #{ad_url}"
42
+ flags << " -listen-client-urls #{client_url}"
43
+ flags << " -initial-cluster #{cluster_urls}"
44
+ flags << " -data-dir #{dir} "
45
+
46
+ command = etcd_binary + flags
47
+ pid = spawn(command, out: '/dev/null', err: '/dev/null')
49
48
  Process.detach(pid)
50
49
  pid
51
50
  end
@@ -70,13 +69,15 @@ module Etcd
70
69
  end
71
70
 
72
71
  module SpecHelper
73
-
72
+ def spawner
73
+ Spawner.instance
74
+ end
74
75
  def start_daemon(numbers = 1, opts={})
75
- Spawner.instance.start(numbers, opts)
76
+ spawner.start(numbers, opts)
76
77
  end
77
78
 
78
79
  def stop_daemon
79
- Spawner.instance.stop
80
+ spawner.stop
80
81
  end
81
82
 
82
83
  def uuid
@@ -91,41 +92,24 @@ module Etcd
91
92
  key
92
93
  end
93
94
 
94
- def etcd_ssl_client
95
- Etcd.client(host: 'localhost') do |config|
96
- config.use_ssl = true
97
- config.ca_file = File.expand_path('../data/ca.crt', __FILE__)
98
- end
95
+ def etcd_client(port = 4001)
96
+ Etcd.client(host: 'localhost', port: port)
99
97
  end
100
98
 
101
- def etcd_ssl_client
102
- Etcd.client(host: 'localhost') do |config|
103
- config.use_ssl = true
104
- config.ca_file = File.expand_path('../data/ca.crt', __FILE__)
105
- end
106
- end
107
-
108
- def etcd_ssl_client_with_cert
109
- client_cert = File.expand_path('../data/client.crt', __FILE__)
110
- client_key = File.expand_path('../data/client.key', __FILE__)
111
- Etcd.client(host: 'localhost') do |config|
112
- config.use_ssl = true
113
- config.ca_file = File.expand_path('../data/ca.crt', __FILE__)
114
- config.ssl_cert = OpenSSL::X509::Certificate.new(File.read(client_cert))
115
- config.ssl_key = OpenSSL::PKey::RSA.new(File.read(client_key))
116
- end
117
- end
118
-
119
- def etcd_client
120
- Etcd.client
121
- end
122
-
123
- def read_only_client
124
- Etcd.client(allow_redirect: false, port: 4002, host: 'localhost')
99
+ def etcd_leader
100
+ clients = spawner.etcd_ports.map{|port| etcd_client(port)}
101
+ clients.detect{|c|c.stats(:self)['state'] == 'StateLeader'}
125
102
  end
126
103
  end
127
104
  end
128
105
 
129
106
  RSpec.configure do |c|
130
107
  c.include Etcd::SpecHelper
108
+ c.before(:suite) do
109
+ Etcd::Spawner.instance.start(3)
110
+ end
111
+ c.after(:suite) do
112
+ Etcd::Spawner.instance.stop
113
+ end
114
+ c.fail_fast = false
131
115
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: etcd
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ranjib Dey
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-14 00:00:00.000000000 Z
11
+ date: 2015-03-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mixlib-log
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rdoc
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: rspec
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -97,15 +111,12 @@ files:
97
111
  - LICENSE.txt
98
112
  - README.md
99
113
  - Rakefile
100
- - build_etcd
101
114
  - etcd.gemspec
102
115
  - lib/etcd.rb
103
116
  - lib/etcd/client.rb
104
117
  - lib/etcd/exceptions.rb
105
118
  - lib/etcd/keys.rb
106
119
  - lib/etcd/log.rb
107
- - lib/etcd/mod/leader.rb
108
- - lib/etcd/mod/lock.rb
109
120
  - lib/etcd/node.rb
110
121
  - lib/etcd/response.rb
111
122
  - lib/etcd/stats.rb
@@ -118,10 +129,7 @@ files:
118
129
  - spec/etcd/basic_auth_client_spec.rb
119
130
  - spec/etcd/client_spec.rb
120
131
  - spec/etcd/keys_spec.rb
121
- - spec/etcd/leader_spec.rb
122
- - spec/etcd/lock_spec.rb
123
132
  - spec/etcd/node_spec.rb
124
- - spec/etcd/read_only_client_spec.rb
125
133
  - spec/etcd/readme_spec.rb
126
134
  - spec/etcd/stats_spec.rb
127
135
  - spec/etcd/test_and_set_spec.rb
@@ -139,7 +147,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
139
147
  requirements:
140
148
  - - ">="
141
149
  - !ruby/object:Gem::Version
142
- version: '0'
150
+ version: '1.9'
143
151
  required_rubygems_version: !ruby/object:Gem::Requirement
144
152
  requirements:
145
153
  - - ">="
@@ -160,10 +168,7 @@ test_files:
160
168
  - spec/etcd/basic_auth_client_spec.rb
161
169
  - spec/etcd/client_spec.rb
162
170
  - spec/etcd/keys_spec.rb
163
- - spec/etcd/leader_spec.rb
164
- - spec/etcd/lock_spec.rb
165
171
  - spec/etcd/node_spec.rb
166
- - spec/etcd/read_only_client_spec.rb
167
172
  - spec/etcd/readme_spec.rb
168
173
  - spec/etcd/stats_spec.rb
169
174
  - spec/etcd/test_and_set_spec.rb
data/build_etcd DELETED
@@ -1,8 +0,0 @@
1
- #!/bin/bash
2
-
3
- wget -c https://go.googlecode.com/files/go1.2.linux-amd64.tar.gz
4
- tar -zxf go1.2.linux-amd64.tar.gz
5
- git clone https://github.com/coreos/etcd
6
- export GOROOT=$PWD/go
7
- export PATH=$GOROOT/bin:$PATH
8
- cd etcd && ./build
@@ -1,28 +0,0 @@
1
- # Encoding: utf-8
2
-
3
- require 'timeout'
4
-
5
- module Etcd
6
- module Mod
7
- # Implement Etcd's Leader module
8
- module Leader
9
- def mod_leader_endpoint
10
- '/mod/v2/leader'
11
- end
12
-
13
- def set_leader(key, value, ttl)
14
- path = mod_leader_endpoint + "#{key}?ttl=#{ttl}"
15
- api_execute(path, :put, params: { name: value }).body
16
- end
17
-
18
- def get_leader(key)
19
- api_execute(mod_leader_endpoint + key, :get).body
20
- end
21
-
22
- def delete_leader(key, value)
23
- path = mod_leader_endpoint + key + '?' + URI.encode_www_form(name: value)
24
- api_execute(path, :delete).body
25
- end
26
- end
27
- end
28
- end
@@ -1,61 +0,0 @@
1
- # Encoding: utf-8
2
-
3
- require 'timeout'
4
-
5
- module Etcd
6
- module Mod
7
- # implement etcd lock module
8
- module Lock
9
- def mod_lock_endpoint
10
- '/mod/v2/lock'
11
- end
12
-
13
- def acquire_lock(key, ttl, opts = {})
14
- path = mod_lock_endpoint + key + "?ttl=#{ttl}"
15
- timeout = opts[:timeout] || 60
16
- Timeout.timeout(timeout) do
17
- return api_execute(path, :post, params: opts).body
18
- end
19
- end
20
-
21
- def renew_lock(key, ttl, opts = {})
22
- unless opts.key?(:index) || opts.key?(:value)
23
- fail ArgumentError, 'You mast pass index or value'
24
- end
25
- path = mod_lock_endpoint + key + "?ttl=#{ttl}"
26
- timeout = opts[:timeout] || 60
27
- Timeout.timeout(timeout) do
28
- api_execute(path, :put, params: opts).body
29
- end
30
- end
31
-
32
- def get_lock(key, opts = {})
33
- api_execute(mod_lock_endpoint + key, :get, params: opts).body
34
- end
35
-
36
- def delete_lock(key, opts = {})
37
- unless opts.key?(:index) || opts.key?(:value)
38
- fail ArgumentError, 'You must pass index or value'
39
- end
40
- api_execute(mod_lock_endpoint + key, :delete, params: opts)
41
- end
42
-
43
- # rubocop:disable RescueException
44
- def lock(key, ttl, opts = {})
45
- key = "/" + key unless key.start_with? '/'
46
- lock_index = acquire_lock(key, ttl, opts)
47
- begin
48
- yield key
49
- rescue Exception => e
50
- raise e
51
- ensure
52
- delete_lock(key, index: lock_index)
53
- end
54
- end
55
- # rubocop:enable RescueException
56
-
57
- alias_method :retrive_lock, :get_lock
58
- alias_method :release_lock, :delete_lock
59
- end
60
- end
61
- end
@@ -1,39 +0,0 @@
1
- # Encoding: utf-8
2
-
3
- require 'spec_helper'
4
- =begin
5
-
6
- describe 'mod leader' do
7
-
8
- before(:all) do
9
- start_daemon
10
- end
11
-
12
- after(:all) do
13
- stop_daemon
14
- end
15
-
16
- let(:client) do
17
- etcd_client
18
- end
19
-
20
- it 'should allow setting a key value with ttl' do
21
- client.set_leader('/db_master1', 'db01', 10)
22
- expect(client.get_leader('/db_master1')).to eq('db01')
23
- end
24
-
25
- it 'should allow deleting key with value' do
26
- client.set_leader('/db_master4', 'db04', 10)
27
- expect do
28
- client.delete_leader('/db_master4', 'db04')
29
- end.to_not raise_error
30
- end
31
-
32
- it 'should not allow deleting key without value' do
33
- client.set_leader('/db_master5', 'db05', 10)
34
- expect do
35
- client.delete_leader('/db_master5', 'db04')
36
- end.to raise_error
37
- end
38
- end
39
- =end
@@ -1,55 +0,0 @@
1
- # Encoding: utf-8
2
-
3
- require 'spec_helper'
4
- =begin
5
- describe 'lock' do
6
-
7
- before(:all) do
8
- start_daemon
9
- end
10
-
11
- after(:all) do
12
- stop_daemon
13
- end
14
-
15
- let(:client) do
16
- etcd_client
17
- end
18
-
19
- it 'should be able to acquire a lock' do
20
- expect do
21
- client.acquire_lock('/my_lock', 10)
22
- end.to_not raise_error
23
- end
24
-
25
- it 'should be able to renew a lock based on value' do
26
- client.acquire_lock('/my_lock1', 10, value: 123)
27
- expect do
28
- client.renew_lock('/my_lock1', 10, value: 123)
29
- end.to_not raise_error
30
- end
31
-
32
- it 'should be able to renew a lock based on index' do
33
- client.acquire_lock('/my_lock2', 10)
34
- index = client.get_lock('/my_lock2', field: 'index')
35
- expect do
36
- client.renew_lock('/my_lock2', 10, index: index)
37
- end.to_not raise_error
38
- end
39
-
40
- it 'should be able to delete a lock based on value' do
41
- client.acquire_lock('/my_lock3', 10, value: 123)
42
- expect do
43
- client.delete_lock('/my_lock3', value: 123)
44
- end.to_not raise_error
45
- end
46
-
47
- it 'should be able to delete a lock based on index' do
48
- client.acquire_lock('/my_lock4', 10)
49
- index = client.get_lock('/my_lock4', field: 'index')
50
- expect do
51
- client.delete_lock('/my_lock4', index: index)
52
- end.to_not raise_error
53
- end
54
- end
55
- =end
@@ -1,39 +0,0 @@
1
- # Encoding: utf-8
2
-
3
- require 'spec_helper'
4
-
5
- describe 'Etcd read only client' do
6
-
7
- before(:all) do
8
- start_daemon(3)
9
- end
10
- after(:all) do
11
- stop_daemon
12
- end
13
-
14
- let(:client) do
15
- etcd_client
16
- end
17
-
18
- it 'should not allow write' do
19
- key = random_key
20
- expect do
21
- read_only_client.set(key, value: uuid.generate)
22
- end.to raise_error(Net::HTTPRetriableError)
23
- end
24
-
25
- it 'should allow reads' do
26
- key = random_key
27
- value = uuid.generate
28
- client.set(key, value: value)
29
- sleep 1
30
- expect(read_only_client.get(key).value).to eq(value)
31
- end
32
-
33
- it 'should allow watch' do
34
- key = random_key
35
- value = uuid.generate
36
- index = client.set(key, value: value).node.modified_index
37
- expect(read_only_client.watch(key, index: index).value).to eq(value)
38
- end
39
- end