diff --git hbase-shell/src/main/ruby/hbase/security.rb hbase-shell/src/main/ruby/hbase/security.rb index 1c4d9ae..00f489f 100644 --- hbase-shell/src/main/ruby/hbase/security.rb +++ hbase-shell/src/main/ruby/hbase/security.rb @@ -19,6 +19,7 @@ include Java # Wrapper for org.apache.hadoop.hbase.client.HBaseAdmin +java_import org.apache.hadoop.hbase.NamespaceNotFoundException module Hbase class SecurityAdmin @@ -150,34 +151,83 @@ module Hbase #---------------------------------------------------------------------------------------------- def user_permission(table_regex=nil) - security_available? - all_perms = org.apache.hadoop.hbase.security.access.AccessControlClient.getUserPermissions(@config,table_regex) + all_perms = get_user_permission(table_regex) res = {} count = 0 - all_perms.each do |value| - user_name = String.from_java_bytes(value.getUser) - table = (value.getTableName != nil) ? value.getTableName.getNameAsString() : '' - family = (value.getFamily != nil) ? - org.apache.hadoop.hbase.util.Bytes::toStringBinary(value.getFamily) : - '' - qualifier = (value.getQualifier != nil) ? - org.apache.hadoop.hbase.util.Bytes::toStringBinary(value.getQualifier) : - '' - - action = org.apache.hadoop.hbase.security.access.Permission.new value.getActions - - if block_given? - yield(user_name, "#{table},#{family},#{qualifier}: #{action.to_s}") - else - res[user_name] ||= {} - res[user_name][family + ":" +qualifier] = action + all_perms.each do |this_perms| + this_perms.each do |value| + user_name = String.from_java_bytes(value.getUser) + if (isNamespace?(table_regex)) + namespace = table_regex[1...table_regex.length] + else + namespace = (value.getTableName != nil) ? value.getTableName.getNamespaceAsString() : '' + end + table = (value.getTableName != nil) ? value.getTableName.getQualifierAsString() : '' + family = (value.getFamily != nil) ? + org.apache.hadoop.hbase.util.Bytes::toStringBinary(value.getFamily) : + '' + qualifier = (value.getQualifier != nil) ? + org.apache.hadoop.hbase.util.Bytes::toStringBinary(value.getQualifier) : + '' + action = org.apache.hadoop.hbase.security.access.Permission.new value.getActions + if block_given? + yield(user_name, "#{namespace},#{table},#{family},#{qualifier}: #{action.to_s}") + else + res[user_name] ||= {} + res[user_name][family + ":" +qualifier] = action + end + count += 1 end - count += 1 end - return ((block_given?) ? count : res) end + def get_user_permission(table_regex=nil) + security_available? + begin + meta_table = org.apache.hadoop.hbase.client.HTable.new(@config, + org.apache.hadoop.hbase.security.access.AccessControlLists::ACL_TABLE_NAME) + service = meta_table.coprocessorService( + org.apache.hadoop.hbase.HConstants::EMPTY_START_ROW) + + protocol = org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos:: + AccessControlService.newBlockingStub(service) + all_perms = [] + tables = [] + if (table_regex == '' || table_regex == nil) + perms = org.apache.hadoop.hbase.protobuf.ProtobufUtil.getUserPermissions(protocol) + all_perms << perms + elsif (isNamespace?(table_regex)) + # Namespace should exist first. + namespace_name = table_regex[1...table_regex.length] + raise(ArgumentError, "Can't find a namespace: #{namespace_name}") unless namespace_exists?(namespace_name) + perms = org.apache.hadoop.hbase.protobuf.ProtobufUtil.getUserPermissions( + protocol, namespace_name.to_java_bytes) + all_perms << perms + else + # handle simple glob '*' but if '.' is passed before '*' then assume regex + if /\*/.match(table_regex) && !/\.\*/.match(table_regex) + table_regex = table_regex.gsub(/\*/, '.*') + end + htds = @admin.listTables(table_regex) + if ( htds.length == 0) + raise(ArgumentError, "Can't find any tables with names #{table_regex}") + end + htds.each { |t| + tables << t.getTableName().toString() + } + tables.each { |t| + perms = org.apache.hadoop.hbase.protobuf.ProtobufUtil.getUserPermissions( + protocol, org.apache.hadoop.hbase.TableName.valueOf(t)) + all_perms << perms + } + end + ensure + meta_table.close() + end + return all_perms + end + # Does table exist? def exists?(table_name) @admin.tableExists(table_name) @@ -189,12 +239,16 @@ module Hbase # Does Namespace exist def namespace_exists?(namespace_name) - namespaceDesc = @admin.getNamespaceDescriptor(namespace_name) - if(namespaceDesc == nil) - return false - else - return true - end + begin + namespaceDesc = @admin.getNamespaceDescriptor(namespace_name) + if(namespaceDesc == nil) + return false + else + return true + end + rescue NamespaceNotFoundException => namespaceError + raise(ArgumentError, "Namespace not found : #{namespace_name}") + end end # Make sure that security tables are available