etcdv3 0.5.1 → 0.5.2

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: 688201ef38aa54b086f120a6b5eaaaef142167de
4
- data.tar.gz: ed7714479e957b95959e26610db9aaab66fdef89
3
+ metadata.gz: bfb94e2d833d0412e229748f89be3697776aa677
4
+ data.tar.gz: a4878727100089890d69309ea3e063d767a8f5ec
5
5
  SHA512:
6
- metadata.gz: 56fe98b7cde847d737d30767894f1e964fbda6935e6775259c94f25cb1bb04af49a9644b2f62a02d05edf58571bf4d379e28f30fc64dc5f6226229ce5a39ab51
7
- data.tar.gz: f00d91763751a2872e09c71790043c639dadc0ffa5e8ce05df6dd9bd6a3f0cf16f646bc84f525be44df801b820d98e05262625c55d46565c807053de7cb8711d
6
+ metadata.gz: 5fbac1f489e35934579e6ed3e92158b23a5ad6aaf39c8c381b1a304b4a9f969cb954c79113c4b207d976a73c2c9638b30fa96ecc8393e77c08ccd77d581e86e1
7
+ data.tar.gz: 2a22159afd0bb01446764763e79dc5fffa47fe8d51edbd063f59f7afa801d40a8532213ca32f9be556482027124172ac169cb0fb11d104ebbe29f5771e113bf7
data/README.md CHANGED
@@ -26,7 +26,7 @@ conn = Etcdv3.new(url: 'http://127.0.0.1:2379')
26
26
  conn = Etcdv3.new(url: 'https://hostname:port')
27
27
 
28
28
  # Secure connection with Auth
29
- conn = Etcdv3.new(url: 'https://hostname:port', user: "gary", password: "secret")
29
+ conn = Etcdv3.new(url: 'https://hostname:port', user: 'root', password: 'mysecretpassword')
30
30
 
31
31
  # Secure connection specifying own certificates
32
32
  # Coming soon...
@@ -35,19 +35,19 @@ conn = Etcdv3.new(url: 'https://hostname:port', user: "gary", password: "secret"
35
35
  ## Adding, Fetching and Deleting Keys
36
36
  ```ruby
37
37
  # Put
38
- conn.put("my", "value")
38
+ conn.put('foo', 'bar')
39
39
 
40
40
  # Get
41
- conn.get("my")
41
+ conn.get('my')
42
42
 
43
43
  # Get Key Range
44
- conn.get('my', range_end: 'myyyy')
44
+ conn.get('foo', range_end: 'foo80')
45
45
 
46
46
  # Delete Key
47
- conn.del('my')
47
+ conn.del('foo')
48
48
 
49
49
  # Delete Key Range
50
- conn.del('my', range_end: 'myyy')
50
+ conn.del('foo', range_end: 'foo80')
51
51
  ```
52
52
 
53
53
  ## User Management
@@ -58,20 +58,23 @@ conn.user_add('admin', 'secret')
58
58
  # Delete User
59
59
  conn.user_delete('admin')
60
60
 
61
- # List users
61
+ # Get User
62
+ conn.user_get('admin')
63
+
64
+ # List Users
62
65
  conn.user_list
63
66
  ```
64
67
 
65
68
  ## Role Management
66
69
  ```ruby
67
70
  # Add Role
68
- conn.role_add('rolename')
71
+ conn.role_add('admin')
69
72
 
70
73
  # Grant Permission to Role
71
- conn.role_grant_permission('rolename', :readwrite, 'a', 'z')
74
+ conn.role_grant_permission('admin', :readwrite, 'foo', 'foo99')
72
75
 
73
76
  # Delete Role
74
- conn.role_delete('rolename')
77
+ conn.role_delete('admin')
75
78
 
76
79
  # List Roles
77
80
  conn.role_list
@@ -82,7 +85,7 @@ conn.role_list
82
85
  # Configure a root user
83
86
  conn.user_add('root', 'mysecretpassword')
84
87
 
85
- # Grant root user the root role
88
+ # Grant root role to root user
86
89
  conn.user_grant_role('root', 'root')
87
90
 
88
91
  # Enable Authentication
@@ -104,7 +107,7 @@ conn.auth_disable
104
107
  conn.lease_grant(100)
105
108
 
106
109
  # Attach key to lease
107
- conn.put("testkey", "testvalue", lease_id: 1234566789)
110
+ conn.put('foo', 'bar', lease_id: 1234566789)
108
111
 
109
112
  # Get information about lease and its attached keys
110
113
  conn.lease_ttl(1234566789)
@@ -116,10 +119,10 @@ conn.lease_revoke(1234566789)
116
119
  ## Watch
117
120
  ```ruby
118
121
  # Watch for changes on a specified key and return
119
- events = conn.watch('names')
122
+ events = conn.watch('foo')
120
123
 
121
124
  # Watch for changes on a specified key range and return
122
- events = conn.watch('boom', range_end: 'booooooom')
125
+ events = conn.watch('foo', range_end: 'fop')
123
126
 
124
127
  # Watches for changes continuously until killed.
125
128
  event_count = 0
@@ -1,35 +1,53 @@
1
+ require 'base64'
1
2
  class Etcdv3
2
3
  class Request
3
4
 
4
- attr_reader :metacache
5
+ HANDLERS = {
6
+ auth: Etcdv3::Auth,
7
+ kv: Etcdv3::KV,
8
+ maintenance: Etcdv3::Maintenance,
9
+ lease: Etcdv3::Lease,
10
+ watch: Etcdv3::Watch
11
+ }
5
12
 
6
- def initialize(hostname, credentials, metadata, metacache='')
7
- @handlers ||= handler_map(hostname, credentials, metadata)
8
- @metacache = metacache
13
+ attr_reader :user, :password, :token
14
+
15
+ def initialize(hostname, credentials)
16
+ @user, @password, @token = nil, nil, nil
17
+ @hostname = hostname
18
+ @credentials = credentials
19
+ @handlers = handler_map
9
20
  end
10
21
 
11
- def handle(stub, method, method_args=[])
22
+ def handle(stub, method, method_args=[], retries: 1)
12
23
  @handlers.fetch(stub).send(method, *method_args)
24
+ rescue GRPC::Unauthenticated => exception
25
+ # Regenerate token in the event it expires.
26
+ if exception.details == 'etcdserver: invalid auth token'
27
+ if retries > 0
28
+ authenticate(@user, @password)
29
+ return handle(stub, method, method_args, retries: retries - 1)
30
+ end
31
+ end
32
+ raise exception
33
+ end
34
+
35
+ def authenticate(user, password)
36
+ # Attempt to generate token using user and password.
37
+ @token = handle(:auth, 'generate_token', [user, password])
38
+ @user = user
39
+ @password = password
40
+ @handlers = handler_map(token: @token)
13
41
  end
14
42
 
15
43
  private
16
44
 
17
- def handler_map(hostname, credentials, metadata)
45
+ def handler_map(metadata={})
18
46
  Hash[
19
- handler_constants.map do |key, klass|
20
- [key, klass.new(hostname, credentials, metadata)]
47
+ HANDLERS.map do |key, klass|
48
+ [key, klass.new(@hostname, @credentials, metadata)]
21
49
  end
22
50
  ]
23
51
  end
24
-
25
- def handler_constants
26
- {
27
- auth: Etcdv3::Auth,
28
- kv: Etcdv3::KV,
29
- maintenance: Etcdv3::Maintenance,
30
- lease: Etcdv3::Lease,
31
- watch: Etcdv3::Watch
32
- }
33
- end
34
52
  end
35
53
  end
@@ -1,3 +1,3 @@
1
1
  class Etcdv3
2
- VERSION = '0.5.1'.freeze
2
+ VERSION = '0.5.2'.freeze
3
3
  end
data/lib/etcdv3.rb CHANGED
@@ -1,16 +1,16 @@
1
1
 
2
2
  require 'grpc'
3
3
  require 'uri'
4
- require 'base64'
5
4
 
6
5
  require 'etcdv3/etcdrpc/rpc_services_pb'
7
6
  require 'etcdv3/auth'
8
7
  require 'etcdv3/kv'
9
8
  require 'etcdv3/maintenance'
10
9
  require 'etcdv3/lease'
11
- require 'etcdv3/request'
12
10
  require 'etcdv3/watch'
13
11
 
12
+ require 'etcdv3/request'
13
+
14
14
  class Etcdv3
15
15
 
16
16
  attr_reader :credentials, :options
@@ -31,24 +31,22 @@ class Etcdv3
31
31
  uri.hostname
32
32
  end
33
33
 
34
- def token
35
- @metadata[:token]
36
- end
37
-
38
34
  def user
39
- @options[:user]
35
+ request.user
40
36
  end
41
37
 
42
38
  def password
43
- @options[:password]
39
+ request.password
40
+ end
41
+
42
+ def token
43
+ request.token
44
44
  end
45
45
 
46
46
  def initialize(options = {})
47
47
  @options = options
48
48
  @credentials = resolve_credentials
49
- @metadata = {}
50
- @metadata[:token] = generate_token(user, password) unless user.nil?
51
- @metacache = set_metacache
49
+ authenticate(options[:user], options[:password]) unless options[:user].nil?
52
50
  end
53
51
 
54
52
  # Version of Etcd running on member
@@ -77,33 +75,23 @@ class Etcdv3
77
75
  end
78
76
 
79
77
  # Authenticate using specified user and password.
80
- # On successful authentication, an auth token will be assigned to the instance.
78
+ # On successful authentication, an auth token will be assigned to the request instance.
81
79
  def authenticate(user, password)
82
- token = generate_token(user, password)
83
- return false unless token
84
- @metadata[:token] = token
85
- @options[:user] = user
86
- @options[:password] = password
87
- @metacache = set_metacache
88
- true
80
+ request.authenticate(user, password)
89
81
  end
90
82
 
91
83
  # Enables authentication.
92
84
  def auth_enable
93
85
  request.handle(:auth, 'auth_enable')
86
+ true
94
87
  end
95
88
 
96
89
  # Disables authentication.
97
90
  # This will clear any active auth / token data.
98
91
  def auth_disable
99
- response = request.handle(:auth, 'auth_disable')
100
- if response
101
- @metadata.delete(:token)
102
- @options[:user] = nil
103
- @options[:password] = nil
104
- @metacache = set_metacache
105
- end
106
- response
92
+ request.handle(:auth, 'auth_disable')
93
+ request(reset: true)
94
+ true
107
95
  end
108
96
 
109
97
  # key - string
@@ -219,19 +207,9 @@ class Etcdv3
219
207
 
220
208
  private
221
209
 
222
- def request
223
- # Only re-initialize when metadata changes.
224
- return @request if @request && @request.metacache == @metacache
225
- @request = Request.new("#{hostname}:#{port}", @credentials, @metadata, @metacache)
226
- end
227
-
228
- # Generates a new hash using a base64 of the metadata.
229
- def set_metacache
230
- Base64.strict_encode64(@metadata.to_s)
231
- end
232
-
233
- def generate_token(user, password)
234
- request.handle(:auth, 'generate_token', [user, password])
210
+ def request(reset: false)
211
+ return @request if @request && !reset
212
+ @request = Request.new("#{hostname}:#{port}", @credentials)
235
213
  end
236
214
 
237
215
  def resolve_credentials
data/spec/etcdv3_spec.rb CHANGED
@@ -201,7 +201,7 @@ describe Etcdv3 do
201
201
  end
202
202
  after { conn.user_delete('root') }
203
203
  subject { conn.auth_disable }
204
- it { is_expected.to be_an_instance_of(Etcdserverpb::AuthDisableResponse) }
204
+ it { is_expected.to eq(true) }
205
205
  end
206
206
 
207
207
  describe '#auth_enable' do
@@ -215,7 +215,7 @@ describe Etcdv3 do
215
215
  conn.user_delete('root')
216
216
  end
217
217
  subject { conn.auth_enable }
218
- it { is_expected.to be_an_instance_of(Etcdserverpb::AuthEnableResponse) }
218
+ it { is_expected.to eq(true) }
219
219
  end
220
220
 
221
221
  describe "#authenticate" do
@@ -243,32 +243,5 @@ describe Etcdv3 do
243
243
  end
244
244
  end
245
245
  end
246
-
247
- describe '#metacache' do
248
- context 'uses cached request object' do
249
- let!(:object_id) { conn.send(:request).object_id }
250
- before { conn.user_add('root', 'test') }
251
- after { conn.user_delete('root') }
252
- subject { conn.send(:request).object_id }
253
- it { is_expected.to eq(object_id) }
254
- end
255
- context 'resets cache on auth' do
256
- let!(:object_id) { conn.send(:request).object_id }
257
- before do
258
- conn.user_add('root', 'test')
259
- conn.user_grant_role('root', 'root')
260
- conn.auth_enable
261
- conn.authenticate('root', 'test')
262
- conn.user_add('boom', 'password')
263
- end
264
- after do
265
- conn.auth_disable
266
- conn.user_delete('root')
267
- conn.user_delete('boom')
268
- end
269
- subject { conn.send(:request).object_id }
270
- it { is_expected.to_not eq(object_id) }
271
- end
272
- end
273
246
  end
274
247
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: etcdv3
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.5.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shaun Davis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-04-17 00:00:00.000000000 Z
11
+ date: 2017-04-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: grpc