HBASE-12552 Backport listSnapshots should list only owned snapshots for non-super user (Ashish Singhi)
This commit is contained in:
parent
5bee2930e0
commit
93af6b65a3
@ -391,6 +391,16 @@ public abstract class BaseMasterAndRegionObserver extends BaseRegionObserver
|
||||
final SnapshotDescription snapshot, final HTableDescriptor hTableDescriptor)
|
||||
throws IOException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preListSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx,
|
||||
final SnapshotDescription snapshot) throws IOException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postListSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx,
|
||||
final SnapshotDescription snapshot) throws IOException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preCloneSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx,
|
||||
|
@ -385,6 +385,16 @@ public class BaseMasterObserver implements MasterObserver {
|
||||
throws IOException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preListSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx,
|
||||
final SnapshotDescription snapshot) throws IOException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postListSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx,
|
||||
final SnapshotDescription snapshot) throws IOException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preCloneSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx,
|
||||
final SnapshotDescription snapshot, final HTableDescriptor hTableDescriptor)
|
||||
|
@ -597,6 +597,26 @@ public interface MasterObserver extends Coprocessor {
|
||||
final SnapshotDescription snapshot, final HTableDescriptor hTableDescriptor)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* Called before listSnapshots request has been processed.
|
||||
* It can't bypass the default action, e.g., ctx.bypass() won't have effect.
|
||||
* @param ctx the environment to interact with the framework and master
|
||||
* @param snapshot the SnapshotDescriptor of the snapshot to list
|
||||
* @throws IOException
|
||||
*/
|
||||
void preListSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx,
|
||||
final SnapshotDescription snapshot) throws IOException;
|
||||
|
||||
/**
|
||||
* Called after listSnapshots request has been processed.
|
||||
* It can't bypass the default action, e.g., ctx.bypass() won't have effect.
|
||||
* @param ctx the environment to interact with the framework and master
|
||||
* @param snapshot the SnapshotDescriptor of the snapshot to list
|
||||
* @throws IOException
|
||||
*/
|
||||
void postListSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx,
|
||||
final SnapshotDescription snapshot) throws IOException;
|
||||
|
||||
/**
|
||||
* Called before a snapshot is cloned.
|
||||
* Called as part of restoreSnapshot RPC call.
|
||||
|
@ -37,9 +37,6 @@ import org.apache.hadoop.hbase.coprocessor.*;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.SnapshotDescription;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.QuotaProtos.Quotas;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Provides the coprocessor framework and environment for master oriented
|
||||
* operations. {@link HMaster} interacts with the loaded coprocessors
|
||||
@ -780,6 +777,26 @@ public class MasterCoprocessorHost
|
||||
});
|
||||
}
|
||||
|
||||
public void preListSnapshot(final SnapshotDescription snapshot) throws IOException {
|
||||
execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
|
||||
@Override
|
||||
public void call(MasterObserver observer, ObserverContext<MasterCoprocessorEnvironment> ctx)
|
||||
throws IOException {
|
||||
observer.preListSnapshot(ctx, snapshot);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void postListSnapshot(final SnapshotDescription snapshot) throws IOException {
|
||||
execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
|
||||
@Override
|
||||
public void call(MasterObserver observer, ObserverContext<MasterCoprocessorEnvironment> ctx)
|
||||
throws IOException {
|
||||
observer.postListSnapshot(ctx, snapshot);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void preCloneSnapshot(final SnapshotDescription snapshot,
|
||||
final HTableDescriptor hTableDescriptor) throws IOException {
|
||||
execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
|
||||
|
@ -65,6 +65,7 @@ import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.ProcedureDescripti
|
||||
import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.SnapshotDescription;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.SnapshotDescription.Type;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.ZooKeeperProtos;
|
||||
import org.apache.hadoop.hbase.security.AccessDeniedException;
|
||||
import org.apache.hadoop.hbase.security.User;
|
||||
import org.apache.hadoop.hbase.snapshot.ClientSnapshotDescriptionUtils;
|
||||
import org.apache.hadoop.hbase.snapshot.HBaseSnapshotException;
|
||||
@ -213,6 +214,7 @@ public class SnapshotManager extends MasterProcedureManager implements Stoppable
|
||||
// ignore all the snapshots in progress
|
||||
FileStatus[] snapshots = fs.listStatus(snapshotDir,
|
||||
new SnapshotDescriptionUtils.CompletedSnaphotDirectoriesFilter(fs));
|
||||
MasterCoprocessorHost cpHost = master.getMasterCoprocessorHost();
|
||||
// loop through all the completed snapshots
|
||||
for (FileStatus snapshot : snapshots) {
|
||||
Path info = new Path(snapshot.getPath(), SnapshotDescriptionUtils.SNAPSHOTINFO_FILE);
|
||||
@ -225,7 +227,22 @@ public class SnapshotManager extends MasterProcedureManager implements Stoppable
|
||||
try {
|
||||
in = fs.open(info);
|
||||
SnapshotDescription desc = SnapshotDescription.parseFrom(in);
|
||||
if (cpHost != null) {
|
||||
try {
|
||||
cpHost.preListSnapshot(desc);
|
||||
} catch (AccessDeniedException e) {
|
||||
LOG.warn("Current user does not have access to " + desc.getName() + " snapshot. "
|
||||
+ "Either you should be owner of this snapshot or admin user.");
|
||||
// Skip this and try for next snapshot
|
||||
continue;
|
||||
}
|
||||
}
|
||||
snapshotDescs.add(desc);
|
||||
|
||||
// call coproc post hook
|
||||
if (cpHost != null) {
|
||||
cpHost.postListSnapshot(desc);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
LOG.warn("Found a corrupted snapshot " + snapshot.getPath(), e);
|
||||
} finally {
|
||||
|
@ -1240,6 +1240,16 @@ public class AccessController extends BaseMasterAndRegionObserver
|
||||
Permission.Action.ADMIN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preListSnapshot(ObserverContext<MasterCoprocessorEnvironment> ctx,
|
||||
final SnapshotDescription snapshot) throws IOException {
|
||||
if (SnapshotDescriptionUtils.isSnapshotOwner(snapshot, getActiveUser())) {
|
||||
// list it, if user is the owner of snapshot
|
||||
} else {
|
||||
requirePermission("listSnapshot", Action.ADMIN);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preCloneSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx,
|
||||
final SnapshotDescription snapshot, final HTableDescriptor hTableDescriptor)
|
||||
|
@ -39,7 +39,6 @@ import org.apache.hadoop.hbase.HBaseTestingUtility;
|
||||
import org.apache.hadoop.hbase.HColumnDescriptor;
|
||||
import org.apache.hadoop.hbase.HRegionInfo;
|
||||
import org.apache.hadoop.hbase.HTableDescriptor;
|
||||
import org.apache.hadoop.hbase.testclassification.MediumTests;
|
||||
import org.apache.hadoop.hbase.MiniHBaseCluster;
|
||||
import org.apache.hadoop.hbase.NamespaceDescriptor;
|
||||
import org.apache.hadoop.hbase.ServerName;
|
||||
@ -58,6 +57,7 @@ import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableDescripto
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableNamesRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.QuotaProtos.Quotas;
|
||||
import org.apache.hadoop.hbase.regionserver.HRegionServer;
|
||||
import org.apache.hadoop.hbase.testclassification.MediumTests;
|
||||
import org.apache.hadoop.hbase.util.Bytes;
|
||||
import org.apache.hadoop.hbase.util.Threads;
|
||||
import org.junit.AfterClass;
|
||||
@ -129,6 +129,8 @@ public class TestMasterObserver {
|
||||
private boolean stopCalled;
|
||||
private boolean preSnapshotCalled;
|
||||
private boolean postSnapshotCalled;
|
||||
private boolean preListSnapshotCalled;
|
||||
private boolean postListSnapshotCalled;
|
||||
private boolean preCloneSnapshotCalled;
|
||||
private boolean postCloneSnapshotCalled;
|
||||
private boolean preRestoreSnapshotCalled;
|
||||
@ -205,6 +207,8 @@ public class TestMasterObserver {
|
||||
postBalanceSwitchCalled = false;
|
||||
preSnapshotCalled = false;
|
||||
postSnapshotCalled = false;
|
||||
preListSnapshotCalled = false;
|
||||
postListSnapshotCalled = false;
|
||||
preCloneSnapshotCalled = false;
|
||||
postCloneSnapshotCalled = false;
|
||||
preRestoreSnapshotCalled = false;
|
||||
@ -759,6 +763,22 @@ public class TestMasterObserver {
|
||||
public boolean wasSnapshotCalled() {
|
||||
return preSnapshotCalled && postSnapshotCalled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preListSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx,
|
||||
final SnapshotDescription snapshot) throws IOException {
|
||||
preListSnapshotCalled = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postListSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx,
|
||||
final SnapshotDescription snapshot) throws IOException {
|
||||
postListSnapshotCalled = true;
|
||||
}
|
||||
|
||||
public boolean wasListSnapshotCalled() {
|
||||
return preListSnapshotCalled && postListSnapshotCalled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preCloneSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx,
|
||||
@ -1387,6 +1407,11 @@ public class TestMasterObserver {
|
||||
admin.snapshot(TEST_SNAPSHOT, tableName);
|
||||
assertTrue("Coprocessor should have been called on snapshot",
|
||||
cp.wasSnapshotCalled());
|
||||
|
||||
//Test list operation
|
||||
admin.listSnapshots();
|
||||
assertTrue("Coprocessor should have been called on snapshot list",
|
||||
cp.wasListSnapshotCalled());
|
||||
|
||||
// Test clone operation
|
||||
admin.cloneSnapshot(TEST_SNAPSHOT, TEST_CLONE);
|
||||
|
Loading…
x
Reference in New Issue
Block a user