diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/TestRMFailover.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/TestRMFailover.java index 97d7fa8..7cfc86b 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/TestRMFailover.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/TestRMFailover.java @@ -29,6 +29,8 @@ import java.io.IOException; import java.net.HttpURLConnection; import java.net.URL; +import java.util.ArrayList; +import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -39,6 +41,9 @@ import org.apache.hadoop.ha.ClientBaseWithFixes; import org.apache.hadoop.ha.HAServiceProtocol; import org.apache.hadoop.ha.proto.HAServiceProtocolProtos; +import org.apache.hadoop.security.GroupMappingServiceProvider; +import org.apache.hadoop.security.Groups; +import org.apache.hadoop.security.UserGroupInformation; import org.apache.hadoop.service.Service.STATE; import org.apache.hadoop.yarn.api.records.ApplicationId; import org.apache.hadoop.yarn.client.api.YarnClient; @@ -48,6 +53,7 @@ import org.apache.hadoop.yarn.exceptions.YarnException; import org.apache.hadoop.yarn.server.MiniYARNCluster; import org.apache.hadoop.yarn.server.api.protocolrecords.RefreshQueuesRequest; +import org.apache.hadoop.yarn.server.api.protocolrecords.RefreshUserToGroupsMappingsRequest; import org.apache.hadoop.yarn.server.resourcemanager.AdminService; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacitySchedulerConfiguration; @@ -109,6 +115,11 @@ public void setup() throws IOException { conf.setBoolean(YarnConfiguration.YARN_MINICLUSTER_FIXED_PORTS, true); conf.setBoolean(YarnConfiguration.YARN_MINICLUSTER_USE_RPC, true); + conf.setClass("hadoop.security.group.mapping", + MockUnixGroupsMapping.class, + GroupMappingServiceProvider.class); + Groups.getUserToGroupsMappingService(conf); + fs = FileSystem.get(conf); workingPath = new Path(fs.getHomeDirectory(), "confStore"); conf.set(YarnConfiguration.RM_CONF_STORE, workingPath.toString()); @@ -299,6 +310,37 @@ public void testAdminServiceRefreshQueuesOnHA() throws IOException, Assert.assertTrue(maxAppsAfter != maxAppsBefore); } + @Test + public void testAdminServiceRefreshUserToGroupsMappingsOnHA() + throws IOException, YarnException { + cluster.init(conf); + cluster.start(); + getAdminService(0).transitionToActive(req); + assertFalse("RM never turned active", -1 == cluster.getActiveRMIndex()); + + // clean the remoteDirectory + cleanRemoteDirectory(); + + RefreshUserToGroupsMappingsRequest request = + RefreshUserToGroupsMappingsRequest.newInstance(); + + Groups groups = Groups.getUserToGroupsMappingService(conf); + String user = UserGroupInformation.getCurrentUser().getUserName(); + List groupBefore = groups.getGroups(user); + + String coreConfFile = writeConfigurationXML(conf, "core-site.xml"); + + // upload the file into Remote File System + uploadToRemoteFileSystem(new Path(coreConfFile)); + getAdminService(0).refreshUserToGroupsMappings(request); + List groupAfter = groups.getGroups(user); + + for (int i = 0; i < groupAfter.size(); i++) { + assertFalse("Should be different group: " + groupBefore.get(i) + " and " + + groupAfter.get(i), groupBefore.get(i).equals(groupAfter.get(i))); + } + } + private String writeConfigurationXML(Configuration conf, String confXMLName) throws IOException { DataOutputStream output = null; @@ -337,4 +379,31 @@ private void cleanRemoteDirectory() throws IOException { } } } + + public static class MockUnixGroupsMapping implements + GroupMappingServiceProvider { + + private int i = 0; + + @Override + public List getGroups(String user) throws IOException { + System.out.println("Getting groups in MockUnixGroupsMapping"); + String g1 = user + (10 * i + 1); + String g2 = user + (10 * i + 2); + List l = new ArrayList(2); + l.add(g1); + l.add(g2); + i++; + return l; + } + + @Override + public void cacheGroupsRefresh() throws IOException { + System.out.println("Refreshing groups in MockUnixGroupsMapping"); + } + + @Override + public void cacheGroupsAdd(List groups) throws IOException { + } + } } diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/AdminService.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/AdminService.java index 24a3b7d..1eab56b 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/AdminService.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/AdminService.java @@ -388,24 +388,33 @@ public RefreshSuperUserGroupsConfigurationResponse refreshSuperUserGroupsConfigu @Override public RefreshUserToGroupsMappingsResponse refreshUserToGroupsMappings( RefreshUserToGroupsMappingsRequest request) - throws YarnException, StandbyException { - UserGroupInformation user = checkAcls("refreshUserToGroupsMappings"); + throws YarnException, IOException { + String argName = "refreshUserToGroupsMappings"; + UserGroupInformation user = checkAcls(argName); - // TODO (YARN-1459): Revisit handling user-groups on Standby RM if (!isRMActive()) { - RMAuditLogger.logFailure(user.getShortUserName(), - "refreshUserToGroupsMapping", + RMAuditLogger.logFailure(user.getShortUserName(), argName, adminAcl.toString(), "AdminService", "ResourceManager is not active. Can not refresh user-groups."); throwStandbyException(); } - Groups.getUserToGroupsMappingService().refresh(); - RMAuditLogger.logSuccess(user.getShortUserName(), - "refreshUserToGroupsMappings", "AdminService"); + Configuration conf = getConfiguration(argName); + RefreshUserToGroupsMappingsResponse response = recordFactory + .newRecordInstance(RefreshUserToGroupsMappingsResponse.class); + if (this.rmContext.isHAEnabled()) { + if (conf == null) { + LOG.warn(printFailureDescription(getConfigurationFileName(argName), + "refreshUserToGroupsMappings")); + return response; + } + Groups.getUserToGroupsMappingService(conf).refresh(); + } else { + Groups.getUserToGroupsMappingService().refresh(); + } + RMAuditLogger.logSuccess(user.getShortUserName(), argName, "AdminService"); - return recordFactory.newRecordInstance( - RefreshUserToGroupsMappingsResponse.class); + return response; } @Override