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