001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.security.access; 019 020import static org.apache.hadoop.hbase.security.access.Permission.Action.READ; 021import static org.apache.hadoop.hbase.security.access.SnapshotScannerHDFSAclController.SnapshotScannerHDFSAclStorage.hasUserTableHdfsAcl; 022import static org.junit.jupiter.api.Assertions.assertFalse; 023import static org.junit.jupiter.api.Assertions.assertTrue; 024 025import org.apache.hadoop.conf.Configuration; 026import org.apache.hadoop.fs.FileSystem; 027import org.apache.hadoop.fs.Path; 028import org.apache.hadoop.fs.permission.FsPermission; 029import org.apache.hadoop.hbase.HBaseTestingUtil; 030import org.apache.hadoop.hbase.TableName; 031import org.apache.hadoop.hbase.client.Admin; 032import org.apache.hadoop.hbase.client.Table; 033import org.apache.hadoop.hbase.coprocessor.CoprocessorHost; 034import org.apache.hadoop.hbase.security.User; 035import org.apache.hadoop.hbase.testclassification.LargeTests; 036import org.apache.hadoop.hbase.testclassification.SecurityTests; 037import org.junit.jupiter.api.AfterAll; 038import org.junit.jupiter.api.BeforeAll; 039import org.junit.jupiter.api.Tag; 040import org.junit.jupiter.api.Test; 041import org.junit.jupiter.api.TestInfo; 042import org.slf4j.Logger; 043import org.slf4j.LoggerFactory; 044 045/** 046 * Separated from {@link TestSnapshotScannerHDFSAclController}. Uses facility from that class. 047 * @see TestSnapshotScannerHDFSAclController 048 */ 049@Tag(SecurityTests.TAG) 050@Tag(LargeTests.TAG) 051public class TestSnapshotScannerHDFSAclController2 { 052 private static final Logger LOG = 053 LoggerFactory.getLogger(TestSnapshotScannerHDFSAclController2.class); 054 055 private static final String UN_GRANT_USER = "un_grant_user"; 056 private static HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil(); 057 private static Configuration conf = TEST_UTIL.getConfiguration(); 058 private static Admin admin = null; 059 private static SnapshotScannerHDFSAclHelper helper; 060 private static Table aclTable; 061 private static FileSystem FS; 062 063 @BeforeAll 064 public static void setupBeforeClass() throws Exception { 065 // enable hdfs acl and set umask to 027 066 conf.setBoolean("dfs.namenode.acls.enabled", true); 067 conf.set("fs.permissions.umask-mode", "027"); 068 // enable hbase hdfs acl feature 069 conf.setBoolean(SnapshotScannerHDFSAclHelper.ACL_SYNC_TO_HDFS_ENABLE, true); 070 // enable secure 071 conf.set(User.HBASE_SECURITY_CONF_KEY, "simple"); 072 conf.set(SnapshotScannerHDFSAclHelper.SNAPSHOT_RESTORE_TMP_DIR, 073 SnapshotScannerHDFSAclHelper.SNAPSHOT_RESTORE_TMP_DIR_DEFAULT); 074 SecureTestUtil.enableSecurity(conf); 075 // add SnapshotScannerHDFSAclController coprocessor 076 conf.set(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY, 077 conf.get(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY) + "," 078 + SnapshotScannerHDFSAclController.class.getName()); 079 080 TEST_UTIL.startMiniCluster(); 081 SnapshotScannerHDFSAclController coprocessor = TEST_UTIL.getHBaseCluster().getMaster() 082 .getMasterCoprocessorHost().findCoprocessor(SnapshotScannerHDFSAclController.class); 083 TEST_UTIL.waitFor(30000, () -> coprocessor.checkInitialized("check initialized")); 084 TEST_UTIL.waitTableAvailable(PermissionStorage.ACL_TABLE_NAME); 085 086 admin = TEST_UTIL.getAdmin(); 087 Path rootDir = TEST_UTIL.getDefaultRootDirPath(); 088 FS = rootDir.getFileSystem(conf); 089 User unGrantUser = User.createUserForTesting(conf, UN_GRANT_USER, new String[] {}); 090 helper = new SnapshotScannerHDFSAclHelper(conf, admin.getConnection()); 091 092 // set hbase directory permission 093 FsPermission commonDirectoryPermission = 094 new FsPermission(conf.get(SnapshotScannerHDFSAclHelper.COMMON_DIRECTORY_PERMISSION, 095 SnapshotScannerHDFSAclHelper.COMMON_DIRECTORY_PERMISSION_DEFAULT)); 096 Path path = rootDir; 097 while (path != null) { 098 FS.setPermission(path, commonDirectoryPermission); 099 path = path.getParent(); 100 } 101 // set restore directory permission 102 Path restoreDir = new Path(SnapshotScannerHDFSAclHelper.SNAPSHOT_RESTORE_TMP_DIR_DEFAULT); 103 if (!FS.exists(restoreDir)) { 104 FS.mkdirs(restoreDir); 105 FS.setPermission(restoreDir, 106 new FsPermission( 107 conf.get(SnapshotScannerHDFSAclHelper.SNAPSHOT_RESTORE_DIRECTORY_PERMISSION, 108 SnapshotScannerHDFSAclHelper.SNAPSHOT_RESTORE_DIRECTORY_PERMISSION_DEFAULT))); 109 } 110 path = restoreDir.getParent(); 111 while (path != null) { 112 FS.setPermission(path, commonDirectoryPermission); 113 path = path.getParent(); 114 } 115 aclTable = admin.getConnection().getTable(PermissionStorage.ACL_TABLE_NAME); 116 } 117 118 @AfterAll 119 public static void tearDownAfterClass() throws Exception { 120 TEST_UTIL.shutdownMiniCluster(); 121 } 122 123 @Test 124 public void testRestoreSnapshot(TestInfo testInfo) throws Exception { 125 final String grantUserName = testInfo.getTestMethod().get().getName(); 126 User grantUser = User.createUserForTesting(conf, grantUserName, new String[] {}); 127 String namespace = testInfo.getTestMethod().get().getName(); 128 TableName table = TableName.valueOf(namespace, testInfo.getTestMethod().get().getName()); 129 String snapshot = namespace + "s1"; 130 String snapshot2 = namespace + "s2"; 131 String snapshot3 = namespace + "s3"; 132 133 LOG.info("Create {}", table); 134 try (Table t = TestHDFSAclHelper.createTable(TEST_UTIL, table)) { 135 TestHDFSAclHelper.put(t); 136 // grant t1, snapshot 137 LOG.info("Grant {}", table); 138 TestHDFSAclHelper.grantOnTable(TEST_UTIL, grantUserName, table, READ); 139 admin.snapshot(snapshot, table); 140 // delete 141 admin.disableTable(table); 142 admin.deleteTable(table); 143 LOG.info("Before scan of shapshot! {}", table); 144 TestHDFSAclHelper.canUserScanSnapshot(TEST_UTIL, grantUser, snapshot, -1); 145 146 // restore snapshot and restore acl 147 admin.restoreSnapshot(snapshot, true, true); 148 TestHDFSAclHelper.put2(t); 149 // snapshot 150 admin.snapshot(snapshot2, table); 151 TestHDFSAclHelper.canUserScanSnapshot(TEST_UTIL, grantUser, snapshot, 6); 152 TestHDFSAclHelper.canUserScanSnapshot(TEST_UTIL, grantUser, snapshot2, 10); 153 assertTrue(hasUserTableHdfsAcl(aclTable, grantUserName, table)); 154 TestSnapshotScannerHDFSAclController.checkUserAclEntry(FS, 155 helper.getTableRootPaths(table, false), grantUserName, true, true); 156 157 // delete 158 admin.disableTable(table); 159 admin.deleteTable(table); 160 // restore snapshot and skip restore acl 161 admin.restoreSnapshot(snapshot); 162 admin.snapshot(snapshot3, table); 163 164 LOG.info("CHECK"); 165 TestHDFSAclHelper.canUserScanSnapshot(TEST_UTIL, grantUser, snapshot, -1); 166 TestHDFSAclHelper.canUserScanSnapshot(TEST_UTIL, grantUser, snapshot2, -1); 167 TestHDFSAclHelper.canUserScanSnapshot(TEST_UTIL, grantUser, snapshot3, -1); 168 assertFalse(hasUserTableHdfsAcl(aclTable, grantUserName, table)); 169 TestSnapshotScannerHDFSAclController.checkUserAclEntry(FS, 170 helper.getPathHelper().getDataTableDir(table), grantUserName, false, false); 171 TestSnapshotScannerHDFSAclController.checkUserAclEntry(FS, 172 helper.getPathHelper().getArchiveTableDir(table), grantUserName, true, false); 173 } 174 } 175}