HADOOP-14212. Expose SecurityEnabled boolean field in JMX for other services besides NameNode. Contributed by Adam Antal.

This commit is contained in:
Wei-Chiu Chuang 2018-08-14 17:19:00 -07:00 committed by Arpit Agarwal
parent 44c4928b64
commit 78fb14ba49
8 changed files with 156 additions and 5 deletions

View File

@ -3142,6 +3142,11 @@ public class DataNode extends ReconfigurableBase
}
}
@Override
public boolean isSecurityEnabled() {
return UserGroupInformation.isSecurityEnabled();
}
public void refreshNamenodes(Configuration conf) throws IOException {
blockPoolManager.refreshNamenodes(conf);
}

View File

@ -146,4 +146,11 @@ public interface DataNodeMXBean {
* @return list of slow disks
*/
String getSlowDisks();
/**
* Gets if security is enabled.
*
* @return true, if security is enabled.
*/
boolean isSecurityEnabled();
}

View File

@ -722,6 +722,11 @@ public class SecondaryNameNode implements Runnable,
return NetUtils.getHostPortString(nameNodeAddr);
}
@Override
public boolean isSecurityEnabled() {
return UserGroupInformation.isSecurityEnabled();
}
@Override // SecondaryNameNodeInfoMXBean
public long getStartTime() {
return starttime;

View File

@ -31,6 +31,13 @@ public interface SecondaryNameNodeInfoMXBean extends VersionInfoMXBean {
*/
public String getHostAndPort();
/**
* Gets if security is enabled.
*
* @return true, if security is enabled.
*/
boolean isSecurityEnabled();
/**
* @return the timestamp of when the SNN starts
*/

View File

@ -38,6 +38,8 @@ import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hdfs.DFSConfigKeys;
import org.apache.hadoop.hdfs.DFSTestUtil;
import org.apache.hadoop.hdfs.MiniDFSCluster;
import org.apache.hadoop.hdfs.protocol.datatransfer.sasl.SaslDataTransferTestCase;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.test.GenericTestUtils;
import org.junit.Assert;
import org.junit.Test;
@ -49,7 +51,7 @@ import static org.junit.Assert.assertTrue;
/**
* Class for testing {@link DataNodeMXBean} implementation
*/
public class TestDataNodeMXBean {
public class TestDataNodeMXBean extends SaslDataTransferTestCase {
public static final Log LOG = LogFactory.getLog(TestDataNodeMXBean.class);
@ -117,6 +119,49 @@ public class TestDataNodeMXBean {
}
}
}
@Test
public void testDataNodeMXBeanSecurityEnabled() throws Exception {
Configuration simpleConf = new Configuration();
Configuration secureConf = createSecureConfig("authentication");
// get attribute "SecurityEnabled" with simple configuration
try (MiniDFSCluster cluster =
new MiniDFSCluster.Builder(simpleConf).build()) {
List<DataNode> datanodes = cluster.getDataNodes();
Assert.assertEquals(datanodes.size(), 1);
DataNode datanode = datanodes.get(0);
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
ObjectName mxbeanName = new ObjectName(
"Hadoop:service=DataNode,name=DataNodeInfo");
boolean securityEnabled = (boolean) mbs.getAttribute(mxbeanName,
"SecurityEnabled");
Assert.assertFalse(securityEnabled);
Assert.assertEquals(datanode.isSecurityEnabled(), securityEnabled);
}
// get attribute "SecurityEnabled" with secure configuration
try (MiniDFSCluster cluster =
new MiniDFSCluster.Builder(secureConf).build()) {
List<DataNode> datanodes = cluster.getDataNodes();
Assert.assertEquals(datanodes.size(), 1);
DataNode datanode = datanodes.get(0);
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
ObjectName mxbeanName = new ObjectName(
"Hadoop:service=DataNode,name=DataNodeInfo");
boolean securityEnabled = (boolean) mbs.getAttribute(mxbeanName,
"SecurityEnabled");
Assert.assertTrue(securityEnabled);
Assert.assertEquals(datanode.isSecurityEnabled(), securityEnabled);
}
// setting back the authentication method
UserGroupInformation.setConfiguration(simpleConf);
}
private static String replaceDigits(final String s) {
return s.replaceAll("[0-9]+", "_DIGITS_");

View File

@ -22,8 +22,10 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.security.PrivilegedExceptionAction;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.permission.FsPermission;
@ -33,10 +35,12 @@ import org.apache.hadoop.hdfs.MiniDFSCluster;
import org.apache.hadoop.hdfs.protocol.datatransfer.sasl.SaslDataTransferTestCase;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.security.UserGroupInformation.AuthenticationMethod;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import javax.management.MBeanServer;
import javax.management.ObjectName;
public class TestSecureNameNode extends SaslDataTransferTestCase {
final static private int NUM_OF_DATANODES = 0;
@ -117,4 +121,50 @@ public class TestSecureNameNode extends SaslDataTransferTestCase {
return;
}
/**
* Test NameNodeStatusMXBean with security enabled and disabled.
*
* @throws Exception
*/
@Test
public void testNameNodeStatusMXBeanSecurityEnabled() throws Exception {
Configuration simpleConf = new Configuration();
Configuration secureConf = createSecureConfig("authentication");
// disabling security
UserGroupInformation.setConfiguration(simpleConf);
// get attribute "SecurityEnabled" with simple configuration
try (MiniDFSCluster cluster =
new MiniDFSCluster.Builder(simpleConf).build()) {
cluster.waitActive();
NameNode namenode = cluster.getNameNode();
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
ObjectName mxbeanName = new ObjectName(
"Hadoop:service=NameNode,name=NameNodeStatus");
boolean securityEnabled = (boolean) mbs.getAttribute(mxbeanName,
"SecurityEnabled");
Assert.assertFalse(securityEnabled);
Assert.assertEquals(namenode.isSecurityEnabled(), securityEnabled);
}
// get attribute "SecurityEnabled" with secure configuration
try (MiniDFSCluster cluster =
new MiniDFSCluster.Builder(secureConf).build()) {
cluster.waitActive();
NameNode namenode = cluster.getNameNode();
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
ObjectName mxbeanName = new ObjectName(
"Hadoop:service=NameNode,name=NameNodeStatus");
boolean securityEnabled = (boolean) mbs.getAttribute(mxbeanName,
"SecurityEnabled");
Assert.assertTrue(securityEnabled);
Assert.assertEquals(namenode.isSecurityEnabled(), securityEnabled);
}
}
}

View File

@ -25,8 +25,10 @@ import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.permission.FsPermission;
import org.apache.hadoop.metrics2.lib.DefaultMetricsSystem;
import org.apache.hadoop.metrics2.util.MBeans;
import org.apache.hadoop.security.Credentials;
import org.apache.hadoop.security.SecurityUtil;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.service.CompositeService;
import org.apache.hadoop.util.ExitUtil;
import org.apache.hadoop.util.GenericOptionsParser;
@ -87,8 +89,8 @@ import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.atomic.AtomicBoolean;
public class NodeManager extends CompositeService
implements EventHandler<NodeManagerEvent> {
public class NodeManager extends CompositeService
implements EventHandler<NodeManagerEvent>, NodeManagerMXBean {
/**
* Node manager return status codes.
@ -470,6 +472,8 @@ public class NodeManager extends CompositeService
throw new YarnRuntimeException("Failed NodeManager login", e);
}
registerMXBean();
super.serviceInit(conf);
// TODO add local dirs to del
}
@ -947,6 +951,18 @@ public class NodeManager extends CompositeService
LOG.warn("Invalid shutdown event " + event.getType() + ". Ignoring.");
}
}
/**
* Register NodeManagerMXBean.
*/
private void registerMXBean() {
MBeans.register("NodeManager", "NodeManager", this);
}
@Override
public boolean isSecurityEnabled() {
return UserGroupInformation.isSecurityEnabled();
}
// For testing
NodeManager createNewNodeManager() {

View File

@ -33,6 +33,7 @@ import org.apache.hadoop.http.HttpServer2;
import org.apache.hadoop.metrics2.MetricsSystem;
import org.apache.hadoop.metrics2.lib.DefaultMetricsSystem;
import org.apache.hadoop.metrics2.source.JvmMetrics;
import org.apache.hadoop.metrics2.util.MBeans;
import org.apache.hadoop.net.NetUtils;
import org.apache.hadoop.security.SecurityUtil;
import org.apache.hadoop.security.UserGroupInformation;
@ -140,7 +141,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
*
*/
@SuppressWarnings("unchecked")
public class ResourceManager extends CompositeService implements Recoverable {
public class ResourceManager extends CompositeService
implements Recoverable, ResourceManagerMXBean {
/**
* Priority of the ResourceManager shutdown hook.
@ -337,6 +339,8 @@ public class ResourceManager extends CompositeService implements Recoverable {
addIfService(systemMetricsPublisher);
rmContext.setSystemMetricsPublisher(systemMetricsPublisher);
registerMXBean();
super.serviceInit(this.conf);
}
@ -1600,4 +1604,16 @@ public class ResourceManager extends CompositeService implements Recoverable {
protected RMAppLifetimeMonitor createRMAppLifetimeMonitor() {
return new RMAppLifetimeMonitor(this.rmContext);
}
/**
* Register ResourceManagerMXBean.
*/
private void registerMXBean() {
MBeans.register("ResourceManager", "ResourceManager", this);
}
@Override
public boolean isSecurityEnabled() {
return UserGroupInformation.isSecurityEnabled();
}
}