You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by sr...@apache.org on 2014/09/21 03:14:54 UTC

git commit: AMBARI-7421. Slider View should support secured cluster (srimanth)

Repository: ambari
Updated Branches:
  refs/heads/trunk 327accb13 -> d46bbdfa9


AMBARI-7421. Slider View should support secured cluster (srimanth)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/d46bbdfa
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/d46bbdfa
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/d46bbdfa

Branch: refs/heads/trunk
Commit: d46bbdfa95e52063899c62d5711b3fcab31c5d81
Parents: 327accb
Author: Srimanth Gunturi <sg...@hortonworks.com>
Authored: Sat Sep 20 17:58:19 2014 -0700
Committer: Srimanth Gunturi <sg...@hortonworks.com>
Committed: Sat Sep 20 18:10:36 2014 -0700

----------------------------------------------------------------------
 contrib/views/slider/docs/index.md              | 63 ++++++++++++++++++
 .../view/slider/SliderAppsViewController.java   |  8 +++
 .../slider/SliderAppsViewControllerImpl.java    | 69 ++++++++++----------
 .../views/slider/src/main/resources/view.xml    | 25 +++++++
 4 files changed, 132 insertions(+), 33 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/d46bbdfa/contrib/views/slider/docs/index.md
----------------------------------------------------------------------
diff --git a/contrib/views/slider/docs/index.md b/contrib/views/slider/docs/index.md
new file mode 100644
index 0000000..534f317
--- /dev/null
+++ b/contrib/views/slider/docs/index.md
@@ -0,0 +1,63 @@
+# Slider Apps View
+
+## Security Guide
+*Slider Apps View* can optionally connect to a Kerberos secured cluster by following the below steps.
+
+#### Step-1: Deploy a HDP cluster and secure it using *Kerberos*
+After deploying a HDP cluster through Ambari, it can be secured by using the *Enable Security* button in *Admin > Seurity* page.
+
+#### Step-2: Create *Kerberos* principal for view
+We need to provide a *Kerberos* identity for the process in which the view is run. We shall identify the user as `view-principal`. Since views are generally hosted by Ambari server, typically this can be named as *ambari*.
+
+On the machine where *KDC Server* is hosted, create user principal by running below command
+
+```
+kadmin.local -q "addprinc -randkey view-principal@EXAMPLE.COM"
+```
+Next, extract keytab file 
+
+```
+kadmin.local -q "xst -k /path/to/keytab/view-principal.headless.keytab view-principal@EXAMPLE.COM"
+```
+The keytab file should then be copied over to the keytabs location on the host where the view is hosted.
+
+```
+cp /path/to/keytab/view-principal.headless.keytab /etc/security/keytabs/
+```
+
+Change file permissions so that only necessary users can access it.
+
+```
+chmod 440 /etc/security/keytabs/view-principal.headless.keytab
+```
+
+#### Step-3: Configure *proxyuser* for created principal
+Add the following configurations in *Custom core-site* section of *HDFS* service.
+
+* hadoop.proxyuser.ambari.groups = *
+* hadoop.proxyuser.ambari.hosts = `view-server-host`
+
+This will in-turn show up in *core-site.xml* as
+
+```
+<property>
+  <name>hadoop.proxyuser.view-principal.groups</name>
+  <value>*</value>
+</property>
+
+<property>
+  <name>hadoop.proxyuser.view-principal.hosts</name>
+  <value>view-server-host.ambari.apache.org</value>
+</property>
+```
+Restart HDFS and YARN services.
+
+#### Step-4: Create *Slider Apps View* with security parameters
+
+From *Ambari-Admin* create a *Slider Apps View* with the below parameters populated
+
+* slider.security.enabled = true
+* yarn.resourcemanager.principal = `rm/_HOST@EXAMPLE.COM`
+* dfs.namenode.kerberos.principal = `nn/_HOST@EXAMPLE.COM`
+* view.kerberos.principal = `view-principal`
+* view.kerberos.principal.keytab = `/etc/security/keytabs/view-principal.headless.keytab`
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/d46bbdfa/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsViewController.java
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsViewController.java b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsViewController.java
index 64ab78c..0cf5d15 100644
--- a/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsViewController.java
+++ b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsViewController.java
@@ -35,6 +35,14 @@ public interface SliderAppsViewController {
   public static final String PROPERTY_YARN_RM_ADDRESS = "yarn.resourcemanager.address";
   public static final String PROPERTY_YARN_RM_SCHEDULER_ADDRESS = "yarn.resourcemanager.scheduler.address";
   public static final String PROPERTY_ZK_QUOROM = "zookeeper.quorum";
+  public static final String PROPERTY_GANGLIA_SERVER_HOSTNAME = "ganglia.server.hostname";
+  public static final String PROPERTY_GANGLIA_CUSTOM_CLUSTERS = "ganglia.custom.clusters";
+  public static final String PROPERTY_SLIDER_USER = "slider.user";
+  public static final String PROPERTY_SLIDER_SECURITY_ENABLED = "slider.security.enabled";
+  public static final String PROPERTY_YARN_RM_PRINCIPAL = "yarn.resourcemanager.principal";
+  public static final String PROPERTY_HDFS_NN_PRINCIPAL = "dfs.namenode.kerberos.principal";
+  public static final String PROPERTY_VIEW_PRINCIPAL = "view.kerberos.principal";
+  public static final String PROPERTY_VIEW_PRINCIPAL_KEYTAB= "view.kerberos.principal.keytab";
 
   public ViewStatus getViewStatus();
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/d46bbdfa/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsViewControllerImpl.java
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsViewControllerImpl.java b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsViewControllerImpl.java
index 6580d90..93c95a0 100644
--- a/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsViewControllerImpl.java
+++ b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsViewControllerImpl.java
@@ -126,16 +126,37 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController {
     }
     return null;
   }
-  
+
   private static interface SliderClientContextRunnable<T> {
     public T run(SliderClient sliderClient) throws YarnException, IOException, InterruptedException;
   }
-  
+
+  private String getUserToRunAs() {
+    String user = viewContext.getProperties().get(PROPERTY_SLIDER_USER);
+    if (user == null || user.trim().length() < 1) {
+      return "yarn";
+    } else if ("${username}".equals(user)) {
+      return viewContext.getUsername();
+    } else {
+      return user;
+    }
+  }
+
   private <T> T invokeSliderClientRunnable(final SliderClientContextRunnable<T> runnable) throws IOException, InterruptedException {
     ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader();
     Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
     try {
-      T value = UserGroupInformation.getBestUGI(null, viewContext.getUsername()).doAs(
+      boolean securityEnabled = Boolean.valueOf(viewContext.getProperties().get(PROPERTY_SLIDER_SECURITY_ENABLED));
+      UserGroupInformation sliderUser;
+      if (securityEnabled) {
+        String viewPrincipal = viewContext.getProperties().get(PROPERTY_VIEW_PRINCIPAL);
+        String viewPrincipalKeytab = viewContext.getProperties().get(PROPERTY_VIEW_PRINCIPAL_KEYTAB);
+        UserGroupInformation ambariUser = UserGroupInformation.loginUserFromKeytabAndReturnUGI(viewPrincipal, viewPrincipalKeytab);
+        sliderUser = UserGroupInformation.createProxyUser(getUserToRunAs(), ambariUser);
+      } else {
+        sliderUser = UserGroupInformation.getBestUGI(null, getUserToRunAs());
+      }
+      T value = sliderUser.doAs(
           new PrivilegedExceptionAction<T>() {
             @Override
             public T run() throws Exception {
@@ -396,36 +417,6 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController {
     Configuration sliderClientConfiguration = getSliderClientConfiguration();
     SliderClient client = new SliderClient() {
       @Override
-      public String getUsername() throws IOException {
-        return viewContext.getUsername();
-      }
-
-      @Override
-      protected void initHadoopBinding() throws IOException, SliderException {
-        super.initHadoopBinding();
-        // Override the default FS client to the calling user
-        try {
-          FileSystem fs = FileSystem.get(FileSystem.getDefaultUri(getConfig()),
-              getConfig(), viewContext.getUsername());
-          SliderFileSystem fileSystem = new SliderFileSystem(fs, getConfig());
-          Field fsField = SliderClient.class
-              .getDeclaredField("sliderFileSystem");
-          fsField.setAccessible(true);
-          fsField.set(this, fileSystem);
-        } catch (InterruptedException e) {
-          throw new SliderException("Slider view unable to override filesystem of Slider client", e);
-        } catch (NoSuchFieldException e) {
-          throw new SliderException("Slider view unable to override filesystem of Slider client", e);
-        } catch (SecurityException e) {
-          throw new SliderException("Slider view unable to override filesystem of Slider client", e);
-        } catch (IllegalArgumentException e) {
-          throw new SliderException("Slider view unable to override filesystem of Slider client", e);
-        } catch (IllegalAccessException e) {
-          throw new SliderException("Slider view unable to override filesystem of Slider client", e);
-        }
-      }
-
-      @Override
       public void init(Configuration conf) {
         super.init(conf);
         try {
@@ -468,6 +459,8 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController {
     String rmAddress = viewContext.getProperties().get(PROPERTY_YARN_RM_ADDRESS);
     String rmSchedulerAddress = viewContext.getProperties().get(PROPERTY_YARN_RM_SCHEDULER_ADDRESS);
     String zkQuorum = viewContext.getProperties().get(PROPERTY_ZK_QUOROM);
+    boolean securedCluster = Boolean.getBoolean(viewContext.getProperties().get(PROPERTY_SLIDER_SECURITY_ENABLED));
+
     HdfsConfiguration hdfsConfig = new HdfsConfiguration();
     YarnConfiguration yarnConfig = new YarnConfiguration(hdfsConfig);
 
@@ -479,6 +472,16 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController {
     yarnConfig.set("slider.zookeeper.quorum", zkQuorum.toString());
     yarnConfig.set("yarn.application.classpath",
             "/etc/hadoop/conf,/usr/lib/hadoop/*,/usr/lib/hadoop/lib/*,/usr/lib/hadoop-hdfs/*,/usr/lib/hadoop-hdfs/lib/*,/usr/lib/hadoop-yarn/*,/usr/lib/hadoop-yarn/lib/*,/usr/lib/hadoop-mapreduce/*,/usr/lib/hadoop-mapreduce/lib/*");
+
+    if (securedCluster) {
+      String rmPrincipal = viewContext.getProperties().get(PROPERTY_YARN_RM_PRINCIPAL);
+      String nnPrincipal = viewContext.getProperties().get(PROPERTY_HDFS_NN_PRINCIPAL);
+      yarnConfig.set("yarn.resourcemanager.principal", rmPrincipal);
+      yarnConfig.set("dfs.namenode.kerberos.principal", nnPrincipal);
+      yarnConfig.set("hadoop.security.authorization", "true");
+      yarnConfig.set("hadoop.security.authentication", "kerberos");
+      yarnConfig.set("slider.security.enabled", "true");
+    }
     return yarnConfig;
   }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/d46bbdfa/contrib/views/slider/src/main/resources/view.xml
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/resources/view.xml b/contrib/views/slider/src/main/resources/view.xml
index 25d81a1..7a05fa3 100644
--- a/contrib/views/slider/src/main/resources/view.xml
+++ b/contrib/views/slider/src/main/resources/view.xml
@@ -53,6 +53,31 @@ limitations under the License. Kerberos, LDAP, Custom. Binary/Htt
     <description>Slider user</description>
     <required>false</required>
   </parameter>
+  <parameter>
+    <name>slider.security.enabled</name>
+    <description>Indicates whether cluster has been secured or not.</description>
+    <required>true</required>
+  </parameter>
+  <parameter>
+    <name>yarn.resourcemanager.principal</name>
+    <description>Kerberos principal used to access YARN ResourceManager. For example: rm/_HOST@EXAMPLE.COM</description>
+    <required>optional</required>
+  </parameter>
+  <parameter>
+    <name>dfs.namenode.kerberos.principal</name>
+    <description>Kerberos principal used to access YARN ResourceManager. For example: nn/_HOST@EXAMPLE.COM</description>
+    <required>optional</required>
+  </parameter>
+  <parameter>
+    <name>view.kerberos.principal</name>
+    <description>Kerberos principal associated with this view. For example: ambari/_HOST@EXAMPLE.COM</description>
+    <required>optional</required>
+  </parameter>
+  <parameter>
+    <name>view.kerberos.principal.keytab</name>
+    <description>Path to the Kerberos principal keytab. For example: /etc/security/keytabs/ambari.headless.keytab</description>
+    <required>optional</required>
+  </parameter>
   <resource>
     <name>status</name>
     <service-class>org.apache.ambari.view.slider.rest.ViewStatusResource</service-class>