HBASE-11013: Clone Snapshots on Secure Cluster Should provide option to apply Retained User Permissions
Signed-off-by: Guanghao Zhang <zg...@apache.org> Project: http://git-wip-us.apache.org/repos/asf/hbase/repo Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/37dd8ff7 Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/37dd8ff7 Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/37dd8ff7 Branch: refs/heads/master Commit: 37dd8ff722fa762d9ef86488dea90e5470672e67 Parents: 32d2062 Author: huzheng <open...@gmail.com> Authored: Mon May 8 21:01:47 2017 +0800 Committer: Guanghao Zhang <zg...@apache.org> Committed: Thu May 18 17:39:50 2017 +0800 ---------------------------------------------------------------------- .../org/apache/hadoop/hbase/client/Admin.java | 30 + .../hadoop/hbase/client/AsyncHBaseAdmin.java | 5 +- .../apache/hadoop/hbase/client/HBaseAdmin.java | 55 +- .../access/ShadedAccessControlUtil.java | 277 + .../hbase/security/access/TablePermission.java | 4 + .../hbase/shaded/protobuf/ProtobufUtil.java | 20 +- .../ClientSnapshotDescriptionUtils.java | 5 +- .../protobuf/generated/AccessControlProtos.java | 11171 +++++++++++++++++ .../shaded/protobuf/generated/AdminProtos.java | 2 - .../shaded/protobuf/generated/HBaseProtos.java | 1393 +- .../generated/MasterProcedureProtos.java | 516 +- .../shaded/protobuf/generated/MasterProtos.java | 1191 +- .../protobuf/generated/SnapshotProtos.java | 1585 ++- .../src/main/protobuf/AccessControl.proto | 130 + .../src/main/protobuf/HBase.proto | 17 +- .../src/main/protobuf/Master.proto | 2 + .../src/main/protobuf/MasterProcedure.proto | 3 + .../src/main/protobuf/Snapshot.proto | 19 + .../hbase/rsgroup/RSGroupAdminEndpoint.java | 4 +- .../hadoop/hbase/backup/util/RestoreTool.java | 4 +- .../hbase/coprocessor/MasterObserver.java | 2 +- .../mapreduce/TableSnapshotInputFormatImpl.java | 2 +- .../org/apache/hadoop/hbase/master/HMaster.java | 7 +- .../hbase/master/MasterCoprocessorHost.java | 2 +- .../hadoop/hbase/master/MasterRpcServices.java | 6 +- .../hadoop/hbase/master/SnapshotSentinel.java | 2 +- .../procedure/CloneSnapshotProcedure.java | 24 +- .../procedure/RestoreSnapshotProcedure.java | 25 +- .../snapshot/DisabledTableSnapshotHandler.java | 2 +- .../snapshot/EnabledTableSnapshotHandler.java | 2 +- .../master/snapshot/MasterSnapshotVerifier.java | 2 +- .../hbase/master/snapshot/SnapshotManager.java | 46 +- .../master/snapshot/TakeSnapshotHandler.java | 2 +- .../hadoop/hbase/regionserver/HRegion.java | 2 +- .../snapshot/FlushSnapshotSubprocedure.java | 2 +- .../snapshot/RegionServerSnapshotManager.java | 2 +- .../security/access/AccessControlLists.java | 2 +- .../hbase/security/access/AccessController.java | 2 +- .../hadoop/hbase/snapshot/ExportSnapshot.java | 2 +- .../hbase/snapshot/RestoreSnapshotHelper.java | 29 +- .../snapshot/SnapshotDescriptionUtils.java | 44 +- .../hadoop/hbase/snapshot/SnapshotInfo.java | 21 +- .../hadoop/hbase/snapshot/SnapshotManifest.java | 2 +- .../hbase/snapshot/SnapshotManifestV1.java | 2 +- .../hbase/snapshot/SnapshotManifestV2.java | 4 +- .../hbase/snapshot/SnapshotReferenceUtil.java | 2 +- .../hbase-webapps/master/snapshotsStats.jsp | 5 +- .../hbase/client/TestSnapshotWithAcl.java | 240 + .../hbase/coprocessor/TestMasterObserver.java | 2 +- .../master/cleaner/TestSnapshotFromMaster.java | 2 +- .../procedure/TestCloneSnapshotProcedure.java | 13 +- .../procedure/TestRestoreSnapshotProcedure.java | 3 +- .../hbase/security/access/SecureTestUtil.java | 2 +- .../security/access/TestAccessController.java | 3 +- .../access/TestWithDisabledAuthorization.java | 2 +- .../hbase/snapshot/SnapshotTestingUtils.java | 34 +- .../hbase/snapshot/TestExportSnapshot.java | 2 +- .../snapshot/TestFlushSnapshotFromClient.java | 5 +- .../snapshot/TestRestoreSnapshotHelper.java | 2 +- .../snapshot/TestSnapshotClientRetries.java | 2 +- .../snapshot/TestSnapshotDescriptionUtils.java | 4 +- .../hbase/snapshot/TestSnapshotManifest.java | 2 +- hbase-shell/src/main/ruby/hbase/admin.rb | 10 +- hbase-shell/src/main/ruby/hbase_constants.rb | 1 + .../main/ruby/shell/commands/clone_snapshot.rb | 11 +- .../ruby/shell/commands/restore_snapshot.rb | 10 +- .../hbase/client/TestReplicationShell.java | 1 - 67 files changed, 14677 insertions(+), 2352 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/hbase/blob/37dd8ff7/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Admin.java ---------------------------------------------------------------------- diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Admin.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Admin.java index 6e7c566..9300372 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Admin.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Admin.java @@ -1521,6 +1521,23 @@ public interface Admin extends Abortable, Closeable { throws IOException, RestoreSnapshotException; /** + * Restore the specified snapshot on the original table. (The table must be disabled) If + * 'takeFailSafeSnapshot' is set to true, a snapshot of the current table is taken before + * executing the restore operation. In case of restore failure, the failsafe snapshot will be + * restored. If the restore completes without problem the failsafe snapshot is deleted. The + * failsafe snapshot name is configurable by using the property + * "hbase.snapshot.restore.failsafe.name". + * @param snapshotName name of the snapshot to restore + * @param takeFailSafeSnapshot true if the failsafe snapshot should be taken + * @param restoreAcl true to restore acl of snapshot + * @throws IOException if a remote or network exception occurs + * @throws RestoreSnapshotException if snapshot failed to be restored + * @throws IllegalArgumentException if the restore request is formatted incorrectly + */ + void restoreSnapshot(final String snapshotName, final boolean takeFailSafeSnapshot, + final boolean restoreAcl) throws IOException, RestoreSnapshotException; + + /** * Create a new table by cloning the snapshot content. * * @param snapshotName name of the snapshot to be cloned @@ -1535,6 +1552,19 @@ public interface Admin extends Abortable, Closeable { /** * Create a new table by cloning the snapshot content. + * @param snapshotName name of the snapshot to be cloned + * @param tableName name of the table where the snapshot will be restored + * @param restoreAcl true to clone acl into newly created table + * @throws IOException if a remote or network exception occurs + * @throws TableExistsException if table to be created already exists + * @throws RestoreSnapshotException if snapshot failed to be cloned + * @throws IllegalArgumentException if the specified table has not a valid name + */ + void cloneSnapshot(final String snapshotName, final TableName tableName, final boolean restoreAcl) + throws IOException, TableExistsException, RestoreSnapshotException; + + /** + * Create a new table by cloning the snapshot content. * * @param snapshotName name of the snapshot to be cloned * @param tableName name of the table where the snapshot will be restored http://git-wip-us.apache.org/repos/asf/hbase/blob/37dd8ff7/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncHBaseAdmin.java ---------------------------------------------------------------------- diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncHBaseAdmin.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncHBaseAdmin.java index baad871..5e64fa3 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncHBaseAdmin.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncHBaseAdmin.java @@ -178,6 +178,7 @@ import org.apache.hadoop.hbase.shaded.protobuf.generated.ReplicationProtos.Remov import org.apache.hadoop.hbase.shaded.protobuf.generated.ReplicationProtos.RemoveReplicationPeerResponse; import org.apache.hadoop.hbase.shaded.protobuf.generated.ReplicationProtos.UpdateReplicationPeerConfigRequest; import org.apache.hadoop.hbase.shaded.protobuf.generated.ReplicationProtos.UpdateReplicationPeerConfigResponse; +import org.apache.hadoop.hbase.shaded.protobuf.generated.SnapshotProtos; import org.apache.hadoop.hbase.snapshot.ClientSnapshotDescriptionUtils; import org.apache.hadoop.hbase.snapshot.RestoreSnapshotException; import org.apache.hadoop.hbase.snapshot.SnapshotCreationException; @@ -1706,7 +1707,7 @@ public class AsyncHBaseAdmin implements AsyncAdmin { @Override public CompletableFuture<Void> snapshot(SnapshotDescription snapshotDesc) { - HBaseProtos.SnapshotDescription snapshot = + SnapshotProtos.SnapshotDescription snapshot = ProtobufUtil.createHBaseProtosSnapshotDesc(snapshotDesc); try { ClientSnapshotDescriptionUtils.assertSnapshotRequestIsValid(snapshot); @@ -1916,7 +1917,7 @@ public class AsyncHBaseAdmin implements AsyncAdmin { private CompletableFuture<Void> internalRestoreSnapshot(String snapshotName, TableName tableName) { - HBaseProtos.SnapshotDescription snapshot = HBaseProtos.SnapshotDescription.newBuilder() + SnapshotProtos.SnapshotDescription snapshot = SnapshotProtos.SnapshotDescription.newBuilder() .setName(snapshotName).setTable(tableName.getNameAsString()).build(); try { ClientSnapshotDescriptionUtils.assertSnapshotRequestIsValid(snapshot); http://git-wip-us.apache.org/repos/asf/hbase/blob/37dd8ff7/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java ---------------------------------------------------------------------- diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java index ca5f0d2..d9bd75e 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java @@ -107,7 +107,6 @@ import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos; import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos.CoprocessorServiceRequest; import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos.CoprocessorServiceResponse; import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos; -import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.NameStringPair; import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.ProcedureDescription; import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.RegionSpecifier.RegionSpecifierType; import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.TableSchema; @@ -186,6 +185,7 @@ import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.UnassignRe import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos; import org.apache.hadoop.hbase.shaded.protobuf.generated.ReplicationProtos; import org.apache.hadoop.hbase.shaded.protobuf.generated.ReplicationProtos.GetReplicationPeerConfigResponse; +import org.apache.hadoop.hbase.shaded.protobuf.generated.SnapshotProtos; import org.apache.hadoop.hbase.snapshot.ClientSnapshotDescriptionUtils; import org.apache.hadoop.hbase.snapshot.HBaseSnapshotException; import org.apache.hadoop.hbase.snapshot.RestoreSnapshotException; @@ -2420,7 +2420,7 @@ public class HBaseAdmin implements Admin { public void snapshot(SnapshotDescription snapshotDesc) throws IOException, SnapshotCreationException, IllegalArgumentException { // actually take the snapshot - HBaseProtos.SnapshotDescription snapshot = + SnapshotProtos.SnapshotDescription snapshot = ProtobufUtil.createHBaseProtosSnapshotDesc(snapshotDesc); SnapshotResponse response = asyncSnapshot(snapshot); final IsSnapshotDoneRequest request = @@ -2466,7 +2466,7 @@ public class HBaseAdmin implements Admin { asyncSnapshot(ProtobufUtil.createHBaseProtosSnapshotDesc(snapshotDesc)); } - private SnapshotResponse asyncSnapshot(HBaseProtos.SnapshotDescription snapshot) + private SnapshotResponse asyncSnapshot(SnapshotProtos.SnapshotDescription snapshot) throws IOException { ClientSnapshotDescriptionUtils.assertSnapshotRequestIsValid(snapshot); final SnapshotRequest request = SnapshotRequest.newBuilder().setSnapshot(snapshot) @@ -2484,7 +2484,7 @@ public class HBaseAdmin implements Admin { @Override public boolean isSnapshotFinished(final SnapshotDescription snapshotDesc) throws IOException, HBaseSnapshotException, UnknownSnapshotException { - final HBaseProtos.SnapshotDescription snapshot = + final SnapshotProtos.SnapshotDescription snapshot = ProtobufUtil.createHBaseProtosSnapshotDesc(snapshotDesc); return executeCallable(new MasterCallable<IsSnapshotDoneResponse>(getConnection(), getRpcControllerFactory()) { @@ -2542,13 +2542,19 @@ public class HBaseAdmin implements Admin { } @Override - public void restoreSnapshot(final String snapshotName, final boolean takeFailSafeSnapshot) + public void restoreSnapshot(String snapshotName, boolean takeFailSafeSnapshot) throws IOException, RestoreSnapshotException { + restoreSnapshot(snapshotName, takeFailSafeSnapshot, false); + } + + @Override + public void restoreSnapshot(final String snapshotName, final boolean takeFailSafeSnapshot, + final boolean restoreAcl) throws IOException, RestoreSnapshotException { TableName tableName = getTableNameBeforeRestoreSnapshot(snapshotName); // The table does not exists, switch to clone. if (!tableExists(tableName)) { - cloneSnapshot(snapshotName, tableName); + cloneSnapshot(snapshotName, tableName, restoreAcl); return; } @@ -2573,7 +2579,7 @@ public class HBaseAdmin implements Admin { try { // Restore snapshot get( - internalRestoreSnapshotAsync(snapshotName, tableName), + internalRestoreSnapshotAsync(snapshotName, tableName, restoreAcl), syncWaitTimeout, TimeUnit.MILLISECONDS); } catch (IOException e) { @@ -2582,7 +2588,7 @@ public class HBaseAdmin implements Admin { if (takeFailSafeSnapshot) { try { get( - internalRestoreSnapshotAsync(failSafeSnapshotSnapshotName, tableName), + internalRestoreSnapshotAsync(failSafeSnapshotSnapshotName, tableName, restoreAcl), syncWaitTimeout, TimeUnit.MILLISECONDS); String msg = "Restore snapshot=" + snapshotName + @@ -2625,7 +2631,7 @@ public class HBaseAdmin implements Admin { throw new TableNotDisabledException(tableName); } - return internalRestoreSnapshotAsync(snapshotName, tableName); + return internalRestoreSnapshotAsync(snapshotName, tableName, false); } @Override @@ -2635,24 +2641,30 @@ public class HBaseAdmin implements Admin { } @Override - public void cloneSnapshot(final String snapshotName, final TableName tableName) + public void cloneSnapshot(String snapshotName, TableName tableName, boolean restoreAcl) throws IOException, TableExistsException, RestoreSnapshotException { if (tableExists(tableName)) { throw new TableExistsException(tableName); } get( - internalRestoreSnapshotAsync(snapshotName, tableName), + internalRestoreSnapshotAsync(snapshotName, tableName, restoreAcl), Integer.MAX_VALUE, TimeUnit.MILLISECONDS); } @Override + public void cloneSnapshot(final String snapshotName, final TableName tableName) + throws IOException, TableExistsException, RestoreSnapshotException { + cloneSnapshot(snapshotName, tableName, false); + } + + @Override public Future<Void> cloneSnapshotAsync(final String snapshotName, final TableName tableName) throws IOException, TableExistsException { if (tableExists(tableName)) { throw new TableExistsException(tableName); } - return internalRestoreSnapshotAsync(snapshotName, tableName); + return internalRestoreSnapshotAsync(snapshotName, tableName, false); } @Override @@ -2740,10 +2752,10 @@ public class HBaseAdmin implements Admin { * @throws RestoreSnapshotException if snapshot failed to be restored * @throws IllegalArgumentException if the restore request is formatted incorrectly */ - private Future<Void> internalRestoreSnapshotAsync( - final String snapshotName, - final TableName tableName) throws IOException, RestoreSnapshotException { - final HBaseProtos.SnapshotDescription snapshot = HBaseProtos.SnapshotDescription.newBuilder() + private Future<Void> internalRestoreSnapshotAsync(final String snapshotName, + final TableName tableName, final boolean restoreAcl) + throws IOException, RestoreSnapshotException { + final SnapshotProtos.SnapshotDescription snapshot = SnapshotProtos.SnapshotDescription.newBuilder() .setName(snapshotName).setTable(tableName.getNameAsString()).build(); // actually restore the snapshot @@ -2757,6 +2769,7 @@ public class HBaseAdmin implements Admin { .setSnapshot(snapshot) .setNonceGroup(ng.getNonceGroup()) .setNonce(ng.newNonce()) + .setRestoreACL(restoreAcl) .build(); return master.restoreSnapshot(getRpcController(), request); } @@ -2768,7 +2781,7 @@ public class HBaseAdmin implements Admin { private static class RestoreSnapshotFuture extends TableFuture<Void> { public RestoreSnapshotFuture( final HBaseAdmin admin, - final HBaseProtos.SnapshotDescription snapshot, + final SnapshotProtos.SnapshotDescription snapshot, final TableName tableName, final RestoreSnapshotResponse response) { super(admin, tableName, @@ -2798,12 +2811,12 @@ public class HBaseAdmin implements Admin { getRpcControllerFactory()) { @Override protected List<SnapshotDescription> rpcCall() throws Exception { - List<HBaseProtos.SnapshotDescription> snapshotsList = master + List<SnapshotProtos.SnapshotDescription> snapshotsList = master .getCompletedSnapshots(getRpcController(), GetCompletedSnapshotsRequest.newBuilder().build()) .getSnapshotsList(); List<SnapshotDescription> result = new ArrayList<>(snapshotsList.size()); - for (HBaseProtos.SnapshotDescription snapshot : snapshotsList) { + for (SnapshotProtos.SnapshotDescription snapshot : snapshotsList) { result.add(ProtobufUtil.createSnapshotDesc(snapshot)); } return result; @@ -2866,7 +2879,7 @@ public class HBaseAdmin implements Admin { protected Void rpcCall() throws Exception { master.deleteSnapshot(getRpcController(), DeleteSnapshotRequest.newBuilder().setSnapshot( - HBaseProtos.SnapshotDescription.newBuilder().setName(snapshotName).build()) + SnapshotProtos.SnapshotDescription.newBuilder().setName(snapshotName).build()) .build() ); return null; @@ -4122,7 +4135,7 @@ public class HBaseAdmin implements Admin { /** * Decide whether the table need replicate to the peer cluster according to the peer config * @param table name of the table - * @param peerConfig config for the peer + * @param peer config for the peer * @return true if the table need replicate to the peer cluster */ private boolean needToReplicate(TableName table, ReplicationPeerDescription peer) { http://git-wip-us.apache.org/repos/asf/hbase/blob/37dd8ff7/hbase-client/src/main/java/org/apache/hadoop/hbase/security/access/ShadedAccessControlUtil.java ---------------------------------------------------------------------- diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/security/access/ShadedAccessControlUtil.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/security/access/ShadedAccessControlUtil.java new file mode 100644 index 0000000..03798ad --- /dev/null +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/security/access/ShadedAccessControlUtil.java @@ -0,0 +1,277 @@ +/* + * 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 com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.ListMultimap; +import org.apache.hadoop.hbase.TableName; +import org.apache.hadoop.hbase.classification.InterfaceAudience; +import org.apache.hadoop.hbase.security.access.Permission.Action; +import org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos; +import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos; +import org.apache.hadoop.hbase.shaded.com.google.protobuf.ByteString; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +/** + * Convert protobuf objects in AccessControl.proto under hbase-protocol-shaded to user-oriented + * objects and vice versa. <br> + * + * In HBASE-15638, we create a hbase-protocol-shaded module for upgrading protobuf version to 3.x, + * but there are still some coprocessor endpoints(such as AccessControl, Authentication, + * MulitRowMutation) which depend on hbase-protocol module for CPEP compatibility. In fact, we use + * PB objects in AccessControl.proto under hbase-protocol for access control logic and use shaded + * AccessControl.proto only for serializing/deserializing permissions of .snapshotinfo. + */ +@InterfaceAudience.Private +public class ShadedAccessControlUtil { + + /** + * Convert a client user permission to a user permission shaded proto. + */ + public static + org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.Permission.Action + toPermissionAction(Permission.Action action) { + switch (action) { + case READ: + return org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.Permission.Action.READ; + case WRITE: + return org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.Permission.Action.WRITE; + case EXEC: + return org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.Permission.Action.EXEC; + case CREATE: + return org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.Permission.Action.CREATE; + case ADMIN: + return org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.Permission.Action.ADMIN; + } + throw new IllegalArgumentException("Unknown action value " + action.name()); + } + + /** + * Convert a Permission.Action shaded proto to a client Permission.Action object. + */ + public static Permission.Action toPermissionAction( + org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.Permission.Action action) { + switch (action) { + case READ: + return Permission.Action.READ; + case WRITE: + return Permission.Action.WRITE; + case EXEC: + return Permission.Action.EXEC; + case CREATE: + return Permission.Action.CREATE; + case ADMIN: + return Permission.Action.ADMIN; + } + throw new IllegalArgumentException("Unknown action value " + action.name()); + } + + /** + * Converts a list of Permission.Action shaded proto to a list of client Permission.Action + * objects. + * @param protoActions the list of shaded protobuf Actions + * @return the converted list of Actions + */ + public static List<Permission.Action> toPermissionActions( + List<org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.Permission.Action> protoActions) { + List<Permission.Action> actions = new ArrayList<>(protoActions.size()); + for (org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.Permission.Action a : protoActions) { + actions.add(toPermissionAction(a)); + } + return actions; + } + + public static org.apache.hadoop.hbase.TableName toTableName(HBaseProtos.TableName tableNamePB) { + return org.apache.hadoop.hbase.TableName.valueOf( + tableNamePB.getNamespace().asReadOnlyByteBuffer(), + tableNamePB.getQualifier().asReadOnlyByteBuffer()); + } + + public static HBaseProtos.TableName toProtoTableName(TableName tableName) { + return HBaseProtos.TableName.newBuilder() + .setNamespace(ByteString.copyFrom(tableName.getNamespace())) + .setQualifier(ByteString.copyFrom(tableName.getQualifier())).build(); + } + + /** + * Converts a Permission shaded proto to a client TablePermission object. + * @param proto the protobuf Permission + * @return the converted TablePermission + */ + public static TablePermission toTablePermission(AccessControlProtos.Permission proto) { + + if (proto.getType() == AccessControlProtos.Permission.Type.Global) { + AccessControlProtos.GlobalPermission perm = proto.getGlobalPermission(); + List<Action> actions = toPermissionActions(perm.getActionList()); + + return new TablePermission(null, null, null, + actions.toArray(new Permission.Action[actions.size()])); + } + if (proto.getType() == AccessControlProtos.Permission.Type.Namespace) { + AccessControlProtos.NamespacePermission perm = proto.getNamespacePermission(); + List<Permission.Action> actions = toPermissionActions(perm.getActionList()); + + if (!proto.hasNamespacePermission()) { + throw new IllegalStateException("Namespace must not be empty in NamespacePermission"); + } + String namespace = perm.getNamespaceName().toStringUtf8(); + return new TablePermission(namespace, actions.toArray(new Permission.Action[actions.size()])); + } + if (proto.getType() == AccessControlProtos.Permission.Type.Table) { + AccessControlProtos.TablePermission perm = proto.getTablePermission(); + List<Permission.Action> actions = toPermissionActions(perm.getActionList()); + + byte[] qualifier = null; + byte[] family = null; + TableName table = null; + + if (!perm.hasTableName()) { + throw new IllegalStateException("TableName cannot be empty"); + } + table = toTableName(perm.getTableName()); + + if (perm.hasFamily()) family = perm.getFamily().toByteArray(); + if (perm.hasQualifier()) qualifier = perm.getQualifier().toByteArray(); + + return new TablePermission(table, family, qualifier, + actions.toArray(new Permission.Action[actions.size()])); + } + throw new IllegalStateException("Unrecognize Perm Type: " + proto.getType()); + } + + /** + * Convert a client Permission to a Permission shaded proto + * @param perm the client Permission + * @return the protobuf Permission + */ + public static org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.Permission + toPermission(Permission perm) { + org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.Permission.Builder ret = + org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.Permission + .newBuilder(); + if (perm instanceof TablePermission) { + TablePermission tablePerm = (TablePermission) perm; + if (tablePerm.hasNamespace()) { + ret.setType( + org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.Permission.Type.Namespace); + + org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.NamespacePermission.Builder builder = + org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.NamespacePermission + .newBuilder(); + builder.setNamespaceName(org.apache.hadoop.hbase.shaded.com.google.protobuf.ByteString + .copyFromUtf8(tablePerm.getNamespace())); + Permission.Action[] actions = perm.getActions(); + if (actions != null) { + for (Permission.Action a : actions) { + builder.addAction(toPermissionAction(a)); + } + } + ret.setNamespacePermission(builder); + return ret.build(); + } else if (tablePerm.hasTable()) { + ret.setType( + org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.Permission.Type.Table); + + org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.TablePermission.Builder builder = + org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.TablePermission + .newBuilder(); + builder.setTableName(toProtoTableName(tablePerm.getTableName())); + if (tablePerm.hasFamily()) { + builder.setFamily(ByteString.copyFrom(tablePerm.getFamily())); + } + if (tablePerm.hasQualifier()) { + builder.setQualifier(ByteString.copyFrom(tablePerm.getQualifier())); + } + Permission.Action actions[] = perm.getActions(); + if (actions != null) { + for (Permission.Action a : actions) { + builder.addAction(toPermissionAction(a)); + } + } + ret.setTablePermission(builder); + return ret.build(); + } + } + + ret.setType( + org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.Permission.Type.Global); + + org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.GlobalPermission.Builder builder = + org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.GlobalPermission + .newBuilder(); + Permission.Action actions[] = perm.getActions(); + if (actions != null) { + for (Permission.Action a : actions) { + builder.addAction(toPermissionAction(a)); + } + } + ret.setGlobalPermission(builder); + return ret.build(); + } + + /** + * Convert a shaded protobuf UserTablePermissions to a ListMultimap<String, TablePermission> + * where key is username. + * @param proto the protobuf UserPermission + * @return the converted UserPermission + */ + public static ListMultimap<String, TablePermission> toUserTablePermissions( + org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.UsersAndPermissions proto) { + ListMultimap<String, TablePermission> perms = ArrayListMultimap.create(); + org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.UsersAndPermissions.UserPermissions userPerm; + for (int i = 0; i < proto.getUserPermissionsCount(); i++) { + userPerm = proto.getUserPermissions(i); + for (int j = 0; j < userPerm.getPermissionsCount(); j++) { + TablePermission tablePerm = toTablePermission(userPerm.getPermissions(j)); + perms.put(userPerm.getUser().toStringUtf8(), tablePerm); + } + } + return perms; + } + + /** + * Convert a ListMultimap<String, TablePermission> where key is username to a shaded + * protobuf UserPermission + * @param perm the list of user and table permissions + * @return the protobuf UserTablePermissions + */ + public static + org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.UsersAndPermissions + toUserTablePermissions(ListMultimap<String, TablePermission> perm) { + org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.UsersAndPermissions.Builder builder = + org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.UsersAndPermissions + .newBuilder(); + for (Map.Entry<String, Collection<TablePermission>> entry : perm.asMap().entrySet()) { + org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.UsersAndPermissions.UserPermissions.Builder userPermBuilder = + org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.UsersAndPermissions.UserPermissions + .newBuilder(); + userPermBuilder.setUser(ByteString.copyFromUtf8(entry.getKey())); + for (TablePermission tablePerm : entry.getValue()) { + userPermBuilder.addPermissions(toPermission(tablePerm)); + } + builder.addUserPermissions(userPermBuilder.build()); + } + return builder.build(); + } +} http://git-wip-us.apache.org/repos/asf/hbase/blob/37dd8ff7/hbase-client/src/main/java/org/apache/hadoop/hbase/security/access/TablePermission.java ---------------------------------------------------------------------- diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/security/access/TablePermission.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/security/access/TablePermission.java index 4804b30..8e88a8c 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/security/access/TablePermission.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/security/access/TablePermission.java @@ -155,6 +155,10 @@ public class TablePermission extends Permission { return table; } + public void setTableName(TableName table) { + this.table = table; + } + public boolean hasFamily() { return family != null; } http://git-wip-us.apache.org/repos/asf/hbase/blob/37dd8ff7/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/ProtobufUtil.java ---------------------------------------------------------------------- diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/ProtobufUtil.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/ProtobufUtil.java index 2e62deb..f8ea0a5 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/ProtobufUtil.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/ProtobufUtil.java @@ -35,7 +35,6 @@ import java.util.NavigableSet; import java.util.Set; import java.util.concurrent.Callable; import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; @@ -164,6 +163,7 @@ import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos.Procedu import org.apache.hadoop.hbase.shaded.protobuf.generated.QuotaProtos; import org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.RegionServerReportRequest; import org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.RegionServerStartupRequest; +import org.apache.hadoop.hbase.shaded.protobuf.generated.SnapshotProtos; import org.apache.hadoop.hbase.shaded.protobuf.generated.WALProtos; import org.apache.hadoop.hbase.shaded.protobuf.generated.WALProtos.BulkLoadDescriptor; import org.apache.hadoop.hbase.shaded.protobuf.generated.WALProtos.CompactionDescriptor; @@ -2954,9 +2954,9 @@ public final class ProtobufUtil { * @param type the SnapshotDescription type * @return the protobuf SnapshotDescription type */ - public static HBaseProtos.SnapshotDescription.Type + public static SnapshotProtos.SnapshotDescription.Type createProtosSnapShotDescType(SnapshotType type) { - return HBaseProtos.SnapshotDescription.Type.valueOf(type.name()); + return SnapshotProtos.SnapshotDescription.Type.valueOf(type.name()); } /** @@ -2965,9 +2965,9 @@ public final class ProtobufUtil { * @param snapshotDesc string representing the snapshot description type * @return the protobuf SnapshotDescription type */ - public static HBaseProtos.SnapshotDescription.Type + public static SnapshotProtos.SnapshotDescription.Type createProtosSnapShotDescType(String snapshotDesc) { - return HBaseProtos.SnapshotDescription.Type.valueOf(snapshotDesc.toUpperCase(Locale.ROOT)); + return SnapshotProtos.SnapshotDescription.Type.valueOf(snapshotDesc.toUpperCase(Locale.ROOT)); } /** @@ -2976,7 +2976,7 @@ public final class ProtobufUtil { * @param type the snapshot description type * @return the protobuf SnapshotDescription type */ - public static SnapshotType createSnapshotType(HBaseProtos.SnapshotDescription.Type type) { + public static SnapshotType createSnapshotType(SnapshotProtos.SnapshotDescription.Type type) { return SnapshotType.valueOf(type.toString()); } @@ -2986,9 +2986,9 @@ public final class ProtobufUtil { * @param snapshotDesc the POJO SnapshotDescription * @return the protobuf SnapshotDescription */ - public static HBaseProtos.SnapshotDescription + public static SnapshotProtos.SnapshotDescription createHBaseProtosSnapshotDesc(SnapshotDescription snapshotDesc) { - HBaseProtos.SnapshotDescription.Builder builder = HBaseProtos.SnapshotDescription.newBuilder(); + SnapshotProtos.SnapshotDescription.Builder builder = SnapshotProtos.SnapshotDescription.newBuilder(); if (snapshotDesc.getTableName() != null) { builder.setTable(snapshotDesc.getTableNameAsString()); } @@ -3005,7 +3005,7 @@ public final class ProtobufUtil { builder.setVersion(snapshotDesc.getVersion()); } builder.setType(ProtobufUtil.createProtosSnapShotDescType(snapshotDesc.getType())); - HBaseProtos.SnapshotDescription snapshot = builder.build(); + SnapshotProtos.SnapshotDescription snapshot = builder.build(); return snapshot; } @@ -3017,7 +3017,7 @@ public final class ProtobufUtil { * @return the POJO SnapshotDescription */ public static SnapshotDescription - createSnapshotDesc(HBaseProtos.SnapshotDescription snapshotDesc) { + createSnapshotDesc(SnapshotProtos.SnapshotDescription snapshotDesc) { return new SnapshotDescription(snapshotDesc.getName(), snapshotDesc.hasTable() ? TableName.valueOf(snapshotDesc.getTable()) : null, createSnapshotType(snapshotDesc.getType()), snapshotDesc.getOwner(), http://git-wip-us.apache.org/repos/asf/hbase/blob/37dd8ff7/hbase-client/src/main/java/org/apache/hadoop/hbase/snapshot/ClientSnapshotDescriptionUtils.java ---------------------------------------------------------------------- diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/snapshot/ClientSnapshotDescriptionUtils.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/snapshot/ClientSnapshotDescriptionUtils.java index 88b6bec..3e83f3e 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/snapshot/ClientSnapshotDescriptionUtils.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/snapshot/ClientSnapshotDescriptionUtils.java @@ -22,6 +22,7 @@ package org.apache.hadoop.hbase.snapshot; import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.classification.InterfaceAudience; import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos; +import org.apache.hadoop.hbase.shaded.protobuf.generated.SnapshotProtos; import org.apache.hadoop.hbase.util.Bytes; /** @@ -36,7 +37,7 @@ public class ClientSnapshotDescriptionUtils { * @throws IllegalArgumentException if the name of the snapshot or the name of the table to * snapshot are not valid names. */ - public static void assertSnapshotRequestIsValid(HBaseProtos.SnapshotDescription snapshot) + public static void assertSnapshotRequestIsValid(SnapshotProtos.SnapshotDescription snapshot) throws IllegalArgumentException { // make sure the snapshot name is valid TableName.isLegalTableQualifierName(Bytes.toBytes(snapshot.getName()), true); @@ -57,7 +58,7 @@ public class ClientSnapshotDescriptionUtils { * @param ssd * @return Single line string with a summary of the snapshot parameters */ - public static String toString(HBaseProtos.SnapshotDescription ssd) { + public static String toString(SnapshotProtos.SnapshotDescription ssd) { if (ssd == null) { return null; }