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

Reply via email to