etcdv3 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +3 -0
- data/README.md +5 -2
- data/lib/etcdv3/auth.rb +42 -7
- data/lib/etcdv3/kv.rb +6 -0
- data/lib/etcdv3/version.rb +1 -1
- data/lib/etcdv3.rb +42 -3
- data/spec/etcd_spec.rb +8 -19
- data/spec/etcdv3/auth_spec.rb +84 -63
- data/spec/etcdv3/kv_spec.rb +8 -14
- data/spec/helpers/test_instance.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b631270b8fb44fc9f63bf971305a3a5336bc9064
|
4
|
+
data.tar.gz: 799324974b4957ace06c52553281a37ac178a1af
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fbe1eb6655e78bd7ba390bb84b5d11d8b2843f8ebab0ee12838d02a0da46508409847f993081307a2eb56192ea8bd0ec98156095964b11034e3872b413940195
|
7
|
+
data.tar.gz: 7124c6966834392ee9f11b44770160ee8e0ee2cdd3fa892901f58d1f87ce46b1f6c78257a0ce86df6bfc97887acba9bf525797da57f4c8302458538f25770278
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# etcdv3-ruby [![Build Status](https://travis-ci.org/davissp14/etcdv3-ruby.svg?branch=master)](https://travis-ci.org/davissp14/etcdv3-ruby)
|
1
|
+
# etcdv3-ruby [![Gem Version](https://badge.fury.io/rb/etcdv3.svg)](https://badge.fury.io/rb/etcdv3) [![Build Status](https://travis-ci.org/davissp14/etcdv3-ruby.svg?branch=master)](https://travis-ci.org/davissp14/etcdv3-ruby)
|
2
2
|
|
3
3
|
Ruby client for Etcd V3
|
4
4
|
|
@@ -55,7 +55,10 @@ conn.user_list
|
|
55
55
|
**Role Management**
|
56
56
|
```
|
57
57
|
# Add Role
|
58
|
-
conn.add_role('rolename'
|
58
|
+
conn.add_role('rolename')
|
59
|
+
|
60
|
+
# Grant Permission to Role
|
61
|
+
conn.grant_permission_to_role('rolename', 'readwrite', 'a', 'z')
|
59
62
|
|
60
63
|
# Delete Role
|
61
64
|
conn.delete_role('rolename')
|
data/lib/etcdv3/auth.rb
CHANGED
@@ -37,14 +37,25 @@ class Etcd
|
|
37
37
|
@stub.user_delete(Authpb::User.new(name: user))
|
38
38
|
end
|
39
39
|
|
40
|
-
def
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
40
|
+
def get_user(user)
|
41
|
+
@stub.user_get(Authpb::User.new(name: user))
|
42
|
+
end
|
43
|
+
|
44
|
+
def change_user_password(user, new_password)
|
45
|
+
request = Etcdserverpb::AuthUserChangePasswordRequest.new(
|
46
|
+
name: user,
|
47
|
+
password: new_password
|
47
48
|
)
|
49
|
+
@stub.user_change_password(request, metadata: @metadata)
|
50
|
+
end
|
51
|
+
|
52
|
+
def add_role(name)
|
53
|
+
@stub.role_add(Authpb::Role.new(name: name), metadata: @metadata)
|
54
|
+
end
|
55
|
+
|
56
|
+
def get_role(name)
|
57
|
+
request = Etcdserverpb::AuthRoleGetRequest.new(role: name)
|
58
|
+
@stub.role_get(request, metadata: @metadata)
|
48
59
|
end
|
49
60
|
|
50
61
|
def delete_role(name)
|
@@ -61,6 +72,30 @@ class Etcd
|
|
61
72
|
@stub.user_revoke_role(request, metadata: @metadata)
|
62
73
|
end
|
63
74
|
|
75
|
+
def grant_permission_to_role(name, permission, key, range_end)
|
76
|
+
permission = Authpb::Permission.new(
|
77
|
+
permType: Etcd::Auth::PERMISSIONS[permission], key: key, range_end: range_end
|
78
|
+
)
|
79
|
+
@stub.role_grant_permission(
|
80
|
+
Etcdserverpb::AuthRoleGrantPermissionRequest.new(
|
81
|
+
name: name,
|
82
|
+
perm: permission
|
83
|
+
),
|
84
|
+
metadata: @metadata
|
85
|
+
)
|
86
|
+
end
|
87
|
+
|
88
|
+
def revoke_permission_from_role(name, permission, key, range_end)
|
89
|
+
@stub.role_revoke_permission(
|
90
|
+
Etcdserverpb::AuthRoleRevokePermissionRequest.new(
|
91
|
+
role: name,
|
92
|
+
key: key,
|
93
|
+
range_end: range_end
|
94
|
+
),
|
95
|
+
metadata: @metadata
|
96
|
+
)
|
97
|
+
end
|
98
|
+
|
64
99
|
def role_list
|
65
100
|
@stub.role_list(Authpb::Role.new, metadata: @metadata)
|
66
101
|
end
|
data/lib/etcdv3/kv.rb
CHANGED
@@ -9,11 +9,17 @@ class Etcd
|
|
9
9
|
def put(key, value)
|
10
10
|
kv = Etcdserverpb::PutRequest.new(key: key, value: value)
|
11
11
|
@stub.put(kv, metadata: @metadata)
|
12
|
+
rescue GRPC::PermissionDenied, GRPC::InvalidArgument => exception
|
13
|
+
puts exception.message
|
14
|
+
false
|
12
15
|
end
|
13
16
|
|
14
17
|
def get(key, range_end="")
|
15
18
|
kv = Etcdserverpb::RangeRequest.new(key: key, range_end: range_end)
|
16
19
|
@stub.range(kv, metadata: @metadata).kvs
|
20
|
+
rescue GRPC::PermissionDenied, GRPC::InvalidArgument => exception
|
21
|
+
puts exception.message
|
22
|
+
false
|
17
23
|
end
|
18
24
|
end
|
19
25
|
end
|
data/lib/etcdv3/version.rb
CHANGED
data/lib/etcdv3.rb
CHANGED
@@ -45,26 +45,43 @@ class Etcd
|
|
45
45
|
@metadata[:token] = auth.generate_token(user, password) unless user.nil?
|
46
46
|
end
|
47
47
|
|
48
|
+
# Inserts a new key.
|
48
49
|
def put(key, value)
|
49
50
|
kv.put(key, value)
|
50
51
|
end
|
51
52
|
|
53
|
+
# Fetches key(s).
|
52
54
|
def get(key, range_end='')
|
53
55
|
kv.get(key, range_end)
|
54
56
|
end
|
55
57
|
|
58
|
+
# Creates new user.
|
56
59
|
def add_user(user, password)
|
57
60
|
auth.add_user(user, password)
|
58
61
|
end
|
59
62
|
|
63
|
+
# Fetch specified user
|
64
|
+
def get_user(user)
|
65
|
+
auth.get_user(user)
|
66
|
+
end
|
67
|
+
|
68
|
+
# Delete specified user.
|
60
69
|
def delete_user(user)
|
61
70
|
auth.delete_user(user)
|
62
71
|
end
|
63
72
|
|
73
|
+
# Changes the specified users password.
|
74
|
+
def change_user_password(user, new_password)
|
75
|
+
auth.change_user_password(user, new_password)
|
76
|
+
end
|
77
|
+
|
78
|
+
# List all users.
|
64
79
|
def user_list
|
65
80
|
auth.user_list
|
66
81
|
end
|
67
82
|
|
83
|
+
# Authenticate using specified user and password.
|
84
|
+
# On successful authentication, an auth token will be assigned to the instance.
|
68
85
|
def authenticate(user, password)
|
69
86
|
token = auth.generate_token(user, password)
|
70
87
|
if token
|
@@ -73,35 +90,57 @@ class Etcd
|
|
73
90
|
@options[:password] = password
|
74
91
|
return true
|
75
92
|
end
|
93
|
+
return false
|
76
94
|
rescue GRPC::InvalidArgument => exception
|
77
|
-
print exception.message
|
78
95
|
return false
|
79
96
|
end
|
80
97
|
|
98
|
+
# List all roles.
|
81
99
|
def role_list
|
82
100
|
auth.role_list
|
83
101
|
end
|
84
102
|
|
85
|
-
|
86
|
-
|
103
|
+
# Add role with specified name.
|
104
|
+
def add_role(name)
|
105
|
+
auth.add_role(name)
|
87
106
|
end
|
88
107
|
|
108
|
+
# Fetches a specified role.
|
109
|
+
def get_role(name)
|
110
|
+
auth.get_role(name)
|
111
|
+
end
|
112
|
+
|
113
|
+
# Delete role.
|
89
114
|
def delete_role(name)
|
90
115
|
auth.delete_role(name)
|
91
116
|
end
|
92
117
|
|
118
|
+
# Grants role to an existing user.
|
93
119
|
def grant_role_to_user(user, role)
|
94
120
|
auth.grant_role_to_user(user, role)
|
95
121
|
end
|
96
122
|
|
123
|
+
# Revokes role from a specified user.
|
97
124
|
def revoke_role_from_user(user, role)
|
98
125
|
auth.revoke_role_from_user(user, role)
|
99
126
|
end
|
100
127
|
|
128
|
+
# Grants a new permission to an existing role.
|
129
|
+
def grant_permission_to_role(name, permission, key, range_end='')
|
130
|
+
auth.grant_permission_to_role(name, permission, key, range_end)
|
131
|
+
end
|
132
|
+
|
133
|
+
def revoke_permission_from_role(name, permission, key, range_end='')
|
134
|
+
auth.revoke_permission_from_role(name, permission, key, range_end)
|
135
|
+
end
|
136
|
+
|
137
|
+
# Enables authentication.
|
101
138
|
def enable_auth
|
102
139
|
auth.enable_auth
|
103
140
|
end
|
104
141
|
|
142
|
+
# Disables authentication.
|
143
|
+
# This will clear any active auth / token data.
|
105
144
|
def disable_auth
|
106
145
|
response = auth.disable_auth
|
107
146
|
if response
|
data/spec/etcd_spec.rb
CHANGED
@@ -6,25 +6,14 @@ describe Etcd do
|
|
6
6
|
Etcd.new(url: 'http://127.0.0.1:2379')
|
7
7
|
end
|
8
8
|
describe '#initialize' do
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
it
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
it 'assigns port' do
|
18
|
-
expect(conn.port).to eq(2379)
|
19
|
-
end
|
20
|
-
|
21
|
-
it 'returns nil token' do
|
22
|
-
expect(conn.token).to eq(nil)
|
23
|
-
end
|
24
|
-
|
25
|
-
it 'assigns proper credentials' do
|
26
|
-
expect(conn.credentials).to eq(:this_channel_is_insecure)
|
27
|
-
end
|
9
|
+
subject { conn }
|
10
|
+
it { is_expected.to have_attributes(scheme: 'http') }
|
11
|
+
it { is_expected.to have_attributes(hostname: '127.0.0.1') }
|
12
|
+
it { is_expected.to have_attributes(port: 2379) }
|
13
|
+
it { is_expected.to have_attributes(credentials: :this_channel_is_insecure) }
|
14
|
+
it { is_expected.to have_attributes(token: nil) }
|
15
|
+
it { is_expected.to have_attributes(user: nil) }
|
16
|
+
it { is_expected.to have_attributes(password: nil) }
|
28
17
|
end
|
29
18
|
end
|
30
19
|
end
|
data/spec/etcdv3/auth_spec.rb
CHANGED
@@ -7,80 +7,100 @@ describe Etcd::Auth do
|
|
7
7
|
end
|
8
8
|
|
9
9
|
describe '#add_user' do
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
end
|
10
|
+
after { conn.delete_user('boom') }
|
11
|
+
subject { conn.add_user('boom', 'test') }
|
12
|
+
it { is_expected.to be_an_instance_of(Etcdserverpb::AuthUserAddResponse) }
|
14
13
|
end
|
15
14
|
|
16
|
-
describe '#
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
15
|
+
describe '#get_user' do
|
16
|
+
before { conn.add_user('get_user', 'password') }
|
17
|
+
after { conn.delete_user('get_user') }
|
18
|
+
subject { conn.get_user('get_user') }
|
19
|
+
it { is_expected.to be_an_instance_of(Etcdserverpb::AuthUserGetResponse) }
|
20
|
+
end
|
22
21
|
|
23
|
-
|
24
|
-
|
25
|
-
|
22
|
+
describe '#user_list' do
|
23
|
+
before { conn.add_user('list', 'test') }
|
24
|
+
after { conn.delete_user('list') }
|
25
|
+
subject { conn.user_list }
|
26
|
+
it 'returns correcty user information' do
|
27
|
+
expect(subject).to be_an_instance_of(Google::Protobuf::RepeatedField)
|
28
|
+
expect(subject).to include('list')
|
26
29
|
end
|
27
30
|
end
|
28
31
|
|
29
32
|
describe '#delete_user' do
|
30
|
-
before
|
31
|
-
|
32
|
-
|
33
|
-
it 'returns AuthUserDeleteResponse' do
|
34
|
-
expect(conn.delete_user('testuser')).to \
|
35
|
-
be_an_instance_of(Etcdserverpb::AuthUserDeleteResponse)
|
36
|
-
end
|
33
|
+
before { conn.add_user('delete_user', 'test') }
|
34
|
+
subject { conn.delete_user('delete_user') }
|
35
|
+
it { is_expected.to be_an_instance_of(Etcdserverpb::AuthUserDeleteResponse) }
|
37
36
|
end
|
38
37
|
|
39
38
|
describe '#grant_role_to_user' do
|
40
|
-
before
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
conn.delete_user('root')
|
45
|
-
end
|
46
|
-
it 'returns AuthUserGrantRoleResponse' do
|
47
|
-
expect(conn.grant_role_to_user("root", 'root')).to \
|
48
|
-
be_an_instance_of(Etcdserverpb::AuthUserGrantRoleResponse)
|
49
|
-
end
|
39
|
+
before { conn.add_user('grant_user', 'test') }
|
40
|
+
after { conn.delete_user('grant_user') }
|
41
|
+
subject { conn.grant_role_to_user('grant_user', 'root') }
|
42
|
+
it { is_expected.to be_an_instance_of(Etcdserverpb::AuthUserGrantRoleResponse) }
|
50
43
|
end
|
51
44
|
|
52
45
|
describe '#revoke_role_from_user' do
|
53
46
|
before do
|
54
|
-
conn.add_user('
|
55
|
-
conn.grant_role_to_user('
|
56
|
-
end
|
57
|
-
after do
|
58
|
-
conn.delete_user('test_user')
|
59
|
-
end
|
60
|
-
it 'returns AuthUserGrantRoleResponse' do
|
61
|
-
expect(conn.revoke_role_from_user("test_user", 'root')).to \
|
62
|
-
be_an_instance_of(Etcdserverpb::AuthUserRevokeRoleResponse)
|
47
|
+
conn.add_user('revoke_user', 'password')
|
48
|
+
conn.grant_role_to_user('revoke_user', 'root')
|
63
49
|
end
|
50
|
+
after { conn.delete_user('revoke_user') }
|
51
|
+
subject { conn.revoke_role_from_user('revoke_user', 'root') }
|
52
|
+
it { is_expected.to be_an_instance_of(Etcdserverpb::AuthUserRevokeRoleResponse) }
|
64
53
|
end
|
65
54
|
|
66
55
|
describe '#add_role' do
|
67
|
-
|
68
|
-
|
69
|
-
|
56
|
+
after { conn.delete_role('add_role') }
|
57
|
+
subject { conn.add_role('add_role') }
|
58
|
+
it 'adds a role' do
|
59
|
+
expect(subject).to be_an_instance_of(Etcdserverpb::AuthRoleAddResponse)
|
60
|
+
expect(conn.role_list.roles).to include('add_role')
|
70
61
|
end
|
71
62
|
end
|
72
63
|
|
73
|
-
describe '#
|
74
|
-
|
75
|
-
|
76
|
-
|
64
|
+
describe '#get_role' do
|
65
|
+
before { conn.add_role('get_role') }
|
66
|
+
after { conn.delete_role('get_role') }
|
67
|
+
subject { conn.get_role('get_role') }
|
68
|
+
it { is_expected.to be_an_instance_of(Etcdserverpb::AuthRoleGetResponse) }
|
69
|
+
end
|
70
|
+
|
71
|
+
describe '#delete_role' do
|
72
|
+
before { conn.add_role('delete_role') }
|
73
|
+
subject { conn.delete_role('delete_role') }
|
74
|
+
it 'deletes role' do
|
75
|
+
expect(subject).to be_an_instance_of(Etcdserverpb::AuthRoleDeleteResponse)
|
76
|
+
expect(conn.role_list.roles).to_not include('delete_role')
|
77
77
|
end
|
78
78
|
end
|
79
79
|
|
80
80
|
describe '#role_list' do
|
81
|
-
|
82
|
-
|
83
|
-
|
81
|
+
subject { conn.role_list }
|
82
|
+
it { is_expected.to be_an_instance_of(Etcdserverpb::AuthRoleListResponse) }
|
83
|
+
end
|
84
|
+
|
85
|
+
describe '#grant_permission_to_role' do
|
86
|
+
before { conn.add_role('grant_perm') }
|
87
|
+
after { conn.delete_role('grant_perm') }
|
88
|
+
subject { conn.grant_permission_to_role('grant_perm', 'write', 'c', 'cc') }
|
89
|
+
it 'sets permission' do
|
90
|
+
expect(subject).to be_an_instance_of(Etcdserverpb::AuthRoleGrantPermissionResponse)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe '#revoke_permission_from_role' do
|
95
|
+
before do
|
96
|
+
conn.add_role('myrole')
|
97
|
+
conn.grant_permission_to_role('myrole', 'write', 'c', 'cc')
|
98
|
+
end
|
99
|
+
after { conn.delete_role('myrole') }
|
100
|
+
subject { conn.revoke_permission_from_role('myrole', 'write', 'c', 'cc') }
|
101
|
+
it 'revokes permission' do
|
102
|
+
expect(subject).to be_an_instance_of(Etcdserverpb::AuthRoleRevokePermissionResponse)
|
103
|
+
expect(conn.get_role('myrole').perm.size).to eq(0)
|
84
104
|
end
|
85
105
|
end
|
86
106
|
|
@@ -91,13 +111,9 @@ describe Etcd::Auth do
|
|
91
111
|
conn.enable_auth
|
92
112
|
conn.authenticate('root', 'test')
|
93
113
|
end
|
94
|
-
after
|
95
|
-
|
96
|
-
|
97
|
-
it 'returns AuthDisableResponse' do
|
98
|
-
expect(conn.disable_auth).to \
|
99
|
-
be_an_instance_of(Etcdserverpb::AuthDisableResponse)
|
100
|
-
end
|
114
|
+
after { conn.delete_user('root') }
|
115
|
+
subject { conn.disable_auth }
|
116
|
+
it { is_expected.to be_an_instance_of(Etcdserverpb::AuthDisableResponse) }
|
101
117
|
end
|
102
118
|
|
103
119
|
describe '#enable_auth' do
|
@@ -110,9 +126,15 @@ describe Etcd::Auth do
|
|
110
126
|
conn.disable_auth
|
111
127
|
conn.delete_user('root')
|
112
128
|
end
|
113
|
-
|
114
|
-
|
115
|
-
|
129
|
+
subject { conn.enable_auth }
|
130
|
+
it { is_expected.to be_an_instance_of(Etcdserverpb::AuthEnableResponse) }
|
131
|
+
end
|
132
|
+
|
133
|
+
describe '#change_user_password' do
|
134
|
+
before { conn.add_user('myuser', 'test') }
|
135
|
+
after { conn.delete_user('myuser') }
|
136
|
+
subject { conn.change_user_password('myuser', 'boom') }
|
137
|
+
it { is_expected.to be_an_instance_of(Etcdserverpb::AuthUserChangePasswordResponse) }
|
116
138
|
end
|
117
139
|
|
118
140
|
describe "#authenticate" do
|
@@ -127,7 +149,7 @@ describe Etcd::Auth do
|
|
127
149
|
conn.disable_auth
|
128
150
|
conn.delete_user('root')
|
129
151
|
end
|
130
|
-
it 'properly reconfigures
|
152
|
+
it 'properly reconfigures auth and token' do
|
131
153
|
expect(conn.token).to_not be_nil
|
132
154
|
expect(conn.user).to eq('root')
|
133
155
|
expect(conn.password).to eq('test')
|
@@ -135,9 +157,8 @@ describe Etcd::Auth do
|
|
135
157
|
end
|
136
158
|
|
137
159
|
context 'auth disabled' do
|
138
|
-
|
139
|
-
|
140
|
-
end
|
160
|
+
subject { conn.authenticate('root', 'root') }
|
161
|
+
it { is_expected.to eq(false) }
|
141
162
|
end
|
142
163
|
end
|
143
164
|
end
|
data/spec/etcdv3/kv_spec.rb
CHANGED
@@ -7,23 +7,17 @@ describe Etcd::KV do
|
|
7
7
|
end
|
8
8
|
|
9
9
|
describe '#put' do
|
10
|
-
|
11
|
-
|
12
|
-
be_an_instance_of(Etcdserverpb::PutResponse)
|
13
|
-
end
|
10
|
+
subject { conn.put('test', 'test') }
|
11
|
+
it { is_expected.to be_an_instance_of(Etcdserverpb::PutResponse) }
|
14
12
|
end
|
15
13
|
|
16
14
|
describe '#get' do
|
17
|
-
before
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
expect(
|
22
|
-
|
23
|
-
end
|
24
|
-
|
25
|
-
it 'returns correct result' do
|
26
|
-
expect(conn.get('test').first.key).to eq('test')
|
15
|
+
before { conn.put('test', "zoom") }
|
16
|
+
subject { conn.get('test') }
|
17
|
+
it 'returns correct response' do
|
18
|
+
expect(subject).to be_an_instance_of(Google::Protobuf::RepeatedField)
|
19
|
+
expect(subject.first.key).to eq('test')
|
20
|
+
expect(subject.size).to eq(1)
|
27
21
|
end
|
28
22
|
end
|
29
23
|
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.1.
|
4
|
+
version: 0.1.1
|
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-
|
11
|
+
date: 2017-04-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: grpc
|
@@ -90,7 +90,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
90
90
|
version: '0'
|
91
91
|
requirements: []
|
92
92
|
rubyforge_project:
|
93
|
-
rubygems_version: 2.6.
|
93
|
+
rubygems_version: 2.6.11
|
94
94
|
signing_key:
|
95
95
|
specification_version: 4
|
96
96
|
summary: A Etcd client library for Version 3
|