HDFS-10324. Trash directory in an encryption zone should be pre-created with correct permissions. Contributed by Wei-Chiu Chuang.
(cherry picked from commit dacd1f50fe
)
This commit is contained in:
parent
d18a991817
commit
35859872b7
|
@ -56,7 +56,6 @@ public class TrashPolicyDefault extends TrashPolicy {
|
||||||
LogFactory.getLog(TrashPolicyDefault.class);
|
LogFactory.getLog(TrashPolicyDefault.class);
|
||||||
|
|
||||||
private static final Path CURRENT = new Path("Current");
|
private static final Path CURRENT = new Path("Current");
|
||||||
private static final Path TRASH = new Path(".Trash/");
|
|
||||||
|
|
||||||
private static final FsPermission PERMISSION =
|
private static final FsPermission PERMISSION =
|
||||||
new FsPermission(FsAction.ALL, FsAction.NONE, FsAction.NONE);
|
new FsPermission(FsAction.ALL, FsAction.NONE, FsAction.NONE);
|
||||||
|
|
|
@ -29,7 +29,6 @@ import java.nio.ByteBuffer;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
|
|
||||||
import org.apache.hadoop.crypto.key.JavaKeyStoreProvider;
|
import org.apache.hadoop.crypto.key.JavaKeyStoreProvider;
|
||||||
import org.apache.hadoop.crypto.key.KeyProviderFactory;
|
|
||||||
import org.apache.hadoop.fs.CommonConfigurationKeys;
|
import org.apache.hadoop.fs.CommonConfigurationKeys;
|
||||||
import org.apache.hadoop.fs.FSDataInputStream;
|
import org.apache.hadoop.fs.FSDataInputStream;
|
||||||
import org.apache.hadoop.fs.FileSystemTestHelper;
|
import org.apache.hadoop.fs.FileSystemTestHelper;
|
||||||
|
@ -38,6 +37,7 @@ import org.apache.hadoop.hdfs.DFSConfigKeys;
|
||||||
import org.apache.hadoop.hdfs.DFSTestUtil;
|
import org.apache.hadoop.hdfs.DFSTestUtil;
|
||||||
import org.apache.hadoop.hdfs.DistributedFileSystem;
|
import org.apache.hadoop.hdfs.DistributedFileSystem;
|
||||||
import org.apache.hadoop.hdfs.MiniDFSCluster;
|
import org.apache.hadoop.hdfs.MiniDFSCluster;
|
||||||
|
import org.apache.hadoop.hdfs.client.CreateEncryptionZoneFlag;
|
||||||
import org.apache.hadoop.hdfs.client.HdfsAdmin;
|
import org.apache.hadoop.hdfs.client.HdfsAdmin;
|
||||||
import org.apache.hadoop.hdfs.nfs.conf.NfsConfigKeys;
|
import org.apache.hadoop.hdfs.nfs.conf.NfsConfigKeys;
|
||||||
import org.apache.hadoop.hdfs.nfs.conf.NfsConfiguration;
|
import org.apache.hadoop.hdfs.nfs.conf.NfsConfiguration;
|
||||||
|
@ -118,6 +118,8 @@ public class TestRpcProgramNfs3 {
|
||||||
private static final String TEST_KEY = "test_key";
|
private static final String TEST_KEY = "test_key";
|
||||||
private static FileSystemTestHelper fsHelper;
|
private static FileSystemTestHelper fsHelper;
|
||||||
private static File testRootDir;
|
private static File testRootDir;
|
||||||
|
private static final EnumSet<CreateEncryptionZoneFlag> NO_TRASH =
|
||||||
|
EnumSet.of(CreateEncryptionZoneFlag.NO_TRASH);
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void setup() throws Exception {
|
public static void setup() throws Exception {
|
||||||
|
@ -340,7 +342,7 @@ public class TestRpcProgramNfs3 {
|
||||||
|
|
||||||
final Path zone = new Path("/zone");
|
final Path zone = new Path("/zone");
|
||||||
hdfs.mkdirs(zone);
|
hdfs.mkdirs(zone);
|
||||||
dfsAdmin.createEncryptionZone(zone, TEST_KEY);
|
dfsAdmin.createEncryptionZone(zone, TEST_KEY, NO_TRASH);
|
||||||
|
|
||||||
final byte[] buffer = new byte[len];
|
final byte[] buffer = new byte[len];
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
/**
|
||||||
|
* 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.hdfs.client;
|
||||||
|
|
||||||
|
import org.apache.hadoop.classification.InterfaceAudience;
|
||||||
|
import org.apache.hadoop.classification.InterfaceStability;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CreateEncryptionZoneFlag is used in
|
||||||
|
* {@link HdfsAdmin#createEncryptionZone(Path, String, EnumSet)} to indicate
|
||||||
|
* what should be done when creating an encryption zone.
|
||||||
|
*
|
||||||
|
* Use CreateEncryptionZoneFlag as follows:
|
||||||
|
* <ol>
|
||||||
|
* <li>PROVISION_TRASH - provision a trash directory for the encryption zone
|
||||||
|
* to support soft delete.</li>
|
||||||
|
* </ol>
|
||||||
|
*/
|
||||||
|
@InterfaceAudience.Public
|
||||||
|
@InterfaceStability.Evolving
|
||||||
|
public enum CreateEncryptionZoneFlag {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do not provision a trash directory in the encryption zone.
|
||||||
|
*
|
||||||
|
* @see CreateEncryptionZoneFlag#NO_TRASH
|
||||||
|
*/
|
||||||
|
NO_TRASH((short) 0x00),
|
||||||
|
/**
|
||||||
|
* Provision a trash directory .Trash/ in the
|
||||||
|
* encryption zone.
|
||||||
|
*
|
||||||
|
* @see CreateEncryptionZoneFlag#PROVISION_TRASH
|
||||||
|
*/
|
||||||
|
PROVISION_TRASH((short) 0x01);
|
||||||
|
|
||||||
|
private final short mode;
|
||||||
|
|
||||||
|
CreateEncryptionZoneFlag(short mode) {
|
||||||
|
this.mode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CreateEncryptionZoneFlag valueOf(short mode) {
|
||||||
|
for (CreateEncryptionZoneFlag flag : CreateEncryptionZoneFlag.values()) {
|
||||||
|
if (flag.getMode() == mode) {
|
||||||
|
return flag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public short getMode() {
|
||||||
|
return mode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -22,14 +22,18 @@ import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
|
|
||||||
|
import org.apache.hadoop.HadoopIllegalArgumentException;
|
||||||
import org.apache.hadoop.classification.InterfaceAudience;
|
import org.apache.hadoop.classification.InterfaceAudience;
|
||||||
import org.apache.hadoop.classification.InterfaceStability;
|
import org.apache.hadoop.classification.InterfaceStability;
|
||||||
import org.apache.hadoop.conf.Configuration;
|
import org.apache.hadoop.conf.Configuration;
|
||||||
import org.apache.hadoop.fs.CacheFlag;
|
import org.apache.hadoop.fs.CacheFlag;
|
||||||
|
import org.apache.hadoop.fs.FileStatus;
|
||||||
import org.apache.hadoop.fs.FileSystem;
|
import org.apache.hadoop.fs.FileSystem;
|
||||||
import org.apache.hadoop.fs.Path;
|
import org.apache.hadoop.fs.Path;
|
||||||
import org.apache.hadoop.fs.RemoteIterator;
|
import org.apache.hadoop.fs.RemoteIterator;
|
||||||
import org.apache.hadoop.fs.StorageType;
|
import org.apache.hadoop.fs.StorageType;
|
||||||
|
import org.apache.hadoop.fs.permission.FsAction;
|
||||||
|
import org.apache.hadoop.fs.permission.FsPermission;
|
||||||
import org.apache.hadoop.hdfs.DFSInotifyEventInputStream;
|
import org.apache.hadoop.hdfs.DFSInotifyEventInputStream;
|
||||||
import org.apache.hadoop.hdfs.DistributedFileSystem;
|
import org.apache.hadoop.hdfs.DistributedFileSystem;
|
||||||
import org.apache.hadoop.hdfs.protocol.CacheDirectiveEntry;
|
import org.apache.hadoop.hdfs.protocol.CacheDirectiveEntry;
|
||||||
|
@ -55,6 +59,8 @@ import org.apache.hadoop.hdfs.tools.DFSAdmin;
|
||||||
public class HdfsAdmin {
|
public class HdfsAdmin {
|
||||||
|
|
||||||
private DistributedFileSystem dfs;
|
private DistributedFileSystem dfs;
|
||||||
|
private static final FsPermission TRASH_PERMISSION = new FsPermission(
|
||||||
|
FsAction.ALL, FsAction.ALL, FsAction.ALL, true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new HdfsAdmin client.
|
* Create a new HdfsAdmin client.
|
||||||
|
@ -269,11 +275,53 @@ public class HdfsAdmin {
|
||||||
* @throws AccessControlException if the caller does not have access to path
|
* @throws AccessControlException if the caller does not have access to path
|
||||||
* @throws FileNotFoundException if the path does not exist
|
* @throws FileNotFoundException if the path does not exist
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public void createEncryptionZone(Path path, String keyName)
|
public void createEncryptionZone(Path path, String keyName)
|
||||||
throws IOException, AccessControlException, FileNotFoundException {
|
throws IOException, AccessControlException, FileNotFoundException {
|
||||||
dfs.createEncryptionZone(path, keyName);
|
dfs.createEncryptionZone(path, keyName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an encryption zone rooted at an empty existing directory, using the
|
||||||
|
* specified encryption key. An encryption zone has an associated encryption
|
||||||
|
* key used when reading and writing files within the zone.
|
||||||
|
*
|
||||||
|
* Additional options, such as provisioning the trash directory, can be
|
||||||
|
* specified using {@link CreateEncryptionZoneFlag} flags.
|
||||||
|
*
|
||||||
|
* @param path The path of the root of the encryption zone. Must refer to
|
||||||
|
* an empty, existing directory.
|
||||||
|
* @param keyName Name of key available at the KeyProvider.
|
||||||
|
* @param flags flags for this operation.
|
||||||
|
* @throws IOException if there was a general IO exception
|
||||||
|
* @throws AccessControlException if the caller does not have access to path
|
||||||
|
* @throws FileNotFoundException if the path does not exist
|
||||||
|
* @throws HadoopIllegalArgumentException if the flags are invalid
|
||||||
|
*/
|
||||||
|
public void createEncryptionZone(Path path, String keyName,
|
||||||
|
EnumSet<CreateEncryptionZoneFlag> flags)
|
||||||
|
throws IOException, AccessControlException, FileNotFoundException,
|
||||||
|
HadoopIllegalArgumentException{
|
||||||
|
dfs.createEncryptionZone(path, keyName);
|
||||||
|
if (flags.contains(CreateEncryptionZoneFlag.PROVISION_TRASH)) {
|
||||||
|
if (flags.contains(CreateEncryptionZoneFlag.NO_TRASH)) {
|
||||||
|
throw new HadoopIllegalArgumentException(
|
||||||
|
"can not have both PROVISION_TRASH and NO_TRASH flags");
|
||||||
|
}
|
||||||
|
this.provisionEZTrash(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provision a trash directory for a given encryption zone.
|
||||||
|
|
||||||
|
* @param path the root of the encryption zone
|
||||||
|
* @throws IOException if the trash directory can not be created.
|
||||||
|
*/
|
||||||
|
public void provisionEncryptionZoneTrash(Path path) throws IOException {
|
||||||
|
this.provisionEZTrash(path);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the path of the encryption zone for a given file or directory.
|
* Get the path of the encryption zone for a given file or directory.
|
||||||
*
|
*
|
||||||
|
@ -363,4 +411,42 @@ public class HdfsAdmin {
|
||||||
throws IOException {
|
throws IOException {
|
||||||
dfs.setStoragePolicy(src, policyName);
|
dfs.setStoragePolicy(src, policyName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void provisionEZTrash(Path path) throws IOException {
|
||||||
|
// make sure the path is an EZ
|
||||||
|
EncryptionZone ez = dfs.getEZForPath(path);
|
||||||
|
if (ez == null) {
|
||||||
|
throw new IllegalArgumentException(path + " is not an encryption zone.");
|
||||||
|
}
|
||||||
|
|
||||||
|
String ezPath = ez.getPath();
|
||||||
|
if (!path.toString().equals(ezPath)) {
|
||||||
|
throw new IllegalArgumentException(path + " is not the root of an " +
|
||||||
|
"encryption zone. Do you mean " + ez.getPath() + "?");
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if the trash directory exists
|
||||||
|
|
||||||
|
Path trashPath = new Path(ez.getPath(), FileSystem.TRASH_PREFIX);
|
||||||
|
|
||||||
|
if (dfs.exists(trashPath)) {
|
||||||
|
String errMessage = "Will not provision new trash directory for " +
|
||||||
|
"encryption zone " + ez.getPath() + ". Path already exists.";
|
||||||
|
FileStatus trashFileStatus = dfs.getFileStatus(trashPath);
|
||||||
|
if (!trashFileStatus.isDirectory()) {
|
||||||
|
errMessage += "\r\n" +
|
||||||
|
"Warning: " + trashPath.toString() + " is not a directory";
|
||||||
|
}
|
||||||
|
if (!trashFileStatus.getPermission().equals(TRASH_PERMISSION)) {
|
||||||
|
errMessage += "\r\n" +
|
||||||
|
"Warning: the permission of " +
|
||||||
|
trashPath.toString() + " is not " + TRASH_PERMISSION;
|
||||||
|
}
|
||||||
|
throw new IOException(errMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the permission bits
|
||||||
|
dfs.mkdir(trashPath, TRASH_PERMISSION);
|
||||||
|
dfs.setPermission(trashPath, TRASH_PERMISSION);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This package provides the administrative APIs for HDFS.
|
||||||
|
*/
|
||||||
|
@InterfaceAudience.Public
|
||||||
|
@InterfaceStability.Evolving
|
||||||
|
package org.apache.hadoop.hdfs.client;
|
||||||
|
|
||||||
|
import org.apache.hadoop.classification.InterfaceAudience;
|
||||||
|
import org.apache.hadoop.classification.InterfaceStability;
|
|
@ -18,15 +18,18 @@
|
||||||
package org.apache.hadoop.hdfs.tools;
|
package org.apache.hadoop.hdfs.tools;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.EnumSet;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.hadoop.classification.InterfaceAudience;
|
import org.apache.hadoop.classification.InterfaceAudience;
|
||||||
import org.apache.hadoop.conf.Configuration;
|
import org.apache.hadoop.conf.Configuration;
|
||||||
import org.apache.hadoop.conf.Configured;
|
import org.apache.hadoop.conf.Configured;
|
||||||
|
import org.apache.hadoop.fs.FileSystem;
|
||||||
import org.apache.hadoop.fs.Path;
|
import org.apache.hadoop.fs.Path;
|
||||||
import org.apache.hadoop.fs.RemoteIterator;
|
import org.apache.hadoop.fs.RemoteIterator;
|
||||||
import org.apache.hadoop.hdfs.DistributedFileSystem;
|
import org.apache.hadoop.hdfs.client.CreateEncryptionZoneFlag;
|
||||||
|
import org.apache.hadoop.hdfs.client.HdfsAdmin;
|
||||||
import org.apache.hadoop.hdfs.protocol.EncryptionZone;
|
import org.apache.hadoop.hdfs.protocol.EncryptionZone;
|
||||||
import org.apache.hadoop.tools.TableListing;
|
import org.apache.hadoop.tools.TableListing;
|
||||||
import org.apache.hadoop.util.StringUtils;
|
import org.apache.hadoop.util.StringUtils;
|
||||||
|
@ -103,7 +106,8 @@ public class CryptoAdmin extends Configured implements Tool {
|
||||||
public String getLongUsage() {
|
public String getLongUsage() {
|
||||||
final TableListing listing = AdminHelper.getOptionDescriptionListing();
|
final TableListing listing = AdminHelper.getOptionDescriptionListing();
|
||||||
listing.addRow("<path>", "The path of the encryption zone to create. " +
|
listing.addRow("<path>", "The path of the encryption zone to create. " +
|
||||||
"It must be an empty directory.");
|
"It must be an empty directory. A trash directory is provisioned " +
|
||||||
|
"under this path.");
|
||||||
listing.addRow("<keyName>", "Name of the key to use for the " +
|
listing.addRow("<keyName>", "Name of the key to use for the " +
|
||||||
"encryption zone.");
|
"encryption zone.");
|
||||||
return getShortUsage() + "\n" +
|
return getShortUsage() + "\n" +
|
||||||
|
@ -131,15 +135,16 @@ public class CryptoAdmin extends Configured implements Tool {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
final DistributedFileSystem dfs = AdminHelper.getDFS(conf);
|
HdfsAdmin admin = new HdfsAdmin(FileSystem.getDefaultUri(conf), conf);
|
||||||
|
EnumSet<CreateEncryptionZoneFlag> flags =
|
||||||
|
EnumSet.of(CreateEncryptionZoneFlag.PROVISION_TRASH);
|
||||||
try {
|
try {
|
||||||
dfs.createEncryptionZone(new Path(path), keyName);
|
admin.createEncryptionZone(new Path(path), keyName, flags);
|
||||||
System.out.println("Added encryption zone " + path);
|
System.out.println("Added encryption zone " + path);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
System.err.println(prettifyException(e));
|
System.err.println(prettifyException(e));
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -168,12 +173,12 @@ public class CryptoAdmin extends Configured implements Tool {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
final DistributedFileSystem dfs = AdminHelper.getDFS(conf);
|
HdfsAdmin admin = new HdfsAdmin(FileSystem.getDefaultUri(conf), conf);
|
||||||
try {
|
try {
|
||||||
final TableListing listing = new TableListing.Builder()
|
final TableListing listing = new TableListing.Builder()
|
||||||
.addField("").addField("", true)
|
.addField("").addField("", true)
|
||||||
.wrapWidth(AdminHelper.MAX_LINE_WIDTH).hideHeaders().build();
|
.wrapWidth(AdminHelper.MAX_LINE_WIDTH).hideHeaders().build();
|
||||||
final RemoteIterator<EncryptionZone> it = dfs.listEncryptionZones();
|
final RemoteIterator<EncryptionZone> it = admin.listEncryptionZones();
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
EncryptionZone ez = it.next();
|
EncryptionZone ez = it.next();
|
||||||
listing.addRow(ez.getPath(), ez.getKeyName());
|
listing.addRow(ez.getPath(), ez.getKeyName());
|
||||||
|
@ -188,8 +193,50 @@ public class CryptoAdmin extends Configured implements Tool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class ProvisionTrashCommand implements AdminHelper.Command {
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "-provisionTrash";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getShortUsage() {
|
||||||
|
return "[" + getName() + " -path <path>]\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getLongUsage() {
|
||||||
|
final TableListing listing = AdminHelper.getOptionDescriptionListing();
|
||||||
|
listing.addRow("<path>", "The path to the root of the encryption zone. ");
|
||||||
|
return getShortUsage() + "\n" +
|
||||||
|
"Provision a trash directory for an encryption zone.\n\n" +
|
||||||
|
listing.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int run(Configuration conf, List<String> args) throws IOException {
|
||||||
|
final String path = StringUtils.popOptionWithArgument("-path", args);
|
||||||
|
|
||||||
|
if (!args.isEmpty()) {
|
||||||
|
System.err.println("Can't understand argument: " + args.get(0));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
HdfsAdmin admin = new HdfsAdmin(FileSystem.getDefaultUri(conf), conf);
|
||||||
|
try {
|
||||||
|
admin.provisionEncryptionZoneTrash(new Path(path));
|
||||||
|
System.out.println("Created a trash directory for " + path);
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
System.err.println(prettifyException(ioe));
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static final AdminHelper.Command[] COMMANDS = {
|
private static final AdminHelper.Command[] COMMANDS = {
|
||||||
new CreateZoneCommand(),
|
new CreateZoneCommand(),
|
||||||
new ListZonesCommand()
|
new ListZonesCommand(),
|
||||||
|
new ProvisionTrashCommand()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -329,6 +329,7 @@ Usage:
|
||||||
|
|
||||||
hdfs crypto -createZone -keyName <keyName> -path <path>
|
hdfs crypto -createZone -keyName <keyName> -path <path>
|
||||||
hdfs crypto -listZones
|
hdfs crypto -listZones
|
||||||
|
hdfs crypto -provisionTrash -path <path>
|
||||||
hdfs crypto -help <command-name>
|
hdfs crypto -help <command-name>
|
||||||
|
|
||||||
See the [HDFS Transparent Encryption Documentation](./TransparentEncryption.html#crypto_command-line_interface) for more information.
|
See the [HDFS Transparent Encryption Documentation](./TransparentEncryption.html#crypto_command-line_interface) for more information.
|
||||||
|
|
|
@ -170,7 +170,7 @@ Create a new encryption zone.
|
||||||
|
|
||||||
| | |
|
| | |
|
||||||
|:---- |:---- |
|
|:---- |:---- |
|
||||||
| *path* | The path of the encryption zone to create. It must be an empty directory. |
|
| *path* | The path of the encryption zone to create. It must be an empty directory. A trash directory is provisioned under this path.|
|
||||||
| *keyName* | Name of the key to use for the encryption zone. |
|
| *keyName* | Name of the key to use for the encryption zone. |
|
||||||
|
|
||||||
### <a name="listZones"></a>listZones
|
### <a name="listZones"></a>listZones
|
||||||
|
@ -179,6 +179,16 @@ Usage: `[-listZones]`
|
||||||
|
|
||||||
List all encryption zones. Requires superuser permissions.
|
List all encryption zones. Requires superuser permissions.
|
||||||
|
|
||||||
|
### <a name="provisionTrash"></a>provisionTrash
|
||||||
|
|
||||||
|
Usage: `[-provisionTrash -path <path>]`
|
||||||
|
|
||||||
|
Provision a trash directory for an encryption zone.
|
||||||
|
|
||||||
|
| | |
|
||||||
|
|:---- |:---- |
|
||||||
|
| *path* | The path to the root of the encryption zone. |
|
||||||
|
|
||||||
<a name="Example_usage"></a>Example usage
|
<a name="Example_usage"></a>Example usage
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
|
@ -222,6 +232,7 @@ This restriction enhances security and eases system management significantly. Al
|
||||||
|
|
||||||
To comply with the above rule, each encryption zone has its own `.Trash` directory under the "zone directory". E.g., after `hdfs dfs rm /zone/encryptedFile`, `encryptedFile` will be moved to `/zone/.Trash`, instead of the `.Trash` directory under the user's home directory. When the entire encryption zone is deleted, the "zone directory" will be moved to the `.Trash` directory under the user's home directory.
|
To comply with the above rule, each encryption zone has its own `.Trash` directory under the "zone directory". E.g., after `hdfs dfs rm /zone/encryptedFile`, `encryptedFile` will be moved to `/zone/.Trash`, instead of the `.Trash` directory under the user's home directory. When the entire encryption zone is deleted, the "zone directory" will be moved to the `.Trash` directory under the user's home directory.
|
||||||
|
|
||||||
|
The `crypto` command before Hadoop 2.8.0 does not provision the `.Trash` directory automatically. If an encryption zone is created before Hadoop 2.8.0, and then the cluster is upgraded to Hadoop 2.8.0 or above, the trash directory can be provisioned using `-provisionTrash` option (e.g., `hdfs crypto -provisionTrash -path /zone`).
|
||||||
<a name="Attack_vectors"></a>Attack vectors
|
<a name="Attack_vectors"></a>Attack vectors
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ import java.security.PrivilegedExceptionAction;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.EnumSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
@ -59,7 +60,9 @@ import org.apache.hadoop.fs.FileSystemTestWrapper;
|
||||||
import org.apache.hadoop.fs.FsShell;
|
import org.apache.hadoop.fs.FsShell;
|
||||||
import org.apache.hadoop.fs.Path;
|
import org.apache.hadoop.fs.Path;
|
||||||
import org.apache.hadoop.fs.RemoteIterator;
|
import org.apache.hadoop.fs.RemoteIterator;
|
||||||
|
import org.apache.hadoop.fs.permission.FsAction;
|
||||||
import org.apache.hadoop.fs.permission.FsPermission;
|
import org.apache.hadoop.fs.permission.FsPermission;
|
||||||
|
import org.apache.hadoop.hdfs.client.CreateEncryptionZoneFlag;
|
||||||
import org.apache.hadoop.hdfs.client.HdfsAdmin;
|
import org.apache.hadoop.hdfs.client.HdfsAdmin;
|
||||||
import org.apache.hadoop.hdfs.protocol.ClientProtocol;
|
import org.apache.hadoop.hdfs.protocol.ClientProtocol;
|
||||||
import org.apache.hadoop.hdfs.protocol.EncryptionZone;
|
import org.apache.hadoop.hdfs.protocol.EncryptionZone;
|
||||||
|
@ -70,6 +73,7 @@ import org.apache.hadoop.hdfs.server.namenode.EncryptionFaultInjector;
|
||||||
import org.apache.hadoop.hdfs.server.namenode.EncryptionZoneManager;
|
import org.apache.hadoop.hdfs.server.namenode.EncryptionZoneManager;
|
||||||
import org.apache.hadoop.hdfs.server.namenode.FSImageTestUtil;
|
import org.apache.hadoop.hdfs.server.namenode.FSImageTestUtil;
|
||||||
import org.apache.hadoop.hdfs.server.namenode.NamenodeFsck;
|
import org.apache.hadoop.hdfs.server.namenode.NamenodeFsck;
|
||||||
|
import org.apache.hadoop.hdfs.tools.CryptoAdmin;
|
||||||
import org.apache.hadoop.hdfs.tools.DFSck;
|
import org.apache.hadoop.hdfs.tools.DFSck;
|
||||||
import org.apache.hadoop.hdfs.tools.offlineImageViewer.PBImageXmlWriter;
|
import org.apache.hadoop.hdfs.tools.offlineImageViewer.PBImageXmlWriter;
|
||||||
import org.apache.hadoop.hdfs.web.WebHdfsConstants;
|
import org.apache.hadoop.hdfs.web.WebHdfsConstants;
|
||||||
|
@ -131,6 +135,9 @@ public class TestEncryptionZones {
|
||||||
protected FileSystemTestWrapper fsWrapper;
|
protected FileSystemTestWrapper fsWrapper;
|
||||||
protected FileContextTestWrapper fcWrapper;
|
protected FileContextTestWrapper fcWrapper;
|
||||||
|
|
||||||
|
protected static final EnumSet< CreateEncryptionZoneFlag > NO_TRASH =
|
||||||
|
EnumSet.of(CreateEncryptionZoneFlag.NO_TRASH);
|
||||||
|
|
||||||
protected String getKeyProviderURI() {
|
protected String getKeyProviderURI() {
|
||||||
return JavaKeyStoreProvider.SCHEME_NAME + "://file" +
|
return JavaKeyStoreProvider.SCHEME_NAME + "://file" +
|
||||||
new Path(testRootDir.toString(), "test.jks").toUri();
|
new Path(testRootDir.toString(), "test.jks").toUri();
|
||||||
|
@ -215,6 +222,106 @@ public class TestEncryptionZones {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make sure hdfs crypto -createZone command creates a trash directory
|
||||||
|
* with sticky bits.
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
@Test(timeout = 60000)
|
||||||
|
public void testTrashStickyBit() throws Exception {
|
||||||
|
// create an EZ /zones/zone1, make it world writable.
|
||||||
|
final Path zoneParent = new Path("/zones");
|
||||||
|
final Path zone1 = new Path(zoneParent, "zone1");
|
||||||
|
CryptoAdmin cryptoAdmin = new CryptoAdmin(conf);
|
||||||
|
fsWrapper.mkdir(zone1, FsPermission.getDirDefault(), true);
|
||||||
|
fsWrapper.setPermission(zone1,
|
||||||
|
new FsPermission(FsAction.ALL, FsAction.ALL, FsAction.ALL));
|
||||||
|
String[] cryptoArgv = new String[]{"-createZone", "-keyName", TEST_KEY,
|
||||||
|
"-path", zone1.toUri().getPath()};
|
||||||
|
cryptoAdmin.run(cryptoArgv);
|
||||||
|
|
||||||
|
// create a file in EZ
|
||||||
|
final Path ezfile1 = new Path(zone1, "file1");
|
||||||
|
// Create the encrypted file in zone1
|
||||||
|
final int len = 8192;
|
||||||
|
DFSTestUtil.createFile(fs, ezfile1, len, (short) 1, 0xFEED);
|
||||||
|
|
||||||
|
// enable trash, delete /zones/zone1/file1,
|
||||||
|
// which moves the file to
|
||||||
|
// /zones/zone1/.Trash/$SUPERUSER/Current/zones/zone1/file1
|
||||||
|
Configuration clientConf = new Configuration(conf);
|
||||||
|
clientConf.setLong(FS_TRASH_INTERVAL_KEY, 1);
|
||||||
|
final FsShell shell = new FsShell(clientConf);
|
||||||
|
String[] argv = new String[]{"-rm", ezfile1.toString()};
|
||||||
|
int res = ToolRunner.run(shell, argv);
|
||||||
|
assertEquals("Can't remove a file in EZ as superuser", 0, res);
|
||||||
|
|
||||||
|
final Path trashDir = new Path(zone1, FileSystem.TRASH_PREFIX);
|
||||||
|
assertTrue(fsWrapper.exists(trashDir));
|
||||||
|
FileStatus trashFileStatus = fsWrapper.getFileStatus(trashDir);
|
||||||
|
assertTrue(trashFileStatus.getPermission().getStickyBit());
|
||||||
|
|
||||||
|
// create a non-privileged user
|
||||||
|
final UserGroupInformation user = UserGroupInformation.
|
||||||
|
createUserForTesting("user", new String[] { "mygroup" });
|
||||||
|
|
||||||
|
user.doAs(new PrivilegedExceptionAction<Object>() {
|
||||||
|
@Override
|
||||||
|
public Object run() throws Exception {
|
||||||
|
final Path ezfile2 = new Path(zone1, "file2");
|
||||||
|
final int len = 8192;
|
||||||
|
// create a file /zones/zone1/file2 in EZ
|
||||||
|
// this file is owned by user:mygroup
|
||||||
|
FileSystem fs2 = FileSystem.get(cluster.getConfiguration(0));
|
||||||
|
DFSTestUtil.createFile(fs2, ezfile2, len, (short) 1, 0xFEED);
|
||||||
|
// delete /zones/zone1/file2,
|
||||||
|
// which moves the file to
|
||||||
|
// /zones/zone1/.Trash/user/Current/zones/zone1/file2
|
||||||
|
String[] argv = new String[]{"-rm", ezfile2.toString()};
|
||||||
|
int res = ToolRunner.run(shell, argv);
|
||||||
|
assertEquals("Can't remove a file in EZ as user:mygroup", 0, res);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make sure hdfs crypto -provisionTrash command creates a trash directory
|
||||||
|
* with sticky bits.
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
@Test(timeout = 60000)
|
||||||
|
public void testProvisionTrash() throws Exception {
|
||||||
|
// create an EZ /zones/zone1
|
||||||
|
final Path zoneParent = new Path("/zones");
|
||||||
|
final Path zone1 = new Path(zoneParent, "zone1");
|
||||||
|
CryptoAdmin cryptoAdmin = new CryptoAdmin(conf);
|
||||||
|
fsWrapper.mkdir(zone1, FsPermission.getDirDefault(), true);
|
||||||
|
String[] cryptoArgv = new String[]{"-createZone", "-keyName", TEST_KEY,
|
||||||
|
"-path", zone1.toUri().getPath()};
|
||||||
|
cryptoAdmin.run(cryptoArgv);
|
||||||
|
|
||||||
|
// remove the trash directory
|
||||||
|
Configuration clientConf = new Configuration(conf);
|
||||||
|
clientConf.setLong(FS_TRASH_INTERVAL_KEY, 1);
|
||||||
|
final FsShell shell = new FsShell(clientConf);
|
||||||
|
final Path trashDir = new Path(zone1, FileSystem.TRASH_PREFIX);
|
||||||
|
String[] argv = new String[]{"-rmdir", trashDir.toUri().getPath()};
|
||||||
|
int res = ToolRunner.run(shell, argv);
|
||||||
|
assertEquals("Unable to delete trash directory.", 0, res);
|
||||||
|
assertFalse(fsWrapper.exists(trashDir));
|
||||||
|
|
||||||
|
// execute -provisionTrash command option and make sure the trash
|
||||||
|
// directory has sticky bit.
|
||||||
|
String[] provisionTrashArgv = new String[]{"-provisionTrash", "-path",
|
||||||
|
zone1.toUri().getPath()};
|
||||||
|
cryptoAdmin.run(provisionTrashArgv);
|
||||||
|
|
||||||
|
assertTrue(fsWrapper.exists(trashDir));
|
||||||
|
FileStatus trashFileStatus = fsWrapper.getFileStatus(trashDir);
|
||||||
|
assertTrue(trashFileStatus.getPermission().getStickyBit());
|
||||||
|
}
|
||||||
|
|
||||||
@Test(timeout = 60000)
|
@Test(timeout = 60000)
|
||||||
public void testBasicOperations() throws Exception {
|
public void testBasicOperations() throws Exception {
|
||||||
|
|
||||||
|
@ -223,8 +330,9 @@ public class TestEncryptionZones {
|
||||||
/* Test failure of create EZ on a directory that doesn't exist. */
|
/* Test failure of create EZ on a directory that doesn't exist. */
|
||||||
final Path zoneParent = new Path("/zones");
|
final Path zoneParent = new Path("/zones");
|
||||||
final Path zone1 = new Path(zoneParent, "zone1");
|
final Path zone1 = new Path(zoneParent, "zone1");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
dfsAdmin.createEncryptionZone(zone1, TEST_KEY);
|
dfsAdmin.createEncryptionZone(zone1, TEST_KEY, NO_TRASH);
|
||||||
fail("expected /test doesn't exist");
|
fail("expected /test doesn't exist");
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
assertExceptionContains("cannot find", e);
|
assertExceptionContains("cannot find", e);
|
||||||
|
@ -232,20 +340,20 @@ public class TestEncryptionZones {
|
||||||
|
|
||||||
/* Normal creation of an EZ */
|
/* Normal creation of an EZ */
|
||||||
fsWrapper.mkdir(zone1, FsPermission.getDirDefault(), true);
|
fsWrapper.mkdir(zone1, FsPermission.getDirDefault(), true);
|
||||||
dfsAdmin.createEncryptionZone(zone1, TEST_KEY);
|
dfsAdmin.createEncryptionZone(zone1, TEST_KEY, NO_TRASH);
|
||||||
assertNumZones(++numZones);
|
assertNumZones(++numZones);
|
||||||
assertZonePresent(null, zone1.toString());
|
assertZonePresent(null, zone1.toString());
|
||||||
|
|
||||||
/* Test failure of create EZ on a directory which is already an EZ. */
|
/* Test failure of create EZ on a directory which is already an EZ. */
|
||||||
try {
|
try {
|
||||||
dfsAdmin.createEncryptionZone(zone1, TEST_KEY);
|
dfsAdmin.createEncryptionZone(zone1, TEST_KEY, NO_TRASH);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
assertExceptionContains("is already an encryption zone", e);
|
assertExceptionContains("is already an encryption zone", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create EZ on parent of an EZ should fail */
|
/* create EZ on parent of an EZ should fail */
|
||||||
try {
|
try {
|
||||||
dfsAdmin.createEncryptionZone(zoneParent, TEST_KEY);
|
dfsAdmin.createEncryptionZone(zoneParent, TEST_KEY, NO_TRASH);
|
||||||
fail("EZ over an EZ");
|
fail("EZ over an EZ");
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
assertExceptionContains("encryption zone for a non-empty directory", e);
|
assertExceptionContains("encryption zone for a non-empty directory", e);
|
||||||
|
@ -256,7 +364,7 @@ public class TestEncryptionZones {
|
||||||
final Path notEmptyChild = new Path(notEmpty, "child");
|
final Path notEmptyChild = new Path(notEmpty, "child");
|
||||||
fsWrapper.mkdir(notEmptyChild, FsPermission.getDirDefault(), true);
|
fsWrapper.mkdir(notEmptyChild, FsPermission.getDirDefault(), true);
|
||||||
try {
|
try {
|
||||||
dfsAdmin.createEncryptionZone(notEmpty, TEST_KEY);
|
dfsAdmin.createEncryptionZone(notEmpty, TEST_KEY, NO_TRASH);
|
||||||
fail("Created EZ on an non-empty directory with folder");
|
fail("Created EZ on an non-empty directory with folder");
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
assertExceptionContains("create an encryption zone", e);
|
assertExceptionContains("create an encryption zone", e);
|
||||||
|
@ -266,7 +374,7 @@ public class TestEncryptionZones {
|
||||||
/* create EZ on a folder with a file fails */
|
/* create EZ on a folder with a file fails */
|
||||||
fsWrapper.createFile(notEmptyChild);
|
fsWrapper.createFile(notEmptyChild);
|
||||||
try {
|
try {
|
||||||
dfsAdmin.createEncryptionZone(notEmpty, TEST_KEY);
|
dfsAdmin.createEncryptionZone(notEmpty, TEST_KEY, NO_TRASH);
|
||||||
fail("Created EZ on an non-empty directory with file");
|
fail("Created EZ on an non-empty directory with file");
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
assertExceptionContains("create an encryption zone", e);
|
assertExceptionContains("create an encryption zone", e);
|
||||||
|
@ -274,7 +382,7 @@ public class TestEncryptionZones {
|
||||||
|
|
||||||
/* Test failure of create EZ on a file. */
|
/* Test failure of create EZ on a file. */
|
||||||
try {
|
try {
|
||||||
dfsAdmin.createEncryptionZone(notEmptyChild, TEST_KEY);
|
dfsAdmin.createEncryptionZone(notEmptyChild, TEST_KEY, NO_TRASH);
|
||||||
fail("Created EZ on a file");
|
fail("Created EZ on a file");
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
assertExceptionContains("create an encryption zone for a file.", e);
|
assertExceptionContains("create an encryption zone for a file.", e);
|
||||||
|
@ -285,7 +393,7 @@ public class TestEncryptionZones {
|
||||||
fsWrapper.mkdir(zone2, FsPermission.getDirDefault(), false);
|
fsWrapper.mkdir(zone2, FsPermission.getDirDefault(), false);
|
||||||
final String myKeyName = "mykeyname";
|
final String myKeyName = "mykeyname";
|
||||||
try {
|
try {
|
||||||
dfsAdmin.createEncryptionZone(zone2, myKeyName);
|
dfsAdmin.createEncryptionZone(zone2, myKeyName, NO_TRASH);
|
||||||
fail("expected key doesn't exist");
|
fail("expected key doesn't exist");
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
assertExceptionContains("doesn't exist.", e);
|
assertExceptionContains("doesn't exist.", e);
|
||||||
|
@ -293,13 +401,13 @@ public class TestEncryptionZones {
|
||||||
|
|
||||||
/* Test failure of empty and null key name */
|
/* Test failure of empty and null key name */
|
||||||
try {
|
try {
|
||||||
dfsAdmin.createEncryptionZone(zone2, "");
|
dfsAdmin.createEncryptionZone(zone2, "", NO_TRASH);
|
||||||
fail("created a zone with empty key name");
|
fail("created a zone with empty key name");
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
assertExceptionContains("Must specify a key name when creating", e);
|
assertExceptionContains("Must specify a key name when creating", e);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
dfsAdmin.createEncryptionZone(zone2, null);
|
dfsAdmin.createEncryptionZone(zone2, null, NO_TRASH);
|
||||||
fail("created a zone with null key name");
|
fail("created a zone with null key name");
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
assertExceptionContains("Must specify a key name when creating", e);
|
assertExceptionContains("Must specify a key name when creating", e);
|
||||||
|
@ -309,7 +417,7 @@ public class TestEncryptionZones {
|
||||||
|
|
||||||
/* Test success of creating an EZ when they key exists. */
|
/* Test success of creating an EZ when they key exists. */
|
||||||
DFSTestUtil.createKey(myKeyName, cluster, conf);
|
DFSTestUtil.createKey(myKeyName, cluster, conf);
|
||||||
dfsAdmin.createEncryptionZone(zone2, myKeyName);
|
dfsAdmin.createEncryptionZone(zone2, myKeyName, NO_TRASH);
|
||||||
assertNumZones(++numZones);
|
assertNumZones(++numZones);
|
||||||
assertZonePresent(myKeyName, zone2.toString());
|
assertZonePresent(myKeyName, zone2.toString());
|
||||||
|
|
||||||
|
@ -325,7 +433,7 @@ public class TestEncryptionZones {
|
||||||
final HdfsAdmin userAdmin =
|
final HdfsAdmin userAdmin =
|
||||||
new HdfsAdmin(FileSystem.getDefaultUri(conf), conf);
|
new HdfsAdmin(FileSystem.getDefaultUri(conf), conf);
|
||||||
try {
|
try {
|
||||||
userAdmin.createEncryptionZone(nonSuper, TEST_KEY);
|
userAdmin.createEncryptionZone(nonSuper, TEST_KEY, NO_TRASH);
|
||||||
fail("createEncryptionZone is superuser-only operation");
|
fail("createEncryptionZone is superuser-only operation");
|
||||||
} catch (AccessControlException e) {
|
} catch (AccessControlException e) {
|
||||||
assertExceptionContains("Superuser privilege is required", e);
|
assertExceptionContains("Superuser privilege is required", e);
|
||||||
|
@ -337,7 +445,7 @@ public class TestEncryptionZones {
|
||||||
// Test success of creating an encryption zone a few levels down.
|
// Test success of creating an encryption zone a few levels down.
|
||||||
Path deepZone = new Path("/d/e/e/p/zone");
|
Path deepZone = new Path("/d/e/e/p/zone");
|
||||||
fsWrapper.mkdir(deepZone, FsPermission.getDirDefault(), true);
|
fsWrapper.mkdir(deepZone, FsPermission.getDirDefault(), true);
|
||||||
dfsAdmin.createEncryptionZone(deepZone, TEST_KEY);
|
dfsAdmin.createEncryptionZone(deepZone, TEST_KEY, NO_TRASH);
|
||||||
assertNumZones(++numZones);
|
assertNumZones(++numZones);
|
||||||
assertZonePresent(null, deepZone.toString());
|
assertZonePresent(null, deepZone.toString());
|
||||||
|
|
||||||
|
@ -345,7 +453,7 @@ public class TestEncryptionZones {
|
||||||
for (int i=1; i<6; i++) {
|
for (int i=1; i<6; i++) {
|
||||||
final Path zonePath = new Path("/listZone" + i);
|
final Path zonePath = new Path("/listZone" + i);
|
||||||
fsWrapper.mkdir(zonePath, FsPermission.getDirDefault(), false);
|
fsWrapper.mkdir(zonePath, FsPermission.getDirDefault(), false);
|
||||||
dfsAdmin.createEncryptionZone(zonePath, TEST_KEY);
|
dfsAdmin.createEncryptionZone(zonePath, TEST_KEY, NO_TRASH);
|
||||||
numZones++;
|
numZones++;
|
||||||
assertNumZones(numZones);
|
assertNumZones(numZones);
|
||||||
assertZonePresent(null, zonePath.toString());
|
assertZonePresent(null, zonePath.toString());
|
||||||
|
@ -365,7 +473,7 @@ public class TestEncryptionZones {
|
||||||
// without persisting the namespace.
|
// without persisting the namespace.
|
||||||
Path nonpersistZone = new Path("/nonpersistZone");
|
Path nonpersistZone = new Path("/nonpersistZone");
|
||||||
fsWrapper.mkdir(nonpersistZone, FsPermission.getDirDefault(), false);
|
fsWrapper.mkdir(nonpersistZone, FsPermission.getDirDefault(), false);
|
||||||
dfsAdmin.createEncryptionZone(nonpersistZone, TEST_KEY);
|
dfsAdmin.createEncryptionZone(nonpersistZone, TEST_KEY, NO_TRASH);
|
||||||
numZones++;
|
numZones++;
|
||||||
cluster.restartNameNode(true);
|
cluster.restartNameNode(true);
|
||||||
assertNumZones(numZones);
|
assertNumZones(numZones);
|
||||||
|
@ -379,7 +487,7 @@ public class TestEncryptionZones {
|
||||||
final Path zone1 = new Path(rootDir, "zone1");
|
final Path zone1 = new Path(rootDir, "zone1");
|
||||||
|
|
||||||
/* Normal creation of an EZ on rootDir */
|
/* Normal creation of an EZ on rootDir */
|
||||||
dfsAdmin.createEncryptionZone(rootDir, TEST_KEY);
|
dfsAdmin.createEncryptionZone(rootDir, TEST_KEY, NO_TRASH);
|
||||||
assertNumZones(++numZones);
|
assertNumZones(++numZones);
|
||||||
assertZonePresent(null, rootDir.toString());
|
assertZonePresent(null, rootDir.toString());
|
||||||
|
|
||||||
|
@ -407,10 +515,10 @@ public class TestEncryptionZones {
|
||||||
final Path allPath = new Path(testRoot, "accessall");
|
final Path allPath = new Path(testRoot, "accessall");
|
||||||
|
|
||||||
fsWrapper.mkdir(superPath, new FsPermission((short) 0700), true);
|
fsWrapper.mkdir(superPath, new FsPermission((short) 0700), true);
|
||||||
dfsAdmin.createEncryptionZone(superPath, TEST_KEY);
|
dfsAdmin.createEncryptionZone(superPath, TEST_KEY, NO_TRASH);
|
||||||
|
|
||||||
fsWrapper.mkdir(allPath, new FsPermission((short) 0707), true);
|
fsWrapper.mkdir(allPath, new FsPermission((short) 0707), true);
|
||||||
dfsAdmin.createEncryptionZone(allPath, TEST_KEY);
|
dfsAdmin.createEncryptionZone(allPath, TEST_KEY, NO_TRASH);
|
||||||
|
|
||||||
user.doAs(new PrivilegedExceptionAction<Object>() {
|
user.doAs(new PrivilegedExceptionAction<Object>() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -450,8 +558,8 @@ public class TestEncryptionZones {
|
||||||
fsWrapper.mkdir(superPath, new FsPermission((short) 0700), false);
|
fsWrapper.mkdir(superPath, new FsPermission((short) 0700), false);
|
||||||
fsWrapper.mkdir(allPath, new FsPermission((short) 0777), false);
|
fsWrapper.mkdir(allPath, new FsPermission((short) 0777), false);
|
||||||
fsWrapper.mkdir(nonEZDir, new FsPermission((short) 0777), false);
|
fsWrapper.mkdir(nonEZDir, new FsPermission((short) 0777), false);
|
||||||
dfsAdmin.createEncryptionZone(superPath, TEST_KEY);
|
dfsAdmin.createEncryptionZone(superPath, TEST_KEY, NO_TRASH);
|
||||||
dfsAdmin.createEncryptionZone(allPath, TEST_KEY);
|
dfsAdmin.createEncryptionZone(allPath, TEST_KEY, NO_TRASH);
|
||||||
dfsAdmin.allowSnapshot(new Path("/"));
|
dfsAdmin.allowSnapshot(new Path("/"));
|
||||||
final Path newSnap = fs.createSnapshot(new Path("/"));
|
final Path newSnap = fs.createSnapshot(new Path("/"));
|
||||||
DFSTestUtil.createFile(fs, superPathFile, len, (short) 1, 0xFEED);
|
DFSTestUtil.createFile(fs, superPathFile, len, (short) 1, 0xFEED);
|
||||||
|
@ -556,7 +664,7 @@ public class TestEncryptionZones {
|
||||||
final Path pathFooBarFile = new Path(pathFooBar, "file");
|
final Path pathFooBarFile = new Path(pathFooBar, "file");
|
||||||
final int len = 8192;
|
final int len = 8192;
|
||||||
wrapper.mkdir(pathFoo, FsPermission.getDirDefault(), true);
|
wrapper.mkdir(pathFoo, FsPermission.getDirDefault(), true);
|
||||||
dfsAdmin.createEncryptionZone(pathFoo, TEST_KEY);
|
dfsAdmin.createEncryptionZone(pathFoo, TEST_KEY, NO_TRASH);
|
||||||
wrapper.mkdir(pathFooBaz, FsPermission.getDirDefault(), true);
|
wrapper.mkdir(pathFooBaz, FsPermission.getDirDefault(), true);
|
||||||
DFSTestUtil.createFile(fs, pathFooBazFile, len, (short) 1, 0xFEED);
|
DFSTestUtil.createFile(fs, pathFooBazFile, len, (short) 1, 0xFEED);
|
||||||
String contents = DFSTestUtil.readFile(fs, pathFooBazFile);
|
String contents = DFSTestUtil.readFile(fs, pathFooBazFile);
|
||||||
|
@ -615,7 +723,7 @@ public class TestEncryptionZones {
|
||||||
// Create the first enc file
|
// Create the first enc file
|
||||||
final Path zone = new Path("/zone");
|
final Path zone = new Path("/zone");
|
||||||
fs.mkdirs(zone);
|
fs.mkdirs(zone);
|
||||||
dfsAdmin.createEncryptionZone(zone, TEST_KEY);
|
dfsAdmin.createEncryptionZone(zone, TEST_KEY, NO_TRASH);
|
||||||
final Path encFile1 = new Path(zone, "myfile");
|
final Path encFile1 = new Path(zone, "myfile");
|
||||||
DFSTestUtil.createFile(fs, encFile1, len, (short) 1, 0xFEED);
|
DFSTestUtil.createFile(fs, encFile1, len, (short) 1, 0xFEED);
|
||||||
// Read them back in and compare byte-by-byte
|
// Read them back in and compare byte-by-byte
|
||||||
|
@ -650,7 +758,7 @@ public class TestEncryptionZones {
|
||||||
|
|
||||||
final Path zone = new Path("/zone");
|
final Path zone = new Path("/zone");
|
||||||
fs.mkdirs(zone);
|
fs.mkdirs(zone);
|
||||||
dfsAdmin.createEncryptionZone(zone, TEST_KEY);
|
dfsAdmin.createEncryptionZone(zone, TEST_KEY, NO_TRASH);
|
||||||
|
|
||||||
/* Create an unencrypted file for comparison purposes. */
|
/* Create an unencrypted file for comparison purposes. */
|
||||||
final Path unencFile = new Path("/unenc");
|
final Path unencFile = new Path("/unenc");
|
||||||
|
@ -696,7 +804,7 @@ public class TestEncryptionZones {
|
||||||
new HdfsAdmin(FileSystem.getDefaultUri(conf), conf);
|
new HdfsAdmin(FileSystem.getDefaultUri(conf), conf);
|
||||||
final Path zone = new Path("/zone");
|
final Path zone = new Path("/zone");
|
||||||
fs.mkdirs(zone);
|
fs.mkdirs(zone);
|
||||||
dfsAdmin.createEncryptionZone(zone, TEST_KEY);
|
dfsAdmin.createEncryptionZone(zone, TEST_KEY, NO_TRASH);
|
||||||
// Create a file in an EZ, which should succeed
|
// Create a file in an EZ, which should succeed
|
||||||
DFSTestUtil
|
DFSTestUtil
|
||||||
.createFile(fs, new Path(zone, "success1"), 0, (short) 1, 0xFEED);
|
.createFile(fs, new Path(zone, "success1"), 0, (short) 1, 0xFEED);
|
||||||
|
@ -827,7 +935,7 @@ public class TestEncryptionZones {
|
||||||
final Path zone1 = new Path("/zone1");
|
final Path zone1 = new Path("/zone1");
|
||||||
fsWrapper.mkdir(zone1, FsPermission.getDirDefault(), true);
|
fsWrapper.mkdir(zone1, FsPermission.getDirDefault(), true);
|
||||||
try {
|
try {
|
||||||
dfsAdmin.createEncryptionZone(zone1, TEST_KEY);
|
dfsAdmin.createEncryptionZone(zone1, TEST_KEY, NO_TRASH);
|
||||||
fail("expected exception");
|
fail("expected exception");
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
assertExceptionContains("since no key provider is available", e);
|
assertExceptionContains("since no key provider is available", e);
|
||||||
|
@ -869,7 +977,7 @@ public class TestEncryptionZones {
|
||||||
// Create an encrypted file to check isEncrypted returns true
|
// Create an encrypted file to check isEncrypted returns true
|
||||||
final Path zone = new Path(prefix, "zone");
|
final Path zone = new Path(prefix, "zone");
|
||||||
fsWrapper.mkdir(zone, FsPermission.getDirDefault(), true);
|
fsWrapper.mkdir(zone, FsPermission.getDirDefault(), true);
|
||||||
dfsAdmin.createEncryptionZone(zone, TEST_KEY);
|
dfsAdmin.createEncryptionZone(zone, TEST_KEY, NO_TRASH);
|
||||||
final Path encFile = new Path(zone, "encfile");
|
final Path encFile = new Path(zone, "encfile");
|
||||||
fsWrapper.createFile(encFile);
|
fsWrapper.createFile(encFile);
|
||||||
stat = fsWrapper.getFileStatus(encFile);
|
stat = fsWrapper.getFileStatus(encFile);
|
||||||
|
@ -1010,7 +1118,7 @@ public class TestEncryptionZones {
|
||||||
executor.submit(new InjectFaultTask() {
|
executor.submit(new InjectFaultTask() {
|
||||||
@Override
|
@Override
|
||||||
public void doFault() throws Exception {
|
public void doFault() throws Exception {
|
||||||
dfsAdmin.createEncryptionZone(zone1, TEST_KEY);
|
dfsAdmin.createEncryptionZone(zone1, TEST_KEY, NO_TRASH);
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void doCleanup() throws Exception {
|
public void doCleanup() throws Exception {
|
||||||
|
@ -1036,14 +1144,14 @@ public class TestEncryptionZones {
|
||||||
fsWrapper.mkdir(zone1, FsPermission.getDirDefault(), true);
|
fsWrapper.mkdir(zone1, FsPermission.getDirDefault(), true);
|
||||||
final String otherKey = "other_key";
|
final String otherKey = "other_key";
|
||||||
DFSTestUtil.createKey(otherKey, cluster, conf);
|
DFSTestUtil.createKey(otherKey, cluster, conf);
|
||||||
dfsAdmin.createEncryptionZone(zone1, TEST_KEY);
|
dfsAdmin.createEncryptionZone(zone1, TEST_KEY, NO_TRASH);
|
||||||
|
|
||||||
executor.submit(new InjectFaultTask() {
|
executor.submit(new InjectFaultTask() {
|
||||||
@Override
|
@Override
|
||||||
public void doFault() throws Exception {
|
public void doFault() throws Exception {
|
||||||
fsWrapper.delete(zone1, true);
|
fsWrapper.delete(zone1, true);
|
||||||
fsWrapper.mkdir(zone1, FsPermission.getDirDefault(), true);
|
fsWrapper.mkdir(zone1, FsPermission.getDirDefault(), true);
|
||||||
dfsAdmin.createEncryptionZone(zone1, otherKey);
|
dfsAdmin.createEncryptionZone(zone1, otherKey, NO_TRASH);
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void doCleanup() throws Exception {
|
public void doCleanup() throws Exception {
|
||||||
|
@ -1056,7 +1164,7 @@ public class TestEncryptionZones {
|
||||||
fsWrapper.mkdir(zone1, FsPermission.getDirDefault(), true);
|
fsWrapper.mkdir(zone1, FsPermission.getDirDefault(), true);
|
||||||
final String anotherKey = "another_key";
|
final String anotherKey = "another_key";
|
||||||
DFSTestUtil.createKey(anotherKey, cluster, conf);
|
DFSTestUtil.createKey(anotherKey, cluster, conf);
|
||||||
dfsAdmin.createEncryptionZone(zone1, anotherKey);
|
dfsAdmin.createEncryptionZone(zone1, anotherKey, NO_TRASH);
|
||||||
String keyToUse = otherKey;
|
String keyToUse = otherKey;
|
||||||
|
|
||||||
MyInjector injector = new MyInjector();
|
MyInjector injector = new MyInjector();
|
||||||
|
@ -1068,7 +1176,7 @@ public class TestEncryptionZones {
|
||||||
injector.ready.await();
|
injector.ready.await();
|
||||||
fsWrapper.delete(zone1, true);
|
fsWrapper.delete(zone1, true);
|
||||||
fsWrapper.mkdir(zone1, FsPermission.getDirDefault(), true);
|
fsWrapper.mkdir(zone1, FsPermission.getDirDefault(), true);
|
||||||
dfsAdmin.createEncryptionZone(zone1, keyToUse);
|
dfsAdmin.createEncryptionZone(zone1, keyToUse, NO_TRASH);
|
||||||
if (keyToUse == otherKey) {
|
if (keyToUse == otherKey) {
|
||||||
keyToUse = anotherKey;
|
keyToUse = anotherKey;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1129,7 +1237,7 @@ public class TestEncryptionZones {
|
||||||
final Path zone1 = new Path(zoneParent, "zone1");
|
final Path zone1 = new Path(zoneParent, "zone1");
|
||||||
final Path zone1File = new Path(zone1, "file");
|
final Path zone1File = new Path(zone1, "file");
|
||||||
fsWrapper.mkdir(zone1, FsPermission.getDirDefault(), true);
|
fsWrapper.mkdir(zone1, FsPermission.getDirDefault(), true);
|
||||||
dfsAdmin.createEncryptionZone(zone1, TEST_KEY);
|
dfsAdmin.createEncryptionZone(zone1, TEST_KEY, NO_TRASH);
|
||||||
DFSTestUtil.createFile(fs, zone1File, len, (short) 1, 0xFEED);
|
DFSTestUtil.createFile(fs, zone1File, len, (short) 1, 0xFEED);
|
||||||
ByteArrayOutputStream bStream = new ByteArrayOutputStream();
|
ByteArrayOutputStream bStream = new ByteArrayOutputStream();
|
||||||
PrintStream out = new PrintStream(bStream, true);
|
PrintStream out = new PrintStream(bStream, true);
|
||||||
|
@ -1164,7 +1272,7 @@ public class TestEncryptionZones {
|
||||||
final Path zoneFile = new Path(zone, "zoneFile");
|
final Path zoneFile = new Path(zone, "zoneFile");
|
||||||
fsWrapper.mkdir(zone, FsPermission.getDirDefault(), true);
|
fsWrapper.mkdir(zone, FsPermission.getDirDefault(), true);
|
||||||
dfsAdmin.allowSnapshot(zoneParent);
|
dfsAdmin.allowSnapshot(zoneParent);
|
||||||
dfsAdmin.createEncryptionZone(zone, TEST_KEY);
|
dfsAdmin.createEncryptionZone(zone, TEST_KEY, NO_TRASH);
|
||||||
DFSTestUtil.createFile(fs, zoneFile, len, (short) 1, 0xFEED);
|
DFSTestUtil.createFile(fs, zoneFile, len, (short) 1, 0xFEED);
|
||||||
String contents = DFSTestUtil.readFile(fs, zoneFile);
|
String contents = DFSTestUtil.readFile(fs, zoneFile);
|
||||||
final Path snap1 = fs.createSnapshot(zoneParent, "snap1");
|
final Path snap1 = fs.createSnapshot(zoneParent, "snap1");
|
||||||
|
@ -1182,7 +1290,7 @@ public class TestEncryptionZones {
|
||||||
dfsAdmin.getEncryptionZoneForPath(snap2Zone));
|
dfsAdmin.getEncryptionZoneForPath(snap2Zone));
|
||||||
|
|
||||||
// Create the encryption zone again
|
// Create the encryption zone again
|
||||||
dfsAdmin.createEncryptionZone(zone, TEST_KEY2);
|
dfsAdmin.createEncryptionZone(zone, TEST_KEY2, NO_TRASH);
|
||||||
final Path snap3 = fs.createSnapshot(zoneParent, "snap3");
|
final Path snap3 = fs.createSnapshot(zoneParent, "snap3");
|
||||||
final Path snap3Zone = new Path(snap3, zone.getName());
|
final Path snap3Zone = new Path(snap3, zone.getName());
|
||||||
// Check that snap3's EZ has the correct settings
|
// Check that snap3's EZ has the correct settings
|
||||||
|
@ -1245,7 +1353,7 @@ public class TestEncryptionZones {
|
||||||
final Path link = new Path(linkParent, "link");
|
final Path link = new Path(linkParent, "link");
|
||||||
final Path target = new Path(targetParent, "target");
|
final Path target = new Path(targetParent, "target");
|
||||||
fs.mkdirs(parent);
|
fs.mkdirs(parent);
|
||||||
dfsAdmin.createEncryptionZone(parent, TEST_KEY);
|
dfsAdmin.createEncryptionZone(parent, TEST_KEY, NO_TRASH);
|
||||||
fs.mkdirs(linkParent);
|
fs.mkdirs(linkParent);
|
||||||
fs.mkdirs(targetParent);
|
fs.mkdirs(targetParent);
|
||||||
DFSTestUtil.createFile(fs, target, len, (short)1, 0xFEED);
|
DFSTestUtil.createFile(fs, target, len, (short)1, 0xFEED);
|
||||||
|
@ -1259,8 +1367,8 @@ public class TestEncryptionZones {
|
||||||
// encryption zones
|
// encryption zones
|
||||||
fs.mkdirs(linkParent);
|
fs.mkdirs(linkParent);
|
||||||
fs.mkdirs(targetParent);
|
fs.mkdirs(targetParent);
|
||||||
dfsAdmin.createEncryptionZone(linkParent, TEST_KEY);
|
dfsAdmin.createEncryptionZone(linkParent, TEST_KEY, NO_TRASH);
|
||||||
dfsAdmin.createEncryptionZone(targetParent, TEST_KEY);
|
dfsAdmin.createEncryptionZone(targetParent, TEST_KEY, NO_TRASH);
|
||||||
DFSTestUtil.createFile(fs, target, len, (short)1, 0xFEED);
|
DFSTestUtil.createFile(fs, target, len, (short)1, 0xFEED);
|
||||||
content = DFSTestUtil.readFile(fs, target);
|
content = DFSTestUtil.readFile(fs, target);
|
||||||
fs.createSymlink(target, link, false);
|
fs.createSymlink(target, link, false);
|
||||||
|
@ -1275,7 +1383,7 @@ public class TestEncryptionZones {
|
||||||
final int len = 8192;
|
final int len = 8192;
|
||||||
final Path ez = new Path("/ez");
|
final Path ez = new Path("/ez");
|
||||||
fs.mkdirs(ez);
|
fs.mkdirs(ez);
|
||||||
dfsAdmin.createEncryptionZone(ez, TEST_KEY);
|
dfsAdmin.createEncryptionZone(ez, TEST_KEY, NO_TRASH);
|
||||||
final Path src1 = new Path(ez, "src1");
|
final Path src1 = new Path(ez, "src1");
|
||||||
final Path src2 = new Path(ez, "src2");
|
final Path src2 = new Path(ez, "src2");
|
||||||
final Path target = new Path(ez, "target");
|
final Path target = new Path(ez, "target");
|
||||||
|
@ -1302,7 +1410,7 @@ public class TestEncryptionZones {
|
||||||
final Path zone1 = new Path(zoneParent, "zone1");
|
final Path zone1 = new Path(zoneParent, "zone1");
|
||||||
final Path zone1File = new Path(zone1, "file");
|
final Path zone1File = new Path(zone1, "file");
|
||||||
fsWrapper.mkdir(zone1, FsPermission.getDirDefault(), true);
|
fsWrapper.mkdir(zone1, FsPermission.getDirDefault(), true);
|
||||||
dfsAdmin.createEncryptionZone(zone1, TEST_KEY);
|
dfsAdmin.createEncryptionZone(zone1, TEST_KEY, NO_TRASH);
|
||||||
DFSTestUtil.createFile(fs, zone1File, len, (short) 1, 0xFEED);
|
DFSTestUtil.createFile(fs, zone1File, len, (short) 1, 0xFEED);
|
||||||
fs.setSafeMode(SafeModeAction.SAFEMODE_ENTER, false);
|
fs.setSafeMode(SafeModeAction.SAFEMODE_ENTER, false);
|
||||||
fs.saveNamespace();
|
fs.saveNamespace();
|
||||||
|
@ -1332,7 +1440,7 @@ public class TestEncryptionZones {
|
||||||
final Path rootDir = new Path("/");
|
final Path rootDir = new Path("/");
|
||||||
final Path zoneFile = new Path(rootDir, "file");
|
final Path zoneFile = new Path(rootDir, "file");
|
||||||
final Path rawFile = new Path("/.reserved/raw/file");
|
final Path rawFile = new Path("/.reserved/raw/file");
|
||||||
dfsAdmin.createEncryptionZone(rootDir, TEST_KEY);
|
dfsAdmin.createEncryptionZone(rootDir, TEST_KEY, NO_TRASH);
|
||||||
DFSTestUtil.createFile(fs, zoneFile, len, (short) 1, 0xFEED);
|
DFSTestUtil.createFile(fs, zoneFile, len, (short) 1, 0xFEED);
|
||||||
|
|
||||||
assertEquals("File can be created on the root encryption zone " +
|
assertEquals("File can be created on the root encryption zone " +
|
||||||
|
@ -1353,7 +1461,7 @@ public class TestEncryptionZones {
|
||||||
final Path zoneFile = new Path("file");
|
final Path zoneFile = new Path("file");
|
||||||
fs.setWorkingDirectory(baseDir);
|
fs.setWorkingDirectory(baseDir);
|
||||||
fs.mkdirs(zoneDir);
|
fs.mkdirs(zoneDir);
|
||||||
dfsAdmin.createEncryptionZone(zoneDir, TEST_KEY);
|
dfsAdmin.createEncryptionZone(zoneDir, TEST_KEY, NO_TRASH);
|
||||||
DFSTestUtil.createFile(fs, zoneFile, len, (short) 1, 0xFEED);
|
DFSTestUtil.createFile(fs, zoneFile, len, (short) 1, 0xFEED);
|
||||||
|
|
||||||
assertNumZones(1);
|
assertNumZones(1);
|
||||||
|
@ -1367,7 +1475,7 @@ public class TestEncryptionZones {
|
||||||
public void testGetEncryptionZoneOnANonExistentZoneFile() throws Exception {
|
public void testGetEncryptionZoneOnANonExistentZoneFile() throws Exception {
|
||||||
final Path ez = new Path("/ez");
|
final Path ez = new Path("/ez");
|
||||||
fs.mkdirs(ez);
|
fs.mkdirs(ez);
|
||||||
dfsAdmin.createEncryptionZone(ez, TEST_KEY);
|
dfsAdmin.createEncryptionZone(ez, TEST_KEY, NO_TRASH);
|
||||||
Path zoneFile = new Path(ez, "file");
|
Path zoneFile = new Path(ez, "file");
|
||||||
try {
|
try {
|
||||||
fs.getEZForPath(zoneFile);
|
fs.getEZForPath(zoneFile);
|
||||||
|
@ -1392,7 +1500,7 @@ public class TestEncryptionZones {
|
||||||
new HdfsAdmin(FileSystem.getDefaultUri(conf), conf);
|
new HdfsAdmin(FileSystem.getDefaultUri(conf), conf);
|
||||||
final Path zone1 = new Path("/zone1");
|
final Path zone1 = new Path("/zone1");
|
||||||
fs.mkdirs(zone1);
|
fs.mkdirs(zone1);
|
||||||
dfsAdmin.createEncryptionZone(zone1, TEST_KEY);
|
dfsAdmin.createEncryptionZone(zone1, TEST_KEY, NO_TRASH);
|
||||||
|
|
||||||
// Create the encrypted file in zone1
|
// Create the encrypted file in zone1
|
||||||
final Path encFile1 = new Path(zone1, "encFile1");
|
final Path encFile1 = new Path(zone1, "encFile1");
|
||||||
|
@ -1413,12 +1521,12 @@ public class TestEncryptionZones {
|
||||||
|
|
||||||
final Path topEZ = new Path("/topEZ");
|
final Path topEZ = new Path("/topEZ");
|
||||||
fs.mkdirs(topEZ);
|
fs.mkdirs(topEZ);
|
||||||
dfsAdmin.createEncryptionZone(topEZ, TEST_KEY);
|
dfsAdmin.createEncryptionZone(topEZ, TEST_KEY, NO_TRASH);
|
||||||
final String NESTED_EZ_TEST_KEY = "nested_ez_test_key";
|
final String NESTED_EZ_TEST_KEY = "nested_ez_test_key";
|
||||||
DFSTestUtil.createKey(NESTED_EZ_TEST_KEY, cluster, conf);
|
DFSTestUtil.createKey(NESTED_EZ_TEST_KEY, cluster, conf);
|
||||||
final Path nestedEZ = new Path(topEZ, "nestedEZ");
|
final Path nestedEZ = new Path(topEZ, "nestedEZ");
|
||||||
fs.mkdirs(nestedEZ);
|
fs.mkdirs(nestedEZ);
|
||||||
dfsAdmin.createEncryptionZone(nestedEZ, NESTED_EZ_TEST_KEY);
|
dfsAdmin.createEncryptionZone(nestedEZ, NESTED_EZ_TEST_KEY, NO_TRASH);
|
||||||
final Path topEZFile = new Path(topEZ, "file");
|
final Path topEZFile = new Path(topEZ, "file");
|
||||||
final Path nestedEZFile = new Path(nestedEZ, "file");
|
final Path nestedEZFile = new Path(nestedEZ, "file");
|
||||||
DFSTestUtil.createFile(fs, topEZFile, len, (short) 1, 0xFEED);
|
DFSTestUtil.createFile(fs, topEZFile, len, (short) 1, 0xFEED);
|
||||||
|
@ -1433,7 +1541,7 @@ public class TestEncryptionZones {
|
||||||
public void testRootDirEZTrash() throws Exception {
|
public void testRootDirEZTrash() throws Exception {
|
||||||
final HdfsAdmin dfsAdmin =
|
final HdfsAdmin dfsAdmin =
|
||||||
new HdfsAdmin(FileSystem.getDefaultUri(conf), conf);
|
new HdfsAdmin(FileSystem.getDefaultUri(conf), conf);
|
||||||
dfsAdmin.createEncryptionZone(new Path("/"), TEST_KEY);
|
dfsAdmin.createEncryptionZone(new Path("/"), TEST_KEY, NO_TRASH);
|
||||||
final Path encFile = new Path("/encFile");
|
final Path encFile = new Path("/encFile");
|
||||||
final int len = 8192;
|
final int len = 8192;
|
||||||
DFSTestUtil.createFile(fs, encFile, len, (short) 1, 0xFEED);
|
DFSTestUtil.createFile(fs, encFile, len, (short) 1, 0xFEED);
|
||||||
|
@ -1449,13 +1557,13 @@ public class TestEncryptionZones {
|
||||||
new HdfsAdmin(FileSystem.getDefaultUri(conf), conf);
|
new HdfsAdmin(FileSystem.getDefaultUri(conf), conf);
|
||||||
Path ezRoot1 = new Path("/ez1");
|
Path ezRoot1 = new Path("/ez1");
|
||||||
fs.mkdirs(ezRoot1);
|
fs.mkdirs(ezRoot1);
|
||||||
dfsAdmin.createEncryptionZone(ezRoot1, TEST_KEY);
|
dfsAdmin.createEncryptionZone(ezRoot1, TEST_KEY, NO_TRASH);
|
||||||
Path ezRoot2 = new Path("/ez2");
|
Path ezRoot2 = new Path("/ez2");
|
||||||
fs.mkdirs(ezRoot2);
|
fs.mkdirs(ezRoot2);
|
||||||
dfsAdmin.createEncryptionZone(ezRoot2, TEST_KEY);
|
dfsAdmin.createEncryptionZone(ezRoot2, TEST_KEY, NO_TRASH);
|
||||||
Path ezRoot3 = new Path("/ez3");
|
Path ezRoot3 = new Path("/ez3");
|
||||||
fs.mkdirs(ezRoot3);
|
fs.mkdirs(ezRoot3);
|
||||||
dfsAdmin.createEncryptionZone(ezRoot3, TEST_KEY);
|
dfsAdmin.createEncryptionZone(ezRoot3, TEST_KEY, NO_TRASH);
|
||||||
Collection<FileStatus> trashRootsBegin = fs.getTrashRoots(true);
|
Collection<FileStatus> trashRootsBegin = fs.getTrashRoots(true);
|
||||||
assertEquals("Unexpected getTrashRoots result", 0, trashRootsBegin.size());
|
assertEquals("Unexpected getTrashRoots result", 0, trashRootsBegin.size());
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ import org.apache.hadoop.crypto.key.KeyProviderCryptoExtension;
|
||||||
import org.apache.hadoop.fs.permission.FsPermission;
|
import org.apache.hadoop.fs.permission.FsPermission;
|
||||||
import org.apache.hadoop.fs.FileSystemTestHelper;
|
import org.apache.hadoop.fs.FileSystemTestHelper;
|
||||||
import org.apache.hadoop.fs.Path;
|
import org.apache.hadoop.fs.Path;
|
||||||
|
import org.apache.hadoop.hdfs.client.CreateEncryptionZoneFlag;
|
||||||
import org.apache.hadoop.hdfs.server.namenode.ha.HATestUtil;
|
import org.apache.hadoop.hdfs.server.namenode.ha.HATestUtil;
|
||||||
import org.apache.hadoop.hdfs.client.HdfsAdmin;
|
import org.apache.hadoop.hdfs.client.HdfsAdmin;
|
||||||
import org.apache.hadoop.hdfs.server.namenode.NameNode;
|
import org.apache.hadoop.hdfs.server.namenode.NameNode;
|
||||||
|
@ -33,6 +34,7 @@ import org.junit.Test;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.EnumSet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests interaction of encryption zones with HA failover.
|
* Tests interaction of encryption zones with HA failover.
|
||||||
|
@ -49,7 +51,8 @@ public class TestEncryptionZonesWithHA {
|
||||||
private File testRootDir;
|
private File testRootDir;
|
||||||
|
|
||||||
private final String TEST_KEY = "test_key";
|
private final String TEST_KEY = "test_key";
|
||||||
|
protected static final EnumSet< CreateEncryptionZoneFlag > NO_TRASH =
|
||||||
|
EnumSet.of(CreateEncryptionZoneFlag.NO_TRASH);
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setupCluster() throws Exception {
|
public void setupCluster() throws Exception {
|
||||||
|
@ -101,7 +104,7 @@ public class TestEncryptionZonesWithHA {
|
||||||
final Path dirChild = new Path(dir, "child");
|
final Path dirChild = new Path(dir, "child");
|
||||||
final Path dirFile = new Path(dir, "file");
|
final Path dirFile = new Path(dir, "file");
|
||||||
fs.mkdir(dir, FsPermission.getDirDefault());
|
fs.mkdir(dir, FsPermission.getDirDefault());
|
||||||
dfsAdmin0.createEncryptionZone(dir, TEST_KEY);
|
dfsAdmin0.createEncryptionZone(dir, TEST_KEY, NO_TRASH);
|
||||||
fs.mkdir(dirChild, FsPermission.getDirDefault());
|
fs.mkdir(dirChild, FsPermission.getDirDefault());
|
||||||
DFSTestUtil.createFile(fs, dirFile, len, (short) 1, 0xFEED);
|
DFSTestUtil.createFile(fs, dirFile, len, (short) 1, 0xFEED);
|
||||||
String contents = DFSTestUtil.readFile(fs, dirFile);
|
String contents = DFSTestUtil.readFile(fs, dirFile);
|
||||||
|
|
|
@ -73,7 +73,7 @@ public class TestEncryptionZonesWithKMS extends TestEncryptionZones {
|
||||||
public void testCreateEZPopulatesEDEKCache() throws Exception {
|
public void testCreateEZPopulatesEDEKCache() throws Exception {
|
||||||
final Path zonePath = new Path("/TestEncryptionZone");
|
final Path zonePath = new Path("/TestEncryptionZone");
|
||||||
fsWrapper.mkdir(zonePath, FsPermission.getDirDefault(), false);
|
fsWrapper.mkdir(zonePath, FsPermission.getDirDefault(), false);
|
||||||
dfsAdmin.createEncryptionZone(zonePath, TEST_KEY);
|
dfsAdmin.createEncryptionZone(zonePath, TEST_KEY, NO_TRASH);
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
KMSClientProvider kcp = (KMSClientProvider) Whitebox
|
KMSClientProvider kcp = (KMSClientProvider) Whitebox
|
||||||
.getInternalState(cluster.getNamesystem().getProvider(), "extension");
|
.getInternalState(cluster.getNamesystem().getProvider(), "extension");
|
||||||
|
@ -102,7 +102,7 @@ public class TestEncryptionZonesWithKMS extends TestEncryptionZones {
|
||||||
public void testWarmupEDEKCacheOnStartup() throws Exception {
|
public void testWarmupEDEKCacheOnStartup() throws Exception {
|
||||||
final Path zonePath = new Path("/TestEncryptionZone");
|
final Path zonePath = new Path("/TestEncryptionZone");
|
||||||
fsWrapper.mkdir(zonePath, FsPermission.getDirDefault(), false);
|
fsWrapper.mkdir(zonePath, FsPermission.getDirDefault(), false);
|
||||||
dfsAdmin.createEncryptionZone(zonePath, TEST_KEY);
|
dfsAdmin.createEncryptionZone(zonePath, TEST_KEY, NO_TRASH);
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
KMSClientProvider spy = (KMSClientProvider) Whitebox
|
KMSClientProvider spy = (KMSClientProvider) Whitebox
|
||||||
|
|
|
@ -21,6 +21,7 @@ import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.PrivilegedExceptionAction;
|
import java.security.PrivilegedExceptionAction;
|
||||||
|
import java.util.EnumSet;
|
||||||
|
|
||||||
import org.apache.hadoop.conf.Configuration;
|
import org.apache.hadoop.conf.Configuration;
|
||||||
import org.apache.hadoop.crypto.key.JavaKeyStoreProvider;
|
import org.apache.hadoop.crypto.key.JavaKeyStoreProvider;
|
||||||
|
@ -31,6 +32,7 @@ import org.apache.hadoop.fs.FileSystemTestHelper;
|
||||||
import org.apache.hadoop.fs.FileSystemTestWrapper;
|
import org.apache.hadoop.fs.FileSystemTestWrapper;
|
||||||
import org.apache.hadoop.fs.Path;
|
import org.apache.hadoop.fs.Path;
|
||||||
import org.apache.hadoop.fs.permission.FsPermission;
|
import org.apache.hadoop.fs.permission.FsPermission;
|
||||||
|
import org.apache.hadoop.hdfs.client.CreateEncryptionZoneFlag;
|
||||||
import org.apache.hadoop.hdfs.client.HdfsAdmin;
|
import org.apache.hadoop.hdfs.client.HdfsAdmin;
|
||||||
import org.apache.hadoop.hdfs.server.namenode.EncryptionZoneManager;
|
import org.apache.hadoop.hdfs.server.namenode.EncryptionZoneManager;
|
||||||
import org.apache.hadoop.hdfs.server.namenode.FSDirectory;
|
import org.apache.hadoop.hdfs.server.namenode.FSDirectory;
|
||||||
|
@ -61,6 +63,8 @@ public class TestReservedRawPaths {
|
||||||
|
|
||||||
protected FileSystemTestWrapper fsWrapper;
|
protected FileSystemTestWrapper fsWrapper;
|
||||||
protected FileContextTestWrapper fcWrapper;
|
protected FileContextTestWrapper fcWrapper;
|
||||||
|
protected static final EnumSet< CreateEncryptionZoneFlag > NO_TRASH =
|
||||||
|
EnumSet.of(CreateEncryptionZoneFlag.NO_TRASH);
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup() throws Exception {
|
public void setup() throws Exception {
|
||||||
|
@ -114,7 +118,7 @@ public class TestReservedRawPaths {
|
||||||
// Create the first enc file
|
// Create the first enc file
|
||||||
final Path zone = new Path("/zone");
|
final Path zone = new Path("/zone");
|
||||||
fs.mkdirs(zone);
|
fs.mkdirs(zone);
|
||||||
dfsAdmin.createEncryptionZone(zone, TEST_KEY);
|
dfsAdmin.createEncryptionZone(zone, TEST_KEY, NO_TRASH);
|
||||||
final Path encFile1 = new Path(zone, "myfile");
|
final Path encFile1 = new Path(zone, "myfile");
|
||||||
DFSTestUtil.createFile(fs, encFile1, len, (short) 1, 0xFEED);
|
DFSTestUtil.createFile(fs, encFile1, len, (short) 1, 0xFEED);
|
||||||
// Read them back in and compare byte-by-byte
|
// Read them back in and compare byte-by-byte
|
||||||
|
@ -154,7 +158,7 @@ public class TestReservedRawPaths {
|
||||||
final Path zone = new Path("zone");
|
final Path zone = new Path("zone");
|
||||||
final Path slashZone = new Path("/", zone);
|
final Path slashZone = new Path("/", zone);
|
||||||
fs.mkdirs(slashZone);
|
fs.mkdirs(slashZone);
|
||||||
dfsAdmin.createEncryptionZone(slashZone, TEST_KEY);
|
dfsAdmin.createEncryptionZone(slashZone, TEST_KEY, NO_TRASH);
|
||||||
|
|
||||||
final Path base = new Path("base");
|
final Path base = new Path("base");
|
||||||
final Path reservedRaw = new Path("/.reserved/raw");
|
final Path reservedRaw = new Path("/.reserved/raw");
|
||||||
|
@ -186,7 +190,7 @@ public class TestReservedRawPaths {
|
||||||
final Path zone = new Path("zone");
|
final Path zone = new Path("zone");
|
||||||
final Path slashZone = new Path("/", zone);
|
final Path slashZone = new Path("/", zone);
|
||||||
fs.mkdirs(slashZone);
|
fs.mkdirs(slashZone);
|
||||||
dfsAdmin.createEncryptionZone(slashZone, TEST_KEY);
|
dfsAdmin.createEncryptionZone(slashZone, TEST_KEY, NO_TRASH);
|
||||||
final Path rawRoot = new Path("/.reserved/raw");
|
final Path rawRoot = new Path("/.reserved/raw");
|
||||||
final Path dir1 = new Path("dir1");
|
final Path dir1 = new Path("dir1");
|
||||||
final Path rawDir1 = new Path(rawRoot, dir1);
|
final Path rawDir1 = new Path(rawRoot, dir1);
|
||||||
|
@ -224,7 +228,7 @@ public class TestReservedRawPaths {
|
||||||
final Path zone = new Path("zone");
|
final Path zone = new Path("zone");
|
||||||
final Path slashZone = new Path("/", zone);
|
final Path slashZone = new Path("/", zone);
|
||||||
fs.mkdirs(slashZone);
|
fs.mkdirs(slashZone);
|
||||||
dfsAdmin.createEncryptionZone(slashZone, TEST_KEY);
|
dfsAdmin.createEncryptionZone(slashZone, TEST_KEY, NO_TRASH);
|
||||||
final Path base = new Path("base");
|
final Path base = new Path("base");
|
||||||
final Path reservedRaw = new Path("/.reserved/raw");
|
final Path reservedRaw = new Path("/.reserved/raw");
|
||||||
final int len = 8192;
|
final int len = 8192;
|
||||||
|
|
|
@ -68,6 +68,7 @@
|
||||||
<command>-fs NAMENODE -mkdir /foo</command>
|
<command>-fs NAMENODE -mkdir /foo</command>
|
||||||
<command>-fs NAMENODE -ls /</command>-
|
<command>-fs NAMENODE -ls /</command>-
|
||||||
<crypto-admin-command>-createZone -path /foo -keyName myKey</crypto-admin-command>
|
<crypto-admin-command>-createZone -path /foo -keyName myKey</crypto-admin-command>
|
||||||
|
<command>-fs NAMENODE -rmdir /foo/.Trash</command>
|
||||||
<crypto-admin-command>-createZone -path /foo -keyName myKey</crypto-admin-command>
|
<crypto-admin-command>-createZone -path /foo -keyName myKey</crypto-admin-command>
|
||||||
</test-commands>
|
</test-commands>
|
||||||
<cleanup-commands>
|
<cleanup-commands>
|
||||||
|
@ -91,7 +92,9 @@
|
||||||
<crypto-admin-command>-createZone -keyName myKey -path /foo/bar</crypto-admin-command>
|
<crypto-admin-command>-createZone -keyName myKey -path /foo/bar</crypto-admin-command>
|
||||||
</test-commands>
|
</test-commands>
|
||||||
<cleanup-commands>
|
<cleanup-commands>
|
||||||
|
<command>-fs NAMENODE -rmdir /foo/bar/.Trash</command>
|
||||||
<command>-fs NAMENODE -rmdir /foo/bar</command>
|
<command>-fs NAMENODE -rmdir /foo/bar</command>
|
||||||
|
<command>-fs NAMENODE -rmdir /foo/.Trash</command>
|
||||||
<command>-fs NAMENODE -rmdir /foo</command>
|
<command>-fs NAMENODE -rmdir /foo</command>
|
||||||
</cleanup-commands>
|
</cleanup-commands>
|
||||||
<comparators>
|
<comparators>
|
||||||
|
@ -180,6 +183,7 @@
|
||||||
<crypto-admin-command>-createZone -path /foo/bar/baz -keyName myKey</crypto-admin-command>
|
<crypto-admin-command>-createZone -path /foo/bar/baz -keyName myKey</crypto-admin-command>
|
||||||
</test-commands>
|
</test-commands>
|
||||||
<cleanup-commands>
|
<cleanup-commands>
|
||||||
|
<command>-fs NAMENODE -rmdir /foo/bar/baz/.Trash</command>
|
||||||
<command>-fs NAMENODE -rmdir /foo/bar/baz</command>
|
<command>-fs NAMENODE -rmdir /foo/bar/baz</command>
|
||||||
<command>-fs NAMENODE -rmdir /foo/bar</command>
|
<command>-fs NAMENODE -rmdir /foo/bar</command>
|
||||||
<command>-fs NAMENODE -rmdir /foo/</command>
|
<command>-fs NAMENODE -rmdir /foo/</command>
|
||||||
|
@ -205,7 +209,9 @@
|
||||||
</test-commands>
|
</test-commands>
|
||||||
<cleanup-commands>
|
<cleanup-commands>
|
||||||
<command>-fs NAMENODE -rmdir /src/subdir</command>
|
<command>-fs NAMENODE -rmdir /src/subdir</command>
|
||||||
|
<command>-fs NAMENODE -rmdir /src/.Trash</command>
|
||||||
<command>-fs NAMENODE -rmdir /src</command>
|
<command>-fs NAMENODE -rmdir /src</command>
|
||||||
|
<command>-fs NAMENODE -rmdir /dst/.Trash</command>
|
||||||
<command>-fs NAMENODE -rmdir /dst</command>
|
<command>-fs NAMENODE -rmdir /dst</command>
|
||||||
</cleanup-commands>
|
</cleanup-commands>
|
||||||
<comparators>
|
<comparators>
|
||||||
|
@ -227,6 +233,7 @@
|
||||||
</test-commands>
|
</test-commands>
|
||||||
<cleanup-commands>
|
<cleanup-commands>
|
||||||
<command>-fs NAMENODE -rmdir /src</command>
|
<command>-fs NAMENODE -rmdir /src</command>
|
||||||
|
<command>-fs NAMENODE -rmdir /dst/.Trash</command>
|
||||||
<command>-fs NAMENODE -rmdir /dst</command>
|
<command>-fs NAMENODE -rmdir /dst</command>
|
||||||
</cleanup-commands>
|
</cleanup-commands>
|
||||||
<comparators>
|
<comparators>
|
||||||
|
@ -249,6 +256,7 @@
|
||||||
</test-commands>
|
</test-commands>
|
||||||
<cleanup-commands>
|
<cleanup-commands>
|
||||||
<command>-fs NAMENODE -rm /src/foo</command>
|
<command>-fs NAMENODE -rm /src/foo</command>
|
||||||
|
<command>-fs NAMENODE -rmdir /src/.Trash</command>
|
||||||
<command>-fs NAMENODE -rmdir /src</command>
|
<command>-fs NAMENODE -rmdir /src</command>
|
||||||
<command>-fs NAMENODE -rmdir /dst</command>
|
<command>-fs NAMENODE -rmdir /dst</command>
|
||||||
</cleanup-commands>
|
</cleanup-commands>
|
||||||
|
@ -269,6 +277,7 @@
|
||||||
<command>-fs NAMENODE -ls /</command>-
|
<command>-fs NAMENODE -ls /</command>-
|
||||||
</test-commands>
|
</test-commands>
|
||||||
<cleanup-commands>
|
<cleanup-commands>
|
||||||
|
<command>-fs NAMENODE -rmdir /src/.Trash</command>
|
||||||
<command>-fs NAMENODE -rmdir /src</command>
|
<command>-fs NAMENODE -rmdir /src</command>
|
||||||
<command>-fs NAMENODE -rmdir /dst</command>
|
<command>-fs NAMENODE -rmdir /dst</command>
|
||||||
</cleanup-commands>
|
</cleanup-commands>
|
||||||
|
@ -292,6 +301,7 @@
|
||||||
<cleanup-commands>
|
<cleanup-commands>
|
||||||
<command>-fs NAMENODE -rmdir /src/subdir2/subdir1</command>
|
<command>-fs NAMENODE -rmdir /src/subdir2/subdir1</command>
|
||||||
<command>-fs NAMENODE -rmdir /src/subdir2</command>
|
<command>-fs NAMENODE -rmdir /src/subdir2</command>
|
||||||
|
<command>-fs NAMENODE -rmdir /src/.Trash</command>
|
||||||
<command>-fs NAMENODE -rmdir /src</command>
|
<command>-fs NAMENODE -rmdir /src</command>
|
||||||
</cleanup-commands>
|
</cleanup-commands>
|
||||||
<comparators>
|
<comparators>
|
||||||
|
@ -302,5 +312,81 @@
|
||||||
</comparators>
|
</comparators>
|
||||||
</test>
|
</test>
|
||||||
|
|
||||||
|
<test>
|
||||||
|
<description>Test failure of provisioning a trash dir if the EZ does not exist</description>
|
||||||
|
<test-commands>
|
||||||
|
<command>-fs NAMENODE -mkdir /src</command>
|
||||||
|
<crypto-admin-command>-provisionTrash -path /src</crypto-admin-command>-
|
||||||
|
</test-commands>
|
||||||
|
<cleanup-commands>
|
||||||
|
<command>-fs NAMENODE -rmdir /src</command>
|
||||||
|
</cleanup-commands>
|
||||||
|
<comparators>
|
||||||
|
<comparator>
|
||||||
|
<type>SubstringComparator</type>
|
||||||
|
<expected-output>/src is not an encryption zone.</expected-output>
|
||||||
|
</comparator>
|
||||||
|
</comparators>
|
||||||
|
</test>
|
||||||
|
|
||||||
|
<test>
|
||||||
|
<description>Test failure of provisioning a trash dir if .Trash exists</description>
|
||||||
|
<test-commands>
|
||||||
|
<command>-fs NAMENODE -mkdir /src</command>
|
||||||
|
<crypto-admin-command>-createZone -path /src -keyName myKey</crypto-admin-command>
|
||||||
|
<crypto-admin-command>-provisionTrash -path /src</crypto-admin-command>-
|
||||||
|
</test-commands>
|
||||||
|
<cleanup-commands>
|
||||||
|
<command>-fs NAMENODE -rm /src/.Trash</command>
|
||||||
|
<command>-fs NAMENODE -rmdir /src</command>
|
||||||
|
</cleanup-commands>
|
||||||
|
<comparators>
|
||||||
|
<comparator>
|
||||||
|
<type>SubstringComparator</type>
|
||||||
|
<expected-output>Will not provision new trash directory for encryption zone /src. Path already exists.</expected-output>
|
||||||
|
</comparator>
|
||||||
|
</comparators>
|
||||||
|
</test>
|
||||||
|
|
||||||
|
<test>
|
||||||
|
<description>Test success of provisioning a trash dir</description>
|
||||||
|
<test-commands>
|
||||||
|
<command>-fs NAMENODE -mkdir /src</command>
|
||||||
|
<crypto-admin-command>-createZone -path /src -keyName myKey</crypto-admin-command>
|
||||||
|
<command>-fs NAMENODE -rmdir /src/.Trash</command>
|
||||||
|
<crypto-admin-command>-provisionTrash -path /src</crypto-admin-command>-
|
||||||
|
</test-commands>
|
||||||
|
<cleanup-commands>
|
||||||
|
<command>-fs NAMENODE -rmdir /src/.Trash</command>
|
||||||
|
<command>-fs NAMENODE -rmdir /src</command>
|
||||||
|
</cleanup-commands>
|
||||||
|
<comparators>
|
||||||
|
<comparator>
|
||||||
|
<type>SubstringComparator</type>
|
||||||
|
<expected-output>Created a trash directory for /src</expected-output>
|
||||||
|
</comparator>
|
||||||
|
</comparators>
|
||||||
|
</test>
|
||||||
|
|
||||||
|
<test>
|
||||||
|
<description>Test failure of provisioning a trash dir for incorrect EZ directory</description>
|
||||||
|
<test-commands>
|
||||||
|
<command>-fs NAMENODE -mkdir /src</command>
|
||||||
|
<crypto-admin-command>-createZone -path /src -keyName myKey</crypto-admin-command>
|
||||||
|
<command>-fs NAMENODE -mkdir /src/dir1</command>
|
||||||
|
<crypto-admin-command>-provisionTrash -path /src/dir1</crypto-admin-command>-
|
||||||
|
</test-commands>
|
||||||
|
<cleanup-commands>
|
||||||
|
<command>-fs NAMENODE -rmdir /src/dir1</command>
|
||||||
|
<command>-fs NAMENODE -rmdir /src/.Trash</command>
|
||||||
|
<command>-fs NAMENODE -rmdir /src</command>
|
||||||
|
</cleanup-commands>
|
||||||
|
<comparators>
|
||||||
|
<comparator>
|
||||||
|
<type>SubstringComparator</type>
|
||||||
|
<expected-output>/src/dir1 is not the root of an encryption zone.</expected-output>
|
||||||
|
</comparator>
|
||||||
|
</comparators>
|
||||||
|
</test>
|
||||||
</tests>
|
</tests>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|
Loading…
Reference in New Issue