YARN-4764. Application submission fails when submitted queue is not available in scheduler xml. Contributed by Bibin A Chundatt

This commit is contained in:
Jian He 2016-03-08 13:07:57 -08:00
parent a14a6f08ee
commit 3c33158d1c
2 changed files with 60 additions and 21 deletions

View File

@ -17,7 +17,11 @@
*/ */
package org.apache.hadoop.yarn.server.resourcemanager; package org.apache.hadoop.yarn.server.resourcemanager;
import com.google.common.annotations.VisibleForTesting; import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.LinkedList;
import java.util.Map;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configuration;
@ -55,14 +59,12 @@ import org.apache.hadoop.yarn.server.resourcemanager.rmapp.attempt.RMAppAttempt;
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.attempt.RMAppAttemptImpl; import org.apache.hadoop.yarn.server.resourcemanager.rmapp.attempt.RMAppAttemptImpl;
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.SchedulerUtils; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.SchedulerUtils;
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.YarnScheduler; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.YarnScheduler;
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CSQueue;
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler;
import org.apache.hadoop.yarn.server.security.ApplicationACLsManager; import org.apache.hadoop.yarn.server.security.ApplicationACLsManager;
import org.apache.hadoop.yarn.server.utils.BuilderUtils; import org.apache.hadoop.yarn.server.utils.BuilderUtils;
import java.io.IOException; import com.google.common.annotations.VisibleForTesting;
import java.nio.ByteBuffer;
import java.util.LinkedList;
import java.util.Map;
/** /**
* This class manages the list of applications for the resource manager. * This class manages the list of applications for the resource manager.
@ -360,23 +362,24 @@ public class RMAppManager implements EventHandler<RMAppManagerEvent>,
// mapping should be done outside scheduler too like CS. // mapping should be done outside scheduler too like CS.
// For now, exclude FS for the acl check. // For now, exclude FS for the acl check.
if (!isRecovery && YarnConfiguration.isAclEnabled(conf) if (!isRecovery && YarnConfiguration.isAclEnabled(conf)
&& scheduler instanceof CapacityScheduler && && scheduler instanceof CapacityScheduler) {
!authorizer.checkPermission(new AccessRequest( String queueName = submissionContext.getQueue();
((CapacityScheduler) scheduler) String appName = submissionContext.getApplicationName();
.getQueue(submissionContext.getQueue()).getPrivilegedEntity(), CSQueue csqueue = ((CapacityScheduler) scheduler).getQueue(queueName);
userUgi, SchedulerUtils.toAccessType(QueueACL.SUBMIT_APPLICATIONS), if (null != csqueue
submissionContext.getApplicationId().toString(), && !authorizer.checkPermission(
submissionContext.getApplicationName())) && new AccessRequest(csqueue.getPrivilegedEntity(), userUgi,
!authorizer.checkPermission(new AccessRequest( SchedulerUtils.toAccessType(QueueACL.SUBMIT_APPLICATIONS),
((CapacityScheduler) scheduler) applicationId.toString(), appName))
.getQueue(submissionContext.getQueue()).getPrivilegedEntity(), && !authorizer.checkPermission(
userUgi, SchedulerUtils.toAccessType(QueueACL.ADMINISTER_QUEUE), new AccessRequest(csqueue.getPrivilegedEntity(), userUgi,
submissionContext.getApplicationId().toString(), SchedulerUtils.toAccessType(QueueACL.ADMINISTER_QUEUE),
submissionContext.getApplicationName()))) { applicationId.toString(), appName))) {
throw new AccessControlException( throw new AccessControlException(
"User " + user + " does not have permission to submit " "User " + user + " does not have permission to submit "
+ applicationId + " to queue " + submissionContext.getQueue()); + applicationId + " to queue " + submissionContext.getQueue());
} }
}
// Create RMApp // Create RMApp
RMAppImpl application = new RMAppImpl(applicationId, rmContext, this.conf, RMAppImpl application = new RMAppImpl(applicationId, rmContext, this.conf,

View File

@ -40,6 +40,7 @@ import org.apache.hadoop.service.Service.STATE;
import org.apache.hadoop.yarn.api.ApplicationClientProtocol; import org.apache.hadoop.yarn.api.ApplicationClientProtocol;
import org.apache.hadoop.yarn.api.protocolrecords.GetApplicationsRequest; import org.apache.hadoop.yarn.api.protocolrecords.GetApplicationsRequest;
import org.apache.hadoop.yarn.api.protocolrecords.GetApplicationReportRequest; 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.GetNewApplicationRequest;
import org.apache.hadoop.yarn.api.protocolrecords.KillApplicationRequest; import org.apache.hadoop.yarn.api.protocolrecords.KillApplicationRequest;
import org.apache.hadoop.yarn.api.protocolrecords.SubmitApplicationRequest; import org.apache.hadoop.yarn.api.protocolrecords.SubmitApplicationRequest;
@ -179,6 +180,8 @@ public class TestApplicationACLs {
verifyEnemyAccess(); verifyEnemyAccess();
verifyAdministerQueueUserAccess(); verifyAdministerQueueUserAccess();
verifyInvalidQueueWithAcl();
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
@ -392,6 +395,39 @@ public class TestApplicationACLs {
-1, usageReport.getNeededResources().getMemory()); -1, usageReport.getNeededResources().getMemory());
} }
private void verifyInvalidQueueWithAcl() throws Exception {
isQueueUser = true;
SubmitApplicationRequest submitRequest =
recordFactory.newRecordInstance(SubmitApplicationRequest.class);
ApplicationSubmissionContext context =
recordFactory.newRecordInstance(ApplicationSubmissionContext.class);
ApplicationId applicationId = rmClient
.getNewApplication(
recordFactory.newRecordInstance(GetNewApplicationRequest.class))
.getApplicationId();
context.setApplicationId(applicationId);
Map<ApplicationAccessType, String> acls =
new HashMap<ApplicationAccessType, String>();
ContainerLaunchContext amContainer =
recordFactory.newRecordInstance(ContainerLaunchContext.class);
Resource resource = BuilderUtils.newResource(1024, 1);
context.setResource(resource);
amContainer.setApplicationACLs(acls);
context.setQueue("InvalidQueue");
context.setAMContainerSpec(amContainer);
submitRequest.setApplicationSubmissionContext(context);
rmClient.submitApplication(submitRequest);
resourceManager.waitForState(applicationId, RMAppState.FAILED);
final GetApplicationReportRequest appReportRequest =
recordFactory.newRecordInstance(GetApplicationReportRequest.class);
appReportRequest.setApplicationId(applicationId);
GetApplicationReportResponse applicationReport =
rmClient.getApplicationReport(appReportRequest);
ApplicationReport appReport = applicationReport.getApplicationReport();
Assert.assertTrue(appReport.getDiagnostics()
.contains("submitted by user owner to unknown queue: InvalidQueue"));
}
private void verifyAdministerQueueUserAccess() throws Exception { private void verifyAdministerQueueUserAccess() throws Exception {
isQueueUser = true; isQueueUser = true;
AccessControlList viewACL = new AccessControlList(""); AccessControlList viewACL = new AccessControlList("");