Browse Source

merge MAPREDUCE-3903 from trunk

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/branch-0.23@1295263 13f79535-47bb-0310-9956-ffa450edef68
Siddharth Seth 13 years ago
parent
commit
c471c3d15f

+ 3 - 0
hadoop-mapreduce-project/CHANGES.txt

@@ -146,6 +146,9 @@ Release 0.23.2 - UNRELEASED
     MAPREDUCE-3920. Revise yarn default port number selection 
     (Dave Thompson via tgraves)
 
+    MAPREDUCE-3903. Add support for mapreduce admin users. (Thomas Graves via
+    sseth)
+
 Release 0.23.1 - 2012-02-17
 
   NEW FEATURES

+ 23 - 1
hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapred/JobACLsManager.java

@@ -20,6 +20,8 @@ package org.apache.hadoop.mapred;
 import java.util.HashMap;
 import java.util.Map;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.classification.InterfaceAudience;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.mapreduce.JobACL;
@@ -31,9 +33,12 @@ import org.apache.hadoop.security.authorize.AccessControlList;
 @InterfaceAudience.Private
 public class JobACLsManager {
 
+  static final Log LOG = LogFactory.getLog(JobACLsManager.class);
   Configuration conf;
+  private final AccessControlList adminAcl;
 
   public JobACLsManager(Configuration conf) {
+    adminAcl = new AccessControlList(conf.get(MRConfig.MR_ADMINS, " "));
     this.conf = conf;
   }
 
@@ -71,6 +76,18 @@ public class JobACLsManager {
     return acls;
   }
 
+  /**
+    * Is the calling user an admin for the mapreduce cluster
+    * i.e. member of mapreduce.cluster.administrators
+    * @return true, if user is an admin
+    */
+   boolean isMRAdmin(UserGroupInformation callerUGI) {
+     if (adminAcl.isUserAllowed(callerUGI)) {
+       return true;
+     }
+     return false;
+   }
+
   /**
    * If authorization is enabled, checks whether the user (in the callerUGI)
    * is authorized to perform the operation specified by 'jobOperation' on
@@ -89,13 +106,18 @@ public class JobACLsManager {
   public boolean checkAccess(UserGroupInformation callerUGI,
       JobACL jobOperation, String jobOwner, AccessControlList jobACL) {
 
+    if (LOG.isDebugEnabled()) {
+      LOG.debug("checkAccess job acls, jobOwner: " + jobOwner + " jobacl: "
+          + jobOperation.toString() + " user: " + callerUGI.getShortUserName());
+    }
     String user = callerUGI.getShortUserName();
     if (!areACLsEnabled()) {
       return true;
     }
 
     // Allow Job-owner for any operation on the job
-    if (user.equals(jobOwner)
+    if (isMRAdmin(callerUGI)
+        || user.equals(jobOwner)
         || jobACL.isUserAllowed(callerUGI)) {
       return true;
     }

+ 142 - 0
hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/test/java/org/apache/hadoop/mapred/TestJobAclsManager.java

@@ -0,0 +1,142 @@
+/**
+ * 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.mapred;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.mapreduce.JobACL;
+import org.apache.hadoop.mapreduce.MRConfig;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.hadoop.security.authorize.AccessControlList;
+import org.junit.Test;
+
+/**
+ * Test the job acls manager
+ */
+public class TestJobAclsManager {
+
+  @Test
+  public void testClusterAdmins() {
+    Map<JobACL, AccessControlList> tmpJobACLs = new HashMap<JobACL, AccessControlList>();
+    Configuration conf = new Configuration();
+    String jobOwner = "testuser";
+    conf.set(JobACL.VIEW_JOB.getAclName(), jobOwner);
+    conf.set(JobACL.MODIFY_JOB.getAclName(), jobOwner);
+    conf.setBoolean(MRConfig.MR_ACLS_ENABLED, true);
+    String clusterAdmin = "testuser2";
+    conf.set(MRConfig.MR_ADMINS, clusterAdmin);
+
+    JobACLsManager aclsManager = new JobACLsManager(conf);
+    tmpJobACLs = aclsManager.constructJobACLs(conf);
+    final Map<JobACL, AccessControlList> jobACLs = tmpJobACLs;
+
+    UserGroupInformation callerUGI = UserGroupInformation.createUserForTesting(
+        clusterAdmin, new String[] {});
+
+    // cluster admin should have access
+    boolean val = aclsManager.checkAccess(callerUGI, JobACL.VIEW_JOB, jobOwner,
+        jobACLs.get(JobACL.VIEW_JOB));
+    assertTrue("cluster admin should have view access", val);
+    val = aclsManager.checkAccess(callerUGI, JobACL.MODIFY_JOB, jobOwner,
+        jobACLs.get(JobACL.MODIFY_JOB));
+    assertTrue("cluster admin should have modify access", val);
+  }
+
+  @Test
+  public void testClusterNoAdmins() {
+    Map<JobACL, AccessControlList> tmpJobACLs = new HashMap<JobACL, AccessControlList>();
+    Configuration conf = new Configuration();
+    String jobOwner = "testuser";
+    conf.set(JobACL.VIEW_JOB.getAclName(), "");
+    conf.setBoolean(MRConfig.MR_ACLS_ENABLED, true);
+    String noAdminUser = "testuser2";
+
+    JobACLsManager aclsManager = new JobACLsManager(conf);
+    tmpJobACLs = aclsManager.constructJobACLs(conf);
+    final Map<JobACL, AccessControlList> jobACLs = tmpJobACLs;
+
+    UserGroupInformation callerUGI = UserGroupInformation.createUserForTesting(
+        noAdminUser, new String[] {});
+    // random user should not have access
+    boolean val = aclsManager.checkAccess(callerUGI, JobACL.VIEW_JOB, jobOwner,
+        jobACLs.get(JobACL.VIEW_JOB));
+    assertFalse("random user should not have view access", val);
+    val = aclsManager.checkAccess(callerUGI, JobACL.MODIFY_JOB, jobOwner,
+        jobACLs.get(JobACL.MODIFY_JOB));
+    assertFalse("random user should not have modify access", val);
+
+    callerUGI = UserGroupInformation.createUserForTesting(jobOwner,
+        new String[] {});
+    // Owner should have access
+    val = aclsManager.checkAccess(callerUGI, JobACL.VIEW_JOB, jobOwner,
+        jobACLs.get(JobACL.VIEW_JOB));
+    assertTrue("owner should have view access", val);
+    val = aclsManager.checkAccess(callerUGI, JobACL.MODIFY_JOB, jobOwner,
+        jobACLs.get(JobACL.MODIFY_JOB));
+    assertTrue("owner should have modify access", val);
+  }
+
+  @Test
+  public void testAclsOff() {
+    Map<JobACL, AccessControlList> tmpJobACLs = new HashMap<JobACL, AccessControlList>();
+    Configuration conf = new Configuration();
+    String jobOwner = "testuser";
+    conf.set(JobACL.VIEW_JOB.getAclName(), jobOwner);
+    conf.setBoolean(MRConfig.MR_ACLS_ENABLED, false);
+    String noAdminUser = "testuser2";
+
+    JobACLsManager aclsManager = new JobACLsManager(conf);
+    tmpJobACLs = aclsManager.constructJobACLs(conf);
+    final Map<JobACL, AccessControlList> jobACLs = tmpJobACLs;
+
+    UserGroupInformation callerUGI = UserGroupInformation.createUserForTesting(
+        noAdminUser, new String[] {});
+    // acls off so anyone should have access
+    boolean val = aclsManager.checkAccess(callerUGI, JobACL.VIEW_JOB, jobOwner,
+        jobACLs.get(JobACL.VIEW_JOB));
+    assertTrue("acls off so anyone should have access", val);
+  }
+
+  @Test
+  public void testGroups() {
+    Map<JobACL, AccessControlList> tmpJobACLs = new HashMap<JobACL, AccessControlList>();
+    Configuration conf = new Configuration();
+    String jobOwner = "testuser";
+    conf.set(JobACL.VIEW_JOB.getAclName(), jobOwner);
+    conf.setBoolean(MRConfig.MR_ACLS_ENABLED, true);
+    String user = "testuser2";
+    String adminGroup = "adminGroup";
+    conf.set(MRConfig.MR_ADMINS, " " + adminGroup);
+
+    JobACLsManager aclsManager = new JobACLsManager(conf);
+    tmpJobACLs = aclsManager.constructJobACLs(conf);
+    final Map<JobACL, AccessControlList> jobACLs = tmpJobACLs;
+
+    UserGroupInformation callerUGI = UserGroupInformation.createUserForTesting(
+     user, new String[] {adminGroup});
+    // acls off so anyone should have access
+    boolean val = aclsManager.checkAccess(callerUGI, JobACL.VIEW_JOB, jobOwner,
+        jobACLs.get(JobACL.VIEW_JOB));
+    assertTrue("user in admin group should have access", val);
+  }
+}

+ 1 - 4
hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-hs/src/main/java/org/apache/hadoop/mapreduce/v2/hs/HistoryClientService.java

@@ -192,7 +192,6 @@ public class HistoryClientService extends AbstractService {
         throw RPCUtil.getRemoteException("Unknown job " + jobID);
       }
       JobACL operation = JobACL.VIEW_JOB;
-      //TODO disable check access for now.
       checkAccess(job, operation);
       return job;
     }
@@ -324,9 +323,7 @@ public class HistoryClientService extends AbstractService {
 
     private void checkAccess(Job job, JobACL jobOperation)
         throws YarnRemoteException {
-      if (!UserGroupInformation.isSecurityEnabled()) {
-        return;
-      }
+
       UserGroupInformation callerUGI;
       try {
         callerUGI = UserGroupInformation.getCurrentUser();

+ 1 - 1
hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java

@@ -140,7 +140,7 @@ public class YarnConfiguration extends Configuration {
   /** Are acls enabled.*/
   public static final String YARN_ACL_ENABLE = 
     YARN_PREFIX + "acl.enable";
-  public static final boolean DEFAULT_YARN_ACL_ENABLE = true;
+  public static final boolean DEFAULT_YARN_ACL_ENABLE = false;
   
   /** ACL of who can be admin of YARN cluster.*/
   public static final String YARN_ADMIN_ACL = 

+ 1 - 1
hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-site/src/site/apt/ClusterSetup.apt.vm

@@ -185,7 +185,7 @@ Hadoop MapReduce Next Generation - Cluster Setup
 *-------------------------+-------------------------+------------------------+
 | <<<yarn.acl.enable>>> | | |
 | | <<<true>>> / <<<false>>> | |
-| | | Enable ACLs? Defaults to <true>. |
+| | | Enable ACLs? Defaults to <false>. |
 *-------------------------+-------------------------+------------------------+
 | <<<yarn.admin.acl>>> | | |
 | | Admin ACL | |