1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.security.access;
20
21 import static org.junit.Assert.assertEquals;
22 import static org.junit.Assert.fail;
23
24 import java.io.IOException;
25 import java.lang.reflect.UndeclaredThrowableException;
26 import java.security.PrivilegedActionException;
27 import java.security.PrivilegedExceptionAction;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.concurrent.Callable;
31 import java.util.concurrent.CountDownLatch;
32
33 import org.apache.commons.logging.Log;
34 import org.apache.commons.logging.LogFactory;
35 import org.apache.hadoop.conf.Configuration;
36 import org.apache.hadoop.hbase.Coprocessor;
37 import org.apache.hadoop.hbase.HBaseTestingUtility;
38 import org.apache.hadoop.hbase.HConstants;
39 import org.apache.hadoop.hbase.HColumnDescriptor;
40 import org.apache.hadoop.hbase.HTableDescriptor;
41 import org.apache.hadoop.hbase.HRegionInfo;
42 import org.apache.hadoop.hbase.MiniHBaseCluster;
43 import org.apache.hadoop.hbase.NamespaceDescriptor;
44 import org.apache.hadoop.hbase.TableName;
45 import org.apache.hadoop.hbase.TableNotEnabledException;
46 import org.apache.hadoop.hbase.Waiter.Predicate;
47 import org.apache.hadoop.hbase.client.Connection;
48 import org.apache.hadoop.hbase.client.ConnectionFactory;
49 import org.apache.hadoop.hbase.client.RetriesExhaustedWithDetailsException;
50 import org.apache.hadoop.hbase.client.Admin;
51 import org.apache.hadoop.hbase.client.Table;
52 import org.apache.hadoop.hbase.coprocessor.BaseMasterObserver;
53 import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
54 import org.apache.hadoop.hbase.coprocessor.ObserverContext;
55 import org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment;
56 import org.apache.hadoop.hbase.io.hfile.HFile;
57 import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
58 import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos;
59 import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.AccessControlService;
60 import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.CheckPermissionsRequest;
61 import org.apache.hadoop.hbase.regionserver.Region;
62 import org.apache.hadoop.hbase.security.AccessDeniedException;
63 import org.apache.hadoop.hbase.security.User;
64 import org.apache.hadoop.hbase.security.access.Permission.Action;
65 import org.apache.hadoop.hbase.util.JVMClusterUtil.RegionServerThread;
66
67 import com.google.common.collect.Lists;
68 import com.google.common.collect.Maps;
69 import com.google.protobuf.BlockingRpcChannel;
70 import com.google.protobuf.ServiceException;
71
72
73
74
75 public class SecureTestUtil {
76
77 private static final Log LOG = LogFactory.getLog(SecureTestUtil.class);
78 private static final int WAIT_TIME = 10000;
79
80 public static void configureSuperuser(Configuration conf) throws IOException {
81
82
83
84
85 String currentUser = User.getCurrent().getName();
86 StringBuffer sb = new StringBuffer();
87 sb.append("admin,");
88 sb.append(currentUser);
89
90 for (int i = 0; i < 5; i++) {
91 sb.append(',');
92 sb.append(currentUser); sb.append(".hfs."); sb.append(i);
93 }
94 conf.set("hbase.superuser", sb.toString());
95 }
96
97 public static void enableSecurity(Configuration conf) throws IOException {
98 conf.set("hadoop.security.authorization", "false");
99 conf.set("hadoop.security.authentication", "simple");
100 conf.set(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY, AccessController.class.getName() +
101 "," + MasterSyncObserver.class.getName());
102 conf.set(CoprocessorHost.REGION_COPROCESSOR_CONF_KEY, AccessController.class.getName() +
103 "," + SecureBulkLoadEndpoint.class.getName());
104 conf.set(CoprocessorHost.REGIONSERVER_COPROCESSOR_CONF_KEY, AccessController.class.getName());
105
106 conf.setInt(HFile.FORMAT_VERSION_KEY, 3);
107 conf.setBoolean(User.HBASE_SECURITY_AUTHORIZATION_CONF_KEY, true);
108 configureSuperuser(conf);
109 }
110
111 public static void verifyConfiguration(Configuration conf) {
112 String coprocs = conf.get(CoprocessorHost.REGION_COPROCESSOR_CONF_KEY);
113 boolean accessControllerLoaded = false;
114 for (String coproc : coprocs.split(",")) {
115 try {
116 accessControllerLoaded = AccessController.class.isAssignableFrom(Class.forName(coproc));
117 if (accessControllerLoaded) break;
118 } catch (ClassNotFoundException cnfe) {
119 }
120 }
121 if (!(conf.get(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY).contains(
122 AccessController.class.getName())
123 && accessControllerLoaded && conf.get(
124 CoprocessorHost.REGIONSERVER_COPROCESSOR_CONF_KEY).contains(
125 AccessController.class.getName()))) {
126 throw new RuntimeException("AccessController is missing from a system coprocessor list");
127 }
128 if (conf.getInt(HFile.FORMAT_VERSION_KEY, 2) < HFile.MIN_FORMAT_VERSION_WITH_TAGS) {
129 throw new RuntimeException("Post 0.96 security features require HFile version >= 3");
130 }
131
132 if (!conf.getBoolean(User.HBASE_SECURITY_AUTHORIZATION_CONF_KEY, false)) {
133 throw new RuntimeException("Post 1.5.0 security features require set "
134 + User.HBASE_SECURITY_AUTHORIZATION_CONF_KEY + " to true");
135 }
136 }
137
138 public static void checkTablePerms(Configuration conf, TableName table, byte[] family, byte[] column,
139 Permission.Action... actions) throws IOException {
140 Permission[] perms = new Permission[actions.length];
141 for (int i = 0; i < actions.length; i++) {
142 perms[i] = new TablePermission(table, family, column, actions[i]);
143 }
144
145 checkTablePerms(conf, table, perms);
146 }
147
148 public static void checkTablePerms(Configuration conf, TableName table, Permission... perms)
149 throws IOException {
150 CheckPermissionsRequest.Builder request = CheckPermissionsRequest.newBuilder();
151 for (Permission p : perms) {
152 request.addPermission(ProtobufUtil.toPermission(p));
153 }
154 try (Connection connection = ConnectionFactory.createConnection(conf)) {
155 try (Table acl = connection.getTable(table)) {
156 AccessControlService.BlockingInterface protocol =
157 AccessControlService.newBlockingStub(acl.coprocessorService(new byte[0]));
158 try {
159 protocol.checkPermissions(null, request.build());
160 } catch (ServiceException se) {
161 ProtobufUtil.toIOException(se);
162 }
163 }
164 }
165 }
166
167
168
169
170
171
172
173
174
175
176
177 public static interface AccessTestAction extends PrivilegedExceptionAction<Object> { }
178
179
180 public static void verifyAllowed(User user, AccessTestAction... actions) throws Exception {
181 for (AccessTestAction action : actions) {
182 try {
183 Object obj = user.runAs(action);
184 if (obj != null && obj instanceof List<?>) {
185 List<?> results = (List<?>) obj;
186 if (results != null && results.isEmpty()) {
187 fail("Empty non null results from action for user '" + user.getShortName() + "'");
188 }
189 }
190 } catch (AccessDeniedException ade) {
191 fail("Expected action to pass for user '" + user.getShortName() + "' but was denied");
192 }
193 }
194 }
195
196
197 public static void verifyAllowed(AccessTestAction action, User... users) throws Exception {
198 for (User user : users) {
199 verifyAllowed(user, action);
200 }
201 }
202
203 public static void verifyAllowed(User user, AccessTestAction action, int count) throws Exception {
204 try {
205 Object obj = user.runAs(action);
206 if (obj != null && obj instanceof List<?>) {
207 List<?> results = (List<?>) obj;
208 if (results != null && results.isEmpty()) {
209 fail("Empty non null results from action for user '" + user.getShortName() + "'");
210 }
211 assertEquals(count, results.size());
212 }
213 } catch (AccessDeniedException ade) {
214 fail("Expected action to pass for user '" + user.getShortName() + "' but was denied");
215 }
216 }
217
218
219 public static void verifyDenied(AccessTestAction action, User... users) throws Exception {
220 for (User user : users) {
221 verifyDenied(user, action);
222 }
223 }
224
225
226 public static void verifyIfEmptyList(AccessTestAction action, User... users) throws Exception {
227 for (User user : users) {
228 try {
229 Object obj = user.runAs(action);
230 if (obj != null && obj instanceof List<?>) {
231 List<?> results = (List<?>) obj;
232 if (results != null && !results.isEmpty()) {
233 fail("Unexpected action results: " + results + " for user '"
234 + user.getShortName() + "'");
235 }
236 } else {
237 fail("Unexpected results for user '" + user.getShortName() + "'");
238 }
239 } catch (AccessDeniedException ade) {
240 fail("Expected action to pass for user '" + user.getShortName() + "' but was denied");
241 }
242 }
243 }
244
245
246 public static void verifyIfNull(AccessTestAction action, User... users) throws Exception {
247 for (User user : users) {
248 try {
249 Object obj = user.runAs(action);
250 if (obj != null) {
251 fail("Non null results from action for user '" + user.getShortName() + "' : " + obj);
252 }
253 } catch (AccessDeniedException ade) {
254 fail("Expected action to pass for user '" + user.getShortName() + "' but was denied");
255 }
256 }
257 }
258
259
260 public static void verifyDenied(User user, AccessTestAction... actions) throws Exception {
261 for (AccessTestAction action : actions) {
262 try {
263 user.runAs(action);
264 fail("Expected exception was not thrown for user '" + user.getShortName() + "'");
265 } catch (IOException e) {
266 boolean isAccessDeniedException = false;
267 if(e instanceof RetriesExhaustedWithDetailsException) {
268
269
270
271 for(Throwable ex : ((RetriesExhaustedWithDetailsException) e).getCauses()) {
272 if (ex instanceof AccessDeniedException) {
273 isAccessDeniedException = true;
274 break;
275 }
276 }
277 }
278 else {
279
280
281 Throwable ex = e;
282 do {
283 if (ex instanceof AccessDeniedException) {
284 isAccessDeniedException = true;
285 break;
286 }
287 } while((ex = ex.getCause()) != null);
288 }
289 if (!isAccessDeniedException) {
290 fail("Expected exception was not thrown for user '" + user.getShortName() + "'");
291 }
292 } catch (UndeclaredThrowableException ute) {
293
294 Throwable ex = ute.getUndeclaredThrowable();
295 if (ex instanceof PrivilegedActionException) {
296 ex = ((PrivilegedActionException) ex).getException();
297 }
298 if (ex instanceof ServiceException) {
299 ServiceException se = (ServiceException)ex;
300 if (se.getCause() != null && se.getCause() instanceof AccessDeniedException) {
301
302 return;
303 }
304 }
305 fail("Expected exception was not thrown for user '" + user.getShortName() + "'");
306 }
307 }
308 }
309
310 private static List<AccessController> getAccessControllers(MiniHBaseCluster cluster) {
311 List<AccessController> result = Lists.newArrayList();
312 for (RegionServerThread t: cluster.getLiveRegionServerThreads()) {
313 for (Region region: t.getRegionServer().getOnlineRegionsLocalContext()) {
314 Coprocessor cp = region.getCoprocessorHost()
315 .findCoprocessor(AccessController.class.getName());
316 if (cp != null) {
317 result.add((AccessController)cp);
318 }
319 }
320 }
321 return result;
322 }
323
324 private static Map<AccessController,Long> getAuthManagerMTimes(MiniHBaseCluster cluster) {
325 Map<AccessController,Long> result = Maps.newHashMap();
326 for (AccessController ac: getAccessControllers(cluster)) {
327 result.put(ac, ac.getAuthManager().getMTime());
328 }
329 return result;
330 }
331
332 @SuppressWarnings("rawtypes")
333 private static void updateACLs(final HBaseTestingUtility util, Callable c) throws Exception {
334
335 final Map<AccessController,Long> oldMTimes = getAuthManagerMTimes(util.getHBaseCluster());
336
337
338 c.call();
339
340
341 util.waitFor(WAIT_TIME, 100, new Predicate<IOException>() {
342 @Override
343 public boolean evaluate() throws IOException {
344 Map<AccessController,Long> mtimes = getAuthManagerMTimes(util.getHBaseCluster());
345 for (Map.Entry<AccessController,Long> e: mtimes.entrySet()) {
346 if (!oldMTimes.containsKey(e.getKey())) {
347 LOG.error("Snapshot of AccessController state does not include instance on region " +
348 e.getKey().getRegion().getRegionInfo().getRegionNameAsString());
349
350 return false;
351 }
352 long old = oldMTimes.get(e.getKey());
353 long now = e.getValue();
354 if (now <= old) {
355 LOG.info("AccessController on region " +
356 e.getKey().getRegion().getRegionInfo().getRegionNameAsString() +
357 " has not updated: mtime=" + now);
358 return false;
359 }
360 }
361 return true;
362 }
363 });
364 }
365
366
367
368
369
370
371 public static void grantGlobal(final HBaseTestingUtility util, final String user,
372 final Permission.Action... actions) throws Exception {
373 SecureTestUtil.updateACLs(util, new Callable<Void>() {
374 @Override
375 public Void call() throws Exception {
376 try (Connection connection = ConnectionFactory.createConnection(util.getConfiguration())) {
377 try (Table acl = connection.getTable(AccessControlLists.ACL_TABLE_NAME)) {
378 BlockingRpcChannel service = acl.coprocessorService(HConstants.EMPTY_START_ROW);
379 AccessControlService.BlockingInterface protocol =
380 AccessControlService.newBlockingStub(service);
381 ProtobufUtil.grant(null, protocol, user, false, actions);
382 }
383 }
384 return null;
385 }
386 });
387 }
388
389
390
391
392
393
394 public static void revokeGlobal(final HBaseTestingUtility util, final String user,
395 final Permission.Action... actions) throws Exception {
396 SecureTestUtil.updateACLs(util, new Callable<Void>() {
397 @Override
398 public Void call() throws Exception {
399 try (Connection connection = ConnectionFactory.createConnection(util.getConfiguration())) {
400 try (Table acl = connection.getTable(AccessControlLists.ACL_TABLE_NAME)) {
401 BlockingRpcChannel service = acl.coprocessorService(HConstants.EMPTY_START_ROW);
402 AccessControlService.BlockingInterface protocol =
403 AccessControlService.newBlockingStub(service);
404 ProtobufUtil.revoke(null, protocol, user, actions);
405 }
406 }
407 return null;
408 }
409 });
410 }
411
412
413
414
415
416
417 public static void grantOnNamespace(final HBaseTestingUtility util, final String user,
418 final String namespace, final Permission.Action... actions) throws Exception {
419 SecureTestUtil.updateACLs(util, new Callable<Void>() {
420 @Override
421 public Void call() throws Exception {
422 try (Connection connection = ConnectionFactory.createConnection(util.getConfiguration())) {
423 try (Table acl = connection.getTable(AccessControlLists.ACL_TABLE_NAME)) {
424 BlockingRpcChannel service = acl.coprocessorService(HConstants.EMPTY_START_ROW);
425 AccessControlService.BlockingInterface protocol =
426 AccessControlService.newBlockingStub(service);
427 ProtobufUtil.grant(null, protocol, user, namespace, false, actions);
428 }
429 }
430 return null;
431 }
432 });
433 }
434
435
436
437
438
439
440 public static void grantOnNamespaceUsingAccessControlClient(final HBaseTestingUtility util,
441 final Connection connection, final String user, final String namespace,
442 final Permission.Action... actions) throws Exception {
443 SecureTestUtil.updateACLs(util, new Callable<Void>() {
444 @Override
445 public Void call() throws Exception {
446 try {
447 AccessControlClient.grant(connection, namespace, user, actions);
448 } catch (Throwable t) {
449 LOG.error("grant failed: ", t);
450 }
451 return null;
452 }
453 });
454 }
455
456 public static void grantOnNamespaceUsingAccessControlClient(final HBaseTestingUtility util,
457 final Connection connection, final String user, final String namespace,
458 final boolean mergeExistingPermissions, final Permission.Action... actions) throws Exception {
459 SecureTestUtil.updateACLs(util, new Callable<Void>() {
460 @Override
461 public Void call() throws Exception {
462 try {
463 AccessControlClient.grant(connection, namespace, user, mergeExistingPermissions, actions);
464 } catch (Throwable t) {
465 LOG.error("grant failed: ", t);
466 }
467 return null;
468 }
469 });
470 }
471
472
473
474
475
476
477 public static void revokeFromNamespaceUsingAccessControlClient(final HBaseTestingUtility util,
478 final Connection connection, final String user, final String namespace,
479 final Permission.Action... actions) throws Exception {
480 SecureTestUtil.updateACLs(util, new Callable<Void>() {
481 @Override
482 public Void call() throws Exception {
483 try {
484 AccessControlClient.revoke(connection, namespace, user, actions);
485 } catch (Throwable t) {
486 LOG.error("revoke failed: ", t);
487 }
488 return null;
489 }
490 });
491 }
492
493
494
495
496
497
498 public static void revokeFromNamespace(final HBaseTestingUtility util, final String user,
499 final String namespace, final Permission.Action... actions) throws Exception {
500 SecureTestUtil.updateACLs(util, new Callable<Void>() {
501 @Override
502 public Void call() throws Exception {
503 try (Connection connection = ConnectionFactory.createConnection(util.getConfiguration())) {
504 try (Table acl = connection.getTable(AccessControlLists.ACL_TABLE_NAME)) {
505 BlockingRpcChannel service = acl.coprocessorService(HConstants.EMPTY_START_ROW);
506 AccessControlService.BlockingInterface protocol =
507 AccessControlService.newBlockingStub(service);
508 ProtobufUtil.revoke(null, protocol, user, namespace, actions);
509 }
510 }
511 return null;
512 }
513 });
514 }
515
516
517
518
519
520
521 public static void grantOnTable(final HBaseTestingUtility util, final String user,
522 final TableName table, final byte[] family, final byte[] qualifier,
523 final Permission.Action... actions) throws Exception {
524 SecureTestUtil.updateACLs(util, new Callable<Void>() {
525 @Override
526 public Void call() throws Exception {
527 try (Connection connection = ConnectionFactory.createConnection(util.getConfiguration())) {
528 try (Table acl = connection.getTable(AccessControlLists.ACL_TABLE_NAME)) {
529 BlockingRpcChannel service = acl.coprocessorService(HConstants.EMPTY_START_ROW);
530 AccessControlService.BlockingInterface protocol =
531 AccessControlService.newBlockingStub(service);
532 ProtobufUtil.grant(null, protocol, user, table, family, qualifier, false, actions);
533 }
534 }
535 return null;
536 }
537 });
538 }
539
540
541
542
543
544
545 public static void grantOnTableUsingAccessControlClient(final HBaseTestingUtility util,
546 final Connection connection, final String user, final TableName table, final byte[] family,
547 final byte[] qualifier, final Permission.Action... actions) throws Exception {
548 SecureTestUtil.updateACLs(util, new Callable<Void>() {
549 @Override
550 public Void call() throws Exception {
551 try {
552 AccessControlClient.grant(connection, table, user, family, qualifier, actions);
553 } catch (Throwable t) {
554 LOG.error("grant failed: ", t);
555 }
556 return null;
557 }
558 });
559 }
560
561 public static void grantOnTableUsingAccessControlClient(final HBaseTestingUtility util,
562 final Connection connection, final String user, final TableName table, final byte[] family,
563 final byte[] qualifier, final boolean mergeExistingPermissions,
564 final Permission.Action... actions) throws Exception {
565 SecureTestUtil.updateACLs(util, new Callable<Void>() {
566 @Override
567 public Void call() throws Exception {
568 try {
569 AccessControlClient.grant(connection, table, user, family, qualifier,
570 mergeExistingPermissions, actions);
571 } catch (Throwable t) {
572 LOG.error("grant failed: ", t);
573 }
574 return null;
575 }
576 });
577 }
578
579
580
581
582
583
584
585
586 public static void grantGlobalUsingAccessControlClient(final HBaseTestingUtility util,
587 final Connection connection, final String user, final Permission.Action... actions)
588 throws Exception {
589 SecureTestUtil.updateACLs(util, new Callable<Void>() {
590 @Override
591 public Void call() throws Exception {
592 try {
593 AccessControlClient.grant(connection, user, actions);
594 } catch (Throwable t) {
595 LOG.error("grant failed: ", t);
596 }
597 return null;
598 }
599 });
600 }
601
602 public static void grantGlobalUsingAccessControlClient(final HBaseTestingUtility util,
603 final Connection connection, final String user, final boolean mergeExistingPermissions,
604 final Permission.Action... actions) throws Exception {
605 SecureTestUtil.updateACLs(util, new Callable<Void>() {
606 @Override
607 public Void call() throws Exception {
608 try {
609 AccessControlClient.grant(connection, user, mergeExistingPermissions, actions);
610 } catch (Throwable t) {
611 LOG.error("grant failed: ", t);
612 }
613 return null;
614 }
615 });
616 }
617
618
619
620
621
622
623 public static void revokeFromTable(final HBaseTestingUtility util, final String user,
624 final TableName table, final byte[] family, final byte[] qualifier,
625 final Permission.Action... actions) throws Exception {
626 SecureTestUtil.updateACLs(util, new Callable<Void>() {
627 @Override
628 public Void call() throws Exception {
629 try (Connection connection = ConnectionFactory.createConnection(util.getConfiguration())) {
630 try (Table acl = connection.getTable(AccessControlLists.ACL_TABLE_NAME)) {
631 BlockingRpcChannel service = acl.coprocessorService(HConstants.EMPTY_START_ROW);
632 AccessControlService.BlockingInterface protocol =
633 AccessControlService.newBlockingStub(service);
634 ProtobufUtil.revoke(null, protocol, user, table, family, qualifier, actions);
635 }
636 }
637 return null;
638 }
639 });
640 }
641
642
643
644
645
646
647 public static void revokeFromTableUsingAccessControlClient(final HBaseTestingUtility util,
648 final Connection connection, final String user, final TableName table, final byte[] family,
649 final byte[] qualifier, final Permission.Action... actions) throws Exception {
650 SecureTestUtil.updateACLs(util, new Callable<Void>() {
651 @Override
652 public Void call() throws Exception {
653 try {
654 AccessControlClient.revoke(connection, table, user, family, qualifier, actions);
655 } catch (Throwable t) {
656 LOG.error("revoke failed: ", t);
657 }
658 return null;
659 }
660 });
661 }
662
663
664
665
666
667
668 public static void revokeGlobalUsingAccessControlClient(final HBaseTestingUtility util,
669 final Connection connection, final String user,final Permission.Action... actions)
670 throws Exception {
671 SecureTestUtil.updateACLs(util, new Callable<Void>() {
672 @Override
673 public Void call() throws Exception {
674 try {
675 AccessControlClient.revoke(connection, user, actions);
676 } catch (Throwable t) {
677 LOG.error("revoke failed: ", t);
678 }
679 return null;
680 }
681 });
682 }
683
684 public static class MasterSyncObserver extends BaseMasterObserver {
685 volatile CountDownLatch tableCreationLatch = null;
686 volatile CountDownLatch tableDeletionLatch = null;
687
688 @Override
689 public void postCreateTableHandler(
690 final ObserverContext<MasterCoprocessorEnvironment> ctx,
691 HTableDescriptor desc, HRegionInfo[] regions) throws IOException {
692
693 if (tableCreationLatch != null) {
694 tableCreationLatch.countDown();
695 }
696 }
697
698 @Override
699 public void postDeleteTableHandler(
700 final ObserverContext<MasterCoprocessorEnvironment> ctx, TableName tableName)
701 throws IOException {
702
703 if (tableDeletionLatch != null) {
704 tableDeletionLatch.countDown();
705 }
706 }
707 }
708
709 public static Table createTable(HBaseTestingUtility testUtil, TableName tableName,
710 byte[][] families) throws Exception {
711 HTableDescriptor htd = new HTableDescriptor(tableName);
712 for (byte[] family : families) {
713 HColumnDescriptor hcd = new HColumnDescriptor(family);
714 htd.addFamily(hcd);
715 }
716 createTable(testUtil, testUtil.getHBaseAdmin(), htd);
717 return testUtil.getConnection().getTable(htd.getTableName());
718 }
719
720 public static void createTable(HBaseTestingUtility testUtil, HTableDescriptor htd)
721 throws Exception {
722 createTable(testUtil, testUtil.getHBaseAdmin(), htd);
723 }
724
725 public static void createTable(HBaseTestingUtility testUtil, HTableDescriptor htd,
726 byte[][] splitKeys) throws Exception {
727 createTable(testUtil, testUtil.getHBaseAdmin(), htd, splitKeys);
728 }
729
730 public static void createTable(HBaseTestingUtility testUtil, Admin admin, HTableDescriptor htd)
731 throws Exception {
732 createTable(testUtil, admin, htd, null);
733 }
734
735 public static void createTable(HBaseTestingUtility testUtil, Admin admin, HTableDescriptor htd,
736 byte[][] splitKeys) throws Exception {
737
738
739 MasterSyncObserver observer = (MasterSyncObserver)testUtil.getHBaseCluster().getMaster()
740 .getMasterCoprocessorHost().findCoprocessor(MasterSyncObserver.class.getName());
741 observer.tableCreationLatch = new CountDownLatch(1);
742 if (splitKeys != null) {
743 admin.createTable(htd, splitKeys);
744 } else {
745 admin.createTable(htd);
746 }
747 observer.tableCreationLatch.await();
748 observer.tableCreationLatch = null;
749 testUtil.waitUntilAllRegionsAssigned(htd.getTableName());
750 }
751
752 public static void deleteTable(HBaseTestingUtility testUtil, TableName tableName)
753 throws Exception {
754 deleteTable(testUtil, testUtil.getHBaseAdmin(), tableName);
755 }
756
757 public static void createNamespace(HBaseTestingUtility testUtil, NamespaceDescriptor nsDesc)
758 throws Exception {
759 testUtil.getHBaseAdmin().createNamespace(nsDesc);
760 }
761
762 public static void deleteNamespace(HBaseTestingUtility testUtil, String namespace)
763 throws Exception {
764 testUtil.getHBaseAdmin().deleteNamespace(namespace);
765 }
766
767 public static void deleteTable(HBaseTestingUtility testUtil, Admin admin, TableName tableName)
768 throws Exception {
769
770
771 MasterSyncObserver observer = (MasterSyncObserver)testUtil.getHBaseCluster().getMaster()
772 .getMasterCoprocessorHost().findCoprocessor(MasterSyncObserver.class.getName());
773 observer.tableDeletionLatch = new CountDownLatch(1);
774 try {
775 admin.disableTable(tableName);
776 } catch (TableNotEnabledException e) {
777 LOG.debug("Table: " + tableName + " already disabled, so just deleting it.");
778 }
779 admin.deleteTable(tableName);
780 observer.tableDeletionLatch.await();
781 observer.tableDeletionLatch = null;
782 }
783
784 public static String convertToNamespace(String namespace) {
785 return AccessControlLists.NAMESPACE_PREFIX + namespace;
786 }
787
788 public static void checkGlobalPerms(HBaseTestingUtility testUtil, Permission.Action... actions)
789 throws IOException {
790 Permission[] perms = new Permission[actions.length];
791 for (int i = 0; i < actions.length; i++) {
792 perms[i] = new Permission(actions[i]);
793 }
794 CheckPermissionsRequest.Builder request = CheckPermissionsRequest.newBuilder();
795 for (Action a : actions) {
796 request.addPermission(AccessControlProtos.Permission.newBuilder()
797 .setType(AccessControlProtos.Permission.Type.Global)
798 .setGlobalPermission(
799 AccessControlProtos.GlobalPermission.newBuilder()
800 .addAction(ProtobufUtil.toPermissionAction(a)).build()));
801 }
802 try(Connection conn = ConnectionFactory.createConnection(testUtil.getConfiguration());
803 Table acl = conn.getTable(AccessControlLists.ACL_TABLE_NAME)) {
804 BlockingRpcChannel channel = acl.coprocessorService(new byte[0]);
805 AccessControlService.BlockingInterface protocol =
806 AccessControlService.newBlockingStub(channel);
807 try {
808 protocol.checkPermissions(null, request.build());
809 } catch (ServiceException se) {
810 ProtobufUtil.toIOException(se);
811 }
812 }
813 }
814
815 public static void checkTablePerms(HBaseTestingUtility testUtil, TableName table, byte[] family,
816 byte[] column, Permission.Action... actions) throws IOException {
817 Permission[] perms = new Permission[actions.length];
818 for (int i = 0; i < actions.length; i++) {
819 perms[i] = new TablePermission(table, family, column, actions[i]);
820 }
821 checkTablePerms(testUtil, table, perms);
822 }
823
824 public static void checkTablePerms(HBaseTestingUtility testUtil, TableName table,
825 Permission... perms) throws IOException {
826 CheckPermissionsRequest.Builder request = CheckPermissionsRequest.newBuilder();
827 for (Permission p : perms) {
828 request.addPermission(ProtobufUtil.toPermission(p));
829 }
830
831 try(Connection conn = ConnectionFactory.createConnection(testUtil.getConfiguration());
832 Table acl = conn.getTable(table)) {
833 AccessControlService.BlockingInterface protocol =
834 AccessControlService.newBlockingStub(acl.coprocessorService(new byte[0]));
835 try {
836 protocol.checkPermissions(null, request.build());
837 } catch (ServiceException se) {
838 ProtobufUtil.toIOException(se);
839 }
840 }
841 }
842
843 }