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;
}