diff --git hadoop-tools/hadoop-sls/src/main/java/org/apache/hadoop/yarn/sls/nodemanager/NodeInfo.java hadoop-tools/hadoop-sls/src/main/java/org/apache/hadoop/yarn/sls/nodemanager/NodeInfo.java index 7667157..9ae3326 100644 --- hadoop-tools/hadoop-sls/src/main/java/org/apache/hadoop/yarn/sls/nodemanager/NodeInfo.java +++ hadoop-tools/hadoop-sls/src/main/java/org/apache/hadoop/yarn/sls/nodemanager/NodeInfo.java @@ -52,6 +52,7 @@ public static NodeId newNodeID(String host, int port) { private volatile ResourceOption perNode; private String rackName; private String healthReport; + private String trustReport; private NodeState state; private List toCleanUpContainers; private List toCleanUpApplications; @@ -72,6 +73,23 @@ public FakeRMNodeImpl(NodeId nodeId, String nodeAddr, String httpAddress, toCleanUpContainers = new ArrayList(); } + public FakeRMNodeImpl(NodeId nodeId, String nodeAddr, String httpAddress, + ResourceOption perNode, String rackName, String healthReport, String trustReport, + int cmdPort, String hostName, NodeState state) { + this.nodeId = nodeId; + this.nodeAddr = nodeAddr; + this.httpAddress = httpAddress; + this.perNode = perNode; + this.rackName = rackName; + this.healthReport = healthReport; + this.trustReport = trustReport; + this.cmdPort = cmdPort; + this.hostName = hostName; + this.state = state; + toCleanUpApplications = new ArrayList(); + toCleanUpContainers = new ArrayList(); + } + public NodeId getNodeID() { return nodeId; } @@ -103,6 +121,14 @@ public String getHealthReport() { public long getLastHealthReportTime() { return 0; } + + public String getTrustReport() { + return trustReport; + } + + public long getLastTrustReportTime() { + return 0; + } public Resource getTotalCapability() { return perNode.getResource(); diff --git hadoop-tools/hadoop-sls/src/main/java/org/apache/hadoop/yarn/sls/scheduler/RMNodeWrapper.java hadoop-tools/hadoop-sls/src/main/java/org/apache/hadoop/yarn/sls/scheduler/RMNodeWrapper.java index bbe24c8..e9ebd8c 100644 --- hadoop-tools/hadoop-sls/src/main/java/org/apache/hadoop/yarn/sls/scheduler/RMNodeWrapper.java +++ hadoop-tools/hadoop-sls/src/main/java/org/apache/hadoop/yarn/sls/scheduler/RMNodeWrapper.java @@ -84,6 +84,16 @@ public long getLastHealthReportTime() { } @Override + public String getTrustReport() { + return node.getTrustReport(); + } + + @Override + public long getLastTrustReportTime() { + return node.getLastTrustReportTime(); + } + + @Override public Resource getTotalCapability() { return node.getTotalCapability(); } 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..771b24e 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 @@ -64,6 +64,27 @@ public static NodeReport newInstance(NodeId nodeId, NodeState nodeState, return nodeReport; } + @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); + 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); + + @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..7d6bce8 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, + UNTRUST, + /** Node is out of service */ DECOMMISSIONED, 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 59e108a..5d32ed6 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 @@ -512,6 +512,12 @@ // Node Manager Configs //////////////////////////////// + /**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"; + /** Prefix for all node manager configs.*/ public static final String NM_PREFIX = "yarn.nodemanager."; @@ -746,6 +752,9 @@ public static final long DEFAULT_NM_DISK_HEALTH_CHECK_INTERVAL_MS = 2 * 60 * 1000; + public static final String NM_TRUST_CHECK_ENABLE = + NM_PREFIX + "node-trust-checker.enable"; + /** * The minimum fraction of number of disks to be healthy for the nodemanager * to launch new containers. This applies to nm-local-dirs and nm-log-dirs. 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 3f1fa6c..d6bcdd0 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 @@ -209,6 +209,7 @@ enum NodeStateProto { NS_DECOMMISSIONED = 4; NS_LOST = 5; NS_REBOOTED = 6; + NS_UNTRUST = 7; } message NodeIdProto { @@ -226,6 +227,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-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..cbbe700 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; @@ -37,6 +39,7 @@ @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..6fd7343 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); } + + @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 aad819d..8ad0bc2 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 @@ -30,6 +30,20 @@ public static NodeStatus newInstance(NodeId nodeId, int responseId, List containerStatuses, List keepAliveApplications, + NodeHealthStatus nodeHealthStatus, + NodeTrustStatus nodeTrustStatus) { + NodeStatus nodeStatus = Records.newRecord(NodeStatus.class); + nodeStatus.setResponseId(responseId); + nodeStatus.setNodeId(nodeId); + nodeStatus.setContainersStatuses(containerStatuses); + nodeStatus.setKeepAliveApplications(keepAliveApplications); + nodeStatus.setNodeHealthStatus(nodeHealthStatus); + nodeStatus.setNodeTrustStatus(nodeTrustStatus); + return nodeStatus; + } + public static NodeStatus newInstance(NodeId nodeId, int responseId, + List containerStatuses, + List keepAliveApplications, NodeHealthStatus nodeHealthStatus) { NodeStatus nodeStatus = Records.newRecord(NodeStatus.class); nodeStatus.setResponseId(responseId); @@ -37,6 +51,7 @@ public static NodeStatus newInstance(NodeId nodeId, int responseId, nodeStatus.setContainersStatuses(containerStatuses); nodeStatus.setKeepAliveApplications(keepAliveApplications); nodeStatus.setNodeHealthStatus(nodeHealthStatus); + nodeStatus.setNodeTrustStatus(null); return nodeStatus; } @@ -53,6 +68,9 @@ public abstract void setContainersStatuses( public abstract NodeHealthStatus getNodeHealthStatus(); public abstract void setNodeHealthStatus(NodeHealthStatus healthStatus); + public abstract NodeTrustStatus getNodeTrustStatus(); + public abstract 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..c22328a --- /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,65 @@ +/** + * 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.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); + + @Public + @Stable + public abstract String getTrustReport(); + + @Private + @Unstable + public abstract void setTrustReport(String healthReport); + + @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 65376dc..3fbf4b2 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 @@ -33,9 +33,11 @@ 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.NodeTrustStatus; import org.apache.hadoop.yarn.server.api.records.NodeStatus; @@ -47,6 +49,7 @@ private NodeId nodeId = null; private List containers = null; private NodeHealthStatus nodeHealthStatus = null; + private NodeTrustStatus nodeTrustStatus = null; private List keepAliveApplications = null; public NodeStatusPBImpl() { @@ -75,6 +78,9 @@ private synchronized void mergeLocalToBuilder() { if (this.nodeHealthStatus != null) { builder.setNodeHealthStatus(convertToProtoFormat(this.nodeHealthStatus)); } + if(this.nodeTrustStatus != null) { + builder.setNodeTrustStatus(convertToProtoFormat(this.nodeTrustStatus)); + } if (this.keepAliveApplications != null) { addKeepAliveApplicationsToProto(); } @@ -291,6 +297,28 @@ 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(); } @@ -307,7 +335,14 @@ private NodeHealthStatusProto convertToProtoFormat( private NodeHealthStatus convertFromProtoFormat(NodeHealthStatusProto proto) { return new NodeHealthStatusPBImpl(proto); } + 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..cfe5475 --- /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,131 @@ +/** + * 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.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 64eb428..53b2838 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 @@ -187,6 +187,25 @@ public static NodeReport newNodeReport(NodeId nodeId, NodeState nodeState, return nodeReport; } + 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..ad0e7f9 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 @@ -36,6 +36,7 @@ message NodeStatusProto { repeated ContainerStatusProto containersStatuses = 3; optional NodeHealthStatusProto nodeHealthStatus = 4; repeated ApplicationIdProto keep_alive_applications = 5; + optional NodeTrustStatusProto nodeTrustStatus = 6; } message MasterKeyProto { @@ -47,4 +48,10 @@ 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 +} + +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 370cc36..6f746f1 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 @@ -160,6 +160,20 @@ org.fusesource.leveldbjni leveldbjni-all + + org.apache.commons + commons-lang3 + 3.3.2 + + + commons-httpclient + commons-httpclient + + + org.codehaus.jackson + jackson-core-asl + 1.9.13 + 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..d18f800 --- /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,218 @@ +/** +* 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; + int port = 8181; + 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); + + 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()); + in.close(); + 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), null, null)); + postMethod.addRequestHeader("Accept", CONTENT_TYPE); + postMethod.addRequestHeader("Content-type", CONTENT_TYPE); + 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..8375cba --- /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..57c88cc --- /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,314 @@ +/** +* 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.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..ad95ad7 --- /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,100 @@ +/** +* 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.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 956ea33..0515180 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.recovery.NMStateStoreService; @@ -62,6 +63,8 @@ NodeHealthStatus getNodeHealthStatus(); + NodeTrustStatus getNodeTrustStatus(); + ContainerManagementProtocol getContainerManager(); LocalDirsHandlerService getLocalDirsHandler(); 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..57530e7 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 @@ -30,7 +30,7 @@ private NodeHealthScriptRunner nodeHealthScriptRunner; private LocalDirsHandlerService dirsHandler; - + private boolean attestNodeTrust = false; static final String SEPARATOR = ";"; public NodeHealthCheckerService() { @@ -45,6 +45,7 @@ protected void serviceInit(Configuration conf) throws Exception { addService(nodeHealthScriptRunner); } addService(dirsHandler); + this.attestNodeTrust = conf.getBoolean(YarnConfiguration.NM_TRUST_CHECK_ENABLE, false); super.serviceInit(conf); } @@ -70,6 +71,15 @@ boolean isHealthy() { return scriptHealthStatus && dirsHandler.areDisksHealthy(); } + boolean isHealthy(String hostname) { + boolean scriptHealthStatus = (nodeHealthScriptRunner == null) ? true + : nodeHealthScriptRunner.isHealthy(); + if(!this.attestNodeTrust) + return scriptHealthStatus && dirsHandler.areDisksHealthy(); + boolean isTrust = AttestationService.testHost(hostname); + return scriptHealthStatus && dirsHandler.areDisksHealthy() && isTrust; + } + /** * @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 1109b08..0d2f256 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 @@ -49,6 +49,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; @@ -75,6 +76,7 @@ protected final NodeManagerMetrics metrics = NodeManagerMetrics.create(); private ApplicationACLsManager aclsManager; private NodeHealthCheckerService nodeHealthChecker; + private NodeTrustCheckerService nodeTrustChecker; private LocalDirsHandlerService dirsHandler; private Context context; private AsyncDispatcher dispatcher; @@ -91,6 +93,11 @@ public NodeManager() { } 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) { return new NodeStatusUpdaterImpl(context, dispatcher, healthChecker, metrics); @@ -206,12 +213,17 @@ protected void serviceInit(Configuration conf) throws Exception { addService(nodeHealthChecker); dirsHandler = nodeHealthChecker.getDiskHandler(); + nodeTrustChecker = new NodeTrustCheckerService(); + addService(nodeTrustChecker); + + // nodeStatusUpdater = + // createNodeStatusUpdater(context, dispatcher, nodeHealthChecker); + this.context = createNMContext(containerTokenSecretManager, nmTokenSecretManager, nmStore); nodeStatusUpdater = - createNodeStatusUpdater(context, dispatcher, nodeHealthChecker); - + createNodeStatusUpdater(context, dispatcher, nodeHealthChecker,nodeTrustChecker); NodeResourceMonitor nodeResourceMonitor = createNodeResourceMonitor(); addService(nodeResourceMonitor); @@ -313,6 +325,8 @@ public void run() { private WebServer webServer; private final NodeHealthStatus nodeHealthStatus = RecordFactoryProvider .getRecordFactory(null).newRecordInstance(NodeHealthStatus.class); + private final NodeTrustStatus nodeTrustStatus = RecordFactoryProvider + .getRecordFactory(null).newRecordInstance(NodeTrustStatus.class); private final NMStateStoreService stateStore; private boolean isDecommissioned = false; @@ -327,6 +341,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()); this.stateStore = stateStore; } @@ -369,6 +386,11 @@ public NodeHealthStatus getNodeHealthStatus() { } @Override + public NodeTrustStatus getNodeTrustStatus() { + return this.nodeTrustStatus; + } + + @Override public ContainerManagementProtocol getContainerManager() { return this.containerManager; } @@ -419,6 +441,10 @@ public NodeHealthCheckerService getNodeHealthChecker() { return nodeHealthChecker; } + 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 0b8f5b4..0c0854b 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 @@ -60,6 +60,7 @@ import org.apache.hadoop.yarn.server.api.protocolrecords.RegisterNodeManagerResponse; 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.NodeTrustStatus; import org.apache.hadoop.yarn.server.api.records.NodeHealthStatus; import org.apache.hadoop.yarn.server.api.records.NodeStatus; import org.apache.hadoop.yarn.server.nodemanager.containermanager.ContainerManagerImpl; @@ -110,6 +111,7 @@ // processed. private final Set previousCompletedContainers; private final NodeHealthCheckerService healthChecker; + private final NodeTrustCheckerService trustChecker; private final NodeManagerMetrics metrics; private Runnable statusUpdaterRunnable; @@ -117,9 +119,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; @@ -128,6 +131,19 @@ public NodeStatusUpdaterImpl(Context context, Dispatcher dispatcher, this.previousCompletedContainers = new HashSet(); } + 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(); + this.previousCompletedContainers = new HashSet(); + } + @Override protected void serviceInit(Configuration conf) throws Exception { int memoryMb = @@ -335,17 +351,26 @@ private NodeStatus getNodeStatus(int responseId) { NodeHealthStatus nodeHealthStatus = this.context.getNodeHealthStatus(); nodeHealthStatus.setHealthReport(healthChecker.getHealthReport()); - nodeHealthStatus.setIsNodeHealthy(healthChecker.isHealthy()); + nodeHealthStatus.setIsNodeHealthy(healthChecker.isHealthy(nodeId.getHost())); nodeHealthStatus.setLastHealthReportTime(healthChecker .getLastHealthReportTime()); + NodeTrustStatus nodeTrustStatus = this.context.getNodeTrustStatus(); + nodeTrustStatus.setTrustReport(trustChecker.getTrusthReport()); + nodeTrustStatus.setIsNodeTrust(trustChecker.isTrust(nodeId.getHost())); + nodeTrustStatus.setLastTrustReportTime( + trustChecker.getLastTrustReportTime()); if (LOG.isDebugEnabled()) { LOG.debug("Node's health-status : " + nodeHealthStatus.getIsNodeHealthy() + ", " + nodeHealthStatus.getHealthReport()); } + if(LOG.isDebugEnabled()){ + LOG.debug("Node's trust-status : " + nodeTrustStatus.getIsNodeTrust() + + ", " + nodeTrustStatus.getTrustReport()); + } List containersStatuses = getContainerStatuses(); NodeStatus nodeStatus = NodeStatus.newInstance(nodeId, responseId, containersStatuses, - createKeepAliveApplicationList(), nodeHealthStatus); + createKeepAliveApplicationList(), nodeHealthStatus, nodeTrustStatus); return nodeStatus; } 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 9743760..15a3b50 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 @@ -828,8 +828,9 @@ private NodeReport createNodeReports(RMNode rmNode) { rmNode.getHttpAddress(), rmNode.getRackName(), used, rmNode.getTotalCapability(), numContainers, rmNode.getHealthReport(), - rmNode.getLastHealthReportTime()); - + rmNode.getLastHealthReportTime(), + 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 942ec81..5855576 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,7 @@ @Metric("# of decommissioned NMs") MutableGaugeInt numDecommissionedNMs; @Metric("# of lost NMs") MutableGaugeInt numLostNMs; @Metric("# of unhealthy NMs") MutableGaugeInt numUnhealthyNMs; + @Metric("# of untrust NMs") MutableGaugeInt numUntrustNMs; @Metric("# of Rebooted NMs") MutableGaugeInt numRebootedNMs; private static final MetricsInfo RECORD_INFO = info("ClusterMetrics", @@ -125,7 +126,20 @@ public void incrNumUnhealthyNMs() { public void decrNumUnhealthyNMs() { numUnhealthyNMs.decr(); } + + //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 d93c45d..274df85 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 @@ -58,7 +58,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 f2a8376..b3d8ed0 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 @@ -412,6 +412,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 24793e8..4fb7aab 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 @@ -82,12 +82,16 @@ * @return the latest health report received from this node. */ public String getHealthReport(); - + /** * the time of the latest health report received from this node. * @return the time of the latest health report received from this node. */ public long getLastHealthReportTime(); + + public String getTrustReport(); + + public long getLastTrustReportTime(); /** * the node manager version of the node received as part of the 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 acee7d7..11c5d92 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 @@ -51,6 +51,7 @@ import org.apache.hadoop.yarn.server.api.protocolrecords.NMContainerStatus; 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; @@ -102,6 +103,8 @@ private String healthReport; private long lastHealthReportTime; + private String trustReport; + private long lastTrustReportTime; private String nodeManagerVersion; /* set of containers that have just launched */ @@ -133,8 +136,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)) @@ -153,7 +156,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, @@ -170,6 +173,27 @@ RMNodeEventType.CLEANUP_APP, new CleanUpAppTransition()) .addTransition(NodeState.UNHEALTHY, NodeState.UNHEALTHY, RMNodeEventType.CLEANUP_CONTAINER, new CleanUpContainerTransition()) + + + //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(); @@ -192,6 +216,8 @@ public RMNodeImpl(NodeId nodeId, RMContext context, String hostName, this.lastHealthReportTime = System.currentTimeMillis(); this.nodeManagerVersion = nodeManagerVersion; + this.trustReport = "Trust"; + this.lastTrustReportTime = System.currentTimeMillis(); this.latestNodeHeartBeatResponse.setResponseId(0); ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); @@ -310,6 +336,45 @@ public String getNodeManagerVersion() { return nodeManagerVersion; } + + @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(); @@ -412,6 +477,10 @@ private void updateMetricsForRejoinedNode(NodeState previousNodeState) { case UNHEALTHY: metrics.decrNumUnhealthyNMs(); break; + + case UNTRUST: + metrics.decrNumUntrustNMs(); + break; } } @@ -426,6 +495,9 @@ private void updateMetricsForDeactivatedNode(NodeState initialState, case UNHEALTHY: metrics.decrNumUnhealthyNMs(); break; + case UNTRUST: + metrics.decrNumUntrustNMs(); + break; } // Decomissioned NMs equals to the nodes missing in include list (if @@ -454,6 +526,9 @@ private void updateMetricsForDeactivatedNode(NodeState initialState, case UNHEALTHY: metrics.incrNumUnhealthyNMs(); break; + case UNTRUST: + metrics.incrNumUntrustNMs(); + break; } } @@ -526,8 +601,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 + + 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)); } @@ -540,6 +617,10 @@ public void transition(RMNodeImpl rmNode, RMNodeEvent event) { case UNHEALTHY: ClusterMetrics.getMetrics().decrNumUnhealthyNMs(); break; + + case UNTRUST: + ClusterMetrics.getMetrics().decrNumUntrustNMs(); + break; } rmNode.context.getRMNodes().put(newNode.getNodeID(), newNode); rmNode.context.getDispatcher().getEventHandler().handle( @@ -587,7 +668,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)) { + + if (!initialState.equals(NodeState.UNHEALTHY) && !initialState.equals(NodeState.UNTRUST)) { rmNode.context.getDispatcher().getEventHandler() .handle(new NodeRemovedSchedulerEvent(rmNode)); } @@ -606,7 +688,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) { @@ -621,9 +703,15 @@ public NodeState transition(RMNodeImpl rmNode, RMNodeEvent event) { rmNode.setHealthReport(remoteNodeHealthStatus.getHealthReport()); rmNode.setLastHealthReportTime( remoteNodeHealthStatus.getLastHealthReportTime()); - if (!remoteNodeHealthStatus.getIsNodeHealthy()) { + + 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( @@ -637,6 +725,21 @@ public NodeState transition(RMNodeImpl rmNode, RMNodeEvent event) { return NodeState.UNHEALTHY; } + 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 = @@ -710,7 +813,20 @@ public NodeState transition(RMNodeImpl rmNode, RMNodeEvent event) { rmNode.setHealthReport(remoteNodeHealthStatus.getHealthReport()); rmNode.setLastHealthReportTime( remoteNodeHealthStatus.getLastHealthReportTime()); - if (remoteNodeHealthStatus.getIsNodeHealthy()) { + + NodeTrustStatus remoteNodeTrustStatus = statusEvent.getNodeTrustStatus(); + rmNode.setTrustReport(remoteNodeTrustStatus.getTrustReport()); + rmNode.setLastTrustReportTime( + remoteNodeTrustStatus.getLastTrustReportTime()); + + 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( @@ -723,11 +839,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()); + + NodeTrustStatus remoteNodeTrustStatus = statusEvent.getNodeTrustStatus(); + rmNode.setTrustReport(remoteNodeTrustStatus.getTrustReport()); + rmNode.setLastTrustReportTime( + remoteNodeTrustStatus.getLastTrustReportTime()); + + 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..d02fe6b 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,19 +25,34 @@ 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; @@ -47,6 +62,10 @@ public NodeHealthStatus getNodeHealthStatus() { return this.nodeHealthStatus; } + public NodeTrustStatus getNodeTrustStatus(){ + return this.nodeTrustStatus; + } + public List getContainers() { return this.containersCollection; } @@ -58,4 +77,4 @@ public NodeHeartbeatResponse getLatestResponse() { 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/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 7e41e53..e1f5665 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 @@ -78,6 +78,7 @@ 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")._(). + th().$class("ui-state-default")._("Untrust Nodes")._(). th().$class("ui-state-default")._("Unhealthy Nodes")._(). th().$class("ui-state-default")._("Rebooted Nodes")._(). _(). @@ -103,6 +104,7 @@ 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()))._(). + 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 f10e255..0e94d92 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 @@ -105,7 +105,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 db553ae..1df242a 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 @@ -54,6 +54,7 @@ protected long totalVirtualCores; protected int totalNodes; protected int lostNodes; + protected int untrustNodes; protected int unhealthyNodes; protected int decommissionedNodes; protected int rebootedNodes; @@ -90,6 +91,7 @@ public ClusterMetricsInfo(final ResourceManager rm, final RMContext rmContext) { this.totalVirtualCores = availableVirtualCores + allocatedVirtualCores; this.activeNodes = clusterMetrics.getNumActiveNMs(); this.lostNodes = clusterMetrics.getNumLostNMs(); + this.untrustNodes = clusterMetrics.getUntrustNMs(); this.unhealthyNodes = clusterMetrics.getUnhealthyNMs(); this.decommissionedNodes = clusterMetrics.getNumDecommisionedNMs(); this.rebootedNodes = clusterMetrics.getNumRebootedNMs(); @@ -181,6 +183,10 @@ public int getRebootedNodes() { return this.rebootedNodes; } + 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 8ef01d9..6d3dcc3 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 @@ -205,6 +205,16 @@ public long getLastHealthReportTime() { } @Override + public String getTrustReport() { + return "report"; + } + + @Override + public long getLastTrustReportTime() { + return 0; + } + + @Override public void setResourceOption(ResourceOption resourceOption) { this.perNode = resourceOption; }