HBASE-19483 Add proper privilege check for rsgroup commands
Signed-off-by: tedyu <yuzhihong@gmail.com>
This commit is contained in:
parent
e6453ab84b
commit
6f1dd258b1
|
@ -28,6 +28,7 @@ import org.apache.hadoop.hbase.security.User;
|
|||
import org.apache.hadoop.hbase.security.visibility.LoadTestDataGeneratorWithVisibilityLabels;
|
||||
import org.apache.hadoop.hbase.security.visibility.VisibilityClient;
|
||||
import org.apache.hadoop.hbase.security.visibility.VisibilityController;
|
||||
import org.apache.hadoop.hbase.security.visibility.VisibilityTestUtil;
|
||||
import org.apache.hadoop.hbase.testclassification.IntegrationTests;
|
||||
import org.apache.hadoop.hbase.util.LoadTestTool;
|
||||
import org.junit.experimental.categories.Category;
|
||||
|
@ -76,9 +77,7 @@ public class IntegrationTestIngestWithVisibilityLabels extends IntegrationTestIn
|
|||
public void setUpCluster() throws Exception {
|
||||
util = getTestingUtil(null);
|
||||
Configuration conf = util.getConfiguration();
|
||||
conf.setInt(HFile.FORMAT_VERSION_KEY, 3);
|
||||
conf.set("hbase.coprocessor.master.classes", VisibilityController.class.getName());
|
||||
conf.set("hbase.coprocessor.region.classes", VisibilityController.class.getName());
|
||||
VisibilityTestUtil.enableVisiblityLabels(conf);
|
||||
conf.set("hbase.superuser", "admin," + User.getCurrent().getName());
|
||||
super.setUpCluster();
|
||||
addLabels();
|
||||
|
|
|
@ -35,6 +35,7 @@ import org.apache.hadoop.hbase.HColumnDescriptor;
|
|||
import org.apache.hadoop.hbase.HRegionLocation;
|
||||
import org.apache.hadoop.hbase.HTableDescriptor;
|
||||
import org.apache.hadoop.hbase.IntegrationTestingUtility;
|
||||
import org.apache.hadoop.hbase.security.visibility.VisibilityTestUtil;
|
||||
import org.apache.hadoop.hbase.testclassification.IntegrationTests;
|
||||
import org.apache.hadoop.hbase.TableName;
|
||||
import org.apache.hadoop.hbase.chaos.factories.MonkeyFactory;
|
||||
|
@ -369,9 +370,7 @@ public class IntegrationTestBigLinkedListWithVisibility extends IntegrationTestB
|
|||
public void setUpCluster() throws Exception {
|
||||
util = getTestingUtil(null);
|
||||
Configuration conf = util.getConfiguration();
|
||||
conf.setInt(HFile.FORMAT_VERSION_KEY, 3);
|
||||
conf.set("hbase.coprocessor.master.classes", VisibilityController.class.getName());
|
||||
conf.set("hbase.coprocessor.region.classes", VisibilityController.class.getName());
|
||||
VisibilityTestUtil.enableVisiblityLabels(conf);
|
||||
conf.set("hbase.superuser", User.getCurrent().getName());
|
||||
conf.setBoolean("dfs.permissions", false);
|
||||
USER = User.createUserForTesting(conf, userName, new String[] {});
|
||||
|
|
|
@ -32,6 +32,7 @@ import org.apache.hadoop.hbase.HColumnDescriptor;
|
|||
import org.apache.hadoop.hbase.HConstants;
|
||||
import org.apache.hadoop.hbase.HTableDescriptor;
|
||||
import org.apache.hadoop.hbase.IntegrationTestingUtility;
|
||||
import org.apache.hadoop.hbase.security.visibility.VisibilityTestUtil;
|
||||
import org.apache.hadoop.hbase.testclassification.IntegrationTests;
|
||||
import org.apache.hadoop.hbase.client.Admin;
|
||||
import org.apache.hadoop.hbase.client.HBaseAdmin;
|
||||
|
@ -115,9 +116,7 @@ public class IntegrationTestWithCellVisibilityLoadAndVerify extends IntegrationT
|
|||
public void setUpCluster() throws Exception {
|
||||
util = getTestingUtil(null);
|
||||
Configuration conf = util.getConfiguration();
|
||||
conf.setInt(HFile.FORMAT_VERSION_KEY, 3);
|
||||
conf.set("hbase.coprocessor.master.classes", VisibilityController.class.getName());
|
||||
conf.set("hbase.coprocessor.region.classes", VisibilityController.class.getName());
|
||||
VisibilityTestUtil.enableVisiblityLabels(conf);
|
||||
conf.set("hbase.superuser", User.getCurrent().getName());
|
||||
conf.setBoolean("dfs.permissions", false);
|
||||
super.setUpCluster();
|
||||
|
|
|
@ -37,6 +37,7 @@ import org.apache.hadoop.hbase.HBaseTestingUtility;
|
|||
import org.apache.hadoop.hbase.HColumnDescriptor;
|
||||
import org.apache.hadoop.hbase.HTableDescriptor;
|
||||
import org.apache.hadoop.hbase.KeyValue;
|
||||
import org.apache.hadoop.hbase.security.visibility.VisibilityTestUtil;
|
||||
import org.apache.hadoop.hbase.testclassification.MediumTests;
|
||||
import org.apache.hadoop.hbase.TableName;
|
||||
import org.apache.hadoop.hbase.client.Admin;
|
||||
|
@ -130,10 +131,8 @@ public class TestScannersWithLabels {
|
|||
conf = TEST_UTIL.getConfiguration();
|
||||
conf.setClass(VisibilityUtils.VISIBILITY_LABEL_GENERATOR_CLASS,
|
||||
SimpleScanLabelGenerator.class, ScanLabelGenerator.class);
|
||||
conf.setInt("hfile.format.version", 3);
|
||||
conf.set("hbase.superuser", SUPERUSER.getShortName());
|
||||
conf.set("hbase.coprocessor.master.classes", VisibilityController.class.getName());
|
||||
conf.set("hbase.coprocessor.region.classes", VisibilityController.class.getName());
|
||||
VisibilityTestUtil.enableVisiblityLabels(conf);
|
||||
TEST_UTIL.startMiniCluster(1);
|
||||
// Wait for the labels table to become available
|
||||
TEST_UTIL.waitTableEnabled(VisibilityConstants.LABELS_TABLE_NAME.getName(), 50000);
|
||||
|
|
|
@ -48,6 +48,7 @@ import org.apache.hadoop.hbase.coprocessor.CoprocessorService;
|
|||
import org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment;
|
||||
import org.apache.hadoop.hbase.coprocessor.MasterObserver;
|
||||
import org.apache.hadoop.hbase.coprocessor.ObserverContext;
|
||||
import org.apache.hadoop.hbase.ipc.RpcServer;
|
||||
import org.apache.hadoop.hbase.master.MasterServices;
|
||||
import org.apache.hadoop.hbase.master.RegionPlan;
|
||||
import org.apache.hadoop.hbase.master.procedure.MasterProcedureEnv;
|
||||
|
@ -83,6 +84,12 @@ import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.RemoveRSGro
|
|||
import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.RemoveServersRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.RemoveServersResponse;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.TableProtos;
|
||||
import org.apache.hadoop.hbase.security.User;
|
||||
import org.apache.hadoop.hbase.security.UserProvider;
|
||||
import org.apache.hadoop.hbase.security.access.AccessChecker;
|
||||
import org.apache.hadoop.hbase.security.access.Permission;
|
||||
import org.apache.hadoop.hbase.security.access.TableAuthManager;
|
||||
import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
|
||||
|
||||
public class RSGroupAdminEndpoint extends RSGroupAdminService
|
||||
implements CoprocessorService, Coprocessor, MasterObserver {
|
||||
|
@ -91,6 +98,10 @@ public class RSGroupAdminEndpoint extends RSGroupAdminService
|
|||
|
||||
private static RSGroupInfoManagerImpl groupInfoManager;
|
||||
private RSGroupAdminServer groupAdminServer;
|
||||
private AccessChecker accessChecker;
|
||||
|
||||
/** Provider for mapping principal names to Users */
|
||||
private UserProvider userProvider;
|
||||
|
||||
@Override
|
||||
public void start(CoprocessorEnvironment env) throws IOException {
|
||||
|
@ -103,10 +114,18 @@ public class RSGroupAdminEndpoint extends RSGroupAdminService
|
|||
if (!RSGroupableBalancer.class.isAssignableFrom(clazz)) {
|
||||
throw new IOException("Configured balancer is not a GroupableBalancer");
|
||||
}
|
||||
ZooKeeperWatcher zk = menv.getMasterServices().getZooKeeper();
|
||||
accessChecker = new AccessChecker(env.getConfiguration(), zk);
|
||||
|
||||
// set the user-provider.
|
||||
this.userProvider = UserProvider.instantiate(env.getConfiguration());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop(CoprocessorEnvironment env) throws IOException {
|
||||
public void stop(CoprocessorEnvironment env) {
|
||||
if (accessChecker.getAuthManager() != null) {
|
||||
TableAuthManager.release(accessChecker.getAuthManager());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -141,6 +160,7 @@ public class RSGroupAdminEndpoint extends RSGroupAdminService
|
|||
GetRSGroupInfoResponse.Builder builder =
|
||||
GetRSGroupInfoResponse.newBuilder();
|
||||
RSGroupInfo RSGroupInfo = groupAdminServer.getRSGroupInfo(request.getRSGroupName());
|
||||
checkPermission("getRSGroupInfo");
|
||||
if(RSGroupInfo != null) {
|
||||
builder.setRSGroupInfo(RSGroupProtobufUtil.toProtoGroupInfo(RSGroupInfo));
|
||||
}
|
||||
|
@ -160,6 +180,7 @@ public class RSGroupAdminEndpoint extends RSGroupAdminService
|
|||
GetRSGroupInfoOfTableResponse.Builder builder =
|
||||
GetRSGroupInfoOfTableResponse.newBuilder();
|
||||
TableName tableName = ProtobufUtil.toTableName(request.getTableName());
|
||||
checkPermission("getRSGroupInfoOfTable");
|
||||
RSGroupInfo RSGroupInfo = groupAdminServer.getRSGroupInfoOfTable(tableName);
|
||||
if (RSGroupInfo == null) {
|
||||
response = builder.build();
|
||||
|
@ -184,6 +205,7 @@ public class RSGroupAdminEndpoint extends RSGroupAdminService
|
|||
for(HBaseProtos.ServerName el: request.getServersList()) {
|
||||
servers.add(Address.fromParts(el.getHostName(), el.getPort()));
|
||||
}
|
||||
checkPermission("moveServers");
|
||||
groupAdminServer.moveServers(servers, request.getTargetGroup());
|
||||
response = builder.build();
|
||||
} catch (IOException e) {
|
||||
|
@ -204,6 +226,7 @@ public class RSGroupAdminEndpoint extends RSGroupAdminService
|
|||
for(TableProtos.TableName tableName: request.getTableNameList()) {
|
||||
tables.add(ProtobufUtil.toTableName(tableName));
|
||||
}
|
||||
checkPermission("moveTables");
|
||||
groupAdminServer.moveTables(tables, request.getTargetGroup());
|
||||
response = builder.build();
|
||||
} catch (IOException e) {
|
||||
|
@ -225,6 +248,7 @@ public class RSGroupAdminEndpoint extends RSGroupAdminService
|
|||
for (TableProtos.TableName tableName : request.getTableNameList()) {
|
||||
tables.add(ProtobufUtil.toTableName(tableName));
|
||||
}
|
||||
checkPermission("moveServersAndTables");
|
||||
groupAdminServer.moveServersAndTables(servers, tables, request.getTargetGroup());
|
||||
} catch (IOException e) {
|
||||
ResponseConverter.setControllerException(controller, e);
|
||||
|
@ -240,6 +264,7 @@ public class RSGroupAdminEndpoint extends RSGroupAdminService
|
|||
try {
|
||||
AddRSGroupResponse.Builder builder =
|
||||
AddRSGroupResponse.newBuilder();
|
||||
checkPermission("addRSGroup");
|
||||
groupAdminServer.addRSGroup(request.getRSGroupName());
|
||||
response = builder.build();
|
||||
} catch (IOException e) {
|
||||
|
@ -256,6 +281,7 @@ public class RSGroupAdminEndpoint extends RSGroupAdminService
|
|||
try {
|
||||
RemoveRSGroupResponse.Builder builder =
|
||||
RemoveRSGroupResponse.newBuilder();
|
||||
checkPermission("removeRSGroup");
|
||||
groupAdminServer.removeRSGroup(request.getRSGroupName());
|
||||
response = builder.build();
|
||||
} catch (IOException e) {
|
||||
|
@ -270,6 +296,7 @@ public class RSGroupAdminEndpoint extends RSGroupAdminService
|
|||
RpcCallback<BalanceRSGroupResponse> done) {
|
||||
BalanceRSGroupResponse.Builder builder = BalanceRSGroupResponse.newBuilder();
|
||||
try {
|
||||
checkPermission("balanceRSGroup");
|
||||
builder.setBalanceRan(groupAdminServer.balanceRSGroup(request.getRSGroupName()));
|
||||
} catch (IOException e) {
|
||||
ResponseConverter.setControllerException(controller, e);
|
||||
|
@ -286,6 +313,7 @@ public class RSGroupAdminEndpoint extends RSGroupAdminService
|
|||
try {
|
||||
ListRSGroupInfosResponse.Builder builder =
|
||||
ListRSGroupInfosResponse.newBuilder();
|
||||
checkPermission("listRSGroupInfos");
|
||||
for(RSGroupInfo RSGroupInfo : groupAdminServer.listRSGroups()) {
|
||||
builder.addRSGroupInfo(RSGroupProtobufUtil.toProtoGroupInfo(RSGroupInfo));
|
||||
}
|
||||
|
@ -304,6 +332,7 @@ public class RSGroupAdminEndpoint extends RSGroupAdminService
|
|||
try {
|
||||
Address server =
|
||||
Address.fromParts(request.getServer().getHostName(), request.getServer().getPort());
|
||||
checkPermission("getRSGroupInfoOfServer");
|
||||
RSGroupInfo RSGroupInfo = groupAdminServer.getRSGroupOfServer(server);
|
||||
if (RSGroupInfo != null) {
|
||||
builder.setRSGroupInfo(RSGroupProtobufUtil.toProtoGroupInfo(RSGroupInfo));
|
||||
|
@ -325,6 +354,7 @@ public class RSGroupAdminEndpoint extends RSGroupAdminService
|
|||
for (HBaseProtos.ServerName el : request.getServersList()) {
|
||||
servers.add(Address.fromParts(el.getHostName(), el.getPort()));
|
||||
}
|
||||
checkPermission("removeServers");
|
||||
groupAdminServer.removeServers(servers);
|
||||
} catch (IOException e) {
|
||||
ResponseConverter.setControllerException(controller, e);
|
||||
|
@ -1080,4 +1110,22 @@ public class RSGroupAdminEndpoint extends RSGroupAdminService
|
|||
String groupName, boolean balancerRan) throws IOException {
|
||||
|
||||
}
|
||||
|
||||
public void checkPermission(String request) throws IOException {
|
||||
accessChecker.requirePermission(getActiveUser(), request, Permission.Action.ADMIN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the active user to which authorization checks should be applied.
|
||||
* If we are in the context of an RPC call, the remote user is used,
|
||||
* otherwise the currently logged in user is used.
|
||||
*/
|
||||
private User getActiveUser() throws IOException {
|
||||
User user = RpcServer.getRequestUser();
|
||||
if (user == null) {
|
||||
// for non-rpc handling, fallback to system user
|
||||
user = userProvider.getCurrent();
|
||||
}
|
||||
return user;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,358 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.hadoop.hbase.rsgroup;
|
||||
|
||||
import static org.apache.hadoop.hbase.AuthUtil.toGroupEntry;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.apache.hadoop.conf.Configuration;
|
||||
import org.apache.hadoop.hbase.HBaseTestingUtility;
|
||||
import org.apache.hadoop.hbase.HColumnDescriptor;
|
||||
import org.apache.hadoop.hbase.HConstants;
|
||||
import org.apache.hadoop.hbase.HTableDescriptor;
|
||||
import org.apache.hadoop.hbase.TableName;
|
||||
import org.apache.hadoop.hbase.TableNotFoundException;
|
||||
import org.apache.hadoop.hbase.client.Connection;
|
||||
import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
|
||||
import org.apache.hadoop.hbase.security.User;
|
||||
import org.apache.hadoop.hbase.security.access.AccessControlClient;
|
||||
import org.apache.hadoop.hbase.security.access.AccessControlLists;
|
||||
import org.apache.hadoop.hbase.security.access.Permission;
|
||||
import org.apache.hadoop.hbase.security.access.SecureTestUtil;
|
||||
import org.apache.hadoop.hbase.security.access.TableAuthManager;
|
||||
import org.apache.hadoop.hbase.testclassification.SecurityTests;
|
||||
import org.apache.hadoop.hbase.util.Bytes;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.experimental.categories.Category;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Performs authorization checks for rsgroup operations, according to different
|
||||
* levels of authorized users.
|
||||
*/
|
||||
@Category({SecurityTests.class})
|
||||
public class TestRSGroupsWithACL extends SecureTestUtil{
|
||||
private static final Logger LOG = LoggerFactory.getLogger(TestRSGroupsWithACL.class);
|
||||
private static TableName TEST_TABLE = TableName.valueOf("testtable1");
|
||||
private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
|
||||
private static Configuration conf;
|
||||
|
||||
private static Connection systemUserConnection;
|
||||
// user with all permissions
|
||||
private static User SUPERUSER;
|
||||
// user granted with all global permission
|
||||
private static User USER_ADMIN;
|
||||
// user with rw permissions on column family.
|
||||
private static User USER_RW;
|
||||
// user with read-only permissions
|
||||
private static User USER_RO;
|
||||
// user is table owner. will have all permissions on table
|
||||
private static User USER_OWNER;
|
||||
// user with create table permissions alone
|
||||
private static User USER_CREATE;
|
||||
// user with no permissions
|
||||
private static User USER_NONE;
|
||||
|
||||
private static final String GROUP_ADMIN = "group_admin";
|
||||
private static final String GROUP_CREATE = "group_create";
|
||||
private static final String GROUP_READ = "group_read";
|
||||
private static final String GROUP_WRITE = "group_write";
|
||||
|
||||
private static User USER_GROUP_ADMIN;
|
||||
private static User USER_GROUP_CREATE;
|
||||
private static User USER_GROUP_READ;
|
||||
private static User USER_GROUP_WRITE;
|
||||
|
||||
private static byte[] TEST_FAMILY = Bytes.toBytes("f1");
|
||||
|
||||
private static RSGroupAdminEndpoint rsGroupAdminEndpoint;
|
||||
|
||||
@BeforeClass
|
||||
public static void setupBeforeClass() throws Exception {
|
||||
// setup configuration
|
||||
conf = TEST_UTIL.getConfiguration();
|
||||
conf.set(HConstants.HBASE_MASTER_LOADBALANCER_CLASS,
|
||||
RSGroupBasedLoadBalancer.class.getName());
|
||||
// Enable security
|
||||
enableSecurity(conf);
|
||||
// Verify enableSecurity sets up what we require
|
||||
verifyConfiguration(conf);
|
||||
// Enable rsgroup
|
||||
configureRSGroupAdminEndpoint(conf);
|
||||
|
||||
TEST_UTIL.startMiniCluster();
|
||||
rsGroupAdminEndpoint = (RSGroupAdminEndpoint) TEST_UTIL.getMiniHBaseCluster().getMaster().
|
||||
getMasterCoprocessorHost().findCoprocessor(RSGroupAdminEndpoint.class.getName());
|
||||
// Wait for the ACL table to become available
|
||||
TEST_UTIL.waitUntilAllRegionsAssigned(AccessControlLists.ACL_TABLE_NAME);
|
||||
|
||||
// create a set of test users
|
||||
SUPERUSER = User.createUserForTesting(conf, "admin", new String[] { "supergroup" });
|
||||
USER_ADMIN = User.createUserForTesting(conf, "admin2", new String[0]);
|
||||
USER_RW = User.createUserForTesting(conf, "rwuser", new String[0]);
|
||||
USER_RO = User.createUserForTesting(conf, "rouser", new String[0]);
|
||||
USER_OWNER = User.createUserForTesting(conf, "owner", new String[0]);
|
||||
USER_CREATE = User.createUserForTesting(conf, "tbl_create", new String[0]);
|
||||
USER_NONE = User.createUserForTesting(conf, "nouser", new String[0]);
|
||||
|
||||
USER_GROUP_ADMIN =
|
||||
User.createUserForTesting(conf, "user_group_admin", new String[] { GROUP_ADMIN });
|
||||
USER_GROUP_CREATE =
|
||||
User.createUserForTesting(conf, "user_group_create", new String[] { GROUP_CREATE });
|
||||
USER_GROUP_READ =
|
||||
User.createUserForTesting(conf, "user_group_read", new String[] { GROUP_READ });
|
||||
USER_GROUP_WRITE =
|
||||
User.createUserForTesting(conf, "user_group_write", new String[] { GROUP_WRITE });
|
||||
|
||||
systemUserConnection = TEST_UTIL.getConnection();
|
||||
setUpTableAndUserPermissions();
|
||||
}
|
||||
|
||||
private static void setUpTableAndUserPermissions() throws Exception {
|
||||
HTableDescriptor htd = new HTableDescriptor(TEST_TABLE);
|
||||
HColumnDescriptor hcd = new HColumnDescriptor(TEST_FAMILY);
|
||||
hcd.setMaxVersions(100);
|
||||
htd.addFamily(hcd);
|
||||
htd.setOwner(USER_OWNER);
|
||||
createTable(TEST_UTIL, htd, new byte[][] { Bytes.toBytes("s") });
|
||||
|
||||
// Set up initial grants
|
||||
grantGlobal(TEST_UTIL, USER_ADMIN.getShortName(),
|
||||
Permission.Action.ADMIN,
|
||||
Permission.Action.CREATE,
|
||||
Permission.Action.READ,
|
||||
Permission.Action.WRITE);
|
||||
|
||||
grantOnTable(TEST_UTIL, USER_RW.getShortName(),
|
||||
TEST_TABLE, TEST_FAMILY, null,
|
||||
Permission.Action.READ,
|
||||
Permission.Action.WRITE);
|
||||
|
||||
// USER_CREATE is USER_RW plus CREATE permissions
|
||||
grantOnTable(TEST_UTIL, USER_CREATE.getShortName(),
|
||||
TEST_TABLE, null, null,
|
||||
Permission.Action.CREATE,
|
||||
Permission.Action.READ,
|
||||
Permission.Action.WRITE);
|
||||
|
||||
grantOnTable(TEST_UTIL, USER_RO.getShortName(),
|
||||
TEST_TABLE, TEST_FAMILY, null,
|
||||
Permission.Action.READ);
|
||||
|
||||
grantGlobal(TEST_UTIL, toGroupEntry(GROUP_ADMIN), Permission.Action.ADMIN);
|
||||
grantGlobal(TEST_UTIL, toGroupEntry(GROUP_CREATE), Permission.Action.CREATE);
|
||||
grantGlobal(TEST_UTIL, toGroupEntry(GROUP_READ), Permission.Action.READ);
|
||||
grantGlobal(TEST_UTIL, toGroupEntry(GROUP_WRITE), Permission.Action.WRITE);
|
||||
|
||||
assertEquals(4, AccessControlLists.getTablePermissions(conf, TEST_TABLE).size());
|
||||
try {
|
||||
assertEquals(4, AccessControlClient.getUserPermissions(systemUserConnection,
|
||||
TEST_TABLE.toString()).size());
|
||||
} catch (Throwable e) {
|
||||
LOG.error("error during call of AccessControlClient.getUserPermissions. ", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void cleanUp() throws Exception {
|
||||
// Clean the _acl_ table
|
||||
try {
|
||||
deleteTable(TEST_UTIL, TEST_TABLE);
|
||||
} catch (TableNotFoundException ex) {
|
||||
// Test deleted the table, no problem
|
||||
LOG.info("Test deleted table " + TEST_TABLE);
|
||||
}
|
||||
// Verify all table/namespace permissions are erased
|
||||
assertEquals(0, AccessControlLists.getTablePermissions(conf, TEST_TABLE).size());
|
||||
assertEquals(0, AccessControlLists.getNamespacePermissions(conf,
|
||||
TEST_TABLE.getNamespaceAsString()).size());
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void tearDownAfterClass() throws Exception {
|
||||
cleanUp();
|
||||
TEST_UTIL.shutdownMiniCluster();
|
||||
int total = TableAuthManager.getTotalRefCount();
|
||||
assertTrue("Unexpected reference count: " + total, total == 0);
|
||||
}
|
||||
|
||||
private static void configureRSGroupAdminEndpoint(Configuration conf) {
|
||||
String currentCoprocessors = conf.get(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY);
|
||||
String coprocessors = RSGroupAdminEndpoint.class.getName();
|
||||
if (currentCoprocessors != null) {
|
||||
coprocessors += "," + currentCoprocessors;
|
||||
}
|
||||
conf.set(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY, coprocessors);
|
||||
conf.set(HConstants.HBASE_MASTER_LOADBALANCER_CLASS,
|
||||
RSGroupBasedLoadBalancer.class.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRSGroupInfo() throws Exception {
|
||||
AccessTestAction action = new AccessTestAction() {
|
||||
@Override
|
||||
public Object run() throws Exception {
|
||||
rsGroupAdminEndpoint.checkPermission("getRSGroupInfo");
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_GROUP_ADMIN);
|
||||
verifyDenied(action, USER_CREATE, USER_OWNER, USER_RW, USER_RO,
|
||||
USER_NONE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRSGroupInfoOfTable() throws Exception {
|
||||
AccessTestAction action = new AccessTestAction() {
|
||||
@Override
|
||||
public Object run() throws Exception {
|
||||
rsGroupAdminEndpoint.checkPermission("getRSGroupInfoOfTable");
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_GROUP_ADMIN);
|
||||
verifyDenied(action, USER_CREATE, USER_OWNER, USER_RW, USER_RO,
|
||||
USER_NONE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMoveServers() throws Exception {
|
||||
AccessTestAction action = new AccessTestAction() {
|
||||
@Override
|
||||
public Object run() throws Exception {
|
||||
rsGroupAdminEndpoint.checkPermission("moveServers");
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_GROUP_ADMIN);
|
||||
verifyDenied(action, USER_CREATE, USER_OWNER, USER_RW, USER_RO,
|
||||
USER_NONE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMoveTables() throws Exception {
|
||||
AccessTestAction action = new AccessTestAction() {
|
||||
@Override
|
||||
public Object run() throws Exception {
|
||||
rsGroupAdminEndpoint.checkPermission("moveTables");
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_GROUP_ADMIN);
|
||||
verifyDenied(action, USER_CREATE, USER_OWNER, USER_RW, USER_RO,
|
||||
USER_NONE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddRSGroup() throws Exception {
|
||||
AccessTestAction action = new AccessTestAction() {
|
||||
@Override
|
||||
public Object run() throws Exception {
|
||||
rsGroupAdminEndpoint.checkPermission("addRSGroup");
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_GROUP_ADMIN);
|
||||
verifyDenied(action, USER_CREATE, USER_OWNER, USER_RW, USER_RO,
|
||||
USER_NONE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveRSGroup() throws Exception {
|
||||
AccessTestAction action = new AccessTestAction() {
|
||||
@Override
|
||||
public Object run() throws Exception {
|
||||
rsGroupAdminEndpoint.checkPermission("removeRSGroup");
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_GROUP_ADMIN);
|
||||
verifyDenied(action, USER_CREATE, USER_OWNER, USER_RW, USER_RO,
|
||||
USER_NONE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBalanceRSGroup() throws Exception {
|
||||
AccessTestAction action = new AccessTestAction() {
|
||||
@Override
|
||||
public Object run() throws Exception {
|
||||
rsGroupAdminEndpoint.checkPermission("balanceRSGroup");
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_GROUP_ADMIN);
|
||||
verifyDenied(action, USER_CREATE, USER_OWNER, USER_RW, USER_RO,
|
||||
USER_NONE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListRSGroup() throws Exception {
|
||||
AccessTestAction action = new AccessTestAction() {
|
||||
@Override
|
||||
public Object run() throws Exception {
|
||||
rsGroupAdminEndpoint.checkPermission("listRSGroup");
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_GROUP_ADMIN);
|
||||
verifyDenied(action, USER_CREATE, USER_OWNER, USER_RW, USER_RO,
|
||||
USER_NONE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRSGroupInfoOfServer() throws Exception {
|
||||
AccessTestAction action = new AccessTestAction() {
|
||||
@Override
|
||||
public Object run() throws Exception {
|
||||
rsGroupAdminEndpoint.checkPermission("getRSGroupInfoOfServer");
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_GROUP_ADMIN);
|
||||
verifyDenied(action, USER_CREATE, USER_OWNER, USER_RW, USER_RO,
|
||||
USER_NONE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMoveServersAndTables() throws Exception {
|
||||
AccessTestAction action = new AccessTestAction() {
|
||||
@Override
|
||||
public Object run() throws Exception {
|
||||
rsGroupAdminEndpoint.checkPermission("moveServersAndTables");
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_GROUP_ADMIN);
|
||||
verifyDenied(action, USER_CREATE, USER_OWNER, USER_RW, USER_RO,
|
||||
USER_NONE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE);
|
||||
}
|
||||
}
|
|
@ -190,6 +190,7 @@ import org.apache.hadoop.hbase.protobuf.generated.RegionServerStatusProtos.Repor
|
|||
import org.apache.hadoop.hbase.protobuf.generated.RegionServerStatusProtos.ReportRegionStateTransitionResponse;
|
||||
import org.apache.hadoop.hbase.regionserver.RSRpcServices;
|
||||
import org.apache.hadoop.hbase.security.User;
|
||||
import org.apache.hadoop.hbase.security.access.AccessChecker;
|
||||
import org.apache.hadoop.hbase.security.access.AccessController;
|
||||
import org.apache.hadoop.hbase.security.visibility.VisibilityController;
|
||||
import org.apache.hadoop.hbase.snapshot.ClientSnapshotDescriptionUtils;
|
||||
|
@ -1669,7 +1670,7 @@ public class MasterRpcServices extends RSRpcServices
|
|||
// The AccessController can provide AUTHORIZATION and CELL_AUTHORIZATION
|
||||
if (master.cpHost != null &&
|
||||
master.cpHost.findCoprocessor(AccessController.class.getName()) != null) {
|
||||
if (AccessController.isAuthorizationSupported(master.getConfiguration())) {
|
||||
if (AccessChecker.isAuthorizationSupported(master.getConfiguration())) {
|
||||
capabilities.add(Capability.AUTHORIZATION);
|
||||
}
|
||||
if (AccessController.isCellAuthorizationSupported(master.getConfiguration())) {
|
||||
|
|
|
@ -0,0 +1,300 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.hadoop.hbase.security.access;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.hadoop.conf.Configuration;
|
||||
import org.apache.hadoop.hbase.TableName;
|
||||
import org.apache.hadoop.hbase.classification.InterfaceAudience;
|
||||
import org.apache.hadoop.hbase.ipc.RpcServer;
|
||||
import org.apache.hadoop.hbase.security.AccessDeniedException;
|
||||
import org.apache.hadoop.hbase.security.User;
|
||||
import org.apache.hadoop.hbase.security.access.Permission.Action;
|
||||
import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@InterfaceAudience.Private
|
||||
public final class AccessChecker {
|
||||
private static final Logger AUDITLOG =
|
||||
LoggerFactory.getLogger("SecurityLogger." + AccessChecker.class.getName());
|
||||
private TableAuthManager authManager;
|
||||
/**
|
||||
* if we are active, usually false, only true if "hbase.security.authorization"
|
||||
* has been set to true in site configuration.see HBASE-19483.
|
||||
*/
|
||||
private boolean authorizationEnabled;
|
||||
|
||||
public static boolean isAuthorizationSupported(Configuration conf) {
|
||||
return conf.getBoolean(User.HBASE_SECURITY_AUTHORIZATION_CONF_KEY, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor with existing configuration
|
||||
*
|
||||
* @param conf Existing configuration to use
|
||||
* @param zkw reference to the {@link ZooKeeperWatcher}
|
||||
*/
|
||||
public AccessChecker(final Configuration conf, final ZooKeeperWatcher zkw)
|
||||
throws RuntimeException {
|
||||
// If zk is null or IOException while obtaining auth manager,
|
||||
// throw RuntimeException so that the coprocessor is unloaded.
|
||||
if (zkw != null) {
|
||||
try {
|
||||
this.authManager = TableAuthManager.getOrCreate(zkw, conf);
|
||||
} catch (IOException ioe) {
|
||||
throw new RuntimeException("Error obtaining AccessChecker", ioe);
|
||||
}
|
||||
} else {
|
||||
throw new NullPointerException("Error obtaining AccessChecker, zk found null.");
|
||||
}
|
||||
authorizationEnabled = isAuthorizationSupported(conf);
|
||||
}
|
||||
|
||||
public TableAuthManager getAuthManager() {
|
||||
return authManager;
|
||||
}
|
||||
|
||||
public void logResult(AuthResult result) {
|
||||
if (AUDITLOG.isTraceEnabled()) {
|
||||
InetAddress remoteAddr = RpcServer.getRemoteAddress();
|
||||
AUDITLOG.trace("Access " + (result.isAllowed() ? "allowed" : "denied") +
|
||||
" for user " + (result.getUser() != null ? result.getUser().getShortName() : "UNKNOWN") +
|
||||
"; reason: " + result.getReason() +
|
||||
"; remote address: " + (remoteAddr != null ? remoteAddr : "") +
|
||||
"; request: " + result.getRequest() +
|
||||
"; context: " + result.toContextString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Authorizes that the current user has any of the given permissions for the
|
||||
* given table, column family and column qualifier.
|
||||
* @param tableName Table requested
|
||||
* @param family Column family requested
|
||||
* @param qualifier Column qualifier requested
|
||||
* @throws IOException if obtaining the current user fails
|
||||
* @throws AccessDeniedException if user has no authorization
|
||||
*/
|
||||
public void requirePermission(User user, String request, TableName tableName, byte[] family,
|
||||
byte[] qualifier, Action... permissions) throws IOException {
|
||||
AuthResult result = null;
|
||||
|
||||
for (Action permission : permissions) {
|
||||
if (authManager.authorize(user, tableName, family, qualifier, permission)) {
|
||||
result = AuthResult.allow(request, "Table permission granted", user,
|
||||
permission, tableName, family, qualifier);
|
||||
break;
|
||||
} else {
|
||||
// rest of the world
|
||||
result = AuthResult.deny(request, "Insufficient permissions", user,
|
||||
permission, tableName, family, qualifier);
|
||||
}
|
||||
}
|
||||
logResult(result);
|
||||
if (authorizationEnabled && !result.isAllowed()) {
|
||||
throw new AccessDeniedException("Insufficient permissions " + result.toContextString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Authorizes that the current user has any of the given permissions for the
|
||||
* given table, column family and column qualifier.
|
||||
* @param tableName Table requested
|
||||
* @param family Column family param
|
||||
* @param qualifier Column qualifier param
|
||||
* @throws IOException if obtaining the current user fails
|
||||
* @throws AccessDeniedException if user has no authorization
|
||||
*/
|
||||
public void requireTablePermission(User user, String request, TableName tableName, byte[] family,
|
||||
byte[] qualifier, Action... permissions) throws IOException {
|
||||
AuthResult result = null;
|
||||
|
||||
for (Action permission : permissions) {
|
||||
if (authManager.authorize(user, tableName, null, null, permission)) {
|
||||
result = AuthResult.allow(request, "Table permission granted", user,
|
||||
permission, tableName, null, null);
|
||||
result.getParams().setFamily(family).setQualifier(qualifier);
|
||||
break;
|
||||
} else {
|
||||
// rest of the world
|
||||
result = AuthResult.deny(request, "Insufficient permissions", user,
|
||||
permission, tableName, family, qualifier);
|
||||
result.getParams().setFamily(family).setQualifier(qualifier);
|
||||
}
|
||||
}
|
||||
logResult(result);
|
||||
if (authorizationEnabled && !result.isAllowed()) {
|
||||
throw new AccessDeniedException("Insufficient permissions " + result.toContextString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Authorizes that the current user has any of the given permissions to access the table.
|
||||
*
|
||||
* @param tableName Table requested
|
||||
* @param permissions Actions being requested
|
||||
* @throws IOException if obtaining the current user fails
|
||||
* @throws AccessDeniedException if user has no authorization
|
||||
*/
|
||||
public void requireAccess(User user, String request, TableName tableName,
|
||||
Action... permissions) throws IOException {
|
||||
AuthResult result = null;
|
||||
|
||||
for (Action permission : permissions) {
|
||||
if (authManager.hasAccess(user, tableName, permission)) {
|
||||
result = AuthResult.allow(request, "Table permission granted", user,
|
||||
permission, tableName, null, null);
|
||||
break;
|
||||
} else {
|
||||
// rest of the world
|
||||
result = AuthResult.deny(request, "Insufficient permissions", user,
|
||||
permission, tableName, null, null);
|
||||
}
|
||||
}
|
||||
logResult(result);
|
||||
if (authorizationEnabled && !result.isAllowed()) {
|
||||
throw new AccessDeniedException("Insufficient permissions " + result.toContextString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Authorizes that the current user has global privileges for the given action.
|
||||
* @param perm The action being requested
|
||||
* @throws IOException if obtaining the current user fails
|
||||
* @throws AccessDeniedException if authorization is denied
|
||||
*/
|
||||
public void requirePermission(User user, String request, Action perm) throws IOException {
|
||||
requireGlobalPermission(user, request, perm, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the user has the given global permission. The generated
|
||||
* audit log message will contain context information for the operation
|
||||
* being authorized, based on the given parameters.
|
||||
* @param perm Action being requested
|
||||
* @param tableName Affected table name.
|
||||
* @param familyMap Affected column families.
|
||||
*/
|
||||
public void requireGlobalPermission(User user, String request, Action perm, TableName tableName,
|
||||
Map<byte[], ? extends Collection<byte[]>> familyMap) throws IOException {
|
||||
AuthResult result = null;
|
||||
if (authManager.authorize(user, perm)) {
|
||||
result = AuthResult.allow(request, "Global check allowed", user, perm, tableName, familyMap);
|
||||
result.getParams().setTableName(tableName).setFamilies(familyMap);
|
||||
logResult(result);
|
||||
} else {
|
||||
result = AuthResult.deny(request, "Global check failed", user, perm, tableName, familyMap);
|
||||
result.getParams().setTableName(tableName).setFamilies(familyMap);
|
||||
logResult(result);
|
||||
if (authorizationEnabled) {
|
||||
throw new AccessDeniedException("Insufficient permissions for user '" +
|
||||
(user != null ? user.getShortName() : "null") +"' (global, action=" +
|
||||
perm.toString() + ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the user has the given global permission. The generated
|
||||
* audit log message will contain context information for the operation
|
||||
* being authorized, based on the given parameters.
|
||||
* @param perm Action being requested
|
||||
* @param namespace The given namespace
|
||||
*/
|
||||
public void requireGlobalPermission(User user, String request, Action perm,
|
||||
String namespace) throws IOException {
|
||||
AuthResult authResult = null;
|
||||
if (authManager.authorize(user, perm)) {
|
||||
authResult = AuthResult.allow(request, "Global check allowed", user, perm, null);
|
||||
authResult.getParams().setNamespace(namespace);
|
||||
logResult(authResult);
|
||||
} else {
|
||||
authResult = AuthResult.deny(request, "Global check failed", user, perm, null);
|
||||
authResult.getParams().setNamespace(namespace);
|
||||
logResult(authResult);
|
||||
if (authorizationEnabled) {
|
||||
throw new AccessDeniedException("Insufficient permissions for user '" +
|
||||
(user != null ? user.getShortName() : "null") +"' (global, action=" +
|
||||
perm.toString() + ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the user has the given global or namespace permission.
|
||||
* @param namespace The given namespace
|
||||
* @param permissions Actions being requested
|
||||
*/
|
||||
public void requireNamespacePermission(User user, String request, String namespace,
|
||||
Action... permissions) throws IOException {
|
||||
AuthResult result = null;
|
||||
|
||||
for (Action permission : permissions) {
|
||||
if (authManager.authorize(user, namespace, permission)) {
|
||||
result = AuthResult.allow(request, "Namespace permission granted",
|
||||
user, permission, namespace);
|
||||
break;
|
||||
} else {
|
||||
// rest of the world
|
||||
result = AuthResult.deny(request, "Insufficient permissions", user,
|
||||
permission, namespace);
|
||||
}
|
||||
}
|
||||
logResult(result);
|
||||
if (authorizationEnabled && !result.isAllowed()) {
|
||||
throw new AccessDeniedException("Insufficient permissions "
|
||||
+ result.toContextString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the user has the given global or namespace permission.
|
||||
* @param namespace The given namespace
|
||||
* @param permissions Actions being requested
|
||||
*/
|
||||
public void requireNamespacePermission(User user, String request, String namespace, TableName tableName,
|
||||
Map<byte[], ? extends Collection<byte[]>> familyMap, Action... permissions)
|
||||
throws IOException {
|
||||
AuthResult result = null;
|
||||
|
||||
for (Action permission : permissions) {
|
||||
if (authManager.authorize(user, namespace, permission)) {
|
||||
result = AuthResult.allow(request, "Namespace permission granted",
|
||||
user, permission, namespace);
|
||||
result.getParams().setTableName(tableName).setFamilies(familyMap);
|
||||
break;
|
||||
} else {
|
||||
// rest of the world
|
||||
result = AuthResult.deny(request, "Insufficient permissions", user,
|
||||
permission, namespace);
|
||||
result.getParams().setTableName(tableName).setFamilies(familyMap);
|
||||
}
|
||||
}
|
||||
logResult(result);
|
||||
if (authorizationEnabled && !result.isAllowed()) {
|
||||
throw new AccessDeniedException("Insufficient permissions "
|
||||
+ result.toContextString());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -31,6 +31,7 @@ import java.util.Set;
|
|||
import java.util.TreeMap;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.hadoop.conf.Configuration;
|
||||
|
@ -510,7 +511,8 @@ public class AccessControlLists {
|
|||
return getPermissions(conf, tableName != null ? tableName.getName() : null, null);
|
||||
}
|
||||
|
||||
static ListMultimap<String, TablePermission> getNamespacePermissions(Configuration conf,
|
||||
@VisibleForTesting
|
||||
public static ListMultimap<String, TablePermission> getNamespacePermissions(Configuration conf,
|
||||
String namespace) throws IOException {
|
||||
return getPermissions(conf, Bytes.toBytes(toNamespaceEntry(namespace)), null);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -758,7 +758,7 @@ public class TableAuthManager implements Closeable {
|
|||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static int getTotalRefCount() {
|
||||
public static int getTotalRefCount() {
|
||||
int total = 0;
|
||||
for (int count : refCount.values()) {
|
||||
total += count;
|
||||
|
|
|
@ -101,6 +101,7 @@ import org.apache.hadoop.hbase.replication.ReplicationEndpoint;
|
|||
import org.apache.hadoop.hbase.security.AccessDeniedException;
|
||||
import org.apache.hadoop.hbase.security.Superusers;
|
||||
import org.apache.hadoop.hbase.security.User;
|
||||
import org.apache.hadoop.hbase.security.access.AccessChecker;
|
||||
import org.apache.hadoop.hbase.security.access.AccessController;
|
||||
import org.apache.hadoop.hbase.util.ByteStringer;
|
||||
import org.apache.hadoop.hbase.util.Bytes;
|
||||
|
@ -139,8 +140,8 @@ public class VisibilityController extends BaseMasterAndRegionObserver implements
|
|||
|
||||
private VisibilityLabelService visibilityLabelService; // FindBugs: MT_CORRECTNESS FIX!!!
|
||||
|
||||
/** if we are active, usually true, only not true if "hbase.security.authorization"
|
||||
has been set to false in site configuration */
|
||||
/** if we are active, usually false, only true if "hbase.security.authorization"
|
||||
has been set to true in site configuration */
|
||||
boolean authorizationEnabled;
|
||||
|
||||
// Add to this list if there are any reserved tag types
|
||||
|
@ -151,19 +152,15 @@ public class VisibilityController extends BaseMasterAndRegionObserver implements
|
|||
RESERVED_VIS_TAG_TYPES.add(TagType.STRING_VIS_TAG_TYPE);
|
||||
}
|
||||
|
||||
public static boolean isAuthorizationSupported(Configuration conf) {
|
||||
return conf.getBoolean(User.HBASE_SECURITY_AUTHORIZATION_CONF_KEY, true);
|
||||
}
|
||||
|
||||
public static boolean isCellAuthorizationSupported(Configuration conf) {
|
||||
return isAuthorizationSupported(conf);
|
||||
return AccessChecker.isAuthorizationSupported(conf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(CoprocessorEnvironment env) throws IOException {
|
||||
this.conf = env.getConfiguration();
|
||||
|
||||
authorizationEnabled = isAuthorizationSupported(conf);
|
||||
authorizationEnabled = AccessChecker.isAuthorizationSupported(conf);
|
||||
if (!authorizationEnabled) {
|
||||
LOG.warn("The VisibilityController has been loaded with authorization checks disabled.");
|
||||
}
|
||||
|
|
|
@ -64,6 +64,7 @@ import org.apache.hadoop.hbase.security.visibility.SimpleScanLabelGenerator;
|
|||
import org.apache.hadoop.hbase.security.visibility.VisibilityClient;
|
||||
import org.apache.hadoop.hbase.security.visibility.VisibilityConstants;
|
||||
import org.apache.hadoop.hbase.security.visibility.VisibilityController;
|
||||
import org.apache.hadoop.hbase.security.visibility.VisibilityTestUtil;
|
||||
import org.apache.hadoop.hbase.security.visibility.VisibilityUtils;
|
||||
import org.apache.hadoop.hbase.testclassification.LargeTests;
|
||||
import org.apache.hadoop.hbase.util.Bytes;
|
||||
|
@ -117,9 +118,7 @@ public class TestImportTSVWithVisibilityLabels implements Configurable {
|
|||
conf = util.getConfiguration();
|
||||
SUPERUSER = User.createUserForTesting(conf, "admin", new String[] { "supergroup" });
|
||||
conf.set("hbase.superuser", "admin,"+User.getCurrent().getName());
|
||||
conf.setInt("hfile.format.version", 3);
|
||||
conf.set("hbase.coprocessor.master.classes", VisibilityController.class.getName());
|
||||
conf.set("hbase.coprocessor.region.classes", VisibilityController.class.getName());
|
||||
VisibilityTestUtil.enableVisiblityLabels(conf);
|
||||
conf.setClass(VisibilityUtils.VISIBILITY_LABEL_GENERATOR_CLASS, SimpleScanLabelGenerator.class,
|
||||
ScanLabelGenerator.class);
|
||||
util.setJobWithoutMRCluster();
|
||||
|
|
|
@ -104,6 +104,7 @@ public class SecureTestUtil {
|
|||
conf.set(CoprocessorHost.REGIONSERVER_COPROCESSOR_CONF_KEY, AccessController.class.getName());
|
||||
// Need HFile V3 for tags for security features
|
||||
conf.setInt(HFile.FORMAT_VERSION_KEY, 3);
|
||||
conf.setBoolean(User.HBASE_SECURITY_AUTHORIZATION_CONF_KEY, true);
|
||||
configureSuperuser(conf);
|
||||
}
|
||||
|
||||
|
@ -127,6 +128,11 @@ public class SecureTestUtil {
|
|||
if (conf.getInt(HFile.FORMAT_VERSION_KEY, 2) < HFile.MIN_FORMAT_VERSION_WITH_TAGS) {
|
||||
throw new RuntimeException("Post 0.96 security features require HFile version >= 3");
|
||||
}
|
||||
|
||||
if (!conf.getBoolean(User.HBASE_SECURITY_AUTHORIZATION_CONF_KEY, false)) {
|
||||
throw new RuntimeException("Post 1.5.0 security features require set "
|
||||
+ User.HBASE_SECURITY_AUTHORIZATION_CONF_KEY + " to true");
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkTablePerms(Configuration conf, TableName table, byte[] family, byte[] column,
|
||||
|
|
|
@ -2966,81 +2966,6 @@ public class TestAccessController extends SecureTestUtil {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMoveServers() throws Exception {
|
||||
AccessTestAction action1 = new AccessTestAction() {
|
||||
@Override
|
||||
public Object run() throws Exception {
|
||||
ACCESS_CONTROLLER.preMoveServers(ObserverContext.createAndPrepare(CP_ENV, null),
|
||||
null, null);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
verifyAllowed(action1, SUPERUSER, USER_ADMIN);
|
||||
verifyDenied(action1, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_OWNER);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMoveTables() throws Exception {
|
||||
AccessTestAction action1 = new AccessTestAction() {
|
||||
@Override
|
||||
public Object run() throws Exception {
|
||||
ACCESS_CONTROLLER.preMoveTables(ObserverContext.createAndPrepare(CP_ENV, null),
|
||||
null, null);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
verifyAllowed(action1, SUPERUSER, USER_ADMIN);
|
||||
verifyDenied(action1, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_OWNER);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddGroup() throws Exception {
|
||||
AccessTestAction action1 = new AccessTestAction() {
|
||||
@Override
|
||||
public Object run() throws Exception {
|
||||
ACCESS_CONTROLLER.preAddRSGroup(ObserverContext.createAndPrepare(CP_ENV, null),
|
||||
null);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
verifyAllowed(action1, SUPERUSER, USER_ADMIN);
|
||||
verifyDenied(action1, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_OWNER);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveGroup() throws Exception {
|
||||
AccessTestAction action1 = new AccessTestAction() {
|
||||
@Override
|
||||
public Object run() throws Exception {
|
||||
ACCESS_CONTROLLER.preRemoveRSGroup(ObserverContext.createAndPrepare(CP_ENV, null),
|
||||
null);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
verifyAllowed(action1, SUPERUSER, USER_ADMIN);
|
||||
verifyDenied(action1, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_OWNER);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBalanceGroup() throws Exception {
|
||||
AccessTestAction action1 = new AccessTestAction() {
|
||||
@Override
|
||||
public Object run() throws Exception {
|
||||
ACCESS_CONTROLLER.preBalanceRSGroup(ObserverContext.createAndPrepare(CP_ENV, null),
|
||||
null);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
verifyAllowed(action1, SUPERUSER, USER_ADMIN);
|
||||
verifyDenied(action1, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_OWNER);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetClusterStatus() throws Exception {
|
||||
AccessTestAction action = new AccessTestAction() {
|
||||
|
|
|
@ -14,7 +14,7 @@ import java.io.IOException;
|
|||
|
||||
import org.apache.hadoop.conf.Configuration;
|
||||
import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
|
||||
|
||||
import org.apache.hadoop.hbase.security.User;
|
||||
|
||||
/**
|
||||
* Utility methods for testing visibility labels.
|
||||
|
@ -23,6 +23,7 @@ public class VisibilityTestUtil {
|
|||
|
||||
public static void enableVisiblityLabels(Configuration conf) throws IOException {
|
||||
conf.setInt("hfile.format.version", 3);
|
||||
conf.setBoolean(User.HBASE_SECURITY_AUTHORIZATION_CONF_KEY, true);
|
||||
appendCoprocessor(conf, CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY,
|
||||
VisibilityController.class.getName());
|
||||
appendCoprocessor(conf, CoprocessorHost.REGION_COPROCESSOR_CONF_KEY,
|
||||
|
|
|
@ -35,6 +35,7 @@ import org.apache.hadoop.conf.Configuration;
|
|||
import org.apache.hadoop.hbase.HBaseTestingUtility;
|
||||
import org.apache.hadoop.hbase.HColumnDescriptor;
|
||||
import org.apache.hadoop.hbase.HTableDescriptor;
|
||||
import org.apache.hadoop.hbase.security.visibility.VisibilityTestUtil;
|
||||
import org.apache.hadoop.hbase.testclassification.MediumTests;
|
||||
import org.apache.hadoop.hbase.TableName;
|
||||
import org.apache.hadoop.hbase.client.Admin;
|
||||
|
@ -73,390 +74,386 @@ import org.junit.experimental.categories.Category;
|
|||
@Category(MediumTests.class)
|
||||
public class TestThriftHBaseServiceHandlerWithLabels {
|
||||
|
||||
private static final HBaseTestingUtility UTIL = new HBaseTestingUtility();
|
||||
private static final HBaseTestingUtility UTIL = new HBaseTestingUtility();
|
||||
|
||||
// Static names for tables, columns, rows, and values
|
||||
private static byte[] tableAname = Bytes.toBytes("tableA");
|
||||
private static byte[] familyAname = Bytes.toBytes("familyA");
|
||||
private static byte[] familyBname = Bytes.toBytes("familyB");
|
||||
private static byte[] qualifierAname = Bytes.toBytes("qualifierA");
|
||||
private static byte[] qualifierBname = Bytes.toBytes("qualifierB");
|
||||
private static byte[] valueAname = Bytes.toBytes("valueA");
|
||||
private static byte[] valueBname = Bytes.toBytes("valueB");
|
||||
private static HColumnDescriptor[] families = new HColumnDescriptor[] {
|
||||
new HColumnDescriptor(familyAname).setMaxVersions(3),
|
||||
new HColumnDescriptor(familyBname).setMaxVersions(2) };
|
||||
// Static names for tables, columns, rows, and values
|
||||
private static byte[] tableAname = Bytes.toBytes("tableA");
|
||||
private static byte[] familyAname = Bytes.toBytes("familyA");
|
||||
private static byte[] familyBname = Bytes.toBytes("familyB");
|
||||
private static byte[] qualifierAname = Bytes.toBytes("qualifierA");
|
||||
private static byte[] qualifierBname = Bytes.toBytes("qualifierB");
|
||||
private static byte[] valueAname = Bytes.toBytes("valueA");
|
||||
private static byte[] valueBname = Bytes.toBytes("valueB");
|
||||
private static HColumnDescriptor[] families = new HColumnDescriptor[] {
|
||||
new HColumnDescriptor(familyAname).setMaxVersions(3),
|
||||
new HColumnDescriptor(familyBname).setMaxVersions(2) };
|
||||
|
||||
private final static String TOPSECRET = "topsecret";
|
||||
private final static String PUBLIC = "public";
|
||||
private final static String PRIVATE = "private";
|
||||
private final static String CONFIDENTIAL = "confidential";
|
||||
private final static String SECRET = "secret";
|
||||
private static User SUPERUSER;
|
||||
private final static String TOPSECRET = "topsecret";
|
||||
private final static String PUBLIC = "public";
|
||||
private final static String PRIVATE = "private";
|
||||
private final static String CONFIDENTIAL = "confidential";
|
||||
private final static String SECRET = "secret";
|
||||
private static User SUPERUSER;
|
||||
|
||||
private static Configuration conf;
|
||||
private static Configuration conf;
|
||||
|
||||
public void assertTColumnValuesEqual(List<TColumnValue> columnValuesA,
|
||||
List<TColumnValue> columnValuesB) {
|
||||
assertEquals(columnValuesA.size(), columnValuesB.size());
|
||||
Comparator<TColumnValue> comparator = new Comparator<TColumnValue>() {
|
||||
@Override
|
||||
public int compare(TColumnValue o1, TColumnValue o2) {
|
||||
return Bytes.compareTo(Bytes.add(o1.getFamily(), o1.getQualifier()),
|
||||
Bytes.add(o2.getFamily(), o2.getQualifier()));
|
||||
}
|
||||
};
|
||||
Collections.sort(columnValuesA, comparator);
|
||||
Collections.sort(columnValuesB, comparator);
|
||||
|
||||
for (int i = 0; i < columnValuesA.size(); i++) {
|
||||
TColumnValue a = columnValuesA.get(i);
|
||||
TColumnValue b = columnValuesB.get(i);
|
||||
assertArrayEquals(a.getFamily(), b.getFamily());
|
||||
assertArrayEquals(a.getQualifier(), b.getQualifier());
|
||||
assertArrayEquals(a.getValue(), b.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
SUPERUSER = User.createUserForTesting(conf, "admin",
|
||||
new String[] { "supergroup" });
|
||||
conf = UTIL.getConfiguration();
|
||||
conf.setClass(VisibilityUtils.VISIBILITY_LABEL_GENERATOR_CLASS,
|
||||
SimpleScanLabelGenerator.class, ScanLabelGenerator.class);
|
||||
conf.set("hbase.superuser", SUPERUSER.getShortName());
|
||||
conf.set("hbase.coprocessor.master.classes",
|
||||
VisibilityController.class.getName());
|
||||
conf.set("hbase.coprocessor.region.classes",
|
||||
VisibilityController.class.getName());
|
||||
conf.setInt("hfile.format.version", 3);
|
||||
UTIL.startMiniCluster(1);
|
||||
// Wait for the labels table to become available
|
||||
UTIL.waitTableEnabled(VisibilityConstants.LABELS_TABLE_NAME.getName(), 50000);
|
||||
createLabels();
|
||||
Admin admin = new HBaseAdmin(UTIL.getConfiguration());
|
||||
HTableDescriptor tableDescriptor = new HTableDescriptor(
|
||||
TableName.valueOf(tableAname));
|
||||
for (HColumnDescriptor family : families) {
|
||||
tableDescriptor.addFamily(family);
|
||||
}
|
||||
admin.createTable(tableDescriptor);
|
||||
admin.close();
|
||||
setAuths();
|
||||
}
|
||||
|
||||
private static void createLabels() throws IOException, InterruptedException {
|
||||
PrivilegedExceptionAction<VisibilityLabelsResponse> action = new PrivilegedExceptionAction<VisibilityLabelsResponse>() {
|
||||
public VisibilityLabelsResponse run() throws Exception {
|
||||
String[] labels = { SECRET, CONFIDENTIAL, PRIVATE, PUBLIC, TOPSECRET };
|
||||
try (Connection conn = ConnectionFactory.createConnection(conf)) {
|
||||
VisibilityClient.addLabels(conn, labels);
|
||||
} catch (Throwable t) {
|
||||
throw new IOException(t);
|
||||
public void assertTColumnValuesEqual(List<TColumnValue> columnValuesA,
|
||||
List<TColumnValue> columnValuesB) {
|
||||
assertEquals(columnValuesA.size(), columnValuesB.size());
|
||||
Comparator<TColumnValue> comparator = new Comparator<TColumnValue>() {
|
||||
@Override
|
||||
public int compare(TColumnValue o1, TColumnValue o2) {
|
||||
return Bytes.compareTo(Bytes.add(o1.getFamily(), o1.getQualifier()),
|
||||
Bytes.add(o2.getFamily(), o2.getQualifier()));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
SUPERUSER.runAs(action);
|
||||
}
|
||||
};
|
||||
Collections.sort(columnValuesA, comparator);
|
||||
Collections.sort(columnValuesB, comparator);
|
||||
|
||||
private static void setAuths() throws IOException {
|
||||
String[] labels = { SECRET, CONFIDENTIAL, PRIVATE, PUBLIC, TOPSECRET };
|
||||
try {
|
||||
VisibilityClient.setAuths(UTIL.getConnection(), labels, User.getCurrent().getShortName());
|
||||
} catch (Throwable t) {
|
||||
throw new IOException(t);
|
||||
for (int i = 0; i < columnValuesA.size(); i++) {
|
||||
TColumnValue a = columnValuesA.get(i);
|
||||
TColumnValue b = columnValuesB.get(i);
|
||||
assertArrayEquals(a.getFamily(), b.getFamily());
|
||||
assertArrayEquals(a.getQualifier(), b.getQualifier());
|
||||
assertArrayEquals(a.getValue(), b.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void afterClass() throws Exception {
|
||||
UTIL.shutdownMiniCluster();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
|
||||
}
|
||||
|
||||
private ThriftHBaseServiceHandler createHandler() throws IOException {
|
||||
return new ThriftHBaseServiceHandler(conf, UserProvider.instantiate(conf));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testScanWithVisibilityLabels() throws Exception {
|
||||
ThriftHBaseServiceHandler handler = createHandler();
|
||||
ByteBuffer table = wrap(tableAname);
|
||||
|
||||
// insert data
|
||||
TColumnValue columnValue = new TColumnValue(wrap(familyAname),
|
||||
wrap(qualifierAname), wrap(valueAname));
|
||||
List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
|
||||
columnValues.add(columnValue);
|
||||
for (int i = 0; i < 10; i++) {
|
||||
TPut put = new TPut(wrap(("testScan" + i).getBytes()), columnValues);
|
||||
if (i == 5) {
|
||||
put.setCellVisibility(new TCellVisibility().setExpression(PUBLIC));
|
||||
} else {
|
||||
put.setCellVisibility(new TCellVisibility().setExpression("(" + SECRET
|
||||
+ "|" + CONFIDENTIAL + ")" + "&" + "!" + TOPSECRET));
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
SUPERUSER = User.createUserForTesting(conf, "admin",
|
||||
new String[] { "supergroup" });
|
||||
conf = UTIL.getConfiguration();
|
||||
conf.setClass(VisibilityUtils.VISIBILITY_LABEL_GENERATOR_CLASS,
|
||||
SimpleScanLabelGenerator.class, ScanLabelGenerator.class);
|
||||
conf.set("hbase.superuser", SUPERUSER.getShortName());
|
||||
VisibilityTestUtil.enableVisiblityLabels(conf);
|
||||
UTIL.startMiniCluster(1);
|
||||
// Wait for the labels table to become available
|
||||
UTIL.waitTableEnabled(VisibilityConstants.LABELS_TABLE_NAME.getName(), 50000);
|
||||
createLabels();
|
||||
Admin admin = new HBaseAdmin(UTIL.getConfiguration());
|
||||
HTableDescriptor tableDescriptor = new HTableDescriptor(
|
||||
TableName.valueOf(tableAname));
|
||||
for (HColumnDescriptor family : families) {
|
||||
tableDescriptor.addFamily(family);
|
||||
}
|
||||
admin.createTable(tableDescriptor);
|
||||
admin.close();
|
||||
setAuths();
|
||||
}
|
||||
|
||||
private static void createLabels() throws IOException, InterruptedException {
|
||||
PrivilegedExceptionAction<VisibilityLabelsResponse> action = new PrivilegedExceptionAction<VisibilityLabelsResponse>() {
|
||||
public VisibilityLabelsResponse run() throws Exception {
|
||||
String[] labels = { SECRET, CONFIDENTIAL, PRIVATE, PUBLIC, TOPSECRET };
|
||||
try (Connection conn = ConnectionFactory.createConnection(conf)) {
|
||||
VisibilityClient.addLabels(conn, labels);
|
||||
} catch (Throwable t) {
|
||||
throw new IOException(t);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
SUPERUSER.runAs(action);
|
||||
}
|
||||
|
||||
private static void setAuths() throws IOException {
|
||||
String[] labels = { SECRET, CONFIDENTIAL, PRIVATE, PUBLIC, TOPSECRET };
|
||||
try {
|
||||
VisibilityClient.setAuths(UTIL.getConnection(), labels, User.getCurrent().getShortName());
|
||||
} catch (Throwable t) {
|
||||
throw new IOException(t);
|
||||
}
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void afterClass() throws Exception {
|
||||
UTIL.shutdownMiniCluster();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
|
||||
}
|
||||
|
||||
private ThriftHBaseServiceHandler createHandler() throws IOException {
|
||||
return new ThriftHBaseServiceHandler(conf, UserProvider.instantiate(conf));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testScanWithVisibilityLabels() throws Exception {
|
||||
ThriftHBaseServiceHandler handler = createHandler();
|
||||
ByteBuffer table = wrap(tableAname);
|
||||
|
||||
// insert data
|
||||
TColumnValue columnValue = new TColumnValue(wrap(familyAname),
|
||||
wrap(qualifierAname), wrap(valueAname));
|
||||
List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
|
||||
columnValues.add(columnValue);
|
||||
for (int i = 0; i < 10; i++) {
|
||||
TPut put = new TPut(wrap(("testScan" + i).getBytes()), columnValues);
|
||||
if (i == 5) {
|
||||
put.setCellVisibility(new TCellVisibility().setExpression(PUBLIC));
|
||||
} else {
|
||||
put.setCellVisibility(new TCellVisibility().setExpression("(" + SECRET
|
||||
+ "|" + CONFIDENTIAL + ")" + "&" + "!" + TOPSECRET));
|
||||
}
|
||||
handler.put(table, put);
|
||||
}
|
||||
|
||||
// create scan instance
|
||||
TScan scan = new TScan();
|
||||
List<TColumn> columns = new ArrayList<TColumn>();
|
||||
TColumn column = new TColumn();
|
||||
column.setFamily(familyAname);
|
||||
column.setQualifier(qualifierAname);
|
||||
columns.add(column);
|
||||
scan.setColumns(columns);
|
||||
scan.setStartRow("testScan".getBytes());
|
||||
scan.setStopRow("testScan\uffff".getBytes());
|
||||
|
||||
TAuthorization tauth = new TAuthorization();
|
||||
List<String> labels = new ArrayList<String>();
|
||||
labels.add(SECRET);
|
||||
labels.add(PRIVATE);
|
||||
tauth.setLabels(labels);
|
||||
scan.setAuthorizations(tauth);
|
||||
// get scanner and rows
|
||||
int scanId = handler.openScanner(table, scan);
|
||||
List<TResult> results = handler.getScannerRows(scanId, 10);
|
||||
assertEquals(9, results.size());
|
||||
Assert.assertFalse(Bytes.equals(results.get(5).getRow(),
|
||||
("testScan" + 5).getBytes()));
|
||||
for (int i = 0; i < 9; i++) {
|
||||
if (i < 5) {
|
||||
assertArrayEquals(("testScan" + i).getBytes(), results.get(i).getRow());
|
||||
} else if (i == 5) {
|
||||
continue;
|
||||
} else {
|
||||
assertArrayEquals(("testScan" + (i + 1)).getBytes(), results.get(i)
|
||||
.getRow());
|
||||
}
|
||||
}
|
||||
|
||||
// check that we are at the end of the scan
|
||||
results = handler.getScannerRows(scanId, 9);
|
||||
assertEquals(0, results.size());
|
||||
|
||||
// close scanner and check that it was indeed closed
|
||||
handler.closeScanner(scanId);
|
||||
try {
|
||||
handler.getScannerRows(scanId, 9);
|
||||
fail("Scanner id should be invalid");
|
||||
} catch (TIllegalArgument e) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="UC_USELESS_CONDITION",
|
||||
justification="Intended")
|
||||
public void testGetScannerResultsWithAuthorizations() throws Exception {
|
||||
ThriftHBaseServiceHandler handler = createHandler();
|
||||
ByteBuffer table = wrap(tableAname);
|
||||
|
||||
// insert data
|
||||
TColumnValue columnValue = new TColumnValue(wrap(familyAname),
|
||||
wrap(qualifierAname), wrap(valueAname));
|
||||
List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
|
||||
columnValues.add(columnValue);
|
||||
for (int i = 0; i < 20; i++) {
|
||||
TPut put = new TPut(
|
||||
wrap(("testGetScannerResults" + pad(i, (byte) 2)).getBytes()),
|
||||
columnValues);
|
||||
if (i == 3) {
|
||||
put.setCellVisibility(new TCellVisibility().setExpression(PUBLIC));
|
||||
} else {
|
||||
put.setCellVisibility(new TCellVisibility().setExpression("(" + SECRET
|
||||
+ "|" + CONFIDENTIAL + ")" + "&" + "!" + TOPSECRET));
|
||||
}
|
||||
handler.put(table, put);
|
||||
}
|
||||
|
||||
// create scan instance
|
||||
TScan scan = new TScan();
|
||||
List<TColumn> columns = new ArrayList<TColumn>();
|
||||
TColumn column = new TColumn();
|
||||
column.setFamily(familyAname);
|
||||
column.setQualifier(qualifierAname);
|
||||
columns.add(column);
|
||||
scan.setColumns(columns);
|
||||
scan.setStartRow("testGetScannerResults".getBytes());
|
||||
|
||||
// get 5 rows and check the returned results
|
||||
scan.setStopRow("testGetScannerResults05".getBytes());
|
||||
TAuthorization tauth = new TAuthorization();
|
||||
List<String> labels = new ArrayList<String>();
|
||||
labels.add(SECRET);
|
||||
labels.add(PRIVATE);
|
||||
tauth.setLabels(labels);
|
||||
scan.setAuthorizations(tauth);
|
||||
List<TResult> results = handler.getScannerResults(table, scan, 5);
|
||||
assertEquals(4, results.size());
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (i < 3) {
|
||||
assertArrayEquals(
|
||||
("testGetScannerResults" + pad(i, (byte) 2)).getBytes(),
|
||||
results.get(i).getRow());
|
||||
} else if (i == 3) {
|
||||
continue;
|
||||
} else {
|
||||
assertArrayEquals(
|
||||
("testGetScannerResults" + pad(i + 1, (byte) 2)).getBytes(), results
|
||||
.get(i).getRow());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetsWithLabels() throws Exception {
|
||||
ThriftHBaseServiceHandler handler = createHandler();
|
||||
byte[] rowName = "testPutGet".getBytes();
|
||||
ByteBuffer table = wrap(tableAname);
|
||||
|
||||
List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
|
||||
columnValues.add(new TColumnValue(wrap(familyAname), wrap(qualifierAname),
|
||||
wrap(valueAname)));
|
||||
columnValues.add(new TColumnValue(wrap(familyBname), wrap(qualifierBname),
|
||||
wrap(valueBname)));
|
||||
TPut put = new TPut(wrap(rowName), columnValues);
|
||||
|
||||
put.setColumnValues(columnValues);
|
||||
put.setCellVisibility(new TCellVisibility().setExpression("(" + SECRET + "|"
|
||||
+ CONFIDENTIAL + ")" + "&" + "!" + TOPSECRET));
|
||||
handler.put(table, put);
|
||||
TGet get = new TGet(wrap(rowName));
|
||||
TAuthorization tauth = new TAuthorization();
|
||||
List<String> labels = new ArrayList<String>();
|
||||
labels.add(SECRET);
|
||||
labels.add(PRIVATE);
|
||||
tauth.setLabels(labels);
|
||||
get.setAuthorizations(tauth);
|
||||
TResult result = handler.get(table, get);
|
||||
assertArrayEquals(rowName, result.getRow());
|
||||
List<TColumnValue> returnedColumnValues = result.getColumnValues();
|
||||
assertTColumnValuesEqual(columnValues, returnedColumnValues);
|
||||
}
|
||||
|
||||
// create scan instance
|
||||
TScan scan = new TScan();
|
||||
List<TColumn> columns = new ArrayList<TColumn>();
|
||||
TColumn column = new TColumn();
|
||||
column.setFamily(familyAname);
|
||||
column.setQualifier(qualifierAname);
|
||||
columns.add(column);
|
||||
scan.setColumns(columns);
|
||||
scan.setStartRow("testScan".getBytes());
|
||||
scan.setStopRow("testScan\uffff".getBytes());
|
||||
@Test
|
||||
public void testIncrementWithTags() throws Exception {
|
||||
ThriftHBaseServiceHandler handler = createHandler();
|
||||
byte[] rowName = "testIncrementWithTags".getBytes();
|
||||
ByteBuffer table = wrap(tableAname);
|
||||
|
||||
TAuthorization tauth = new TAuthorization();
|
||||
List<String> labels = new ArrayList<String>();
|
||||
labels.add(SECRET);
|
||||
labels.add(PRIVATE);
|
||||
tauth.setLabels(labels);
|
||||
scan.setAuthorizations(tauth);
|
||||
// get scanner and rows
|
||||
int scanId = handler.openScanner(table, scan);
|
||||
List<TResult> results = handler.getScannerRows(scanId, 10);
|
||||
assertEquals(9, results.size());
|
||||
Assert.assertFalse(Bytes.equals(results.get(5).getRow(),
|
||||
("testScan" + 5).getBytes()));
|
||||
for (int i = 0; i < 9; i++) {
|
||||
if (i < 5) {
|
||||
assertArrayEquals(("testScan" + i).getBytes(), results.get(i).getRow());
|
||||
} else if (i == 5) {
|
||||
continue;
|
||||
} else {
|
||||
assertArrayEquals(("testScan" + (i + 1)).getBytes(), results.get(i)
|
||||
.getRow());
|
||||
}
|
||||
}
|
||||
|
||||
// check that we are at the end of the scan
|
||||
results = handler.getScannerRows(scanId, 9);
|
||||
assertEquals(0, results.size());
|
||||
|
||||
// close scanner and check that it was indeed closed
|
||||
handler.closeScanner(scanId);
|
||||
try {
|
||||
handler.getScannerRows(scanId, 9);
|
||||
fail("Scanner id should be invalid");
|
||||
} catch (TIllegalArgument e) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="UC_USELESS_CONDITION",
|
||||
justification="Intended")
|
||||
public void testGetScannerResultsWithAuthorizations() throws Exception {
|
||||
ThriftHBaseServiceHandler handler = createHandler();
|
||||
ByteBuffer table = wrap(tableAname);
|
||||
|
||||
// insert data
|
||||
TColumnValue columnValue = new TColumnValue(wrap(familyAname),
|
||||
wrap(qualifierAname), wrap(valueAname));
|
||||
List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
|
||||
columnValues.add(columnValue);
|
||||
for (int i = 0; i < 20; i++) {
|
||||
TPut put = new TPut(
|
||||
wrap(("testGetScannerResults" + pad(i, (byte) 2)).getBytes()),
|
||||
columnValues);
|
||||
if (i == 3) {
|
||||
put.setCellVisibility(new TCellVisibility().setExpression(PUBLIC));
|
||||
} else {
|
||||
put.setCellVisibility(new TCellVisibility().setExpression("(" + SECRET
|
||||
+ "|" + CONFIDENTIAL + ")" + "&" + "!" + TOPSECRET));
|
||||
}
|
||||
List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
|
||||
columnValues.add(new TColumnValue(wrap(familyAname), wrap(qualifierAname),
|
||||
wrap(Bytes.toBytes(1L))));
|
||||
TPut put = new TPut(wrap(rowName), columnValues);
|
||||
put.setColumnValues(columnValues);
|
||||
put.setCellVisibility(new TCellVisibility().setExpression(PRIVATE));
|
||||
handler.put(table, put);
|
||||
|
||||
List<TColumnIncrement> incrementColumns = new ArrayList<TColumnIncrement>();
|
||||
incrementColumns.add(new TColumnIncrement(wrap(familyAname),
|
||||
wrap(qualifierAname)));
|
||||
TIncrement increment = new TIncrement(wrap(rowName), incrementColumns);
|
||||
increment.setCellVisibility(new TCellVisibility().setExpression(SECRET));
|
||||
handler.increment(table, increment);
|
||||
|
||||
TGet get = new TGet(wrap(rowName));
|
||||
TAuthorization tauth = new TAuthorization();
|
||||
List<String> labels = new ArrayList<String>();
|
||||
labels.add(SECRET);
|
||||
tauth.setLabels(labels);
|
||||
get.setAuthorizations(tauth);
|
||||
TResult result = handler.get(table, get);
|
||||
|
||||
assertArrayEquals(rowName, result.getRow());
|
||||
assertEquals(1, result.getColumnValuesSize());
|
||||
TColumnValue columnValue = result.getColumnValues().get(0);
|
||||
assertArrayEquals(Bytes.toBytes(2L), columnValue.getValue());
|
||||
}
|
||||
|
||||
// create scan instance
|
||||
TScan scan = new TScan();
|
||||
List<TColumn> columns = new ArrayList<TColumn>();
|
||||
TColumn column = new TColumn();
|
||||
column.setFamily(familyAname);
|
||||
column.setQualifier(qualifierAname);
|
||||
columns.add(column);
|
||||
scan.setColumns(columns);
|
||||
scan.setStartRow("testGetScannerResults".getBytes());
|
||||
@Test
|
||||
public void testIncrementWithTagsWithNotMatchLabels() throws Exception {
|
||||
ThriftHBaseServiceHandler handler = createHandler();
|
||||
byte[] rowName = "testIncrementWithTagsWithNotMatchLabels".getBytes();
|
||||
ByteBuffer table = wrap(tableAname);
|
||||
|
||||
// get 5 rows and check the returned results
|
||||
scan.setStopRow("testGetScannerResults05".getBytes());
|
||||
TAuthorization tauth = new TAuthorization();
|
||||
List<String> labels = new ArrayList<String>();
|
||||
labels.add(SECRET);
|
||||
labels.add(PRIVATE);
|
||||
tauth.setLabels(labels);
|
||||
scan.setAuthorizations(tauth);
|
||||
List<TResult> results = handler.getScannerResults(table, scan, 5);
|
||||
assertEquals(4, results.size());
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (i < 3) {
|
||||
assertArrayEquals(
|
||||
("testGetScannerResults" + pad(i, (byte) 2)).getBytes(),
|
||||
results.get(i).getRow());
|
||||
} else if (i == 3) {
|
||||
continue;
|
||||
} else {
|
||||
assertArrayEquals(
|
||||
("testGetScannerResults" + pad(i + 1, (byte) 2)).getBytes(), results
|
||||
.get(i).getRow());
|
||||
}
|
||||
List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
|
||||
columnValues.add(new TColumnValue(wrap(familyAname), wrap(qualifierAname),
|
||||
wrap(Bytes.toBytes(1L))));
|
||||
TPut put = new TPut(wrap(rowName), columnValues);
|
||||
put.setColumnValues(columnValues);
|
||||
put.setCellVisibility(new TCellVisibility().setExpression(PRIVATE));
|
||||
handler.put(table, put);
|
||||
|
||||
List<TColumnIncrement> incrementColumns = new ArrayList<TColumnIncrement>();
|
||||
incrementColumns.add(new TColumnIncrement(wrap(familyAname),
|
||||
wrap(qualifierAname)));
|
||||
TIncrement increment = new TIncrement(wrap(rowName), incrementColumns);
|
||||
increment.setCellVisibility(new TCellVisibility().setExpression(SECRET));
|
||||
handler.increment(table, increment);
|
||||
|
||||
TGet get = new TGet(wrap(rowName));
|
||||
TAuthorization tauth = new TAuthorization();
|
||||
List<String> labels = new ArrayList<String>();
|
||||
labels.add(PUBLIC);
|
||||
tauth.setLabels(labels);
|
||||
get.setAuthorizations(tauth);
|
||||
TResult result = handler.get(table, get);
|
||||
assertNull(result.getRow());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAppend() throws Exception {
|
||||
ThriftHBaseServiceHandler handler = createHandler();
|
||||
byte[] rowName = "testAppend".getBytes();
|
||||
ByteBuffer table = wrap(tableAname);
|
||||
byte[] v1 = Bytes.toBytes(1L);
|
||||
byte[] v2 = Bytes.toBytes(5L);
|
||||
List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
|
||||
columnValues.add(new TColumnValue(wrap(familyAname), wrap(qualifierAname),
|
||||
wrap(Bytes.toBytes(1L))));
|
||||
TPut put = new TPut(wrap(rowName), columnValues);
|
||||
put.setColumnValues(columnValues);
|
||||
put.setCellVisibility(new TCellVisibility().setExpression(PRIVATE));
|
||||
handler.put(table, put);
|
||||
|
||||
List<TColumnValue> appendColumns = new ArrayList<TColumnValue>();
|
||||
appendColumns.add(new TColumnValue(wrap(familyAname), wrap(qualifierAname),
|
||||
wrap(v2)));
|
||||
TAppend append = new TAppend(wrap(rowName), appendColumns);
|
||||
append.setCellVisibility(new TCellVisibility().setExpression(SECRET));
|
||||
handler.append(table, append);
|
||||
|
||||
TGet get = new TGet(wrap(rowName));
|
||||
TAuthorization tauth = new TAuthorization();
|
||||
List<String> labels = new ArrayList<String>();
|
||||
labels.add(SECRET);
|
||||
tauth.setLabels(labels);
|
||||
get.setAuthorizations(tauth);
|
||||
TResult result = handler.get(table, get);
|
||||
|
||||
assertArrayEquals(rowName, result.getRow());
|
||||
assertEquals(1, result.getColumnValuesSize());
|
||||
TColumnValue columnValue = result.getColumnValues().get(0);
|
||||
assertArrayEquals(Bytes.add(v1, v2), columnValue.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Padding numbers to make comparison of sort order easier in a for loop
|
||||
*
|
||||
* @param n
|
||||
* The number to pad.
|
||||
* @param pad
|
||||
* The length to pad up to.
|
||||
* @return The padded number as a string.
|
||||
*/
|
||||
private String pad(int n, byte pad) {
|
||||
String res = Integer.toString(n);
|
||||
while (res.length() < pad)
|
||||
res = "0" + res;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetsWithLabels() throws Exception {
|
||||
ThriftHBaseServiceHandler handler = createHandler();
|
||||
byte[] rowName = "testPutGet".getBytes();
|
||||
ByteBuffer table = wrap(tableAname);
|
||||
|
||||
List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
|
||||
columnValues.add(new TColumnValue(wrap(familyAname), wrap(qualifierAname),
|
||||
wrap(valueAname)));
|
||||
columnValues.add(new TColumnValue(wrap(familyBname), wrap(qualifierBname),
|
||||
wrap(valueBname)));
|
||||
TPut put = new TPut(wrap(rowName), columnValues);
|
||||
|
||||
put.setColumnValues(columnValues);
|
||||
put.setCellVisibility(new TCellVisibility().setExpression("(" + SECRET + "|"
|
||||
+ CONFIDENTIAL + ")" + "&" + "!" + TOPSECRET));
|
||||
handler.put(table, put);
|
||||
TGet get = new TGet(wrap(rowName));
|
||||
TAuthorization tauth = new TAuthorization();
|
||||
List<String> labels = new ArrayList<String>();
|
||||
labels.add(SECRET);
|
||||
labels.add(PRIVATE);
|
||||
tauth.setLabels(labels);
|
||||
get.setAuthorizations(tauth);
|
||||
TResult result = handler.get(table, get);
|
||||
assertArrayEquals(rowName, result.getRow());
|
||||
List<TColumnValue> returnedColumnValues = result.getColumnValues();
|
||||
assertTColumnValuesEqual(columnValues, returnedColumnValues);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIncrementWithTags() throws Exception {
|
||||
ThriftHBaseServiceHandler handler = createHandler();
|
||||
byte[] rowName = "testIncrementWithTags".getBytes();
|
||||
ByteBuffer table = wrap(tableAname);
|
||||
|
||||
List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
|
||||
columnValues.add(new TColumnValue(wrap(familyAname), wrap(qualifierAname),
|
||||
wrap(Bytes.toBytes(1L))));
|
||||
TPut put = new TPut(wrap(rowName), columnValues);
|
||||
put.setColumnValues(columnValues);
|
||||
put.setCellVisibility(new TCellVisibility().setExpression(PRIVATE));
|
||||
handler.put(table, put);
|
||||
|
||||
List<TColumnIncrement> incrementColumns = new ArrayList<TColumnIncrement>();
|
||||
incrementColumns.add(new TColumnIncrement(wrap(familyAname),
|
||||
wrap(qualifierAname)));
|
||||
TIncrement increment = new TIncrement(wrap(rowName), incrementColumns);
|
||||
increment.setCellVisibility(new TCellVisibility().setExpression(SECRET));
|
||||
handler.increment(table, increment);
|
||||
|
||||
TGet get = new TGet(wrap(rowName));
|
||||
TAuthorization tauth = new TAuthorization();
|
||||
List<String> labels = new ArrayList<String>();
|
||||
labels.add(SECRET);
|
||||
tauth.setLabels(labels);
|
||||
get.setAuthorizations(tauth);
|
||||
TResult result = handler.get(table, get);
|
||||
|
||||
assertArrayEquals(rowName, result.getRow());
|
||||
assertEquals(1, result.getColumnValuesSize());
|
||||
TColumnValue columnValue = result.getColumnValues().get(0);
|
||||
assertArrayEquals(Bytes.toBytes(2L), columnValue.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIncrementWithTagsWithNotMatchLabels() throws Exception {
|
||||
ThriftHBaseServiceHandler handler = createHandler();
|
||||
byte[] rowName = "testIncrementWithTagsWithNotMatchLabels".getBytes();
|
||||
ByteBuffer table = wrap(tableAname);
|
||||
|
||||
List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
|
||||
columnValues.add(new TColumnValue(wrap(familyAname), wrap(qualifierAname),
|
||||
wrap(Bytes.toBytes(1L))));
|
||||
TPut put = new TPut(wrap(rowName), columnValues);
|
||||
put.setColumnValues(columnValues);
|
||||
put.setCellVisibility(new TCellVisibility().setExpression(PRIVATE));
|
||||
handler.put(table, put);
|
||||
|
||||
List<TColumnIncrement> incrementColumns = new ArrayList<TColumnIncrement>();
|
||||
incrementColumns.add(new TColumnIncrement(wrap(familyAname),
|
||||
wrap(qualifierAname)));
|
||||
TIncrement increment = new TIncrement(wrap(rowName), incrementColumns);
|
||||
increment.setCellVisibility(new TCellVisibility().setExpression(SECRET));
|
||||
handler.increment(table, increment);
|
||||
|
||||
TGet get = new TGet(wrap(rowName));
|
||||
TAuthorization tauth = new TAuthorization();
|
||||
List<String> labels = new ArrayList<String>();
|
||||
labels.add(PUBLIC);
|
||||
tauth.setLabels(labels);
|
||||
get.setAuthorizations(tauth);
|
||||
TResult result = handler.get(table, get);
|
||||
assertNull(result.getRow());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAppend() throws Exception {
|
||||
ThriftHBaseServiceHandler handler = createHandler();
|
||||
byte[] rowName = "testAppend".getBytes();
|
||||
ByteBuffer table = wrap(tableAname);
|
||||
byte[] v1 = Bytes.toBytes(1L);
|
||||
byte[] v2 = Bytes.toBytes(5L);
|
||||
List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
|
||||
columnValues.add(new TColumnValue(wrap(familyAname), wrap(qualifierAname),
|
||||
wrap(Bytes.toBytes(1L))));
|
||||
TPut put = new TPut(wrap(rowName), columnValues);
|
||||
put.setColumnValues(columnValues);
|
||||
put.setCellVisibility(new TCellVisibility().setExpression(PRIVATE));
|
||||
handler.put(table, put);
|
||||
|
||||
List<TColumnValue> appendColumns = new ArrayList<TColumnValue>();
|
||||
appendColumns.add(new TColumnValue(wrap(familyAname), wrap(qualifierAname),
|
||||
wrap(v2)));
|
||||
TAppend append = new TAppend(wrap(rowName), appendColumns);
|
||||
append.setCellVisibility(new TCellVisibility().setExpression(SECRET));
|
||||
handler.append(table, append);
|
||||
|
||||
TGet get = new TGet(wrap(rowName));
|
||||
TAuthorization tauth = new TAuthorization();
|
||||
List<String> labels = new ArrayList<String>();
|
||||
labels.add(SECRET);
|
||||
tauth.setLabels(labels);
|
||||
get.setAuthorizations(tauth);
|
||||
TResult result = handler.get(table, get);
|
||||
|
||||
assertArrayEquals(rowName, result.getRow());
|
||||
assertEquals(1, result.getColumnValuesSize());
|
||||
TColumnValue columnValue = result.getColumnValues().get(0);
|
||||
assertArrayEquals(Bytes.add(v1, v2), columnValue.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Padding numbers to make comparison of sort order easier in a for loop
|
||||
*
|
||||
* @param n
|
||||
* The number to pad.
|
||||
* @param pad
|
||||
* The length to pad up to.
|
||||
* @return The padded number as a string.
|
||||
*/
|
||||
private String pad(int n, byte pad) {
|
||||
String res = Integer.toString(n);
|
||||
while (res.length() < pad)
|
||||
res = "0" + res;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -156,6 +156,18 @@ In case the table goes out of date, the unit tests which check for accuracy of p
|
|||
| | mergeRegions | superuser\|global(A)
|
||||
| | rollWALWriterRequest | superuser\|global(A)
|
||||
| | replicateLogEntries | superuser\|global(W)
|
||||
|RSGroup |addRSGroup |superuser\|global(A)
|
||||
| |balanceRSGroup |superuser\|global(A)
|
||||
| |getRSGroupInfo |superuser\|global(A)
|
||||
| |getRSGroupInfoOfTable|superuser\|global(A)
|
||||
| |getRSGroupOfServer |superuser\|global(A)
|
||||
| |listRSGroups |superuser\|global(A)
|
||||
| |moveServers |superuser\|global(A)
|
||||
| |moveServersAndTables |superuser\|global(A)
|
||||
| |moveTables |superuser\|global(A)
|
||||
| |removeRSGroup |superuser\|global(A)
|
||||
| |removeServers |superuser\|global(A)
|
||||
|
||||
|===
|
||||
|
||||
:numbered:
|
||||
|
|
|
@ -782,6 +782,10 @@ For an example of using both together, see <<security.example.config>>.
|
|||
+
|
||||
[source,xml]
|
||||
----
|
||||
<property>
|
||||
<name>hbase.security.authorization</name>
|
||||
<value>true</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>hbase.coprocessor.region.classes</name>
|
||||
<value>org.apache.hadoop.hbase.security.access.AccessController, org.apache.hadoop.hbase.security.token.TokenProvider</value>
|
||||
|
@ -1177,6 +1181,10 @@ NOTE: Visibility labels are not currently applied for superusers.
|
|||
<property>
|
||||
<name>hbase.coprocessor.master.classes</name>
|
||||
<value>org.apache.hadoop.hbase.security.visibility.VisibilityController</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>hbase.security.authorization</name>
|
||||
<value>true</value>
|
||||
</property>
|
||||
----
|
||||
+
|
||||
|
@ -1650,6 +1658,10 @@ To enable secure bulk load, add the following properties to _hbase-site.xml_.
|
|||
<name>hbase.coprocessor.region.classes</name>
|
||||
<value>org.apache.hadoop.hbase.security.token.TokenProvider,
|
||||
org.apache.hadoop.hbase.security.access.AccessController,org.apache.hadoop.hbase.security.access.SecureBulkLoadEndpoint</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>hbase.security.authorization</name>
|
||||
<value>true</value>
|
||||
</property>
|
||||
----
|
||||
|
||||
|
@ -1745,6 +1757,10 @@ All options have been discussed separately in the sections above.
|
|||
<name>hbase.coprocessor.region.classes</name>
|
||||
<value>org.apache.hadoop.hbase.security.token.TokenProvider,
|
||||
org.apache.hadoop.hbase.security.access.AccessController,org.apache.hadoop.hbase.security.access.SecureBulkLoadEndpoint</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>hbase.security.authorization</name>
|
||||
<value>true</value>
|
||||
</property>
|
||||
----
|
||||
====
|
||||
|
|
Loading…
Reference in New Issue