From: Andrew Purtell Subject: [PATCH] HBASE-11001 Shell support for granting cell permissions for testing --- hbase-shell/src/main/ruby/hbase/table.rb | 74 ++++++++++++++------- hbase-shell/src/main/ruby/shell/commands/grant.rb | 69 ++++++++++++++++++- 2 files changed, 115 insertions(+), 28 deletions(-) diff --git hbase-shell/src/main/ruby/hbase/table.rb hbase-shell/src/main/ruby/hbase/table.rb index ef1cee7..ce2d96f 100644 --- hbase-shell/src/main/ruby/hbase/table.rb +++ hbase-shell/src/main/ruby/hbase/table.rb @@ -126,6 +126,7 @@ EOF # Note the below methods are prefixed with '_' to hide them from the average user, as # they will be much less likely to tab complete to the 'dangerous' internal method #---------------------------------------------------------------------------------------------- + # Put a cell 'value' at specified table/row/column def _put_internal(row, column, value, timestamp = nil, args = {}) p = org.apache.hadoop.hbase.client.Put.new(row.to_s.to_java_bytes) @@ -368,17 +369,7 @@ EOF org.apache.hadoop.hbase.util.Bytes::toLong(cell.getValue) end - #---------------------------------------------------------------------------------------------- - # Scans whole table or a range of keys and returns rows matching specific criteria - def _scan_internal(args = {}) - unless args.kind_of?(Hash) - raise ArgumentError, "Arguments should be a hash. Failed to parse #{args.inspect}, #{args.class}" - end - - limit = args.delete("LIMIT") || -1 - maxlength = args.delete("MAXLENGTH") || -1 - @converters.clear() - + def _hash_to_scan(args) if args.any? filter = args["FILTER"] startrow = args["STARTROW"] || '' @@ -433,10 +424,29 @@ EOF scan = org.apache.hadoop.hbase.client.Scan.new end - # Start the scanner - scanner = @table.getScanner(scan) + scan + end + + def _get_scanner(args) + @table.getScanner(_hash_to_scan(args)) + end + + #---------------------------------------------------------------------------------------------- + # Scans whole table or a range of keys and returns rows matching specific criteria + def _scan_internal(args = {}) + unless args.kind_of?(Hash) + raise ArgumentError, "Arguments should be a hash. Failed to parse #{args.inspect}, #{args.class}" + end + + limit = args.delete("LIMIT") || -1 + maxlength = args.delete("MAXLENGTH") || -1 count = 0 res = {} + + @converters.clear() + + # Start the scanner + scanner = @table.getScanner(_hash_to_scan(args)) iter = scanner.iterator # Iterate results @@ -472,23 +482,37 @@ EOF # Apply OperationAttributes to puts/scans/gets def set_attributes(oprattr, attributes) - raise(ArgumentError, "#{"ATTRIBUTES"} must be a Hash type") unless attributes.kind_of?(Hash) - for k,v in attributes - v = v.to_s unless v.nil? - oprattr.setAttribute(k.to_s, v.to_java_bytes) - end + raise(ArgumentError, "Attributes must be a Hash type") unless attributes.kind_of?(Hash) + for k,v in attributes + v = v.to_s unless v.nil? + oprattr.setAttribute(k.to_s, v.to_java_bytes) + end end - + + def set_cell_permissions(op, permissions) + raise(ArgumentError, "Permissions must be a Hash type") unless permissions.kind_of?(Hash) + map = java.util.HashMap.new + permissions.each do |user,perms| + map.put(user.to_s, org.apache.hadoop.hbase.security.access.Permission.new( + perms.to_java_bytes)) + end + op.setACL(map) + end + def set_cell_visibility(oprattr, visibility) - oprattr.setCellVisibility(org.apache.hadoop.hbase.security.visibility.CellVisibility.new(visibility.to_s)) + oprattr.setCellVisibility( + org.apache.hadoop.hbase.security.visibility.CellVisibility.new( + visibility.to_s)) end - + def set_authorizations(oprattr, authorizations) - raise(ArgumentError, "#{"authorizations"} must be a Array type type") unless authorizations.kind_of?(Array) - auths = [ authorizations ].flatten.compact - oprattr.setAuthorizations(org.apache.hadoop.hbase.security.visibility.Authorizations.new(auths.to_java(:string))) + raise(ArgumentError, "Authorizations must be a Array type") unless authorizations.kind_of?(Array) + auths = [ authorizations ].flatten.compact + oprattr.setAuthorizations( + org.apache.hadoop.hbase.security.visibility.Authorizations.new( + auths.to_java(:string))) end - + #---------------------------- # Add general administration utilities to the shell # each of the names below adds this method name to the table diff --git hbase-shell/src/main/ruby/shell/commands/grant.rb hbase-shell/src/main/ruby/shell/commands/grant.rb index aaa5863..192d331 100644 --- hbase-shell/src/main/ruby/shell/commands/grant.rb +++ hbase-shell/src/main/ruby/shell/commands/grant.rb @@ -35,10 +35,73 @@ For example: EOF end - def command(user, rights, table_name=nil, family=nil, qualifier=nil) - format_simple_command do - security_admin.grant(user, rights, table_name, family, qualifier) + def command(*args) + + # command form is ambiguous at first argument + table_name = user = args[0] + raise(ArgumentError, "First argument should be a String") unless user.kind_of?(String) + + if args[1].kind_of?(String) + + # Original form of the command + # user in args[0] + # permissions in args[1] + # table_name in args[2] + # family in args[3] or nil + # qualifier in args[4] or nil + + permissions = args[1] + raise(ArgumentError, "Permissions are not of String type") unless permissions.kind_of?(String) + table_name = args[2] + raise(ArgumentError, "Table name is not of String type") unless table_name.kind_of?(String) + family = args[3] # will be nil if unset + if not family.nil? + raise(ArgumentError, "Family is not of String type") unless family.kind_of?(String) + qualifier = args[4] # will be nil if unset + if not qualifier.nil? + raise(ArgumentError, "Qualifier is not of String type") unless qualifier.kind_of?(String) + end + else + qualifier = nil + end + format_simple_command do + security_admin.grant(user, permissions, table_name, family, qualifier) + end + + elsif args[1].kind_of?(Hash) + + # New form of the command, a cell ACL update + # table_name in args[0], a string + # a Hash mapping users (or groups) to permisisons in args[1] + # a Hash argument suitable for passing to Table#_get_scanner in args[2] + # Useful for feature testing and debugging. + + permissions = args[1] + raise(ArgumentError, "Permissions are not of Hash type") unless permissions.kind_of?(Hash) + scan = args[2] + raise(ArgumentError, "Scanner specification is not a Hash") unless scan.kind_of?(Hash) + + t = table(table_name) + now = Time.now + scanner = t._get_scanner(scan) + count = 0 + iter = scanner.iterator + while iter.hasNext + row = iter.next + row.list.each do |cell| + put = org.apache.hadoop.hbase.client.Put.new(row.getRow) + put.add(cell) + t.set_cell_permissions(put, permissions) + t.table.put(put) + end + count += 1 + end + formatter.footer(now, count) + + else + raise(ArgumentError, "Second argument should be a String or Hash") end + end end end -- 1.7.10.4