HDFS-13129. Add a test for DfsAdmin refreshSuperUserGroupsConfiguration. Contributed by Mukul Kumar Singh

(cherry picked from commit a68b04370f)
This commit is contained in:
Bharat Viswanadham 2018-04-17 12:37:30 -07:00
parent 42aef3b655
commit fc11555caf
2 changed files with 85 additions and 5 deletions

View File

@ -26,6 +26,7 @@ import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_NAMENODE_HEARTBEAT_RECHEC
import com.google.common.base.Supplier;
import com.google.common.collect.Lists;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.text.StrBuilder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -56,17 +57,24 @@ import org.apache.hadoop.hdfs.server.datanode.DataNode;
import org.apache.hadoop.hdfs.server.datanode.StorageLocation;
import org.apache.hadoop.hdfs.server.namenode.NameNode;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.ipc.RemoteException;
import org.apache.hadoop.security.AccessControlException;
import org.apache.hadoop.security.TestRefreshUserMappings;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.security.authorize.DefaultImpersonationProvider;
import org.apache.hadoop.test.GenericTestUtils;
import org.apache.hadoop.test.PathUtils;
import org.apache.hadoop.util.ToolRunner;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.Assert;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@ -101,6 +109,7 @@ public class TestDFSAdmin {
private final ByteArrayOutputStream err = new ByteArrayOutputStream();
private static final PrintStream OLD_OUT = System.out;
private static final PrintStream OLD_ERR = System.err;
private String tempResource = null;
@Before
public void setUp() throws Exception {
@ -108,7 +117,7 @@ public class TestDFSAdmin {
conf.setInt(IPC_CLIENT_CONNECT_MAX_RETRIES_KEY, 3);
restartCluster();
admin = new DFSAdmin();
admin = new DFSAdmin(conf);
}
private void redirectStream() {
@ -137,6 +146,11 @@ public class TestDFSAdmin {
}
resetStream();
if (tempResource != null) {
File f = new File(tempResource);
FileUtils.deleteQuietly(f);
tempResource = null;
}
}
private void restartCluster() throws IOException {
@ -923,4 +937,68 @@ public class TestDFSAdmin {
cluster.shutdown();
}
}
@Test
public void testRefreshProxyUser() throws Exception {
Path dirPath = new Path("/testdir1");
Path subDirPath = new Path("/testdir1/subdir1");
UserGroupInformation loginUserUgi = UserGroupInformation.getLoginUser();
String proxyUser = "fakeuser";
String realUser = loginUserUgi.getShortUserName();
UserGroupInformation proxyUgi =
UserGroupInformation.createProxyUserForTesting(proxyUser,
loginUserUgi, loginUserUgi.getGroupNames());
// create a directory as login user and re-assign it to proxy user
loginUserUgi.doAs(new PrivilegedExceptionAction<Integer>() {
@Override
public Integer run() throws Exception {
cluster.getFileSystem().mkdirs(dirPath);
cluster.getFileSystem().setOwner(dirPath, proxyUser,
proxyUgi.getPrimaryGroupName());
return 0;
}
});
// try creating subdirectory inside the directory as proxy user,
// This should fail because of the current user hasn't still been proxied
try {
proxyUgi.doAs(new PrivilegedExceptionAction<Integer>() {
@Override public Integer run() throws Exception {
cluster.getFileSystem().mkdirs(subDirPath);
return 0;
}
});
} catch (RemoteException re) {
Assert.assertTrue(re.unwrapRemoteException()
instanceof AccessControlException);
Assert.assertTrue(re.unwrapRemoteException().getMessage()
.equals("User: " + realUser +
" is not allowed to impersonate " + proxyUser));
}
// refresh will look at configuration on the server side
// add additional resource with the new value
// so the server side will pick it up
String userKeyGroups = DefaultImpersonationProvider.getTestProvider().
getProxySuperuserGroupConfKey(realUser);
String userKeyHosts = DefaultImpersonationProvider.getTestProvider().
getProxySuperuserIpConfKey(realUser);
String rsrc = "testGroupMappingRefresh_rsrc.xml";
tempResource = TestRefreshUserMappings.addNewConfigResource(rsrc,
userKeyGroups, "*", userKeyHosts, "*");
String[] args = new String[]{"-refreshSuperUserGroupsConfiguration"};
admin.run(args);
// After proxying the fakeuser, the mkdir should work
proxyUgi.doAs(new PrivilegedExceptionAction<Integer>() {
@Override
public Integer run() throws Exception {
cluster.getFileSystem().mkdirs(dirPath);
return 0;
}
});
}
}

View File

@ -208,7 +208,8 @@ public class TestRefreshUserMappings {
// add additional resource with the new value
// so the server side will pick it up
String rsrc = "testGroupMappingRefresh_rsrc.xml";
addNewConfigResource(rsrc, userKeyGroups, "gr2", userKeyHosts, "127.0.0.1");
tempResource = addNewConfigResource(rsrc, userKeyGroups, "gr2",
userKeyHosts, "127.0.0.1");
DFSAdmin admin = new DFSAdmin(config);
String [] args = new String[]{"-refreshSuperUserGroupsConfiguration"};
@ -232,7 +233,7 @@ public class TestRefreshUserMappings {
}
private void addNewConfigResource(String rsrcName, String keyGroup,
public static String addNewConfigResource(String rsrcName, String keyGroup,
String groups, String keyHosts, String hosts)
throws FileNotFoundException, UnsupportedEncodingException {
// location for temp resource should be in CLASSPATH
@ -242,17 +243,18 @@ public class TestRefreshUserMappings {
String urlPath = URLDecoder.decode(url.getPath().toString(), "UTF-8");
Path p = new Path(urlPath);
Path dir = p.getParent();
tempResource = dir.toString() + "/" + rsrcName;
String tmp = dir.toString() + "/" + rsrcName;
String newResource =
"<configuration>"+
"<property><name>" + keyGroup + "</name><value>"+groups+"</value></property>" +
"<property><name>" + keyHosts + "</name><value>"+hosts+"</value></property>" +
"</configuration>";
PrintWriter writer = new PrintWriter(new FileOutputStream(tempResource));
PrintWriter writer = new PrintWriter(new FileOutputStream(tmp));
writer.println(newResource);
writer.close();
Configuration.addDefaultResource(rsrcName);
return tmp;
}
}