Repository: ambari Updated Branches: refs/heads/branch-alerts-dev 7f86e75c0 -> e6cc05872
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/branch-alerts-dev Commit: d46bbdfa95e52063899c62d5711b3fcab31c5d81 Parents: 327accb Author: Srimanth Gunturi <sgunt...@hortonworks.com> Authored: Sat Sep 20 17:58:19 2014 -0700 Committer: Srimanth Gunturi <sgunt...@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-princi...@example.com" +``` +Next, extract keytab file + +``` +kadmin.local -q "xst -k /path/to/keytab/view-principal.headless.keytab view-princi...@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/_h...@example.com` +* dfs.namenode.kerberos.principal = `nn/_h...@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/_h...@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/_h...@example.com</description> + <required>optional</required> + </parameter> + <parameter> + <name>view.kerberos.principal</name> + <description>Kerberos principal associated with this view. For example: ambari/_h...@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>