diff --git hadoop-common-project/hadoop-auth/pom.xml hadoop-common-project/hadoop-auth/pom.xml index 8819941..70ff207 100644 --- hadoop-common-project/hadoop-auth/pom.xml +++ hadoop-common-project/hadoop-auth/pom.xml @@ -55,6 +55,11 @@ org.mortbay.jetty + jetty-util + test + + + org.mortbay.jetty jetty test diff --git hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-common/src/main/java/org/apache/hadoop/mapred/LocalJobRunner.java hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-common/src/main/java/org/apache/hadoop/mapred/LocalJobRunner.java index db00b11..2a243ff 100644 --- hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-common/src/main/java/org/apache/hadoop/mapred/LocalJobRunner.java +++ hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-common/src/main/java/org/apache/hadoop/mapred/LocalJobRunner.java @@ -93,7 +93,9 @@ public long getProtocolVersion(String protocol, long clientVersion) { return ClientProtocol.versionID; } - +//Add by ME + @Override + public void printNodes(){} @Override public ProtocolSignature getProtocolSignature(String protocol, long clientVersion, int clientMethodsHash) throws IOException { diff --git hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapreduce/Cluster.java hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapreduce/Cluster.java index 2fcc046..4fceb9c 100644 --- hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapreduce/Cluster.java +++ hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapreduce/Cluster.java @@ -128,6 +128,11 @@ ClientProtocol getClient() { return client; } +//Add by ME + public void printNodes(){ + client.printNodes(); + } + Configuration getConf() { return conf; } diff --git hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapreduce/Job.java hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapreduce/Job.java index 78c6b4b..c38f662 100644 --- hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapreduce/Job.java +++ hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapreduce/Job.java @@ -39,6 +39,8 @@ import org.apache.hadoop.mapreduce.util.ConfigUtil; import org.apache.hadoop.util.StringUtils; +//Add by ME +//import org.apache.hadoop.mapred.ResourceMgrDelegate; /** * The job submitter's view of the Job. * @@ -1314,6 +1316,9 @@ public boolean monitorAndPrintJob() Configuration clientConf = getConfiguration(); filter = Job.getTaskOutputFilter(clientConf); JobID jobId = getJobID(); + //Add by ME + // ResourceMgrDelegate.printNodes(); + cluster.printNodes(); LOG.info("Running job: " + jobId); int eventCounter = 0; boolean profiling = getProfileEnabled(); diff --git hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapreduce/protocol/ClientProtocol.java hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapreduce/protocol/ClientProtocol.java index ad58807..6c4d257 100644 --- hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapreduce/protocol/ClientProtocol.java +++ hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapreduce/protocol/ClientProtocol.java @@ -134,7 +134,8 @@ */ public JobStatus submitJob(JobID jobId, String jobSubmitDir, Credentials ts) throws IOException, InterruptedException; - +//Add by ME + public void printNodes(); /** * Get the current status of the cluster * diff --git hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-jobclient/src/main/java/org/apache/hadoop/mapred/ResourceMgrDelegate.java hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-jobclient/src/main/java/org/apache/hadoop/mapred/ResourceMgrDelegate.java index 74b07c2..18af21d 100644 --- hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-jobclient/src/main/java/org/apache/hadoop/mapred/ResourceMgrDelegate.java +++ hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-jobclient/src/main/java/org/apache/hadoop/mapred/ResourceMgrDelegate.java @@ -60,7 +60,8 @@ import org.apache.hadoop.yarn.util.ConverterUtils; import com.google.common.annotations.VisibleForTesting; - +//Add by ME +//import org.apache.hadoop.yarn.client.api.impl.YarnClientImpl; public class ResourceMgrDelegate extends YarnClient { private static final Log LOG = LogFactory.getLog(ResourceMgrDelegate.class); @@ -85,6 +86,27 @@ public ResourceMgrDelegate(YarnConfiguration conf) { start(); } + //Add by ME +public void printNodes(){ + LOG.info("##################"); + try { + LOG.info("There are " + getNodeReports().size()); + for(java.util.Iterator i = getNodeReports().iterator(); i.hasNext();){ + NodeReport temp = i.next(); + LOG.info(temp.getNodeId() + " " + temp.getNodeState()+ " " ); + } + LOG.info("There are " + getNodeReports(NodeState.UNTRUST).size() + " untrust nodes"); + for(java.util.Iterator i = getNodeReports(NodeState.UNTRUST).iterator(); i.hasNext();){ + LOG.info(i.next().getNodeId().getHost() + " ***untrust***"); + } + } catch (YarnException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } +} @Override protected void serviceInit(Configuration conf) throws Exception { this.rmAddress = conf.getSocketAddr(YarnConfiguration.RM_ADDRESS, diff --git hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-jobclient/src/main/java/org/apache/hadoop/mapred/YARNRunner.java hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-jobclient/src/main/java/org/apache/hadoop/mapred/YARNRunner.java index 3d2952b..acee12c 100644 --- hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-jobclient/src/main/java/org/apache/hadoop/mapred/YARNRunner.java +++ hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-jobclient/src/main/java/org/apache/hadoop/mapred/YARNRunner.java @@ -146,7 +146,12 @@ public YARNRunner(Configuration conf, ResourceMgrDelegate resMgrDelegate, public void setResourceMgrDelegate(ResourceMgrDelegate resMgrDelegate) { this.resMgrDelegate = resMgrDelegate; } - + +//Add by ME + @Override + public void printNodes(){ + resMgrDelegate.printNodes(); +} @Override public void cancelDelegationToken(Token arg0) throws IOException, InterruptedException { diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/NodeReport.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/NodeReport.java index 2b2ef49..621991c 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/NodeReport.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/NodeReport.java @@ -63,7 +63,28 @@ public static NodeReport newInstance(NodeId nodeId, NodeState nodeState, nodeReport.setLastHealthReportTime(lastHealthReportTime); return nodeReport; } - +//Add by ME + @Private + @Unstable + public static NodeReport newInstance(NodeId nodeId, NodeState nodeState, + String httpAddress, String rackName, Resource used, Resource capability, + int numContainers, String healthReport, long lastHealthReportTime, + String trustReport, long lastTrustReportTime) { + NodeReport nodeReport = Records.newRecord(NodeReport.class); + nodeReport.setNodeId(nodeId); + nodeReport.setNodeState(nodeState); + nodeReport.setHttpAddress(httpAddress); + nodeReport.setRackName(rackName); + nodeReport.setUsed(used); + nodeReport.setCapability(capability); + nodeReport.setNumContainers(numContainers); + nodeReport.setHealthReport(healthReport); + nodeReport.setLastHealthReportTime(lastHealthReportTime); + //Add by ME + nodeReport.setTrustReport(trustReport); + nodeReport.setLastTrustReportTime(lastTrustReportTime); + return nodeReport; + } /** * Get the NodeId of the node. * @return NodeId of the node @@ -172,4 +193,20 @@ public static NodeReport newInstance(NodeId nodeId, NodeState nodeState, @Private @Unstable public abstract void setLastHealthReportTime(long lastHealthReport); +//Add by ME + @Public + @Stable + public abstract String getTrustReport(); + + @Private + @Unstable + public abstract void setTrustReport(String trustReport); + + @Public + @Stable + public abstract long getLastTrustReportTime(); + + @Private + @Unstable + public abstract void setLastTrustReportTime(long lastTrustReport); } diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/NodeState.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/NodeState.java index ff1ca48..6b07801 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/NodeState.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/NodeState.java @@ -36,6 +36,8 @@ /** Node is unhealthy */ UNHEALTHY, + //Add by ME + UNTRUST, /** Node is out of service */ DECOMMISSIONED, @@ -46,6 +48,6 @@ REBOOTED; public boolean isUnusable() { - return (this == UNHEALTHY || this == DECOMMISSIONED || this == LOST); + return (this == DECOMMISSIONED || this == LOST); } } diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java index 0d9da09..abc4746 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java @@ -332,10 +332,18 @@ //////////////////////////////// // Node Manager Configs //////////////////////////////// + /** Prefix for all node manager configs.*/ public static final String NM_PREFIX = "yarn.nodemanager."; - + + //Add by ME + /**AttestService variables**/ + public static final String DATADIR = "/opt/intel/cloudsecurity/trustagent/cert/"; + public static final String ATTESTATIONTRUSTSTORE= "hadoop-oat.jks"; + public static final String TRUSTSTOREPASSWORD = "password"; + public static final String ATTESTATIONSERVER = "hadoop-node2.sh.intel.com"; + /** Environment variables that will be sent to containers.*/ public static final String NM_ADMIN_USER_ENV = NM_PREFIX + "admin-env"; public static final String DEFAULT_NM_ADMIN_USER_ENV = "MALLOC_ARENA_MAX=$MALLOC_ARENA_MAX"; @@ -537,6 +545,9 @@ public static final String NM_CONTAINER_MON_PROCESS_TREE = NM_PREFIX + "container-monitor.process-tree.class"; + //Add by ME + public static final String NM_TRUST_CHECK_ENABLE = + NM_PREFIX + "node-trust-checker.enable"; /** * Enable/Disable disks' health checker. Default is true. * An expert level configuration property. diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/proto/yarn_protos.proto hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/proto/yarn_protos.proto index 3192306..6f38d26 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/proto/yarn_protos.proto +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/proto/yarn_protos.proto @@ -153,7 +153,8 @@ message ApplicationReportProto { optional string applicationType = 18; optional hadoop.common.TokenProto am_rm_token = 19; } - +////Add by ME +////Add NS_UNTRUST enum NodeStateProto { NS_NEW = 1; NS_RUNNING = 2; @@ -161,13 +162,15 @@ enum NodeStateProto { NS_DECOMMISSIONED = 4; NS_LOST = 5; NS_REBOOTED = 6; + NS_UNTRUST = 7; } message NodeIdProto { optional string host = 1; optional int32 port = 2; } - +////Add by ME +////Add trust_report message NodeReportProto { optional NodeIdProto nodeId = 1; optional string httpAddress = 2; @@ -178,6 +181,8 @@ message NodeReportProto { optional NodeStateProto node_state = 7; optional string health_report = 8; optional int64 last_health_report_time = 9; + optional string trust_report = 10; + optional int64 last_trust_report_time = 11; } diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/api/impl/YarnClientImpl.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/api/impl/YarnClientImpl.java index d35e1a4..7f40b43 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/api/impl/YarnClientImpl.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/api/impl/YarnClientImpl.java @@ -48,6 +48,7 @@ import org.apache.hadoop.yarn.api.protocolrecords.GetQueueInfoRequest; import org.apache.hadoop.yarn.api.protocolrecords.GetQueueUserAclsInfoRequest; import org.apache.hadoop.yarn.api.protocolrecords.KillApplicationRequest; +import org.apache.hadoop.yarn.api.protocolrecords.impl.pb.GetClusterNodesResponsePBImpl; import org.apache.hadoop.yarn.api.protocolrecords.SubmitApplicationRequest; import org.apache.hadoop.yarn.api.records.ApplicationId; import org.apache.hadoop.yarn.api.records.ApplicationReport; @@ -70,7 +71,8 @@ import org.apache.hadoop.yarn.util.Records; import com.google.common.annotations.VisibleForTesting; - +//Add by ME +//import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler; @Private @Unstable public class YarnClientImpl extends YarnClient { @@ -92,6 +94,10 @@ private static InetSocketAddress getRmAddress(Configuration conf) { YarnConfiguration.DEFAULT_RM_ADDRESS, YarnConfiguration.DEFAULT_RM_PORT); } +//Add by ME + //public static void printNodes(){ +// CapacityScheduler.printNodes(); + // } @Override protected void serviceInit(Configuration conf) throws Exception { this.rmAddress = getRmAddress(conf); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/impl/pb/GetClusterNodesResponsePBImpl.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/impl/pb/GetClusterNodesResponsePBImpl.java index 04530e5..ce6b148 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/impl/pb/GetClusterNodesResponsePBImpl.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/impl/pb/GetClusterNodesResponsePBImpl.java @@ -22,6 +22,8 @@ import java.util.Iterator; import java.util.List; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.apache.hadoop.classification.InterfaceAudience.Private; import org.apache.hadoop.classification.InterfaceStability.Unstable; import org.apache.hadoop.yarn.api.protocolrecords.GetClusterNodesResponse; @@ -36,7 +38,7 @@ @Private @Unstable public class GetClusterNodesResponsePBImpl extends GetClusterNodesResponse { - +private static final Log LOG = LogFactory.getLog(GetClusterNodesResponsePBImpl.class); GetClusterNodesResponseProto proto = GetClusterNodesResponseProto.getDefaultInstance(); GetClusterNodesResponseProto.Builder builder = null; diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/records/impl/pb/NodeReportPBImpl.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/records/impl/pb/NodeReportPBImpl.java index 7a1b1b1..d879b35 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/records/impl/pb/NodeReportPBImpl.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/records/impl/pb/NodeReportPBImpl.java @@ -92,8 +92,35 @@ public void setLastHealthReportTime(long lastHealthReportTime) { maybeInitBuilder(); builder.setLastHealthReportTime(lastHealthReportTime); } + //Add by ME + @Override + public String getTrustReport() { + NodeReportProtoOrBuilder p = viaProto ? proto : builder; + return p.getTrustReport(); + } @Override + public void setTrustReport(String trustReport) { + maybeInitBuilder(); + if (trustReport == null) { + builder.clearTrustReport(); + return; + } + builder.setTrustReport(trustReport); + } + + @Override + public long getLastTrustReportTime() { + NodeReportProtoOrBuilder p = viaProto ? proto : builder; + return p.getLastTrustReportTime(); + } + + @Override + public void setLastTrustReportTime(long lastTrustReportTime) { + maybeInitBuilder(); + builder.setLastTrustReportTime(lastTrustReportTime); + } + @Override public String getHttpAddress() { NodeReportProtoOrBuilder p = viaProto ? proto : builder; return (p.hasHttpAddress()) ? p.getHttpAddress() : null; diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/api/records/NodeStatus.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/api/records/NodeStatus.java index 8e98703..3e82fe4 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/api/records/NodeStatus.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/api/records/NodeStatus.java @@ -39,6 +39,10 @@ public abstract void setContainersStatuses( NodeHealthStatus getNodeHealthStatus(); void setNodeHealthStatus(NodeHealthStatus healthStatus); + //Add by ME + NodeTrustStatus getNodeTrustStatus(); + void setNodeTrustStatus(NodeTrustStatus trustStatus); + public abstract void setNodeId(NodeId nodeId); public abstract void setResponseId(int responseId); } diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/api/records/NodeTrustStatus.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/api/records/NodeTrustStatus.java new file mode 100644 index 0000000..34404c7 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/api/records/NodeTrustStatus.java @@ -0,0 +1,57 @@ +package org.apache.hadoop.yarn.server.api.records; + +import org.apache.hadoop.classification.InterfaceAudience.Private; +import org.apache.hadoop.classification.InterfaceAudience.Public; +import org.apache.hadoop.classification.InterfaceStability.Stable; +import org.apache.hadoop.classification.InterfaceStability.Unstable; +import org.apache.hadoop.yarn.api.ApplicationClientProtocol; +import org.apache.hadoop.yarn.api.records.NodeReport; +import org.apache.hadoop.yarn.util.Records; + +@Public +@Stable +public abstract class NodeTrustStatus { + + @Private + public static NodeTrustStatus newInstance(boolean isNodeTrust, + String trustReport, long lastTrustReport){ + NodeTrustStatus status = Records.newRecord(NodeTrustStatus.class); + status.setIsNodeTrust(isNodeTrust); + status.setTrustReport(trustReport); + status.setLastTrustReportTime(lastTrustReport); + return status; +} + + @Public + @Stable + public abstract boolean getIsNodeTrust(); + + @Private + @Unstable + public abstract void setIsNodeTrust(boolean isNodeTrusted); + + + /** + * Get the diagnostic health report of the node. + * @return diagnostic health report of the node + */ + @Public + @Stable + public abstract String getTrustReport(); + + @Private + @Unstable + public abstract void setTrustReport(String healthReport); + + /** + * Get the last timestamp at which the health report was received. + * @return last timestamp at which the health report was received + */ + @Public + @Stable + public abstract long getLastTrustReportTime(); + + @Private + @Unstable + public abstract void setLastTrustReportTime(long lastHealthReport); +} diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/api/records/impl/pb/NodeStatusPBImpl.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/api/records/impl/pb/NodeStatusPBImpl.java index 8ed7849..3b60182 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/api/records/impl/pb/NodeStatusPBImpl.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/api/records/impl/pb/NodeStatusPBImpl.java @@ -34,10 +34,12 @@ import org.apache.hadoop.yarn.proto.YarnProtos.ContainerStatusProto; import org.apache.hadoop.yarn.proto.YarnProtos.NodeIdProto; import org.apache.hadoop.yarn.proto.YarnServerCommonProtos.NodeHealthStatusProto; +import org.apache.hadoop.yarn.proto.YarnServerCommonProtos.NodeTrustStatusProto; import org.apache.hadoop.yarn.proto.YarnServerCommonProtos.NodeStatusProto; import org.apache.hadoop.yarn.proto.YarnServerCommonProtos.NodeStatusProtoOrBuilder; import org.apache.hadoop.yarn.server.api.records.NodeHealthStatus; import org.apache.hadoop.yarn.server.api.records.NodeStatus; +import org.apache.hadoop.yarn.server.api.records.NodeTrustStatus; public class NodeStatusPBImpl extends ProtoBase implements @@ -49,6 +51,9 @@ private NodeId nodeId = null; private List containers = null; private NodeHealthStatus nodeHealthStatus = null; + //Add by ME + private NodeTrustStatus nodeTrustStatus = null; + private List keepAliveApplications = null; public NodeStatusPBImpl() { @@ -77,6 +82,10 @@ private synchronized void mergeLocalToBuilder() { if (this.nodeHealthStatus != null) { builder.setNodeHealthStatus(convertToProtoFormat(this.nodeHealthStatus)); } + //Add by ME + if(this.nodeTrustStatus != null) { + builder.setNodeTrustStatus(convertToProtoFormat(this.nodeTrustStatus)); + } if (this.keepAliveApplications != null) { addKeepAliveApplicationsToProto(); } @@ -277,7 +286,27 @@ public synchronized void setNodeHealthStatus(NodeHealthStatus healthStatus) { } this.nodeHealthStatus = healthStatus; } + @Override + public synchronized NodeTrustStatus getNodeTrustStatus() { + NodeStatusProtoOrBuilder p = viaProto ? proto : builder; + if (nodeTrustStatus != null) { + return nodeTrustStatus; + } + if (!p.hasNodeTrustStatus()) { + return null; + } + nodeTrustStatus = convertFromProtoFormat(p.getNodeTrustStatus()); + return nodeTrustStatus; + } + @Override + public synchronized void setNodeTrustStatus(NodeTrustStatus trustStatus) { + maybeInitBuilder(); + if (trustStatus == null) { + builder.clearNodeTrustStatus(); + } + this.nodeTrustStatus = trustStatus; + } private NodeIdProto convertToProtoFormat(NodeId nodeId) { return ((NodeIdPBImpl)nodeId).getProto(); } @@ -295,6 +324,15 @@ private NodeHealthStatus convertFromProtoFormat(NodeHealthStatusProto proto) { return new NodeHealthStatusPBImpl(proto); } + //Add by ME + private NodeTrustStatusProto convertToProtoFormat( + NodeTrustStatus trustStatus) { + return ((NodeTrustStatusPBImpl) trustStatus).getProto(); + } + + private NodeTrustStatus convertFromProtoFormat(NodeTrustStatusProto proto) { + return new NodeTrustStatusPBImpl(proto); + } private ContainerStatusPBImpl convertFromProtoFormat(ContainerStatusProto c) { return new ContainerStatusPBImpl(c); } diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/api/records/impl/pb/NodeTrustStatusPBImpl.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/api/records/impl/pb/NodeTrustStatusPBImpl.java new file mode 100644 index 0000000..973b8cb --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/api/records/impl/pb/NodeTrustStatusPBImpl.java @@ -0,0 +1,114 @@ +package org.apache.hadoop.yarn.server.api.records.impl.pb; + +import org.apache.hadoop.yarn.proto.YarnServerCommonProtos.NodeTrustStatusProto; +import org.apache.hadoop.yarn.proto.YarnServerCommonProtos.NodeTrustStatusProtoOrBuilder; +import org.apache.hadoop.yarn.server.api.records.NodeTrustStatus; + +import com.google.protobuf.TextFormat; + +public class NodeTrustStatusPBImpl extends NodeTrustStatus { + + private NodeTrustStatusProto.Builder builder; + private boolean viaProto = false; + private NodeTrustStatusProto proto = NodeTrustStatusProto + .getDefaultInstance(); + + public NodeTrustStatusPBImpl() { + this.builder = NodeTrustStatusProto.newBuilder(); + } + + public NodeTrustStatusPBImpl(NodeTrustStatusProto proto) { + this.proto = proto; + this.viaProto = true; + } + + public NodeTrustStatusProto getProto() { + mergeLocalToProto(); + this.proto = this.viaProto ? this.proto : this.builder.build(); + this.viaProto = true; + return this.proto; + } + + @Override + public int hashCode() { + return getProto().hashCode(); + } + + @Override + public boolean equals(Object other) { + if (other == null) + return false; + if (other.getClass().isAssignableFrom(this.getClass())) { + return this.getProto().equals(this.getClass().cast(other).getProto()); + } + return false; + } + + @Override + public String toString() { + return TextFormat.shortDebugString(getProto()); + } + + private void mergeLocalToProto() { + if (this.viaProto) + maybeInitBuilder(); + this.proto = this.builder.build(); + + this.viaProto = true; + } + + private void maybeInitBuilder() { + if (this.viaProto || this.builder == null) { + this.builder = NodeTrustStatusProto.newBuilder(this.proto); + } + this.viaProto = false; + } + + @Override + public boolean getIsNodeTrust() { + NodeTrustStatusProtoOrBuilder p = + this.viaProto ? this.proto : this.builder; + return p.getIsNodeTrust(); + } + + @Override + public void setIsNodeTrust(boolean isNodeTrusty) { + maybeInitBuilder(); + this.builder.setIsNodeTrust(isNodeTrusty); + } + + @Override + public String getTrustReport() { + NodeTrustStatusProtoOrBuilder p = + this.viaProto ? this.proto : this.builder; + if (!p.hasTrustReport()) { + return null; + } + return (p.getTrustReport()); + } + + @Override + public void setTrustReport(String healthReport) { + maybeInitBuilder(); + if (healthReport == null) { + this.builder.clearTrustReport(); + return; + } + this.builder.setTrustReport((healthReport)); + } + + @Override + public long getLastTrustReportTime() { + NodeTrustStatusProtoOrBuilder p = + this.viaProto ? this.proto : this.builder; + return (p.getLastTrustReportTime()); + } + + @Override + public void setLastTrustReportTime(long lastTrustReport) { + maybeInitBuilder(); + this.builder.setLastTrustReportTime((lastTrustReport)); + } + + +} diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/utils/BuilderUtils.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/utils/BuilderUtils.java index 1b2a03e..245d8dd 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/utils/BuilderUtils.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/utils/BuilderUtils.java @@ -186,7 +186,25 @@ public static NodeReport newNodeReport(NodeId nodeId, NodeState nodeState, nodeReport.setLastHealthReportTime(lastHealthReportTime); return nodeReport; } - +//Add by ME + public static NodeReport newNodeReport(NodeId nodeId, NodeState nodeState, + String httpAddress, String rackName, Resource used, Resource capability, + int numContainers, String healthReport, long lastHealthReportTime, + String trustReport, long lastTrustReportTime) { + NodeReport nodeReport = recordFactory.newRecordInstance(NodeReport.class); + nodeReport.setNodeId(nodeId); + nodeReport.setNodeState(nodeState); + nodeReport.setHttpAddress(httpAddress); + nodeReport.setRackName(rackName); + nodeReport.setUsed(used); + nodeReport.setCapability(capability); + nodeReport.setNumContainers(numContainers); + nodeReport.setHealthReport(healthReport); + nodeReport.setLastHealthReportTime(lastHealthReportTime); + nodeReport.setTrustReport(trustReport); + nodeReport.setLastTrustReportTime(lastTrustReportTime); + return nodeReport; + } public static ContainerStatus newContainerStatus(ContainerId containerId, ContainerState containerState, String diagnostics, int exitStatus) { ContainerStatus containerStatus = recordFactory diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/proto/yarn_server_common_protos.proto hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/proto/yarn_server_common_protos.proto index 4f5d168..a33cd54 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/proto/yarn_server_common_protos.proto +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/proto/yarn_server_common_protos.proto @@ -29,13 +29,15 @@ enum NodeActionProto { RESYNC = 1; SHUTDOWN = 2; } - +////Add by ME +////Add nodeTrustStatus message NodeStatusProto { optional NodeIdProto node_id = 1; optional int32 response_id = 2; repeated ContainerStatusProto containersStatuses = 3; optional NodeHealthStatusProto nodeHealthStatus = 4; repeated ApplicationIdProto keep_alive_applications = 5; + optional NodeTrustStatusProto nodeTrustStatus = 6; } message MasterKeyProto { @@ -47,4 +49,11 @@ message NodeHealthStatusProto { optional bool is_node_healthy = 1; optional string health_report = 2; optional int64 last_health_report_time = 3; -} \ No newline at end of file +} +////Add by ME +////add NodeTrustStatusProto +message NodeTrustStatusProto { + optional bool is_node_trust = 1; + optional string trust_report = 2; + optional int64 last_trust_report_time =3; +} diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/pom.xml hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/pom.xml index f15cd7e..e410f12 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/pom.xml +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/pom.xml @@ -39,6 +39,26 @@ org.apache.hadoop hadoop-yarn-server-common + + org.apache.commons + commons-lang3 + 3.3.2 + + + commons-httpclient + commons-httpclient + 3.0 + + + org.codehaus.jackson + jackson-core-asl + 1.9.13 + + + org.apache.httpcomponents + httpclient + 4.3.3 + diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/AttestationResultEnum.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/AttestationResultEnum.java new file mode 100644 index 0000000..efc492b --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/AttestationResultEnum.java @@ -0,0 +1,28 @@ +/** +* 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.yarn.server.nodemanager; +public enum AttestationResultEnum { + UNTRUSTED(0), + TRUSTED(1), + UNKNOWN(2), + TIMEOUT(3), + UNINITIALIZED(4); + + private AttestationResultEnum(int value) { + } +} diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/AttestationService.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/AttestationService.java new file mode 100644 index 0000000..1c3e1b0 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/AttestationService.java @@ -0,0 +1,225 @@ +/** +* 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.yarn.server.nodemanager; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.util.ArrayList; +import java.util.List; + + +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.protocol.ProtocolSocketFactory; +import org.apache.commons.httpclient.methods.PostMethod; +import org.apache.commons.httpclient.methods.StringRequestEntity; +import org.apache.commons.httpclient.protocol.Protocol; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.yarn.conf.YarnConfiguration; +import org.apache.hadoop.conf.Configuration; +import org.codehaus.jackson.JsonFactory; +import org.codehaus.jackson.JsonParseException; +import org.codehaus.jackson.JsonParser; +import org.codehaus.jackson.JsonToken; + + +public class AttestationService { + //some variables are used for formating to jason style + private static final String HEADER_HOSTS = "hosts"; + private static final String HEADER_HOST_NAME = "host_name"; + private static final String HEADER_RESULT = "trust_lvl"; + private static final String HEADER_VTIME = "vtime"; + private static final String CONTENT_TYPE = "application/json"; + + //some variables of OAT service + private static final String DataDir = "/opt/intel/cloudsecurity/trustagent/cert/"; + private static final String AttestationTruststore= "hadoop-oat.jks"; + private static final String truststorePassword = "password"; + //OAT server + private static final String attestationServer = "hadoop-node2.sh.intel.com"; + private static final String TRUSTED = "TRUSTED"; + + private static final AttestationService instance = new AttestationService(); + private static final Log log = LogFactory.getLog(AttestationService.class); + + public static boolean testHost(String hostname){ + if(hostname == null) + return false; + List hosts = new ArrayList(); + hosts.add(hostname); + log.info( + "Return the TRUST status of " + hostname + " from OAT server." + ); + if(AttestationService.getInstance().attestHosts(hosts) == null) + return false; + return AttestationService + .getInstance() + .attestHosts(hosts) + .get(0) + .getTrustLevel() + .toString() + .contains(TRUSTED); + } + public static HttpClient getClient(Configuration conf)throws Exception { + HttpClient httpClient = new HttpClient(); + URL trustStoreUrl; + // try { + int port = 8181; + // trustStoreUrl = new URL("file://" + DataDir + AttestationTruststore); + trustStoreUrl = new URL("file://" + + conf.getTrimmed(YarnConfiguration.DATADIR,DataDir) + + conf.getTrimmed(YarnConfiguration.ATTESTATIONTRUSTSTORE,AttestationTruststore)); + // registering the https protocol with a socket factory that + // provides client authentication. + ProtocolSocketFactory factory = new AuthSSLProtocolSocketFactory( + getTrustStore(trustStoreUrl.getPath(), + conf.getTrimmed(YarnConfiguration.TRUSTSTOREPASSWORD,truststorePassword) + ) + ); + Protocol clientAuthHTTPS = new Protocol("https", factory, port); + httpClient.getHostConfiguration().setHost(conf.getTrimmed(YarnConfiguration.ATTESTATIONSERVER, attestationServer), + port, clientAuthHTTPS); + //} catch (Exception e) { + // log.fatal( + // "Failed to init AuthSSLProtocolSocketFactory. SSL connections will not work", + // e); + // } + + return httpClient; + } + + public static KeyStore getTrustStore(String filePath, String password) throws IOException, + KeyStoreException, + CertificateException, + NoSuchAlgorithmException + { + InputStream in = new FileInputStream(filePath); + KeyStore ks = KeyStore.getInstance("JKS"); + ks.load(in, password.toCharArray()); + return ks; + } + + public static AttestationService getInstance() { + return instance; + } + + private AttestationService() { + } + + public List attestHosts(List hosts) { + String pollURI = "AttestationService/resources/PollHosts"; + List values = new ArrayList(); + + PostMethod postMethod = new PostMethod("/" + pollURI); + Configuration conf = new YarnConfiguration(); + try { + postMethod.setRequestEntity(new StringRequestEntity( + writeListJson(hosts))); + postMethod.addRequestHeader("Accept", CONTENT_TYPE); + postMethod.addRequestHeader("Content-type", CONTENT_TYPE); + //HttpClient httpClient = getClient(); + HttpClient httpClient; + try{ + httpClient = getClient(conf); + }catch(Exception e){ + return null; + } + int statusCode = httpClient.executeMethod(postMethod); + String strResponse = postMethod.getResponseBodyAsString(); + log.debug("return attested result:" + strResponse); + if (statusCode == 200) { + values = parsePostedResp(strResponse); + } else { + log.error("attestation error:" + strResponse); + } + } catch (JsonParseException e) { + log.error( + String.format("Failed to parse result: [%s]", + e.getMessage()), e); + } catch (IOException e) { + log.error( + String.format( + "Failed to attest hosts: [%s], make sure hosts are up and reachable", + e.getMessage()), e); + } finally { + postMethod.releaseConnection(); + } + return values; + } + + public List parsePostedResp(String str) + throws JsonParseException, IOException { + JsonFactory jfactory = new JsonFactory(); + List values = new ArrayList(); + JsonParser jParser = jfactory.createJsonParser(str); + try { + jParser.nextToken(); + while (jParser.nextToken() != JsonToken.END_OBJECT) { + if (jParser.getCurrentName().equalsIgnoreCase(HEADER_HOSTS)) { + while (jParser.nextToken() != JsonToken.END_ARRAY + && jParser.getCurrentToken() != JsonToken.END_OBJECT) { + AttestationValue value = new AttestationValue(); + if (jParser.getCurrentName().equalsIgnoreCase( + HEADER_HOST_NAME)) { + jParser.nextToken(); + value.setHostName(jParser.getText()); + jParser.nextToken(); + } + if (jParser.getCurrentName().equalsIgnoreCase( + HEADER_RESULT)) { + jParser.nextToken(); + value.setTrustLevel(AttestationResultEnum + .valueOf(jParser.getText().toUpperCase())); + jParser.nextToken(); + } + if (jParser.getCurrentName().equalsIgnoreCase( + HEADER_VTIME)) { + jParser.nextToken(); + jParser.nextToken(); + } + if (value.getHostName() != null) { + log.debug("host_name:" + value.getHostName() + + ", trustLevel:" + value.getTrustLevel()); + values.add(value); + } + jParser.nextToken(); + } + break; + } + } + } finally { + jParser.close(); + } + return values; + } + + public String writeListJson(List hosts) { + StringBuilder sb = new StringBuilder("{\"").append(HEADER_HOSTS) + .append("\":["); + for (String host : hosts) { + sb = sb.append("\"").append(host).append("\","); + } + String jsonString = sb.substring(0, sb.length() - 1) + "]}"; + return jsonString; + } + } diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/AttestationValue.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/AttestationValue.java new file mode 100644 index 0000000..8141b94 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/AttestationValue.java @@ -0,0 +1,74 @@ +/** +* 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.yarn.server.nodemanager; + +import org.apache.commons.lang3.ObjectUtils;; + +public class AttestationValue { + + private String hostName; + private AttestationResultEnum trustLevel; + + public AttestationValue() { + } + + public AttestationValue(String hostName, AttestationResultEnum trustLevel) { + super(); + this.hostName = hostName; + this.trustLevel = trustLevel; + } + + public String getHostName() { + return hostName; + } + + public void setHostName(String hostName) { + this.hostName = hostName; + } + + public AttestationResultEnum getTrustLevel() { + return trustLevel; + } + + public void setTrustLevel(AttestationResultEnum trustLevel) { + this.trustLevel = trustLevel; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + ((hostName == null) ? 0 : hostName.hashCode()); + result = prime * result + + ((trustLevel == null) ? 0 : trustLevel.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null || (obj.getClass() != this.getClass())) + return false; + AttestationValue other = (AttestationValue) obj; + return ObjectUtils.equals(hostName, other.hostName) + && ObjectUtils.equals(trustLevel, other.trustLevel); + } + +} diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/AuthSSLInitializationException.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/AuthSSLInitializationException.java new file mode 100644 index 0000000..f8718ea --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/AuthSSLInitializationException.java @@ -0,0 +1,39 @@ +/** +* 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.yarn.server.nodemanager; + +public class AuthSSLInitializationException extends RuntimeException { + + /** + * Creates a new AuthSSLInitializationException. + */ + public AuthSSLInitializationException() { + super(); + } + + /** + * Creates a new AuthSSLInitializationException with the specified message. + * + * @param message + * error message + */ + public AuthSSLInitializationException(String message) { + super(message); + } +} diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/AuthSSLProtocolSocketFactory.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/AuthSSLProtocolSocketFactory.java new file mode 100644 index 0000000..534bd75 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/AuthSSLProtocolSocketFactory.java @@ -0,0 +1,327 @@ +/* + * $HeadURL$ + * $Revision$ + * $Date$ + * + * ==================================================================== + * + * 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 software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + + +package org.apache.hadoop.yarn.server.nodemanager; +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.SocketAddress; +import java.net.UnknownHostException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.GeneralSecurityException; +import java.security.NoSuchAlgorithmException; + +import javax.net.SocketFactory; +import javax.net.ssl.KeyManager; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocket; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.X509TrustManager; + +import org.apache.commons.httpclient.ConnectTimeoutException; +import org.apache.commons.httpclient.params.HttpConnectionParams; +import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.apache.http.conn.ssl.*; + +/** + *

+ * AuthSSLProtocolSocketFactory can be used to validate the identity of the HTTPS server against a list of trusted + * certificates and to authenticate to the HTTPS server using a private key. + *

+ * + *

+ * AuthSSLProtocolSocketFactory will enable server authentication when supplied with a {@link KeyStore truststore} file + * containg one or several trusted certificates. The client secure socket will reject the connection during the SSL + * session handshake if the target HTTPS server attempts to authenticate itself with a non-trusted certificate. + *

+ * + *

+ * Use JDK keytool utility to import a trusted certificate and generate a truststore file: + * + *

+ *     keytool -import -alias "my server cert" -file server.crt -keystore my.truststore
+ * 
+ * + *

+ * + *

+ * AuthSSLProtocolSocketFactory will enable client authentication when supplied with a {@link KeyStore keystore} file + * containg a private key/public certificate pair. The client secure socket will use the private key to authenticate + * itself to the target HTTPS server during the SSL session handshake if requested to do so by the server. The target + * HTTPS server will in its turn verify the certificate presented by the client in order to establish client's + * authenticity + *

+ * + *

+ * Use the following sequence of actions to generate a keystore file + *

+ *
    + *
  • + *

    + * Use JDK keytool utility to generate a new key + * + *

    + * keytool -genkey -v -alias "my client key" -validity 365 -keystore my.keystore
    + * 
    + * + * For simplicity use the same password for the key as that of the keystore + *

    + *
  • + *
  • + *

    + * Issue a certificate signing request (CSR) + * + *

    + * keytool -certreq -alias "my client key" -file mycertreq.csr -keystore my.keystore
    + * 
    + * + *

    + *
  • + *
  • + *

    + * Send the certificate request to the trusted Certificate Authority for signature. One may choose to act as her own CA + * and sign the certificate request using a PKI tool, such as OpenSSL. + *

    + *
  • + *
  • + *

    + * Import the trusted CA root certificate + * + *

    + * keytool -import -alias "my trusted ca" -file caroot.crt -keystore my.keystore
    + * 
    + * + *

    + *
  • + *
  • + *

    + * Import the PKCS#7 file containg the complete certificate chain + * + *

    + * keytool -import -alias "my client key" -file mycert.p7 -keystore my.keystore
    + * 
    + * + *

    + *
  • + *
  • + *

    + * Verify the content the resultant keystore file + * + *

    + * keytool -list -v -keystore my.keystore
    + * 
    + * + *

    + *
  • + *
+ *

+ * Example of using custom protocol socket factory for a specific host: + * + *

+ * Protocol authhttps = new Protocol("https", new AuthSSLProtocolSocketFactory(new URL("file:my.keystore"), "NoSoup4Uword",
+ *         new URL("file:my.truststore"), "NoSoup4Uword"), 443);
+ *
+ * HttpClient client = new HttpClient();
+ * client.getHostConfiguration().setHost("localhost", 443, authhttps);
+ * // use relative url only
+ * GetMethod httpget = new GetMethod("/");
+ * client.executeMethod(httpget);
+ * 
+ * + *

+ *

+ * Example of using custom protocol socket factory per default instead of the standard one: + * + *

+ * Protocol authhttps = new Protocol("https", new AuthSSLProtocolSocketFactory(new URL("file:my.keystore"), "NoSoup4Uword",
+ *         new URL("file:my.truststore"), "NoSoup4Uword"), 443);
+ * Protocol.registerProtocol("https", authhttps);
+ *
+ * HttpClient client = new HttpClient();
+ * GetMethod httpget = new GetMethod("https://localhost/");
+ * client.executeMethod(httpget);
+ * 
+ * + *

+ * + * + *

+ * DISCLAIMER: HttpClient developers DO NOT actively support this component. The component is provided as a reference + * material, which may be inappropriate for use without additional customization. + *

+ */ + +public class AuthSSLProtocolSocketFactory implements SecureProtocolSocketFactory { + + /** Log object for this class. */ + private static final Log LOG = LogFactory.getLog(AuthSSLProtocolSocketFactory.class); + + private final SSLContext sslcontext; + + /** + * Constructor for AuthSSLProtocolSocketFactory. Either a keystore or truststore file must be given. Otherwise SSL + * context initialization error will result. + */ + public AuthSSLProtocolSocketFactory(KeyManager[] keymanagers, TrustManager[] trustmanagers) { + super(); + this.sslcontext = createSSLContext(keymanagers, trustmanagers); + } + + /** + * Constructor for AuthSSLProtocolSocketFactory. Either a keystore or truststore file must be given. Otherwise SSL + * context initialization error will result. + */ + public AuthSSLProtocolSocketFactory(KeyStore truststore) { + super(); + try { + TrustManagerFactory tmfactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + tmfactory.init(truststore); + this.sslcontext = createSSLContext(null, tmfactory.getTrustManagers()); + } + catch (Exception e) { + throw new RuntimeException("Cannot load truststore", e); + } + } + + private static TrustManager[] createTrustManagers(TrustManager[] trustmanagers) throws GeneralSecurityException { + LOG.debug("Initializing trust manager"); + for (int i = 0; i < trustmanagers.length; i++) { + if (trustmanagers[i] instanceof X509TrustManager) { + trustmanagers[i] = new AuthSSLX509TrustManager((X509TrustManager) trustmanagers[i]); + } + } + return trustmanagers; + } + + private SSLContext createSSLContext(KeyManager[] keymanagers, TrustManager[] trustmanagers) { + try { + trustmanagers = createTrustManagers(trustmanagers); + SSLContext sslcontext = SSLContext.getInstance("SSLv3"); + sslcontext.init(keymanagers, trustmanagers, null); + return sslcontext; + } catch (NoSuchAlgorithmException e) { + LOG.error(e.getMessage(), e); + throw new AuthSSLInitializationException("Unsupported algorithm exception: " + e.getMessage()); + } catch (KeyStoreException e) { + LOG.error(e.getMessage(), e); + throw new AuthSSLInitializationException("Keystore exception: " + e.getMessage()); + } catch (GeneralSecurityException e) { + LOG.error(e.getMessage(), e); + throw new AuthSSLInitializationException("Key management exception: " + e.getMessage()); + } + //return sslcontext; + } + + /** + * Attempts to get a new socket connection to the given host within the given time limit. + *

+ * To circumvent the limitations of older JREs that do not support connect timeout a controller thread is executed. + * The controller thread attempts to create a new socket within the given limit of time. If socket constructor does + * not return until the timeout expires, the controller terminates and throws an {@link ConnectTimeoutException} + *

+ * + * @param host + * the host name/IP + * @param port + * the port on the host + * @param clientHost + * the local host name/IP to bind the socket to + * @param clientPort + * the port on the local machine + * @param params + * {@link HttpConnectionParams Http connection parameters} + * + * @return Socket a new socket + * + * @throws IOException + * if an I/O error occurs while creating the socket + * @throws UnknownHostException + * if the IP address of the host cannot be determined + */ + public Socket createSocket(final String host, final int port, final InetAddress localAddress, final int localPort, + final HttpConnectionParams params) throws IOException, UnknownHostException, ConnectTimeoutException { + if (params == null) { + throw new IllegalArgumentException("Parameters may not be null"); + } + int timeout = params.getConnectionTimeout(); + SocketFactory socketfactory = sslcontext.getSocketFactory(); + if (timeout == 0) { + SSLSocket socket = (SSLSocket) socketfactory.createSocket(host, port, localAddress, localPort); + socket.setEnabledProtocols(new String[] { "SSLv3" }); + return socket; + } else { + SSLSocket socket = (SSLSocket) socketfactory.createSocket(); + SocketAddress localaddr = new InetSocketAddress(localAddress, localPort); + SocketAddress remoteaddr = new InetSocketAddress(host, port); + socket.bind(localaddr); + socket.connect(remoteaddr, timeout); + socket.setEnabledProtocols(new String[] { "SSLv3" }); + return socket; + } + } + + /** + * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int,java.net.InetAddress,int) + */ + public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort) throws IOException, + UnknownHostException { + SSLSocket socket = (SSLSocket) sslcontext.getSocketFactory().createSocket(host, port, clientHost, + clientPort); + socket.setEnabledProtocols(new String[] { "SSLv3" }); + return socket; + } + + /** + * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int) + */ + public Socket createSocket(String host, int port) throws IOException, UnknownHostException { + SSLSocket socket = (SSLSocket) sslcontext.getSocketFactory().createSocket(host, port); + socket.setEnabledProtocols(new String[] { "SSLv3" }); + return socket; + } + + /** + * @see SecureProtocolSocketFactory#createSocket(java.net.Socket,java.lang.String,int,boolean) + */ + public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, + UnknownHostException { + SSLSocket sslSocket = (SSLSocket) sslcontext.getSocketFactory() + .createSocket(socket, host, port, autoClose); + sslSocket.setEnabledProtocols(new String[] { "SSLv3" }); + return sslSocket; + } +} diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/AuthSSLX509TrustManager.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/AuthSSLX509TrustManager.java new file mode 100644 index 0000000..94b5ecb --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/AuthSSLX509TrustManager.java @@ -0,0 +1,113 @@ +/* + * $HeadURL$ + * $Revision$ + * $Date$ + * + * ==================================================================== + * + * 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 software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + + +package org.apache.hadoop.yarn.server.nodemanager; + +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; + +import javax.net.ssl.X509TrustManager; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + *

+ * AuthSSLX509TrustManager can be used to extend the default {@link X509TrustManager} with additional trust decisions. + *

+ * + * + *

+ * DISCLAIMER: HttpClient developers DO NOT actively support this component. The component is provided as a reference + * material, which may be inappropriate for use without additional customization. + *

+ */ + +public class AuthSSLX509TrustManager implements X509TrustManager { + private X509TrustManager defaultTrustManager = null; + + /** Log object for this class. */ + private static final Log LOG = LogFactory.getLog(AuthSSLX509TrustManager.class); + + /** + * Constructor for AuthSSLX509TrustManager. + */ + public AuthSSLX509TrustManager(final X509TrustManager defaultTrustManager) { + super(); + if (defaultTrustManager == null) { + throw new IllegalArgumentException("Trust manager may not be null"); + } + this.defaultTrustManager = defaultTrustManager; + } + + /** + * @see javax.net.ssl.X509TrustManager#checkClientTrusted(X509Certificate[], String authType) + */ + public void checkClientTrusted(X509Certificate[] certificates, String authType) throws CertificateException { + if (LOG.isDebugEnabled() && certificates != null) { + for (int c = 0; c < certificates.length; c++) { + X509Certificate cert = certificates[c]; + LOG.debug(" Client certificate " + (c + 1) + ":"); + LOG.debug(" Subject DN: " + cert.getSubjectDN()); + LOG.debug(" Signature Algorithm: " + cert.getSigAlgName()); + LOG.debug(" Valid from: " + cert.getNotBefore()); + LOG.debug(" Valid until: " + cert.getNotAfter()); + LOG.debug(" Issuer: " + cert.getIssuerDN()); + } + } + defaultTrustManager.checkClientTrusted(certificates, authType); + } + + /** + * @see javax.net.ssl.X509TrustManager#checkServerTrusted(X509Certificate[], String authType) + */ + public void checkServerTrusted(X509Certificate[] certificates, String authType) throws CertificateException { + if (LOG.isDebugEnabled() && certificates != null) { + for (int c = 0; c < certificates.length; c++) { + X509Certificate cert = certificates[c]; + LOG.debug(" Server certificate " + (c + 1) + ":"); + LOG.debug(" Subject DN: " + cert.getSubjectDN()); + LOG.debug(" Signature Algorithm: " + cert.getSigAlgName()); + LOG.debug(" Valid from: " + cert.getNotBefore()); + LOG.debug(" Valid until: " + cert.getNotAfter()); + LOG.debug(" Issuer: " + cert.getIssuerDN()); + } + } + defaultTrustManager.checkServerTrusted(certificates, authType); + } + + /** + * @see javax.net.ssl.X509TrustManager#getAcceptedIssuers() + */ + public X509Certificate[] getAcceptedIssuers() { + return this.defaultTrustManager.getAcceptedIssuers(); + } +} diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/Context.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/Context.java index f66be98..4813ce8 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/Context.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/Context.java @@ -25,6 +25,7 @@ import org.apache.hadoop.yarn.api.records.ContainerId; import org.apache.hadoop.yarn.api.records.NodeId; import org.apache.hadoop.yarn.server.api.records.NodeHealthStatus; +import org.apache.hadoop.yarn.server.api.records.NodeTrustStatus; import org.apache.hadoop.yarn.server.nodemanager.containermanager.application.Application; import org.apache.hadoop.yarn.server.nodemanager.containermanager.container.Container; import org.apache.hadoop.yarn.server.nodemanager.security.NMContainerTokenSecretManager; @@ -60,5 +61,8 @@ NodeHealthStatus getNodeHealthStatus(); + //Add by ME + NodeTrustStatus getNodeTrustStatus(); + ContainerManagementProtocol getContainerManager(); } diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/NodeHealthCheckerService.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/NodeHealthCheckerService.java index 446d05c..b0b6264 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/NodeHealthCheckerService.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/NodeHealthCheckerService.java @@ -20,7 +20,7 @@ import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.service.CompositeService; - +import org.apache.hadoop.yarn.conf.YarnConfiguration; /** * The class which provides functionality of checking the health of the node and * reporting back to the service for which the health checker has been asked to @@ -31,6 +31,8 @@ private NodeHealthScriptRunner nodeHealthScriptRunner; private LocalDirsHandlerService dirsHandler; +//Add by ME + private boolean attestNodeTrust = false; static final String SEPARATOR = ";"; public NodeHealthCheckerService() { @@ -45,6 +47,8 @@ protected void serviceInit(Configuration conf) throws Exception { addService(nodeHealthScriptRunner); } addService(dirsHandler); +//Add by ME + this.attestNodeTrust = conf.getBoolean(YarnConfiguration.NM_TRUST_CHECK_ENABLE, false); super.serviceInit(conf); } @@ -64,12 +68,21 @@ String getHealthReport() { /** * @return true if the node is healthy */ - boolean isHealthy() { + boolean isHealthy(String hostname) { boolean scriptHealthStatus = (nodeHealthScriptRunner == null) ? true - : nodeHealthScriptRunner.isHealthy(); - return scriptHealthStatus && dirsHandler.areDisksHealthy(); + : nodeHealthScriptRunner.isHealthy();//Add by ME + if(!this.attestNodeTrust) + return scriptHealthStatus && dirsHandler.areDisksHealthy(); + boolean isTrust = AttestationService.testHost(hostname); + return scriptHealthStatus && dirsHandler.areDisksHealthy() && isTrust; } + boolean isHealthy(){ + + boolean scriptHealthStatus = (nodeHealthScriptRunner == null) ? true + : nodeHealthScriptRunner.isHealthy();//Add by ME + return scriptHealthStatus && dirsHandler.areDisksHealthy() ; +} /** * @return when the last time the node health status is reported */ diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/NodeManager.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/NodeManager.java index 39d416e..15386f2 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/NodeManager.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/NodeManager.java @@ -48,6 +48,7 @@ import org.apache.hadoop.yarn.exceptions.YarnRuntimeException; import org.apache.hadoop.yarn.factory.providers.RecordFactoryProvider; import org.apache.hadoop.yarn.server.api.records.NodeHealthStatus; +import org.apache.hadoop.yarn.server.api.records.NodeTrustStatus; import org.apache.hadoop.yarn.server.nodemanager.containermanager.ContainerManagerImpl; import org.apache.hadoop.yarn.server.nodemanager.containermanager.application.Application; import org.apache.hadoop.yarn.server.nodemanager.containermanager.container.Container; @@ -71,6 +72,8 @@ protected final NodeManagerMetrics metrics = NodeManagerMetrics.create(); private ApplicationACLsManager aclsManager; private NodeHealthCheckerService nodeHealthChecker; + //Add by ME + private NodeTrustCheckerService nodeTrustChecker; private LocalDirsHandlerService dirsHandler; private Context context; private AsyncDispatcher dispatcher; @@ -83,6 +86,12 @@ public NodeManager() { super(NodeManager.class.getName()); } +//Add by ME + protected NodeStatusUpdater createNodeStatusUpdater(Context context, + Dispatcher dispatcher, NodeHealthCheckerService healthChecker,NodeTrustCheckerService trustChecker) { + return new NodeStatusUpdaterImpl(context, dispatcher, healthChecker,trustChecker, + metrics); + } protected NodeStatusUpdater createNodeStatusUpdater(Context context, Dispatcher dispatcher, NodeHealthCheckerService healthChecker) { @@ -157,9 +166,13 @@ protected void serviceInit(Configuration conf) throws Exception { addService(nodeHealthChecker); dirsHandler = nodeHealthChecker.getDiskHandler(); + nodeTrustChecker = new NodeTrustCheckerService(); + addService(nodeTrustChecker); + - nodeStatusUpdater = - createNodeStatusUpdater(context, dispatcher, nodeHealthChecker); + nodeStatusUpdater =//Add by ME + createNodeStatusUpdater(context, dispatcher, nodeHealthChecker,nodeTrustChecker); + // createNodeStatusUpdater(context, dispatcher, nodeHealthChecker); NodeResourceMonitor nodeResourceMonitor = createNodeResourceMonitor(); addService(nodeResourceMonitor); @@ -249,7 +262,9 @@ public void run() { private WebServer webServer; private final NodeHealthStatus nodeHealthStatus = RecordFactoryProvider .getRecordFactory(null).newRecordInstance(NodeHealthStatus.class); - + //Add by ME + private final NodeTrustStatus nodeTrustStatus = RecordFactoryProvider + .getRecordFactory(null).newRecordInstance(NodeTrustStatus.class); public NMContext(NMContainerTokenSecretManager containerTokenSecretManager, NMTokenSecretManagerInNM nmTokenSecretManager) { this.containerTokenSecretManager = containerTokenSecretManager; @@ -257,6 +272,9 @@ public NMContext(NMContainerTokenSecretManager containerTokenSecretManager, this.nodeHealthStatus.setIsNodeHealthy(true); this.nodeHealthStatus.setHealthReport("Healthy"); this.nodeHealthStatus.setLastHealthReportTime(System.currentTimeMillis()); + this.nodeTrustStatus.setIsNodeTrust(true); + this.nodeTrustStatus.setTrustReport("Trust"); + this.nodeTrustStatus.setLastTrustReportTime(System.currentTimeMillis()); } /** @@ -313,6 +331,12 @@ public void setWebServer(WebServer webServer) { public void setNodeId(NodeId nodeId) { this.nodeId = nodeId; } +//Add by ME + @Override + public NodeTrustStatus getNodeTrustStatus() { + // TODO Auto-generated method stub + return this.nodeTrustStatus; + } } @@ -322,7 +346,11 @@ public void setNodeId(NodeId nodeId) { public NodeHealthCheckerService getNodeHealthChecker() { return nodeHealthChecker; } - +//Add by ME + public NodeTrustCheckerService getNodeTrustChecker() { + return nodeTrustChecker; + } + private void initAndStartNodeManager(Configuration conf, boolean hasToReboot) { try { diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/NodeStatusUpdaterImpl.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/NodeStatusUpdaterImpl.java index 9b68bec..44943f9 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/NodeStatusUpdaterImpl.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/NodeStatusUpdaterImpl.java @@ -59,6 +59,7 @@ import org.apache.hadoop.yarn.server.api.records.MasterKey; import org.apache.hadoop.yarn.server.api.records.NodeAction; import org.apache.hadoop.yarn.server.api.records.NodeHealthStatus; +import org.apache.hadoop.yarn.server.api.records.NodeTrustStatus; import org.apache.hadoop.yarn.server.api.records.NodeStatus; import org.apache.hadoop.yarn.server.nodemanager.containermanager.ContainerManagerImpl; import org.apache.hadoop.yarn.server.nodemanager.containermanager.container.Container; @@ -98,6 +99,8 @@ private long durationToTrackStoppedContainers; private final NodeHealthCheckerService healthChecker; +//Add by ME + private final NodeTrustCheckerService trustChecker; private final NodeManagerMetrics metrics; private Runnable statusUpdaterRunnable; @@ -105,9 +108,10 @@ private long rmIdentifier = ResourceManagerConstants.RM_INVALID_IDENTIFIER; public NodeStatusUpdaterImpl(Context context, Dispatcher dispatcher, - NodeHealthCheckerService healthChecker, NodeManagerMetrics metrics) { + NodeHealthCheckerService healthChecker,NodeTrustCheckerService trustChecker, NodeManagerMetrics metrics) { super(NodeStatusUpdaterImpl.class.getName()); this.healthChecker = healthChecker; + this.trustChecker = trustChecker; this.context = context; this.dispatcher = dispatcher; this.metrics = metrics; @@ -115,6 +119,17 @@ public NodeStatusUpdaterImpl(Context context, Dispatcher dispatcher, new LinkedHashMap(); } + public NodeStatusUpdaterImpl(Context context, Dispatcher dispatcher, + NodeHealthCheckerService healthChecker, NodeManagerMetrics metrics) { + super(NodeStatusUpdaterImpl.class.getName()); + this.healthChecker = healthChecker; + this.trustChecker = null ; + this.context = context; + this.dispatcher = dispatcher; + this.metrics = metrics; + this.recentlyStoppedContainers = + new LinkedHashMap(); + } @Override protected void serviceInit(Configuration conf) throws Exception { int memoryMb = @@ -331,7 +346,8 @@ public NodeStatus getNodeStatusAndUpdateContainersInContext() { NodeHealthStatus nodeHealthStatus = this.context.getNodeHealthStatus(); nodeHealthStatus.setHealthReport(healthChecker.getHealthReport()); - nodeHealthStatus.setIsNodeHealthy(healthChecker.isHealthy()); +//Add by ME + nodeHealthStatus.setIsNodeHealthy(healthChecker.isHealthy(nodeStatus.getNodeId().getHost())); nodeHealthStatus.setLastHealthReportTime( healthChecker.getLastHealthReportTime()); if (LOG.isDebugEnabled()) { @@ -339,6 +355,17 @@ public NodeStatus getNodeStatusAndUpdateContainersInContext() { + ", " + nodeHealthStatus.getHealthReport()); } nodeStatus.setNodeHealthStatus(nodeHealthStatus); + //Add by ME + NodeTrustStatus nodeTrustStatus = this.context.getNodeTrustStatus(); + nodeTrustStatus.setTrustReport(trustChecker.getTrusthReport()); + nodeTrustStatus.setIsNodeTrust(trustChecker.isTrust(nodeStatus.getNodeId().getHost())); + nodeTrustStatus.setLastTrustReportTime( + trustChecker.getLastTrustReportTime()); + if(LOG.isDebugEnabled()){ + LOG.debug("Node's trust-status : " + nodeTrustStatus.getIsNodeTrust() + + ", " + nodeTrustStatus.getTrustReport()); + } + nodeStatus.setNodeTrustStatus(nodeTrustStatus); List keepAliveAppIds = createKeepAliveApplicationList(); nodeStatus.setKeepAliveApplications(keepAliveAppIds); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/NodeTrustCheckerService.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/NodeTrustCheckerService.java new file mode 100644 index 0000000..cc646fc --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/NodeTrustCheckerService.java @@ -0,0 +1,63 @@ +/** +* 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.yarn.server.nodemanager; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.service.CompositeService; +import org.apache.hadoop.yarn.conf.YarnConfiguration; +public class NodeTrustCheckerService extends CompositeService{ + + private boolean attestNodeTrust = false; + + public NodeTrustCheckerService() { + super(NodeTrustCheckerService.class.getName()); + } + + @Override + protected void serviceInit(Configuration conf) throws Exception { + super.serviceInit(conf); + this.attestNodeTrust = conf.getBoolean(YarnConfiguration.NM_TRUST_CHECK_ENABLE, true); + } + + /** + * @return the reporting string of health of the node + */ + String getTrusthReport() { + return "Trust status now is not implemented"; + } + + /** + * @return true if the node is healthy + */ + boolean isTrust(String hostname) { + if(!this.attestNodeTrust) + return true; + return AttestationService.testHost(hostname); + } + + /** + * @return when the last time the node health status is reported + */ + long getLastTrustReportTime() { + //Not implements + long lastReportTime = 0; + return lastReportTime; + } + +} diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ClientRMService.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ClientRMService.java index a25735e..d92c83b 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ClientRMService.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ClientRMService.java @@ -450,7 +450,6 @@ public GetClusterNodesResponse getClusterNodes(GetClusterNodesRequest request) } Collection nodes = RMServerUtils.queryRMNodes(rmContext, nodeStates); - List nodeReports = new ArrayList(nodes.size()); for (RMNode nodeInfo : nodes) { nodeReports.add(createNodeReports(nodeInfo)); @@ -504,7 +503,10 @@ private NodeReport createNodeReports(RMNode rmNode) { rmNode.getHttpAddress(), rmNode.getRackName(), used, rmNode.getTotalCapability(), numContainers, rmNode.getHealthReport(), - rmNode.getLastHealthReportTime()); + rmNode.getLastHealthReportTime(), +//Add by ME + rmNode.getTrustReport(), + rmNode.getLastTrustReportTime()); return report; } diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ClusterMetrics.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ClusterMetrics.java index 5c94ef4..0d0a6a2 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ClusterMetrics.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ClusterMetrics.java @@ -42,6 +42,8 @@ @Metric("# of decommissioned NMs") MutableGaugeInt numDecommissionedNMs; @Metric("# of lost NMs") MutableGaugeInt numLostNMs; @Metric("# of unhealthy NMs") MutableGaugeInt numUnhealthyNMs; + //Add by ME + @Metric("# of untrust NMs") MutableGaugeInt numUntrustNMs; @Metric("# of Rebooted NMs") MutableGaugeInt numRebootedNMs; private static final MetricsInfo RECORD_INFO = info("ClusterMetrics", @@ -121,7 +123,19 @@ public void incrNumUnhealthyNMs() { public void decrNumUnhealthyNMs() { numUnhealthyNMs.decr(); } + // Add by ME + //Untrust NMs + public int getUntrustNMs(){ + return numUntrustNMs.value(); + } + + public void incrNumUntrustNMs(){ + numUntrustNMs.incr(); + } + public void decrNumUntrustNMs(){ + numUntrustNMs.decr(); + } //Rebooted NMs public int getNumRebootedNMs() { return numRebootedNMs.value(); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/RMServerUtils.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/RMServerUtils.java index 370040a..08a4c82 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/RMServerUtils.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/RMServerUtils.java @@ -47,7 +47,8 @@ ArrayList results = new ArrayList(); if (acceptedStates.contains(NodeState.NEW) || acceptedStates.contains(NodeState.RUNNING) || - acceptedStates.contains(NodeState.UNHEALTHY)) { + acceptedStates.contains(NodeState.UNHEALTHY) || + acceptedStates.contains(NodeState.UNTRUST)) { for (RMNode rmNode : context.getRMNodes().values()) { if (acceptedStates.contains(rmNode.getState())) { results.add(rmNode); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ResourceTrackerService.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ResourceTrackerService.java index aa8f120..25e2a94 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ResourceTrackerService.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ResourceTrackerService.java @@ -307,6 +307,7 @@ public NodeHeartbeatResponse nodeHeartbeat(NodeHeartbeatRequest request) // 4. Send status to RMNode, saving the latest response. this.rmContext.getDispatcher().getEventHandler().handle( new RMNodeStatusEvent(nodeId, remoteNodeStatus.getNodeHealthStatus(), + remoteNodeStatus.getNodeTrustStatus(), remoteNodeStatus.getContainersStatuses(), remoteNodeStatus.getKeepAliveApplications(), nodeHeartBeatResponse)); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmnode/RMNode.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmnode/RMNode.java index 0021e25..a435af1 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmnode/RMNode.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmnode/RMNode.java @@ -85,6 +85,10 @@ */ public long getLastHealthReportTime(); + //Add by ME + public String getTrustReport(); + + public long getLastTrustReportTime(); /** * the total available resource. * @return the total available resource. diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmnode/RMNodeImpl.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmnode/RMNodeImpl.java index 7964e75..3221609 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmnode/RMNodeImpl.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmnode/RMNodeImpl.java @@ -48,6 +48,7 @@ import org.apache.hadoop.yarn.factory.providers.RecordFactoryProvider; import org.apache.hadoop.yarn.server.api.protocolrecords.NodeHeartbeatResponse; import org.apache.hadoop.yarn.server.api.records.NodeHealthStatus; +import org.apache.hadoop.yarn.server.api.records.NodeTrustStatus; import org.apache.hadoop.yarn.server.resourcemanager.ClusterMetrics; import org.apache.hadoop.yarn.server.resourcemanager.NodesListManagerEvent; import org.apache.hadoop.yarn.server.resourcemanager.NodesListManagerEventType; @@ -97,6 +98,10 @@ private String healthReport; private long lastHealthReportTime; + + //Add by ME + private String trustReport; + private long lastTrustReportTime; /* set of containers that have just launched */ private final Map justLaunchedContainers = @@ -127,8 +132,8 @@ //Transitions from RUNNING state .addTransition(NodeState.RUNNING, - EnumSet.of(NodeState.RUNNING, NodeState.UNHEALTHY), - RMNodeEventType.STATUS_UPDATE, new StatusUpdateWhenHealthyTransition()) + EnumSet.of(NodeState.RUNNING, NodeState.UNHEALTHY, NodeState.UNTRUST), + RMNodeEventType.STATUS_UPDATE, new StatusUpdateWhenHealthyAndTrustTransition()) .addTransition(NodeState.RUNNING, NodeState.DECOMMISSIONED, RMNodeEventType.DECOMMISSION, new DeactivateNodeTransition(NodeState.DECOMMISSIONED)) @@ -147,7 +152,7 @@ //Transitions from UNHEALTHY state .addTransition(NodeState.UNHEALTHY, - EnumSet.of(NodeState.UNHEALTHY, NodeState.RUNNING), + EnumSet.of(NodeState.UNHEALTHY, NodeState.RUNNING, NodeState.UNTRUST), RMNodeEventType.STATUS_UPDATE, new StatusUpdateWhenUnHealthyTransition()) .addTransition(NodeState.UNHEALTHY, NodeState.DECOMMISSIONED, RMNodeEventType.DECOMMISSION, @@ -164,6 +169,27 @@ RMNodeEventType.CLEANUP_APP, new CleanUpAppTransition()) .addTransition(NodeState.UNHEALTHY, NodeState.UNHEALTHY, RMNodeEventType.CLEANUP_CONTAINER, new CleanUpContainerTransition()) + + //Add by ME + //Transitions from UNTRUST state + .addTransition(NodeState.UNTRUST, + EnumSet.of(NodeState.UNTRUST,NodeState.RUNNING,NodeState.UNHEALTHY), + RMNodeEventType.STATUS_UPDATE,new StatusUpdateWhenUnTrustTransition()) + .addTransition(NodeState.UNTRUST,NodeState.DECOMMISSIONED, + RMNodeEventType.DECOMMISSION, + new DeactivateNodeTransition(NodeState.DECOMMISSIONED)) + .addTransition(NodeState.UNTRUST, NodeState.LOST, + RMNodeEventType.EXPIRE, + new DeactivateNodeTransition(NodeState.LOST)) + .addTransition(NodeState.UNTRUST, NodeState.REBOOTED, + RMNodeEventType.REBOOTING, + new DeactivateNodeTransition(NodeState.REBOOTED)) + .addTransition(NodeState.UNTRUST, NodeState.UNTRUST, + RMNodeEventType.RECONNECTED, new ReconnectNodeTransition()) + .addTransition(NodeState.UNTRUST, NodeState.UNTRUST, + RMNodeEventType.CLEANUP_APP, new CleanUpAppTransition()) + .addTransition(NodeState.UNTRUST, NodeState.UNTRUST, + RMNodeEventType.CLEANUP_CONTAINER, new CleanUpContainerTransition()) // create the topology tables .installTopology(); @@ -184,7 +210,9 @@ public RMNodeImpl(NodeId nodeId, RMContext context, String hostName, this.node = node; this.healthReport = "Healthy"; this.lastHealthReportTime = System.currentTimeMillis(); - +//Add by ME + this.trustReport = "Trust"; + this.lastTrustReportTime = System.currentTimeMillis(); this.latestNodeHeartBeatResponse.setResponseId(0); ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); @@ -288,6 +316,45 @@ public long getLastHealthReportTime() { } } + //Add by ME + @Override + public String getTrustReport(){ + this.readLock.lock(); + try{ + return this.trustReport; + }finally{ + this.readLock.unlock(); + } + } + + public void setTrustReport(String trustReport){ + this.writeLock.lock(); + try{ + this.trustReport = trustReport; + }finally{ + this.writeLock.unlock(); + } + } + + @Override + public long getLastTrustReportTime(){ + this.readLock.lock(); + try{ + return this.lastTrustReportTime; + }finally { + this.readLock.unlock(); + } + } + + public void setLastTrustReportTime(long lastTrustReportTime){ + this.writeLock.lock(); + try{ + this.lastTrustReportTime = lastTrustReportTime; + }finally{ + this.writeLock.unlock(); + } + } + @Override public NodeState getState() { this.readLock.lock(); @@ -389,6 +456,9 @@ private void updateMetricsForRejoinedNode(NodeState previousNodeState) { break; case UNHEALTHY: metrics.decrNumUnhealthyNMs(); + //Add by ME + case UNTRUST: + metrics.decrNumUntrustNMs(); break; } } @@ -404,6 +474,9 @@ private void updateMetricsForDeactivatedNode(NodeState initialState, case UNHEALTHY: metrics.decrNumUnhealthyNMs(); break; + case UNTRUST: + metrics.decrNumUntrustNMs(); + break; } switch (finalState) { @@ -419,6 +492,9 @@ private void updateMetricsForDeactivatedNode(NodeState initialState, case UNHEALTHY: metrics.incrNumUnhealthyNMs(); break; + case UNTRUST: + metrics.incrNumUntrustNMs(); + break; } } @@ -460,8 +536,10 @@ public void transition(RMNodeImpl rmNode, RMNodeEvent event) { && rmNode.getHttpPort() == newNode.getHttpPort()) { // Reset heartbeat ID since node just restarted. rmNode.getLastNodeHeartBeatResponse().setResponseId(0); - if (rmNode.getState() != NodeState.UNHEALTHY) { - // Only add new node if old state is not UNHEALTHY + //Add by ME + if ((rmNode.getState() != NodeState.UNHEALTHY) + && (rmNode.getState() != NodeState.UNTRUST)) { + // Only add new node if old state is not UNHEALTHY and not UNTRUST rmNode.context.getDispatcher().getEventHandler().handle( new NodeAddedSchedulerEvent(rmNode)); } @@ -474,6 +552,10 @@ public void transition(RMNodeImpl rmNode, RMNodeEvent event) { case UNHEALTHY: ClusterMetrics.getMetrics().decrNumUnhealthyNMs(); break; + //Add by ME + case UNTRUST: + ClusterMetrics.getMetrics().decrNumUntrustNMs(); + break; } rmNode.context.getRMNodes().put(newNode.getNodeID(), newNode); rmNode.context.getDispatcher().getEventHandler().handle( @@ -518,7 +600,8 @@ public void transition(RMNodeImpl rmNode, RMNodeEvent event) { // Then node is already been removed from the // Scheduler NodeState initialState = rmNode.getState(); - if (!initialState.equals(NodeState.UNHEALTHY)) { + //Add by ME + if (!initialState.equals(NodeState.UNHEALTHY) && !initialState.equals(NodeState.UNTRUST)) { rmNode.context.getDispatcher().getEventHandler() .handle(new NodeRemovedSchedulerEvent(rmNode)); } @@ -537,7 +620,7 @@ public void transition(RMNodeImpl rmNode, RMNodeEvent event) { } } - public static class StatusUpdateWhenHealthyTransition implements + public static class StatusUpdateWhenHealthyAndTrustTransition implements MultipleArcTransition { @Override public NodeState transition(RMNodeImpl rmNode, RMNodeEvent event) { @@ -552,9 +635,15 @@ public NodeState transition(RMNodeImpl rmNode, RMNodeEvent event) { rmNode.setHealthReport(remoteNodeHealthStatus.getHealthReport()); rmNode.setLastHealthReportTime( remoteNodeHealthStatus.getLastHealthReportTime()); - if (!remoteNodeHealthStatus.getIsNodeHealthy()) { + //Add by ME + NodeTrustStatus remoteNodeTrustStatus = + statusEvent.getNodeTrustStatus(); + rmNode.setTrustReport(remoteNodeTrustStatus.getTrustReport()); + rmNode.setLastHealthReportTime( + remoteNodeTrustStatus.getLastTrustReportTime()); + if (!remoteNodeHealthStatus.getIsNodeHealthy() ) {//assumed 'trust' and 'healthy' are mutual LOG.info("Node " + rmNode.nodeId + " reported UNHEALTHY with details: " - + remoteNodeHealthStatus.getHealthReport()); + + remoteNodeHealthStatus.getHealthReport() ); rmNode.nodeUpdateQueue.clear(); // Inform the scheduler rmNode.context.getDispatcher().getEventHandler().handle( @@ -567,7 +656,22 @@ public NodeState transition(RMNodeImpl rmNode, RMNodeEvent event) { NodeState.UNHEALTHY); return NodeState.UNHEALTHY; } - +//Add by ME + if(!remoteNodeTrustStatus.getIsNodeTrust()){ + LOG.info("Node " + rmNode.nodeId + " reported UNTRUST with details: " + + remoteNodeTrustStatus.getTrustReport() ); + rmNode.nodeUpdateQueue.clear(); + // Inform the scheduler + rmNode.context.getDispatcher().getEventHandler().handle( + new NodeRemovedSchedulerEvent(rmNode)); + rmNode.context.getDispatcher().getEventHandler().handle( + new NodesListManagerEvent( + NodesListManagerEventType.NODE_UNUSABLE, rmNode)); + // Update metrics + rmNode.updateMetricsForDeactivatedNode(rmNode.getState(), + NodeState.UNTRUST); + return NodeState.UNTRUST; + } // Filter the map to only obtain just launched containers and finished // containers. List newlyLaunchedContainers = @@ -641,7 +745,20 @@ public NodeState transition(RMNodeImpl rmNode, RMNodeEvent event) { rmNode.setHealthReport(remoteNodeHealthStatus.getHealthReport()); rmNode.setLastHealthReportTime( remoteNodeHealthStatus.getLastHealthReportTime()); - if (remoteNodeHealthStatus.getIsNodeHealthy()) { + //Add by ME + NodeTrustStatus remoteNodeTrustStatus = statusEvent.getNodeTrustStatus(); + rmNode.setTrustReport(remoteNodeTrustStatus.getTrustReport()); + rmNode.setLastTrustReportTime( + remoteNodeTrustStatus.getLastTrustReportTime()); + //Add by ME + if(!remoteNodeHealthStatus.getIsNodeHealthy()){ + return NodeState.UNHEALTHY; + } + if (!remoteNodeTrustStatus.getIsNodeTrust()) { + rmNode.updateMetricsForDeactivatedNode(NodeState.UNHEALTHY, NodeState.UNTRUST); + return NodeState.UNTRUST; + } + { rmNode.context.getDispatcher().getEventHandler().handle( new NodeAddedSchedulerEvent(rmNode)); rmNode.context.getDispatcher().getEventHandler().handle( @@ -654,11 +771,49 @@ public NodeState transition(RMNodeImpl rmNode, RMNodeEvent event) { rmNode.updateMetricsForRejoinedNode(NodeState.UNHEALTHY); return NodeState.RUNNING; } - - return NodeState.UNHEALTHY; } } + public static class StatusUpdateWhenUnTrustTransition implements + MultipleArcTransition { + @Override + public NodeState transition(RMNodeImpl rmNode, RMNodeEvent event) { + RMNodeStatusEvent statusEvent = (RMNodeStatusEvent) event; + + // Switch the last heartbeatresponse. + rmNode.latestNodeHeartBeatResponse = statusEvent.getLatestResponse(); + NodeHealthStatus remoteNodeHealthStatus = statusEvent.getNodeHealthStatus(); + rmNode.setHealthReport(remoteNodeHealthStatus.getHealthReport()); + rmNode.setLastHealthReportTime( + remoteNodeHealthStatus.getLastHealthReportTime()); + //Add by ME + NodeTrustStatus remoteNodeTrustStatus = statusEvent.getNodeTrustStatus(); + rmNode.setTrustReport(remoteNodeTrustStatus.getTrustReport()); + rmNode.setLastTrustReportTime( + remoteNodeTrustStatus.getLastTrustReportTime()); + //Add by ME + if(!remoteNodeHealthStatus.getIsNodeHealthy()){ + rmNode.updateMetricsForDeactivatedNode(NodeState.UNTRUST, NodeState.UNHEALTHY); + return NodeState.UNHEALTHY; + } + if (!remoteNodeTrustStatus.getIsNodeTrust()) { + return NodeState.UNTRUST; + } + { + rmNode.context.getDispatcher().getEventHandler().handle( + new NodeAddedSchedulerEvent(rmNode)); + rmNode.context.getDispatcher().getEventHandler().handle( + new NodesListManagerEvent( + NodesListManagerEventType.NODE_USABLE, rmNode)); + // ??? how about updating metrics before notifying to ensure that + // notifiers get update metadata because they will very likely query it + // upon notification + // Update metrics + rmNode.updateMetricsForRejoinedNode(NodeState.UNTRUST); + return NodeState.RUNNING; + } + } + } @Override public List pullContainerUpdates() { List latestContainerInfoList = diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmnode/RMNodeStatusEvent.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmnode/RMNodeStatusEvent.java index abfacbb..e85141b 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmnode/RMNodeStatusEvent.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmnode/RMNodeStatusEvent.java @@ -25,24 +25,38 @@ import org.apache.hadoop.yarn.api.records.NodeId; import org.apache.hadoop.yarn.server.api.protocolrecords.NodeHeartbeatResponse; import org.apache.hadoop.yarn.server.api.records.NodeHealthStatus; +import org.apache.hadoop.yarn.server.api.records.NodeTrustStatus; public class RMNodeStatusEvent extends RMNodeEvent { private final NodeHealthStatus nodeHealthStatus; + private final NodeTrustStatus nodeTrustStatus; private final List containersCollection; private final NodeHeartbeatResponse latestResponse; private final List keepAliveAppIds; public RMNodeStatusEvent(NodeId nodeId, NodeHealthStatus nodeHealthStatus, + NodeTrustStatus nodeTrustStatus, List collection, List keepAliveAppIds, NodeHeartbeatResponse latestResponse) { super(nodeId, RMNodeEventType.STATUS_UPDATE); this.nodeHealthStatus = nodeHealthStatus; + this.nodeTrustStatus = nodeTrustStatus; this.containersCollection = collection; this.keepAliveAppIds = keepAliveAppIds; this.latestResponse = latestResponse; } + public RMNodeStatusEvent(NodeId nodeId, NodeHealthStatus nodeHealthStatus, + List collection, List keepAliveAppIds, + NodeHeartbeatResponse latestResponse) { + super(nodeId, RMNodeEventType.STATUS_UPDATE); + this.nodeHealthStatus = nodeHealthStatus; + this.nodeTrustStatus = null; + this.containersCollection = collection; + this.keepAliveAppIds = keepAliveAppIds; + this.latestResponse = latestResponse; + } public NodeHealthStatus getNodeHealthStatus() { return this.nodeHealthStatus; } @@ -55,7 +69,12 @@ public NodeHeartbeatResponse getLatestResponse() { return this.latestResponse; } + //Add by ME + public NodeTrustStatus getNodeTrustStatus(){ + return this.nodeTrustStatus; + } + public List getKeepAliveAppIds() { return this.keepAliveAppIds; } -} \ No newline at end of file +} diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/CapacityScheduler.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/CapacityScheduler.java index a8a47c9..b6558ee 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/CapacityScheduler.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/CapacityScheduler.java @@ -172,8 +172,17 @@ public Configuration getConf() { private Map queues = new ConcurrentHashMap(); - private Map nodes = + private static Map nodes = new ConcurrentHashMap(); + //Add by ME + //public static void printNodes(){ +// LOG.info("There are " + nodes.size() + "node"); +// for(Map.Entry entry :nodes.entrySet()){ +// LOG.info(entry.getKey().getHost()); +// } + + //} + private Resource clusterResource = RecordFactoryProvider.getRecordFactory(null).newRecordInstance(Resource.class); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/MetricsOverviewTable.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/MetricsOverviewTable.java index 7a8b681..96e5ac2 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/MetricsOverviewTable.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/MetricsOverviewTable.java @@ -75,6 +75,8 @@ protected void render(Block html) { th().$class("ui-state-default")._("Active Nodes")._(). th().$class("ui-state-default")._("Decommissioned Nodes")._(). th().$class("ui-state-default")._("Lost Nodes")._(). + //Add by ME + th().$class("ui-state-default")._("Untrust Nodes")._(). th().$class("ui-state-default")._("Unhealthy Nodes")._(). th().$class("ui-state-default")._("Rebooted Nodes")._(). _(). @@ -97,6 +99,8 @@ protected void render(Block html) { td().a(url("nodes"),String.valueOf(clusterMetrics.getActiveNodes()))._(). td().a(url("nodes/decommissioned"),String.valueOf(clusterMetrics.getDecommissionedNodes()))._(). td().a(url("nodes/lost"),String.valueOf(clusterMetrics.getLostNodes()))._(). + //Add by ME + td().a(url("nodes/untrust"),String.valueOf(clusterMetrics.getUntrustNodes()))._(). td().a(url("nodes/unhealthy"),String.valueOf(clusterMetrics.getUnhealthyNodes()))._(). td().a(url("nodes/rebooted"),String.valueOf(clusterMetrics.getRebootedNodes()))._(). _(). diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/NodesPage.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/NodesPage.java index 87720e0..9c11234 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/NodesPage.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/NodesPage.java @@ -103,7 +103,7 @@ protected void render(Block html) { } else { // No filter. User is asking for all nodes. Make sure you skip the // unhealthy nodes. - if (ni.getState() == NodeState.UNHEALTHY) { + if (ni.getState() == NodeState.UNHEALTHY || ni.getState() == NodeState.UNTRUST) { continue; } } diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/ClusterMetricsInfo.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/ClusterMetricsInfo.java index 92c9678..c13177d 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/ClusterMetricsInfo.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/ClusterMetricsInfo.java @@ -49,6 +49,8 @@ protected long totalMB; protected int totalNodes; protected int lostNodes; + //Add by ME + protected int untrustNodes; protected int unhealthyNodes; protected int decommissionedNodes; protected int rebootedNodes; @@ -80,6 +82,8 @@ public ClusterMetricsInfo(final ResourceManager rm, final RMContext rmContext) { this.totalMB = availableMB + allocatedMB; this.activeNodes = clusterMetrics.getNumActiveNMs(); this.lostNodes = clusterMetrics.getNumLostNMs(); + //Add by ME + this.untrustNodes = clusterMetrics.getUntrustNMs(); this.unhealthyNodes = clusterMetrics.getUnhealthyNMs(); this.decommissionedNodes = clusterMetrics.getNumDecommisionedNMs(); this.rebootedNodes = clusterMetrics.getNumRebootedNMs(); @@ -155,6 +159,11 @@ public int getRebootedNodes() { return this.rebootedNodes; } +//Add by ME + public int getUntrustNodes() { + return this.untrustNodes; + } + public int getUnhealthyNodes() { return this.unhealthyNodes; } diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/MockNodes.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/MockNodes.java index d69828d..881324b 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/MockNodes.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/MockNodes.java @@ -197,6 +197,16 @@ public String getHealthReport() { public long getLastHealthReportTime() { return lastHealthReportTime; } + + @Override + public String getTrustReport() { + return null; + } + + @Override + public long getLastTrustReportTime() { + return 0; + } }; private static RMNode buildRMNode(int rack, final Resource perNode, NodeState state, String httpAddr) {