etcdv3 0.5.2 → 0.6.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 +4 -4
- data/.travis.yml +1 -1
- data/Gemfile +1 -3
- data/README.md +25 -0
- data/etcdv3.gemspec +3 -2
- data/lib/etcdv3.rb +6 -0
- data/lib/etcdv3/kv.rb +31 -15
- data/lib/etcdv3/kv/requests.rb +23 -0
- data/lib/etcdv3/kv/transaction.rb +87 -0
- data/lib/etcdv3/version.rb +1 -1
- data/spec/etcdv3/kv_spec.rb +11 -0
- data/spec/etcdv3_spec.rb +43 -0
- metadata +25 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 30310caddc0edd306f6c292f980628a01e9555c6
|
4
|
+
data.tar.gz: 602d665808709503255bb941b604482ca5a0b91e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9d2dd95400f50f1a185593659d5651f9607b20fadd6f9bf712cb85e8a8832f735ef71a6b52dd7acaa76e46e43139a3ffa1031c8c5c34b10ef9dfd26e834eba7a
|
7
|
+
data.tar.gz: a26775aba02b2b2a7f3244544362cf33cfcdfd748196d3fedee1721357dbf2b2dd73e985db6dd7424ca4c11af48588ecd9a14c07a4a90266bafaebbbac5d8794
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -116,6 +116,31 @@ conn.lease_ttl(1234566789)
|
|
116
116
|
conn.lease_revoke(1234566789)
|
117
117
|
```
|
118
118
|
|
119
|
+
## Transaction
|
120
|
+
Transactions provide an easy way to process multiple requests in a single transaction.
|
121
|
+
|
122
|
+
_Note: You cannot modify the same key multiple times within a single transaction._
|
123
|
+
|
124
|
+
```ruby
|
125
|
+
# https://github.com/davissp14/etcdv3-ruby/blob/txns/lib/etcdv3/kv/transaction.rb
|
126
|
+
conn.transaction do |txn|
|
127
|
+
txn.compare = [
|
128
|
+
# Is the value of 'target_key' equal to 'compare_value'
|
129
|
+
txn.value('target_key', :equal, 'compare_value'),
|
130
|
+
# Is the version of 'target_key' greater than 10
|
131
|
+
txn.version('target_key', :greater, 10)
|
132
|
+
]
|
133
|
+
|
134
|
+
txn.success = [
|
135
|
+
txn.put('txn1', 'success')
|
136
|
+
]
|
137
|
+
|
138
|
+
txn.failure = [
|
139
|
+
txn.put('txn1', 'failed')
|
140
|
+
]
|
141
|
+
end
|
142
|
+
```
|
143
|
+
|
119
144
|
## Watch
|
120
145
|
```ruby
|
121
146
|
# Watch for changes on a specified key and return
|
data/etcdv3.gemspec
CHANGED
@@ -14,6 +14,7 @@ Gem::Specification.new do |s|
|
|
14
14
|
s.files = `git ls-files`.split("\n")
|
15
15
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
16
16
|
|
17
|
-
s.add_dependency("grpc", "1.2.
|
18
|
-
s.
|
17
|
+
s.add_dependency("grpc", "1.2.5")
|
18
|
+
s.add_dependency("faraday", "0.11.0")
|
19
|
+
s.add_development_dependency("rspec")
|
19
20
|
end
|
data/lib/etcdv3.rb
CHANGED
@@ -4,6 +4,8 @@ require 'uri'
|
|
4
4
|
|
5
5
|
require 'etcdv3/etcdrpc/rpc_services_pb'
|
6
6
|
require 'etcdv3/auth'
|
7
|
+
require 'etcdv3/kv/requests'
|
8
|
+
require 'etcdv3/kv/transaction'
|
7
9
|
require 'etcdv3/kv'
|
8
10
|
require 'etcdv3/maintenance'
|
9
11
|
require 'etcdv3/lease'
|
@@ -205,6 +207,10 @@ class Etcdv3
|
|
205
207
|
request.handle(:watch, 'watch', [key, range_end, block])
|
206
208
|
end
|
207
209
|
|
210
|
+
def transaction(&block)
|
211
|
+
request.handle(:kv, 'transaction', [block])
|
212
|
+
end
|
213
|
+
|
208
214
|
private
|
209
215
|
|
210
216
|
def request(reset: false)
|
data/lib/etcdv3/kv.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
|
2
2
|
class Etcdv3
|
3
3
|
class KV
|
4
|
+
include Etcdv3::KV::Requests
|
4
5
|
|
5
6
|
SORT_TARGET = {
|
6
7
|
key: 0,
|
@@ -22,27 +23,42 @@ class Etcdv3
|
|
22
23
|
end
|
23
24
|
|
24
25
|
def get(key, opts={})
|
25
|
-
opts
|
26
|
-
if opts[:sort_order]
|
27
|
-
opts[:sort_target] = SORT_TARGET[opts[:sort_target]] \
|
28
|
-
if opts[:sort_target]
|
29
|
-
opts[:key] = key
|
30
|
-
kv = Etcdserverpb::RangeRequest.new(opts)
|
31
|
-
@stub.range(kv, metadata: @metadata)
|
26
|
+
@stub.range(get_request(key, opts), metadata: @metadata)
|
32
27
|
end
|
33
28
|
|
34
29
|
def del(key, range_end="")
|
35
|
-
|
36
|
-
key: key,
|
37
|
-
range_end: range_end
|
38
|
-
)
|
39
|
-
@stub.delete_range(request, metadata: @metadata)
|
30
|
+
@stub.delete_range(del_request(key, range_end), metadata: @metadata)
|
40
31
|
end
|
41
32
|
|
42
33
|
def put(key, value, lease=nil)
|
43
|
-
|
44
|
-
|
45
|
-
|
34
|
+
@stub.put(put_request(key, value, lease), metadata: @metadata)
|
35
|
+
end
|
36
|
+
|
37
|
+
def transaction(block)
|
38
|
+
txn = Etcdv3::KV::Transaction.new
|
39
|
+
block.call(txn)
|
40
|
+
request = Etcdserverpb::TxnRequest.new(
|
41
|
+
compare: txn.compare,
|
42
|
+
success: generate_request_ops(txn.success),
|
43
|
+
failure: generate_request_ops(txn.failure)
|
44
|
+
)
|
45
|
+
@stub.txn(request)
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def generate_request_ops(requests)
|
51
|
+
requests.map do |request|
|
52
|
+
if request.is_a?(Etcdserverpb::RangeRequest)
|
53
|
+
Etcdserverpb::RequestOp.new(request_range: request)
|
54
|
+
elsif request.is_a?(Etcdserverpb::PutRequest)
|
55
|
+
Etcdserverpb::RequestOp.new(request_put: request)
|
56
|
+
elsif request.is_a?(Etcdserverpb::DeleteRangeRequest)
|
57
|
+
Etcdserverpb::RequestOp.new(request_delete_range: request)
|
58
|
+
else
|
59
|
+
raise "Invalid command. Not sure how you got here!"
|
60
|
+
end
|
61
|
+
end
|
46
62
|
end
|
47
63
|
end
|
48
64
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class Etcdv3::KV
|
2
|
+
module Requests
|
3
|
+
|
4
|
+
def get_request(key, opts)
|
5
|
+
opts[:sort_order] = SORT_ORDER[opts[:sort_order]] \
|
6
|
+
if opts[:sort_order]
|
7
|
+
opts[:sort_target] = SORT_TARGET[opts[:sort_target]] \
|
8
|
+
if opts[:sort_target]
|
9
|
+
opts[:key] = key
|
10
|
+
Etcdserverpb::RangeRequest.new(opts)
|
11
|
+
end
|
12
|
+
|
13
|
+
def del_request(key, range_end="")
|
14
|
+
Etcdserverpb::DeleteRangeRequest.new(key: key, range_end: range_end)
|
15
|
+
end
|
16
|
+
|
17
|
+
def put_request(key, value, lease=nil)
|
18
|
+
kv = Etcdserverpb::PutRequest.new(key: key, value: value)
|
19
|
+
kv.lease = lease if lease
|
20
|
+
kv
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
class Etcdv3::KV
|
2
|
+
class Transaction
|
3
|
+
include Etcdv3::KV::Requests
|
4
|
+
|
5
|
+
# Available comparison identifiers.
|
6
|
+
COMPARISON_IDENTIFIERS = {
|
7
|
+
equal: 0,
|
8
|
+
greater: 1,
|
9
|
+
less: 2,
|
10
|
+
not_equal: 3
|
11
|
+
}
|
12
|
+
|
13
|
+
# Available targets to compare with.
|
14
|
+
TARGETS = {
|
15
|
+
version: 0,
|
16
|
+
create_revision: 1,
|
17
|
+
mod_revision: 2,
|
18
|
+
value: 3
|
19
|
+
}
|
20
|
+
|
21
|
+
attr_writer :compare, :success, :failure
|
22
|
+
|
23
|
+
def initialize; end
|
24
|
+
|
25
|
+
def compare
|
26
|
+
@compare ||= []
|
27
|
+
end
|
28
|
+
|
29
|
+
def success
|
30
|
+
@success ||= []
|
31
|
+
end
|
32
|
+
|
33
|
+
def failure
|
34
|
+
@failure ||=[]
|
35
|
+
end
|
36
|
+
|
37
|
+
# Request Operations
|
38
|
+
|
39
|
+
# txn.put('my', 'key')
|
40
|
+
def put(key, value)
|
41
|
+
put_request(key, value)
|
42
|
+
end
|
43
|
+
|
44
|
+
# txn.get('key')
|
45
|
+
def get(key, opts={})
|
46
|
+
get_request(key, opts)
|
47
|
+
end
|
48
|
+
|
49
|
+
# txn.del('key')
|
50
|
+
def del(key, opts={})
|
51
|
+
del_request(key, opts)
|
52
|
+
end
|
53
|
+
|
54
|
+
### Compare Operations
|
55
|
+
|
56
|
+
# txn.version('names', :greater, 0 )
|
57
|
+
def version(key, compare_type, value)
|
58
|
+
generate_compare(:version, key, compare_type, value)
|
59
|
+
end
|
60
|
+
|
61
|
+
# txn.value('names', :equal, 'wowza' )
|
62
|
+
def value(key, compare_type, value)
|
63
|
+
generate_compare(:value, key, compare_type, value)
|
64
|
+
end
|
65
|
+
|
66
|
+
# txn.mod_revision('names', :not_equal, 0)
|
67
|
+
def mod_revision(key, compare_type, value)
|
68
|
+
generate_compare(:mod_revision, key, compare_type, value)
|
69
|
+
end
|
70
|
+
|
71
|
+
# txn.create_revision('names', :less, 10)
|
72
|
+
def create_revision(key, compare_type, value)
|
73
|
+
generate_compare(:create_revision, key, compare_type, value)
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def generate_compare(target_union, key, compare_type, value)
|
79
|
+
Etcdserverpb::Compare.new(
|
80
|
+
key: key,
|
81
|
+
result: COMPARISON_IDENTIFIERS[compare_type],
|
82
|
+
target: TARGETS[target_union],
|
83
|
+
target_union => value
|
84
|
+
)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
data/lib/etcdv3/version.rb
CHANGED
data/spec/etcdv3/kv_spec.rb
CHANGED
@@ -33,4 +33,15 @@ describe Etcdv3::KV do
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
+
describe '#transaction' do
|
37
|
+
let!(:block) do
|
38
|
+
Proc.new do |txn|
|
39
|
+
txn.compare = [ txn.value('txn', :equal, 'value') ]
|
40
|
+
txn.success = [ txn.put('txn-test', 'success') ]
|
41
|
+
txn.failure = [ txn.put('txn-test', 'failed') ]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
subject { stub.transaction(block) }
|
45
|
+
it { is_expected.to be_an_instance_of(Etcdserverpb::TxnResponse) }
|
46
|
+
end
|
36
47
|
end
|
data/spec/etcdv3_spec.rb
CHANGED
@@ -243,5 +243,48 @@ describe Etcdv3 do
|
|
243
243
|
end
|
244
244
|
end
|
245
245
|
end
|
246
|
+
|
247
|
+
describe '#transaction' do
|
248
|
+
context 'success' do
|
249
|
+
before { conn.put('txn', 'value') }
|
250
|
+
after { conn.del('txn') }
|
251
|
+
subject do
|
252
|
+
conn.transaction do |txn|
|
253
|
+
txn.compare = [ txn.value('txn', :equal, 'value') ]
|
254
|
+
txn.success = [ txn.put('txn-test', 'success') ]
|
255
|
+
txn.failure = [ txn.put('txn-test', 'failed') ]
|
256
|
+
end
|
257
|
+
end
|
258
|
+
it { is_expected.to be_an_instance_of(Etcdserverpb::TxnResponse) }
|
259
|
+
it 'returns successful' do
|
260
|
+
expect(subject.succeeded).to eq(true)
|
261
|
+
end
|
262
|
+
it 'sets correct key' do
|
263
|
+
expect(conn.get('txn-test').kvs.first.value).to eq('success')
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
context 'failure' do
|
268
|
+
before { conn.put('txn', 'value') }
|
269
|
+
after { conn.del('txn') }
|
270
|
+
subject do
|
271
|
+
conn.transaction do |txn|
|
272
|
+
txn.compare = [
|
273
|
+
txn.create_revision('txn', :greater, 500),
|
274
|
+
txn.mod_revision('txn', :less, 1000)
|
275
|
+
]
|
276
|
+
txn.success = [ txn.put('txn-test', 'success') ]
|
277
|
+
txn.failure = [ txn.put('txn-test', 'failed') ]
|
278
|
+
end
|
279
|
+
end
|
280
|
+
it 'returns successful' do
|
281
|
+
expect(subject.succeeded).to eq(false)
|
282
|
+
end
|
283
|
+
it 'sets correct key' do
|
284
|
+
expect(conn.get('txn-test').kvs.first.value).to eq('failed')
|
285
|
+
end
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
246
289
|
end
|
247
290
|
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.
|
4
|
+
version: 0.6.0
|
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-
|
11
|
+
date: 2017-04-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: grpc
|
@@ -16,28 +16,42 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 1.2.
|
19
|
+
version: 1.2.5
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 1.2.
|
26
|
+
version: 1.2.5
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: faraday
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - '='
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
34
|
-
type: :
|
33
|
+
version: 0.11.0
|
34
|
+
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - '='
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: 0.11.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
41
55
|
description: Etcd v3 Ruby Client
|
42
56
|
email: davissp14@gmail.com
|
43
57
|
executables: []
|
@@ -58,6 +72,8 @@ files:
|
|
58
72
|
- lib/etcdv3/etcdrpc/rpc_pb.rb
|
59
73
|
- lib/etcdv3/etcdrpc/rpc_services_pb.rb
|
60
74
|
- lib/etcdv3/kv.rb
|
75
|
+
- lib/etcdv3/kv/requests.rb
|
76
|
+
- lib/etcdv3/kv/transaction.rb
|
61
77
|
- lib/etcdv3/lease.rb
|
62
78
|
- lib/etcdv3/maintenance.rb
|
63
79
|
- lib/etcdv3/protos/annotations.proto
|
@@ -98,7 +114,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
98
114
|
version: '0'
|
99
115
|
requirements: []
|
100
116
|
rubyforge_project:
|
101
|
-
rubygems_version: 2.
|
117
|
+
rubygems_version: 2.4.5.1
|
102
118
|
signing_key:
|
103
119
|
specification_version: 4
|
104
120
|
summary: A Etcd client library for Version 3
|