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

View File

@ -40,6 +40,7 @@
import org.apache.hadoop.yarn.api.ApplicationClientProtocol;
import org.apache.hadoop.yarn.api.protocolrecords.GetApplicationsRequest;
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.KillApplicationRequest;
import org.apache.hadoop.yarn.api.protocolrecords.SubmitApplicationRequest;
@ -179,6 +180,8 @@ public void testApplicationACLs() throws Exception {
verifyEnemyAccess();
verifyAdministerQueueUserAccess();
verifyInvalidQueueWithAcl();
}
@SuppressWarnings("deprecation")
@ -392,6 +395,39 @@ private void verifyEnemyAppReport(ApplicationReport appReport) {
-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 {
isQueueUser = true;
AccessControlList viewACL = new AccessControlList("");