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 { public void refreshNamenodes(Configuration conf) throws IOException {
blockPoolManager.refreshNamenodes(conf); blockPoolManager.refreshNamenodes(conf);
} }

View File

@ -146,4 +146,11 @@ public interface DataNodeMXBean {
* @return list of slow disks * @return list of slow disks
*/ */
String getSlowDisks(); 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); return NetUtils.getHostPortString(nameNodeAddr);
} }
@Override
public boolean isSecurityEnabled() {
return UserGroupInformation.isSecurityEnabled();
}
@Override // SecondaryNameNodeInfoMXBean @Override // SecondaryNameNodeInfoMXBean
public long getStartTime() { public long getStartTime() {
return starttime; return starttime;

View File

@ -31,6 +31,13 @@ public interface SecondaryNameNodeInfoMXBean extends VersionInfoMXBean {
*/ */
public String getHostAndPort(); public String getHostAndPort();
/**
* Gets if security is enabled.
*
* @return true, if security is enabled.
*/
boolean isSecurityEnabled();
/** /**
* @return the timestamp of when the SNN starts * @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.DFSConfigKeys;
import org.apache.hadoop.hdfs.DFSTestUtil; import org.apache.hadoop.hdfs.DFSTestUtil;
import org.apache.hadoop.hdfs.MiniDFSCluster; 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.apache.hadoop.test.GenericTestUtils;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
@ -49,7 +51,7 @@ import static org.junit.Assert.assertTrue;
/** /**
* Class for testing {@link DataNodeMXBean} implementation * Class for testing {@link DataNodeMXBean} implementation
*/ */
public class TestDataNodeMXBean { public class TestDataNodeMXBean extends SaslDataTransferTestCase {
public static final Log LOG = LogFactory.getLog(TestDataNodeMXBean.class); public static final Log LOG = LogFactory.getLog(TestDataNodeMXBean.class);
@ -118,6 +120,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) { private static String replaceDigits(final String s) {
return s.replaceAll("[0-9]+", "_DIGITS_"); 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 static org.junit.Assert.fail;
import java.io.IOException; import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.security.PrivilegedExceptionAction; import java.security.PrivilegedExceptionAction;
import org.apache.hadoop.conf.Configuration;
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.permission.FsPermission; 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.hdfs.protocol.datatransfer.sasl.SaslDataTransferTestCase;
import org.apache.hadoop.security.UserGroupInformation; import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.security.UserGroupInformation.AuthenticationMethod; import org.apache.hadoop.security.UserGroupInformation.AuthenticationMethod;
import org.junit.Assert;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.ExpectedException; import org.junit.rules.ExpectedException;
import javax.management.MBeanServer;
import javax.management.ObjectName;
public class TestSecureNameNode extends SaslDataTransferTestCase { public class TestSecureNameNode extends SaslDataTransferTestCase {
final static private int NUM_OF_DATANODES = 0; final static private int NUM_OF_DATANODES = 0;
@ -117,4 +121,50 @@ public class TestSecureNameNode extends SaslDataTransferTestCase {
return; 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.Path;
import org.apache.hadoop.fs.permission.FsPermission; import org.apache.hadoop.fs.permission.FsPermission;
import org.apache.hadoop.metrics2.lib.DefaultMetricsSystem; 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.Credentials;
import org.apache.hadoop.security.SecurityUtil; import org.apache.hadoop.security.SecurityUtil;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.service.CompositeService; import org.apache.hadoop.service.CompositeService;
import org.apache.hadoop.util.ExitUtil; import org.apache.hadoop.util.ExitUtil;
import org.apache.hadoop.util.GenericOptionsParser; import org.apache.hadoop.util.GenericOptionsParser;
@ -88,7 +90,7 @@ import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
public class NodeManager extends CompositeService public class NodeManager extends CompositeService
implements EventHandler<NodeManagerEvent> { implements EventHandler<NodeManagerEvent>, NodeManagerMXBean {
/** /**
* Node manager return status codes. * Node manager return status codes.
@ -470,6 +472,8 @@ public class NodeManager extends CompositeService
throw new YarnRuntimeException("Failed NodeManager login", e); throw new YarnRuntimeException("Failed NodeManager login", e);
} }
registerMXBean();
super.serviceInit(conf); super.serviceInit(conf);
// TODO add local dirs to del // TODO add local dirs to del
} }
@ -948,6 +952,18 @@ public class NodeManager extends CompositeService
} }
} }
/**
* Register NodeManagerMXBean.
*/
private void registerMXBean() {
MBeans.register("NodeManager", "NodeManager", this);
}
@Override
public boolean isSecurityEnabled() {
return UserGroupInformation.isSecurityEnabled();
}
// For testing // For testing
NodeManager createNewNodeManager() { NodeManager createNewNodeManager() {
return new NodeManager(); return new NodeManager();

View File

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