diff --git a/Gemfile b/Gemfile index a981d21..63611a6 100644 --- a/Gemfile +++ b/Gemfile @@ -2,3 +2,6 @@ source 'https://rubygems.org' gem "grpc" gem 'rspec' +gem 'faraday', '0.11.0' + + diff --git a/README.md b/README.md index 9971149..c27bb7d 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,10 @@ conn.user_list **Role Management** ``` # Add Role -conn.add_role('rolename', 'readwrite', 'a', 'Z') +conn.add_role('rolename') + +# Grant Permission to Role +conn.grant_permission_to_role('rolename', 'readwrite', 'a', 'z') # Delete Role conn.delete_role('rolename') diff --git a/lib/etcdv3.rb b/lib/etcdv3.rb index a2f68d5..d354465 100644 --- a/lib/etcdv3.rb +++ b/lib/etcdv3.rb @@ -45,34 +45,43 @@ def initialize(options = {}) @metadata[:token] = auth.generate_token(user, password) unless user.nil? end + # Inserts a new key. def put(key, value) kv.put(key, value) end + # Fetches key(s). def get(key, range_end='') kv.get(key, range_end) end + # Creates new user. def add_user(user, password) auth.add_user(user, password) end + # Fetch specified user def get_user(user) auth.get_user(user) end + # Delete specified user. def delete_user(user) auth.delete_user(user) end + # Changes the specified users password. def change_user_password(user, new_password) auth.change_user_password(user, new_password) end + # List all users. def user_list auth.user_list end + # Authenticate using specified user and password. + # On successful authentication, an auth token will be assigned to the instance. def authenticate(user, password) token = auth.generate_token(user, password) if token @@ -81,39 +90,57 @@ def authenticate(user, password) @options[:password] = password return true end + return false rescue GRPC::InvalidArgument => exception - print exception.message return false end + # List all roles. def role_list auth.role_list end - def add_role(name, permission, key, range_end='') - auth.add_role(name, permission, key, range_end) + # Add role with specified name. + def add_role(name) + auth.add_role(name) end + # Fetches a specified role. def get_role(name) auth.get_role(name) end + # Delete role. def delete_role(name) auth.delete_role(name) end + # Grants role to an existing user. def grant_role_to_user(user, role) auth.grant_role_to_user(user, role) end + # Revokes role from a specified user. def revoke_role_from_user(user, role) auth.revoke_role_from_user(user, role) end + # Grants a new permission to an existing role. + def grant_permission_to_role(name, permission, key, range_end='') + auth.grant_permission_to_role(name, permission, key, range_end) + end + + def revoke_permission_from_role(name, permission, key, range_end='') + auth.revoke_permission_from_role(name, permission, key, range_end) + end + + # Enables authentication. def enable_auth auth.enable_auth end + # Disables authentication. + # This will clear any active auth / token data. def disable_auth response = auth.disable_auth if response diff --git a/lib/etcdv3/auth.rb b/lib/etcdv3/auth.rb index faab3af..e9b8568 100644 --- a/lib/etcdv3/auth.rb +++ b/lib/etcdv3/auth.rb @@ -49,14 +49,8 @@ def change_user_password(user, new_password) @stub.user_change_password(request, metadata: @metadata) end - def add_role(name, permission, key, range_end) - permission = Authpb::Permission.new( - permType: Etcd::Auth::PERMISSIONS[permission], key: key, range_end: range_end - ) - @stub.role_add( - Authpb::Role.new(name: name, keyPermission: [permission]), - metadata: @metadata - ) + def add_role(name) + @stub.role_add(Authpb::Role.new(name: name), metadata: @metadata) end def get_role(name) @@ -78,6 +72,30 @@ def revoke_role_from_user(user, role) @stub.user_revoke_role(request, metadata: @metadata) end + def grant_permission_to_role(name, permission, key, range_end) + permission = Authpb::Permission.new( + permType: Etcd::Auth::PERMISSIONS[permission], key: key, range_end: range_end + ) + @stub.role_grant_permission( + Etcdserverpb::AuthRoleGrantPermissionRequest.new( + name: name, + perm: permission + ), + metadata: @metadata + ) + end + + def revoke_permission_from_role(name, permission, key, range_end) + @stub.role_revoke_permission( + Etcdserverpb::AuthRoleRevokePermissionRequest.new( + role: name, + key: key, + range_end: range_end + ), + metadata: @metadata + ) + end + def role_list @stub.role_list(Authpb::Role.new, metadata: @metadata) end diff --git a/spec/etcdv3/auth_spec.rb b/spec/etcdv3/auth_spec.rb index 0beaac9..82ff0b2 100644 --- a/spec/etcdv3/auth_spec.rb +++ b/spec/etcdv3/auth_spec.rb @@ -54,7 +54,7 @@ describe '#add_role' do after { conn.delete_role('add_role') } - subject { conn.add_role('add_role', 'readwrite', 'a', 'Z') } + subject { conn.add_role('add_role') } it 'adds a role' do expect(subject).to be_an_instance_of(Etcdserverpb::AuthRoleAddResponse) expect(conn.role_list.roles).to include('add_role') @@ -62,14 +62,14 @@ end describe '#get_role' do - before { conn.add_role('get_role', 'readwrite', 'a', 'Z') } + before { conn.add_role('get_role') } after { conn.delete_role('get_role') } subject { conn.get_role('get_role') } it { is_expected.to be_an_instance_of(Etcdserverpb::AuthRoleGetResponse) } end describe '#delete_role' do - before { conn.add_role('delete_role', 'readwrite', 'a', 'Z') } + before { conn.add_role('delete_role') } subject { conn.delete_role('delete_role') } it 'deletes role' do expect(subject).to be_an_instance_of(Etcdserverpb::AuthRoleDeleteResponse) @@ -82,6 +82,28 @@ it { is_expected.to be_an_instance_of(Etcdserverpb::AuthRoleListResponse) } end + describe '#grant_permission_to_role' do + before { conn.add_role('grant_perm') } + after { conn.delete_role('grant_perm') } + subject { conn.grant_permission_to_role('grant_perm', 'write', 'c', 'cc') } + it 'sets permission' do + expect(subject).to be_an_instance_of(Etcdserverpb::AuthRoleGrantPermissionResponse) + end + end + + describe '#revoke_permission_from_role' do + before do + conn.add_role('myrole') + conn.grant_permission_to_role('myrole', 'write', 'c', 'cc') + end + after { conn.delete_role('myrole') } + subject { conn.revoke_permission_from_role('myrole', 'write', 'c', 'cc') } + it 'revokes permission' do + expect(subject).to be_an_instance_of(Etcdserverpb::AuthRoleRevokePermissionResponse) + expect(conn.get_role('myrole').perm.size).to eq(0) + end + end + describe '#disable_auth' do before do conn.add_user('root', 'test') diff --git a/spec/helpers/test_instance.rb b/spec/helpers/test_instance.rb index f6323b4..dac478d 100644 --- a/spec/helpers/test_instance.rb +++ b/spec/helpers/test_instance.rb @@ -42,7 +42,7 @@ def spawn_etcd_instance end def stop - @pids.each { |pid| Process.kill('TERM', pid) } + @pids.each { |pid| Process.kill('TERM', pid) } rescue nil FileUtils.remove_entry_secure(@tmpdir, true) @pids.clear end