Repository: ambari Updated Branches: refs/heads/trunk 2cac6678d -> 4caf4b56c
AMBARI-14384 Ambari Metrics doesn't use SPNEGO to authenticate (dsen) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/4caf4b56 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/4caf4b56 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/4caf4b56 Branch: refs/heads/trunk Commit: 4caf4b56c941624fc08d1f4cab7c5abfb68668c9 Parents: 2cac667 Author: Dmytro Sen <[email protected]> Authored: Mon Oct 24 17:20:34 2016 +0300 Committer: Dmytro Sen <[email protected]> Committed: Mon Oct 24 17:20:50 2016 +0300 ---------------------------------------------------------------------- ambari-metrics/ambari-metrics-common/pom.xml | 10 +++++ .../timeline/AbstractTimelineMetricsSink.java | 43 +++++++++++++++++--- .../availability/MetricCollectorHATest.java | 5 +++ 3 files changed, 53 insertions(+), 5 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/4caf4b56/ambari-metrics/ambari-metrics-common/pom.xml ---------------------------------------------------------------------- diff --git a/ambari-metrics/ambari-metrics-common/pom.xml b/ambari-metrics/ambari-metrics-common/pom.xml index 0e66a6d..b1b8667 100644 --- a/ambari-metrics/ambari-metrics-common/pom.xml +++ b/ambari-metrics/ambari-metrics-common/pom.xml @@ -149,6 +149,16 @@ <version>2.6.0</version> </dependency> <dependency> + <groupId>org.apache.hadoop</groupId> + <artifactId>hadoop-auth</artifactId> + <version>2.7.3</version> + </dependency> + <dependency> + <groupId>org.apache.hadoop</groupId> + <artifactId>hadoop-common</artifactId> + <version>2.7.3</version> + </dependency> + <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-mapper-asl</artifactId> <version>1.9.13</version> http://git-wip-us.apache.org/repos/asf/ambari/blob/4caf4b56/ambari-metrics/ambari-metrics-common/src/main/java/org/apache/hadoop/metrics2/sink/timeline/AbstractTimelineMetricsSink.java ---------------------------------------------------------------------- diff --git a/ambari-metrics/ambari-metrics-common/src/main/java/org/apache/hadoop/metrics2/sink/timeline/AbstractTimelineMetricsSink.java b/ambari-metrics/ambari-metrics-common/src/main/java/org/apache/hadoop/metrics2/sink/timeline/AbstractTimelineMetricsSink.java index efa5cba..5d0790b 100644 --- a/ambari-metrics/ambari-metrics-common/src/main/java/org/apache/hadoop/metrics2/sink/timeline/AbstractTimelineMetricsSink.java +++ b/ambari-metrics/ambari-metrics-common/src/main/java/org/apache/hadoop/metrics2/sink/timeline/AbstractTimelineMetricsSink.java @@ -25,6 +25,8 @@ import com.google.gson.JsonSyntaxException; import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.security.UserGroupInformation; +import org.apache.hadoop.security.authentication.client.AuthenticationException; import org.apache.hadoop.metrics2.sink.timeline.availability.MetricCollectorHAHelper; import org.apache.hadoop.metrics2.sink.timeline.availability.MetricCollectorUnavailableException; import org.apache.hadoop.metrics2.sink.timeline.availability.MetricSinkWriteShardHostnameHashingStrategy; @@ -34,6 +36,7 @@ import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.map.annotate.JsonSerialize; import org.codehaus.jackson.xc.JaxbAnnotationIntrospector; +import org.apache.hadoop.security.authentication.client.AuthenticatedURL; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; @@ -195,9 +198,11 @@ public abstract class AbstractTimelineMetricsSink { if (LOG.isDebugEnabled()) { LOG.debug(String.format("Ignoring %s AMS connection exceptions", NUMBER_OF_SKIPPED_COLLECTOR_EXCEPTIONS)); } - return false; } + } catch (AuthenticationException e) { + LOG.error("AuthenticationException while posting metrics to metrics collector", e); } + return false; } protected boolean emitMetrics(TimelineMetrics metrics) { @@ -258,16 +263,42 @@ public abstract class AbstractTimelineMetricsSink { return sb.toString(); } + /** + * Uses UGI to find and renew (if needed) kerberos ticket and opens authenticated connection + * + * @param spec - requested URL + * @return HttpURLConnection - opened authenticated connection + * @throws IOException + * @throws AuthenticationException + */ + public HttpURLConnection getAuthenticatedConnection(String spec, UserGroupInformation userGroupInformation) throws IOException, AuthenticationException { + //renew ticked if needed + if (userGroupInformation != null) { + userGroupInformation.checkTGTAndReloginFromKeytab(); + } + //open authenticated connection + AuthenticatedURL.Token token = new AuthenticatedURL.Token(); + URL url = new URL(spec); + return new AuthenticatedURL().openConnection(url, token); + } + // Get a connection - protected HttpURLConnection getConnection(String spec) throws IOException { - return (HttpURLConnection) new URL(spec).openConnection(); + protected HttpURLConnection getConnection(String spec) throws IOException, AuthenticationException { + UserGroupInformation userGroupInformation = UserGroupInformation.getLoginUser(); + + if (UserGroupInformation.isSecurityEnabled() && userGroupInformation != null && + userGroupInformation.getAuthenticationMethod() == UserGroupInformation.AuthenticationMethod.KERBEROS) { + return getAuthenticatedConnection(spec, userGroupInformation); + } else { + return (HttpURLConnection) new URL(spec).openConnection(); + } } // Get an ssl connection protected HttpsURLConnection getSSLConnection(String spec) - throws IOException, IllegalStateException { + throws IOException, IllegalStateException, AuthenticationException { - HttpsURLConnection connection = (HttpsURLConnection) (new URL(spec).openConnection()); + HttpsURLConnection connection = (HttpsURLConnection) getConnection(spec); connection.setSSLSocketFactory(sslSocketFactory); @@ -449,6 +480,8 @@ public abstract class AbstractTimelineMetricsSink { String warnMsg = "Unable to connect to collector to find live nodes."; LOG.warn(warnMsg); throw new MetricCollectorUnavailableException(warnMsg); + } catch (AuthenticationException e) { + LOG.error("AuthenticationException while posting metrics to metrics collector", e); } return collectors; } http://git-wip-us.apache.org/repos/asf/ambari/blob/4caf4b56/ambari-metrics/ambari-metrics-common/src/test/java/org/apache/hadoop/metrics2/sink/timeline/availability/MetricCollectorHATest.java ---------------------------------------------------------------------- diff --git a/ambari-metrics/ambari-metrics-common/src/test/java/org/apache/hadoop/metrics2/sink/timeline/availability/MetricCollectorHATest.java b/ambari-metrics/ambari-metrics-common/src/test/java/org/apache/hadoop/metrics2/sink/timeline/availability/MetricCollectorHATest.java index 3d00270..066cbaa 100644 --- a/ambari-metrics/ambari-metrics-common/src/test/java/org/apache/hadoop/metrics2/sink/timeline/availability/MetricCollectorHATest.java +++ b/ambari-metrics/ambari-metrics-common/src/test/java/org/apache/hadoop/metrics2/sink/timeline/availability/MetricCollectorHATest.java @@ -157,6 +157,11 @@ public class MetricCollectorHATest { } @Override + protected HttpURLConnection getConnection(String spec) throws IOException { + return (HttpURLConnection) new URL(spec).openConnection(); + } + + @Override protected String getCollectorProtocol() { return "http"; }
