diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ClientRMService.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ClientRMService.java index bee6bf8..a0176ab 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ClientRMService.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ClientRMService.java @@ -329,7 +329,7 @@ public GetApplicationReportResponse getApplicationReport( boolean allowAccess = checkAccess(callerUGI, application.getUser(), ApplicationAccessType.VIEW_APP, application); ApplicationReport report = - application.createAndGetApplicationReport(callerUGI.getUserName(), + application.createAndGetApplicationReport(callerUGI.getShortUserName(), allowAccess); GetApplicationReportResponse response = recordFactory diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/TestAMRMTokenRetrieval.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/TestAMRMTokenRetrieval.java new file mode 100644 index 0000000..bd6f314 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/TestAMRMTokenRetrieval.java @@ -0,0 +1,191 @@ +/** + * 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.yarn.server.resourcemanager; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.security.UserGroupInformation; +import org.apache.hadoop.security.authentication.util.KerberosName; +import org.apache.hadoop.yarn.api.protocolrecords.GetApplicationReportRequest; +import org.apache.hadoop.yarn.api.protocolrecords.GetApplicationReportResponse; +import org.apache.hadoop.yarn.api.protocolrecords.GetNewApplicationRequest; +import org.apache.hadoop.yarn.api.protocolrecords.GetNewApplicationResponse; +import org.apache.hadoop.yarn.api.protocolrecords.SubmitApplicationRequest; +import org.apache.hadoop.yarn.api.records.ApplicationId; +import org.apache.hadoop.yarn.api.records.ApplicationSubmissionContext; +import org.apache.hadoop.yarn.api.records.ContainerLaunchContext; +import org.apache.hadoop.yarn.api.records.Token; +import org.apache.hadoop.yarn.conf.YarnConfiguration; +import org.apache.hadoop.yarn.exceptions.YarnException; +import org.apache.hadoop.yarn.factories.RecordFactory; +import org.apache.hadoop.yarn.factory.providers.RecordFactoryProvider; +import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMApp; +import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMAppState; +import org.apache.hadoop.yarn.server.resourcemanager.scheduler.fifo.FifoScheduler; +import org.apache.hadoop.yarn.util.Records; +import org.apache.hadoop.yarn.util.resource.Resources; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.io.IOException; +import java.security.PrivilegedExceptionAction; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +public class TestAMRMTokenRetrieval { + + private final static String kerberosRule = "RULE:[1:$1@$0](.*@EXAMPLE.COM)s/@.*//\nDEFAULT"; + + static { + KerberosName.setRules(kerberosRule); + } + + private static final UserGroupInformation owner = + UserGroupInformation.createRemoteUser("owner"); + private static final UserGroupInformation other = + UserGroupInformation.createRemoteUser("other"); + private static final UserGroupInformation ownerKerb = + UserGroupInformation.createRemoteUser("owner@EXAMPLE.COM"); + private static final UserGroupInformation otherKerb = + UserGroupInformation.createRemoteUser("other@EXAMPLE.COM"); + private final static RecordFactory recordFactory = + RecordFactoryProvider.getRecordFactory(null); + + private ResourceManager resourceManager; + + @Before + public void setup() { + Configuration conf = new YarnConfiguration(); + conf.setClass(YarnConfiguration.RM_SCHEDULER, + TestMoveApplication.FifoSchedulerWithMove.class, FifoScheduler.class); + conf.set(YarnConfiguration.YARN_ADMIN_ACL, " "); + conf.setBoolean(YarnConfiguration.YARN_ACL_ENABLE, true); + resourceManager = new ResourceManager(); + resourceManager.init(conf); + resourceManager.getRMContext().getContainerTokenSecretManager().rollMasterKey(); + resourceManager.getRMContext().getNMTokenSecretManager().rollMasterKey(); + resourceManager.start(); + } + + @Test + public void testGetAMRMTokenByOwner() throws Exception { + ApplicationId unmanagedAppKerberizedOwner = + submitApplication(ownerKerb, true); + ApplicationId unmanagedAppRegularOwner = submitApplication(owner, true); + + Token amrmToken = getAMRMToken(ownerKerb, unmanagedAppKerberizedOwner); + assertNotNull(amrmToken); + + Token amrmToken1 = getAMRMToken(owner, unmanagedAppRegularOwner); + assertNotNull(amrmToken1); + + ApplicationId managedAppKerberizedOwner = + submitApplication(ownerKerb, false); + ApplicationId managedAppRegularOwner = submitApplication(owner, false); + + Token amrmToken2 = getAMRMToken(ownerKerb, managedAppKerberizedOwner); + assertNull(amrmToken2); + + Token amrmToken3 = getAMRMToken(owner, managedAppRegularOwner); + assertNull(amrmToken3); + } + + @Test + public void testGetAMRMTokenByOtherUser() throws Exception { + ApplicationId unmanagedAppKerberizedOwner = + submitApplication(ownerKerb, true); + ApplicationId unmanagedAppRegularOwner = submitApplication(owner, true); + + Token amrmToken = getAMRMToken(otherKerb, unmanagedAppKerberizedOwner); + assertNull(amrmToken); + + Token amrmToken1 = getAMRMToken(other, unmanagedAppRegularOwner); + assertNull(amrmToken1); + } + + private ApplicationId submitApplication(UserGroupInformation submitter, + boolean isUnmanaged) throws YarnException, IOException, + InterruptedException { + GetNewApplicationRequest request = + Records.newRecord(GetNewApplicationRequest.class); + GetNewApplicationResponse newApp = + this.resourceManager.getClientRMService().getNewApplication(request); + + ApplicationSubmissionContext context = + recordFactory.newRecordInstance(ApplicationSubmissionContext.class); + context.setApplicationId(newApp.getApplicationId()); + context.setQueue("test"); + context.setUnmanagedAM(isUnmanaged); + + ContainerLaunchContext amContainer + = Records.newRecord(ContainerLaunchContext.class); + context.setAMContainerSpec(amContainer); + context.setResource(Resources.createResource( + YarnConfiguration.DEFAULT_RM_SCHEDULER_MINIMUM_ALLOCATION_MB)); + + final SubmitApplicationRequest submitApplicationRequest = recordFactory + .newRecordInstance(SubmitApplicationRequest.class); + submitApplicationRequest.setApplicationSubmissionContext(context); + + submitter.doAs(new PrivilegedExceptionAction() { + @Override + public Object run() throws Exception { + resourceManager.getClientRMService() + .submitApplication(submitApplicationRequest); + return null; + } + }); + + RMApp app = resourceManager.rmContext.getRMApps() + .get(newApp.getApplicationId()); + + for(int i = 0; (app.getState() != RMAppState.ACCEPTED) && i < 20; i++) { + Thread.sleep(100); + } + + assertTrue(app.getState() == RMAppState.ACCEPTED); + return newApp.getApplicationId(); + } + + private Token getAMRMToken(UserGroupInformation requester, ApplicationId + appId) throws IOException, InterruptedException { + final GetApplicationReportRequest applicationReportRequest = recordFactory + .newRecordInstance(GetApplicationReportRequest.class); + applicationReportRequest.setApplicationId(appId); + + return requester.doAs(new PrivilegedExceptionAction() { + @Override + public Token run() throws Exception { + GetApplicationReportResponse applicationReportResponse = + resourceManager.getClientRMService() + .getApplicationReport(applicationReportRequest); + + return applicationReportResponse.getApplicationReport().getAMRMToken(); + } + }); + } + + @After + public void tearDown() { + resourceManager.stop(); + } + +}