diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/ReservationACL.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/ReservationACL.java
new file mode 100644
index 0000000..7923a50
--- /dev/null
+++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/ReservationACL.java
@@ -0,0 +1,56 @@
+/**
+ * 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.api.records;
+
+import org.apache.hadoop.classification.InterfaceAudience.Public;
+import org.apache.hadoop.classification.InterfaceStability.Stable;
+
+/**
+ * {@code ReservationACL} enumerates the various ACLs for reservations.
+ *
+ * The ACL is one of:
+ *
+ *
+ * {@link #ADMINISTER_RESERVATIONS} - ACL to create, list, update and
+ * delete reservations.
+ *
+ *
{@link #LIST_RESERVATIONS} - ACL to list reservations.
+ *
{@link #SUBMIT_RESERVATIONS} - ACL to create reservations.
+ *
+ * Users can always list, update and delete their own reservations.
+ */
+@Public
+@Stable
+public enum ReservationACL {
+ /**
+ * ACL to create, list, update and delete reservations.
+ */
+ ADMINISTER_RESERVATIONS,
+
+ /**
+ * ACL to list reservations.
+ */
+ LIST_RESERVATIONS,
+
+ /**
+ * ACL to create reservations.
+ */
+ SUBMIT_RESERVATIONS
+
+}
\ No newline at end of file
diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java
index 57bd118..f844391 100644
--- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java
+++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java
@@ -278,7 +278,12 @@ private static void addDeprecatedKeys() {
public static final String YARN_ACL_ENABLE =
YARN_PREFIX + "acl.enable";
public static final boolean DEFAULT_YARN_ACL_ENABLE = false;
-
+
+ /** Are reservation acls enabled.*/
+ public static final String YARN_RESERVATION_ACL_ENABLE =
+ YARN_PREFIX + "acl.reservation-enable";
+ public static final boolean DEFAULT_YARN_RESERVATION_ACL_ENABLE = false;
+
/** ACL of who can be admin of YARN cluster.*/
public static final String YARN_ADMIN_ACL =
YARN_PREFIX + "admin.acl";
diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/yarn-default.xml hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/yarn-default.xml
index 80f0fea..1c7f078 100644
--- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/yarn-default.xml
+++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/yarn-default.xml
@@ -191,6 +191,12 @@
+ Are reservation acls enabled.
+ yarn.acl.reservation-enable
+ false
+
+
+ ACL of who can be admin of the YARN cluster.yarn.admin.acl*
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 630c804..36d1033 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
@@ -33,6 +33,7 @@
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
+import org.apache.commons.cli.UnrecognizedOptionException;
import org.apache.commons.lang.math.LongRange;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -117,6 +118,7 @@
import org.apache.hadoop.yarn.api.records.Priority;
import org.apache.hadoop.yarn.api.records.QueueACL;
import org.apache.hadoop.yarn.api.records.QueueInfo;
+import org.apache.hadoop.yarn.api.records.ReservationACL;
import org.apache.hadoop.yarn.api.records.ReservationAllocationState;
import org.apache.hadoop.yarn.api.records.ReservationDefinition;
import org.apache.hadoop.yarn.api.records.ReservationId;
@@ -158,6 +160,7 @@
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.YarnScheduler;
import org.apache.hadoop.yarn.server.resourcemanager.security.QueueACLsManager;
import org.apache.hadoop.yarn.server.resourcemanager.security.RMDelegationTokenSecretManager;
+import org.apache.hadoop.yarn.server.resourcemanager.security.ReservationsACLsManager;
import org.apache.hadoop.yarn.server.resourcemanager.security.authorize.RMPolicyProvider;
import org.apache.hadoop.yarn.server.security.ApplicationACLsManager;
import org.apache.hadoop.yarn.server.utils.BuilderUtils;
@@ -602,6 +605,12 @@ public SubmitApplicationResponse submitApplication(
}
}
+ ReservationId reservationId = request.getApplicationSubmissionContext()
+ .getReservationID();
+
+ checkReservationACLs(submissionContext.getQueue(), AuditConstants
+ .SUBMIT_RESERVATION_REQUEST, reservationId);
+
try {
// call RMAppManager to submit application directly
rmAppManager.submitApplication(submissionContext,
@@ -1220,7 +1229,7 @@ public ReservationSubmissionResponse submitReservation(
String queueName = request.getQueue();
String user =
checkReservationACLs(queueName,
- AuditConstants.SUBMIT_RESERVATION_REQUEST);
+ AuditConstants.SUBMIT_RESERVATION_REQUEST, null);
try {
// Try to place the reservation using the agent
boolean result =
@@ -1262,7 +1271,7 @@ public ReservationUpdateResponse updateReservation(
// Check ACLs
String user =
checkReservationACLs(queueName,
- AuditConstants.UPDATE_RESERVATION_REQUEST);
+ AuditConstants.UPDATE_RESERVATION_REQUEST, reservationId);
// Try to update the reservation using default agent
try {
boolean result =
@@ -1301,7 +1310,7 @@ public ReservationDeleteResponse deleteReservation(
// Check ACLs
String user =
checkReservationACLs(queueName,
- AuditConstants.DELETE_RESERVATION_REQUEST);
+ AuditConstants.DELETE_RESERVATION_REQUEST, reservationId);
// Try to update the reservation using default agent
try {
boolean result =
@@ -1338,8 +1347,15 @@ public ReservationListResponse listReservations(
boolean includeResourceAllocations = requestInfo
.getIncludeResourceAllocations();
- String user = checkReservationACLs(requestInfo.getQueue(),
- AuditConstants.LIST_RESERVATION_REQUEST);
+ ReservationId reservationId = null;
+ if (requestInfo.getReservationId() != null && !requestInfo
+ .getReservationId().isEmpty()) {
+ reservationId = ReservationId.parseReservationId(
+ requestInfo.getReservationId());
+ }
+
+ checkReservationACLs(requestInfo.getQueue(),
+ AuditConstants.LIST_RESERVATION_REQUEST, reservationId);
ReservationId requestedId = null;
if (requestInfo.getReservationId() != null
@@ -1352,8 +1368,10 @@ public ReservationListResponse listReservations(
long endTime = requestInfo.getEndTime() <= -1? Long.MAX_VALUE : requestInfo
.getEndTime();
- Set reservations = plan.getReservations(
- requestedId, new ReservationInterval(startTime, endTime), user);
+ Set reservations;
+
+ reservations = plan.getReservations(requestedId, new ReservationInterval(
+ startTime, endTime));
List info =
ReservationSystemUtil.convertAllocationsToReservationInfo(
@@ -1417,7 +1435,8 @@ private void refreshScheduler(String planName,
}
}
- private String checkReservationACLs(String queueName, String auditConstant)
+ private String checkReservationACLs(String queueName, String auditConstant,
+ ReservationId reservationId)
throws YarnException {
UserGroupInformation callerUGI;
try {
@@ -1427,20 +1446,79 @@ private String checkReservationACLs(String queueName, String auditConstant)
"ClientRMService", "Error getting UGI");
throw RPCUtil.getRemoteException(ie);
}
- // Check if user has access on the managed queue
- if (!queueACLsManager.checkAccess(callerUGI, QueueACL.SUBMIT_APPLICATIONS,
- queueName)) {
- RMAuditLogger.logFailure(
- callerUGI.getShortUserName(),
- auditConstant,
- "User doesn't have permissions to "
- + QueueACL.SUBMIT_APPLICATIONS.toString(), "ClientRMService",
- AuditConstants.UNAUTHORIZED_USER);
- throw RPCUtil.getRemoteException(new AccessControlException("User "
- + callerUGI.getShortUserName() + " cannot perform operation "
- + QueueACL.SUBMIT_APPLICATIONS.name() + " on queue" + queueName));
+
+ if (reservationSystem == null) {
+ return callerUGI.getShortUserName();
}
- return callerUGI.getShortUserName();
+
+ ReservationsACLsManager manager = reservationSystem
+ .getReservationsACLsManager();
+ ReservationACL reservationACL = getReservationACLFromAuditConstant(
+ auditConstant);
+
+ if (manager == null) {
+ return callerUGI.getShortUserName();
+ }
+
+ String reservationCreatorName = "";
+ ReservationAllocation reservation;
+ // Get the user associated with the reservation.
+ Plan plan = reservationSystem.getPlan(queueName);
+ if (reservationId != null && plan != null) {
+ reservation = plan.getReservationById(reservationId);
+ if (reservation != null) {
+ reservationCreatorName = reservation.getUser();
+ }
+ }
+
+ // If the reservation to be altered or listed belongs to the current user,
+ // access will be given.
+ if (reservationCreatorName != null && !reservationCreatorName.isEmpty()
+ && reservationCreatorName.equals(callerUGI.getUserName())) {
+ return callerUGI.getShortUserName();
+ }
+
+ // Check if the user has access to the specific ACL
+ if (manager.checkAccess(callerUGI, reservationACL, queueName)) {
+ return callerUGI.getShortUserName();
+ }
+
+ // If the user has Administer ACL then access is granted
+ if (manager.checkAccess(callerUGI, ReservationACL
+ .ADMINISTER_RESERVATIONS, queueName)) {
+ return callerUGI.getShortUserName();
+ }
+
+ handleNoAccess(callerUGI.getShortUserName(), queueName, auditConstant,
+ reservationACL.toString(), reservationACL.name());
+ throw new IllegalStateException();
+ }
+
+ private ReservationACL getReservationACLFromAuditConstant(
+ String auditConstant) throws YarnException{
+ if (auditConstant.equals(AuditConstants.SUBMIT_RESERVATION_REQUEST)) {
+ return ReservationACL.SUBMIT_RESERVATIONS;
+ } else if (auditConstant.equals(AuditConstants.LIST_RESERVATION_REQUEST)) {
+ return ReservationACL.LIST_RESERVATIONS;
+ } else if (auditConstant.equals(AuditConstants.DELETE_RESERVATION_REQUEST)
+ || auditConstant.equals(AuditConstants.UPDATE_RESERVATION_REQUEST)) {
+ return ReservationACL.ADMINISTER_RESERVATIONS;
+ } else {
+ String error = "Audit Constant " + auditConstant + " is not recognized.";
+ LOG.error(error);
+ throw RPCUtil.getRemoteException(new UnrecognizedOptionException(error));
+ }
+ }
+
+ private void handleNoAccess(String name, String queue, String auditConstant,
+ String acl, String op) throws YarnException {
+ RMAuditLogger.logFailure(
+ name,
+ auditConstant,
+ "User doesn't have permissions to " + acl, "ClientRMService",
+ auditConstant);
+ throw RPCUtil.getRemoteException(new AccessControlException("User "
+ + name + " cannot perform operation " + op + " on queue " + queue));
}
@Override
diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/AbstractReservationSystem.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/AbstractReservationSystem.java
index 551be1c..601a2a7 100644
--- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/AbstractReservationSystem.java
+++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/AbstractReservationSystem.java
@@ -39,6 +39,7 @@
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.ResourceScheduler;
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler;
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler;
+import org.apache.hadoop.yarn.server.resourcemanager.security.ReservationsACLsManager;
import org.apache.hadoop.yarn.util.Clock;
import org.apache.hadoop.yarn.util.UTCClock;
import org.apache.hadoop.yarn.util.resource.ResourceCalculator;
@@ -98,6 +99,8 @@
private PlanFollower planFollower;
+ private ReservationsACLsManager reservationsACLsManager;
+
private boolean isRecoveryEnabled = false;
/**
@@ -158,6 +161,13 @@ private void initialize(Configuration conf) throws YarnException {
isRecoveryEnabled = conf.getBoolean(
YarnConfiguration.RECOVERY_ENABLED,
YarnConfiguration.DEFAULT_RM_RECOVERY_ENABLED);
+
+ if (conf.getBoolean(YarnConfiguration.YARN_RESERVATION_ACL_ENABLE,
+ YarnConfiguration.DEFAULT_YARN_RESERVATION_ACL_ENABLE) &&
+ conf.getBoolean(YarnConfiguration.YARN_ACL_ENABLE,
+ YarnConfiguration.DEFAULT_YARN_ACL_ENABLE)) {
+ reservationsACLsManager = new ReservationsACLsManager(scheduler, conf);
+ }
}
private void loadPlan(String planName,
@@ -475,6 +485,10 @@ protected SharingPolicy getAdmissionPolicy(String queueName) {
}
}
+ public ReservationsACLsManager getReservationsACLsManager() {
+ return this.reservationsACLsManager;
+ }
+
protected abstract ReservationSchedulerConfiguration
getReservationSchedulerConfiguration();
diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/CapacityOverTimePolicy.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/CapacityOverTimePolicy.java
index 80f6c88..f8b68e3 100644
--- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/CapacityOverTimePolicy.java
+++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/CapacityOverTimePolicy.java
@@ -26,7 +26,6 @@
import org.apache.hadoop.yarn.api.records.ReservationId;
import org.apache.hadoop.yarn.api.records.Resource;
import org.apache.hadoop.yarn.server.resourcemanager.reservation.RLESparseResourceAllocation.RLEOperator;
-import org.apache.hadoop.yarn.server.resourcemanager.reservation.exceptions.MismatchedUserException;
import org.apache.hadoop.yarn.server.resourcemanager.reservation.exceptions.PlanningException;
import org.apache.hadoop.yarn.server.resourcemanager.reservation.exceptions.PlanningQuotaException;
import org.apache.hadoop.yarn.server.resourcemanager.reservation.exceptions.ResourceOverCommitException;
@@ -85,14 +84,6 @@ public void validate(Plan plan, ReservationAllocation reservation)
ReservationAllocation oldReservation =
plan.getReservationById(reservation.getReservationId());
- // sanity check that the update of a reservation is not changing username
- if (oldReservation != null
- && !oldReservation.getUser().equals(reservation.getUser())) {
- throw new MismatchedUserException(
- "Updating an existing reservation with mismatched user:"
- + oldReservation.getUser() + " != " + reservation.getUser());
- }
-
long startTime = reservation.getStartTime();
long endTime = reservation.getEndTime();
long step = plan.getStep();
diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/InMemoryPlan.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/InMemoryPlan.java
index 586f1c0..12a584a 100644
--- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/InMemoryPlan.java
+++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/InMemoryPlan.java
@@ -476,7 +476,13 @@ public Resource getTotalCommittedResources(long t) {
}
@Override
- public Set getReservations(ReservationId
+ public Set getReservations(ReservationId
+ reservationID, ReservationInterval interval) {
+ return getReservations(reservationID, interval, null);
+ }
+
+ @Override
+ public Set getReservations(ReservationId
reservationID, ReservationInterval interval, String user) {
if (reservationID != null) {
ReservationAllocation allocation = getReservationById(reservationID);
diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/PlanView.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/PlanView.java
index 0ad6485..699f461 100644
--- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/PlanView.java
+++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/PlanView.java
@@ -42,13 +42,27 @@
* greater than the interval end time, and end time no less
* than the interval start time will be selected.
* @param user the user to retrieve the reservation allocation from.
- * @return {@link ReservationAllocation} identified by the user who
+ * @return a set of {@link ReservationAllocation} identified by the user who
* made the reservation
*/
Set getReservations(ReservationId
reservationID, ReservationInterval interval, String user);
/**
+ * Return a set of {@link ReservationAllocation} identified by any user.
+ *
+ * @param reservationID the unqiue id to identify the
+ * {@link ReservationAllocation}
+ * @param interval the time interval used to retrieve the reservation
+ * allocations from. Only reservations with start time no
+ * greater than the interval end time, and end time no less
+ * than the interval start time will be selected.
+ * @return a set of {@link ReservationAllocation} identified by any user
+ */
+ Set getReservations(ReservationId reservationID,
+ ReservationInterval interval);
+
+ /**
* Return a {@link ReservationAllocation} identified by its
* {@link ReservationId}
*
diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/ReservationSchedulerConfiguration.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/ReservationSchedulerConfiguration.java
index afca8f9..740b88c 100644
--- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/ReservationSchedulerConfiguration.java
+++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/ReservationSchedulerConfiguration.java
@@ -20,8 +20,12 @@
import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.security.authorize.AccessControlList;
+import org.apache.hadoop.yarn.api.records.ReservationACL;
import org.apache.hadoop.yarn.api.records.ReservationDefinition;
+import java.util.Map;
+
public abstract class ReservationSchedulerConfiguration extends Configuration {
@InterfaceAudience.Private
@@ -68,6 +72,17 @@ public ReservationSchedulerConfiguration(
public abstract boolean isReservable(String queue);
/**
+ * Gets a map containing the {@link AccessControlList} of users for each
+ * {@link ReservationACL} acl on thee specified queue.
+ *
+ * @param queue the queue with which to check a user's permissions.
+ * @return The a Map of {@link ReservationACL} to {@link AccessControlList}
+ * which contains a list of users that have the specified permission level.
+ */
+ public abstract Map getReservationAcls(
+ String queue);
+
+ /**
* Gets the length of time in milliseconds for which the {@link SharingPolicy}
* checks for validity
* @param queue name of the queue
diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/ReservationSystem.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/ReservationSystem.java
index 56a08ef..8b62972 100644
--- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/ReservationSystem.java
+++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/ReservationSystem.java
@@ -27,6 +27,7 @@
import org.apache.hadoop.yarn.server.resourcemanager.recovery.Recoverable;
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.Queue;
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.ResourceScheduler;
+import org.apache.hadoop.yarn.server.resourcemanager.security.ReservationsACLsManager;
import java.util.Map;
@@ -123,4 +124,12 @@ void reinitialize(Configuration conf, RMContext rmContext)
*/
void setQueueForReservation(ReservationId reservationId, String queueName);
+ /**
+ * Get the {@link ReservationsACLsManager} to use to check for the reservation
+ * access on a user.
+ *
+ * @return the reservation ACL manager to use to check reservation ACLs.
+ *
+ */
+ ReservationsACLsManager getReservationsACLsManager();
}
diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/CapacitySchedulerConfiguration.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/CapacitySchedulerConfiguration.java
index 2e8fd24..3756d9e 100644
--- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/CapacitySchedulerConfiguration.java
+++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/CapacitySchedulerConfiguration.java
@@ -40,6 +40,7 @@
import org.apache.hadoop.util.StringUtils;
import org.apache.hadoop.yarn.api.records.QueueACL;
import org.apache.hadoop.yarn.api.records.QueueState;
+import org.apache.hadoop.yarn.api.records.ReservationACL;
import org.apache.hadoop.yarn.api.records.Resource;
import org.apache.hadoop.yarn.conf.YarnConfiguration;
import org.apache.hadoop.yarn.nodelabels.CommonNodeLabelsManager;
@@ -566,6 +567,35 @@ public void setAcl(String queue, QueueACL acl, String aclString) {
set(queuePrefix + getAclKey(acl), aclString);
}
+ private static String getAclKey(ReservationACL acl) {
+ return "acl_" + StringUtils.toLowerCase(acl.toString());
+ }
+
+ @Override
+ public Map getReservationAcls(String
+ queue) {
+ Map resAcls = new HashMap<>();
+ for (ReservationACL acl : ReservationACL.values()) {
+ resAcls.put(acl, getReservationAcl(queue, acl));
+ }
+ return resAcls;
+ }
+
+ private AccessControlList getReservationAcl(String queue, ReservationACL
+ acl) {
+ String queuePrefix = getQueuePrefix(queue);
+ // The root queue defaults to all access if not defined
+ // Sub queues inherit access if not defined
+ String defaultAcl = ALL_ACL;
+ String aclString = get(queuePrefix + getAclKey(acl), defaultAcl);
+ return new AccessControlList(aclString);
+ }
+
+ private void setAcl(String queue, ReservationACL acl, String aclString) {
+ String queuePrefix = getQueuePrefix(queue);
+ set(queuePrefix + getAclKey(acl), aclString);
+ }
+
public Map getAcls(String queue) {
Map acls =
new HashMap();
@@ -581,6 +611,14 @@ public void setAcls(String queue, Map acls) {
}
}
+ @VisibleForTesting
+ public void setReservationAcls(String queue,
+ Map acls) {
+ for (Map.Entry e : acls.entrySet()) {
+ setAcl(queue, e.getKey(), e.getValue().getAclString());
+ }
+ }
+
public String[] getQueues(String queue) {
LOG.debug("CSConf - getQueues called for: queuePrefix=" + getQueuePrefix(queue));
String[] queues = getStrings(getQueuePrefix(queue) + QUEUES);
diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/AllocationConfiguration.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/AllocationConfiguration.java
index bf4eae8..4c8ebfa 100644
--- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/AllocationConfiguration.java
+++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/AllocationConfiguration.java
@@ -26,6 +26,7 @@
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.security.authorize.AccessControlList;
import org.apache.hadoop.yarn.api.records.QueueACL;
+import org.apache.hadoop.yarn.api.records.ReservationACL;
import org.apache.hadoop.yarn.api.records.Resource;
import org.apache.hadoop.yarn.server.resourcemanager.reservation.ReservationSchedulerConfiguration;
import org.apache.hadoop.yarn.server.resourcemanager.resource.ResourceWeights;
@@ -65,6 +66,10 @@
// ACL's for each queue. Only specifies non-default ACL's from configuration.
private final Map> queueAcls;
+ // Reservation ACL's for each queue. Only specifies non-default ACL's from
+ // configuration.
+ private final Map> resAcls;
+
// Min share preemption timeout for each queue in seconds. If a job in the queue
// waits this long without receiving its guaranteed share, it is allowed to
// preempt other jobs' tasks.
@@ -111,6 +116,7 @@ public AllocationConfiguration(Map minQueueResources,
Map fairSharePreemptionTimeouts,
Map fairSharePreemptionThresholds,
Map> queueAcls,
+ Map> resAcls,
QueuePlacementPolicy placementPolicy,
Map> configuredQueues,
ReservationQueueConfiguration globalReservationQueueConfig,
@@ -131,6 +137,7 @@ public AllocationConfiguration(Map minQueueResources,
this.fairSharePreemptionTimeouts = fairSharePreemptionTimeouts;
this.fairSharePreemptionThresholds = fairSharePreemptionThresholds;
this.queueAcls = queueAcls;
+ this.resAcls = resAcls;
this.reservableQueues = reservableQueues;
this.globalReservationQueueConfig = globalReservationQueueConfig;
this.placementPolicy = placementPolicy;
@@ -149,6 +156,7 @@ public AllocationConfiguration(Configuration conf) {
queueMaxResourcesDefault = Resources.unbounded();
queueMaxAMShareDefault = 0.5f;
queueAcls = new HashMap>();
+ resAcls = new HashMap>();
minSharePreemptionTimeouts = new HashMap();
fairSharePreemptionTimeouts = new HashMap();
fairSharePreemptionThresholds = new HashMap();
@@ -179,7 +187,17 @@ public AccessControlList getQueueAcl(String queue, QueueACL operation) {
}
return (queue.equals("root")) ? EVERYBODY_ACL : NOBODY_ACL;
}
-
+
+ @Override
+ /**
+ * Get the map of reservation ACLs to {@link AccessControlList} for the
+ * specified queue.
+ */
+ public Map getReservationAcls(String
+ queue) {
+ return this.resAcls.get(queue);
+ }
+
/**
* Get a queue's min share preemption timeout configured in the allocation
* file, in milliseconds. Return -1 if not set.
diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/AllocationFileLoaderService.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/AllocationFileLoaderService.java
index 9049525..d49cb41 100644
--- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/AllocationFileLoaderService.java
+++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/AllocationFileLoaderService.java
@@ -39,6 +39,7 @@
import org.apache.hadoop.security.authorize.AccessControlList;
import org.apache.hadoop.service.AbstractService;
import org.apache.hadoop.yarn.api.records.QueueACL;
+import org.apache.hadoop.yarn.api.records.ReservationACL;
import org.apache.hadoop.yarn.api.records.Resource;
import org.apache.hadoop.yarn.server.resourcemanager.resource.ResourceWeights;
import org.apache.hadoop.yarn.util.Clock;
@@ -223,6 +224,8 @@ public synchronized void reloadAllocations() throws IOException,
new HashMap();
Map> queueAcls =
new HashMap>();
+ Map> reservationAcls =
+ new HashMap>();
Set reservableQueues = new HashSet();
int userMaxAppsDefault = Integer.MAX_VALUE;
int queueMaxAppsDefault = Integer.MAX_VALUE;
@@ -359,8 +362,8 @@ public synchronized void reloadAllocations() throws IOException,
loadQueue(parent, element, minQueueResources, maxQueueResources,
queueMaxApps, userMaxApps, queueMaxAMShares, queueWeights,
queuePolicies, minSharePreemptionTimeouts, fairSharePreemptionTimeouts,
- fairSharePreemptionThresholds, queueAcls, configuredQueues,
- reservableQueues);
+ fairSharePreemptionThresholds, queueAcls, reservationAcls,
+ configuredQueues, reservableQueues);
}
// Load placement policy and pass it configured queues
@@ -408,9 +411,9 @@ public synchronized void reloadAllocations() throws IOException,
queueMaxResourcesDefault, queueMaxAMShareDefault, queuePolicies,
defaultSchedPolicy, minSharePreemptionTimeouts,
fairSharePreemptionTimeouts, fairSharePreemptionThresholds, queueAcls,
- newPlacementPolicy, configuredQueues, globalReservationQueueConfig,
- reservableQueues);
-
+ reservationAcls, newPlacementPolicy, configuredQueues,
+ globalReservationQueueConfig, reservableQueues);
+
lastSuccessfulReload = clock.getTime();
lastReloadAttemptFailed = false;
@@ -430,6 +433,7 @@ private void loadQueue(String parentName, Element element,
Map fairSharePreemptionTimeouts,
Map fairSharePreemptionThresholds,
Map> queueAcls,
+ Map> resAcls,
Map> configuredQueues,
Set reservableQueues)
throws AllocationConfigurationException {
@@ -451,6 +455,7 @@ private void loadQueue(String parentName, Element element,
}
Map acls =
new HashMap();
+ Map racls = new HashMap<>();
NodeList fields = element.getChildNodes();
boolean isLeaf = true;
@@ -504,6 +509,18 @@ private void loadQueue(String parentName, Element element,
} else if ("aclAdministerApps".equals(field.getTagName())) {
String text = ((Text)field.getFirstChild()).getData();
acls.put(QueueACL.ADMINISTER_QUEUE, new AccessControlList(text));
+ } else if ("aclAdministerReservations".equals(field.getTagName())) {
+ String text = ((Text)field.getFirstChild()).getData();
+ racls.put(ReservationACL.ADMINISTER_RESERVATIONS,
+ new AccessControlList(text));
+ } else if ("aclListReservations".equals(field.getTagName())) {
+ String text = ((Text)field.getFirstChild()).getData();
+ racls.put(ReservationACL.LIST_RESERVATIONS, new AccessControlList(
+ text));
+ } else if ("aclSubmitReservations".equals(field.getTagName())) {
+ String text = ((Text)field.getFirstChild()).getData();
+ racls.put(ReservationACL.SUBMIT_RESERVATIONS,
+ new AccessControlList(text));
} else if ("reservation".equals(field.getTagName())) {
isLeaf = false;
reservableQueues.add(queueName);
@@ -514,7 +531,7 @@ private void loadQueue(String parentName, Element element,
queueMaxApps, userMaxApps, queueMaxAMShares, queueWeights,
queuePolicies, minSharePreemptionTimeouts,
fairSharePreemptionTimeouts, fairSharePreemptionThresholds,
- queueAcls, configuredQueues, reservableQueues);
+ queueAcls, resAcls, configuredQueues, reservableQueues);
isLeaf = false;
}
}
@@ -535,6 +552,7 @@ private void loadQueue(String parentName, Element element,
configuredQueues.get(FSQueueType.PARENT).add(queueName);
}
queueAcls.put(queueName, acls);
+ resAcls.put(queueName, racls);
if (maxQueueResources.containsKey(queueName) &&
minQueueResources.containsKey(queueName)
&& !Resources.fitsIn(minQueueResources.get(queueName),
diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/security/ReservationsACLsManager.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/security/ReservationsACLsManager.java
new file mode 100644
index 0000000..5586f86b
--- /dev/null
+++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/security/ReservationsACLsManager.java
@@ -0,0 +1,92 @@
+/**
+* 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.security;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.hadoop.security.authorize.AccessControlList;
+import org.apache.hadoop.yarn.api.records.ReservationACL;
+import org.apache.hadoop.yarn.conf.YarnConfiguration;
+import org.apache.hadoop.yarn.exceptions.YarnException;
+import org.apache.hadoop.yarn.server.resourcemanager.scheduler.ResourceScheduler;
+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.CapacitySchedulerConfiguration;
+import org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.AllocationConfiguration;
+import org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * The {@link ReservationsACLsManager} is used to check a specified user's
+ * permissons to perform a reservation operation on the
+ * {@link CapacityScheduler} and the {@link FairScheduler}.
+ * {@link ReservationACL}s are used to specify reservation operations.
+ */
+public class ReservationsACLsManager {
+ private boolean isReservationACLsEnable;
+ private Map> reservationAcls
+ = new HashMap<>();
+
+ public ReservationsACLsManager(ResourceScheduler scheduler,
+ Configuration conf) throws YarnException {
+ this.isReservationACLsEnable =
+ conf.getBoolean(YarnConfiguration.YARN_RESERVATION_ACL_ENABLE,
+ YarnConfiguration.DEFAULT_YARN_RESERVATION_ACL_ENABLE) &&
+ conf.getBoolean(YarnConfiguration.YARN_ACL_ENABLE,
+ YarnConfiguration.DEFAULT_YARN_ACL_ENABLE);
+ if (scheduler instanceof CapacityScheduler) {
+ CapacitySchedulerConfiguration csConf = new
+ CapacitySchedulerConfiguration(conf);
+
+ for (String planQueue : scheduler.getPlanQueues()) {
+ CSQueue queue = ((CapacityScheduler) scheduler).getQueue(planQueue);
+ reservationAcls.put(planQueue, csConf.getReservationAcls(queue
+ .getQueuePath()));
+ }
+ } else if (scheduler instanceof FairScheduler) {
+ AllocationConfiguration aConf = ((FairScheduler) scheduler)
+ .getAllocationConfiguration();
+ for (String planQueue : scheduler.getPlanQueues()) {
+ reservationAcls.put(planQueue, aConf.getReservationAcls(planQueue));
+ }
+ }
+ }
+
+ public boolean checkAccess(UserGroupInformation callerUGI,
+ ReservationACL acl, String queueName) {
+ if (!isReservationACLsEnable) {
+ return true;
+ }
+
+ if (this.reservationAcls.containsKey(queueName)) {
+ Map acls = this.reservationAcls.get(
+ queueName);
+ if (acls.containsKey(acl)) {
+ return acls.get(acl).isUserAllowed(callerUGI);
+ } else {
+ // Give access if acl is undefined for queue.
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/ACLsTestBase.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/ACLsTestBase.java
new file mode 100644
index 0000000..e661703
--- /dev/null
+++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/ACLsTestBase.java
@@ -0,0 +1,123 @@
+/**
+* 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 java.io.IOException;
+import java.net.InetSocketAddress;
+import java.security.PrivilegedExceptionAction;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.hadoop.security.authorize.AccessControlList;
+import org.apache.hadoop.service.Service.STATE;
+import org.apache.hadoop.yarn.api.ApplicationClientProtocol;
+import org.apache.hadoop.yarn.conf.YarnConfiguration;
+import org.apache.hadoop.yarn.event.Dispatcher;
+import org.apache.hadoop.yarn.event.DrainDispatcher;
+import org.apache.hadoop.yarn.ipc.YarnRPC;
+import org.junit.Before;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public abstract class ACLsTestBase {
+
+ protected static final String COMMON_USER = "common_user";
+ protected static final String QUEUE_A_USER = "queueA_user";
+ protected static final String QUEUE_B_USER = "queueB_user";
+ protected static final String ROOT_ADMIN = "root_admin";
+ protected static final String QUEUE_A_ADMIN = "queueA_admin";
+ protected static final String QUEUE_B_ADMIN = "queueB_admin";
+
+ protected static final String QUEUEA = "queueA";
+ protected static final String QUEUEB = "queueB";
+ protected static final String QUEUEC = "queueC";
+
+ protected static final Log LOG = LogFactory.getLog(TestApplicationACLs.class);
+
+ MockRM resourceManager;
+ Configuration conf;
+ YarnRPC rpc;
+ InetSocketAddress rmAddress;
+
+ @Before
+ public void setup() throws InterruptedException, IOException {
+ conf = createConfiguration();
+ rpc = YarnRPC.create(conf);
+ rmAddress = conf.getSocketAddr(
+ YarnConfiguration.RM_ADDRESS, YarnConfiguration.DEFAULT_RM_ADDRESS,
+ YarnConfiguration.DEFAULT_RM_PORT);
+
+ AccessControlList adminACL = new AccessControlList("");
+ conf.set(YarnConfiguration.YARN_ADMIN_ACL, adminACL.getAclString());
+
+ resourceManager = new MockRM(conf) {
+ protected ClientRMService createClientRMService() {
+ return new ClientRMService(getRMContext(), this.scheduler,
+ this.rmAppManager, this.applicationACLsManager,
+ this.queueACLsManager, getRMContext()
+ .getRMDelegationTokenSecretManager());
+ }
+
+ @Override
+ protected Dispatcher createDispatcher() {
+ return new DrainDispatcher();
+ }
+
+ @Override
+ protected void doSecureLogin() throws IOException {
+ }
+ };
+ new Thread() {
+ public void run() {
+ resourceManager.start();
+ };
+ }.start();
+ int waitCount = 0;
+ while (resourceManager.getServiceState() == STATE.INITED
+ && waitCount++ < 60) {
+ LOG.info("Waiting for RM to start...");
+ Thread.sleep(1500);
+ }
+ if (resourceManager.getServiceState() != STATE.STARTED) {
+ // RM could have failed.
+ throw new IOException("ResourceManager failed to start. Final state is "
+ + resourceManager.getServiceState());
+ }
+ }
+
+ protected ApplicationClientProtocol getRMClientForUser(String user)
+ throws IOException, InterruptedException {
+ UserGroupInformation userUGI = UserGroupInformation.createRemoteUser(user);
+ ApplicationClientProtocol userClient =
+ userUGI
+ .doAs(new PrivilegedExceptionAction() {
+ @Override
+ public ApplicationClientProtocol run() throws Exception {
+ return (ApplicationClientProtocol) rpc.getProxy(
+ ApplicationClientProtocol.class, rmAddress, conf);
+ }
+ });
+ return userClient;
+ }
+
+ protected abstract Configuration createConfiguration() throws IOException;
+}
diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/QueueACLsTestBase.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/QueueACLsTestBase.java
index e8f1425..82b3e24 100644
--- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/QueueACLsTestBase.java
+++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/QueueACLsTestBase.java
@@ -18,20 +18,12 @@
package org.apache.hadoop.yarn.server.resourcemanager;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.security.PrivilegedExceptionAction;
import java.util.HashMap;
import java.util.Map;
import org.junit.Assert;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.security.authorize.AccessControlList;
-import org.apache.hadoop.service.Service.STATE;
import org.apache.hadoop.yarn.api.ApplicationClientProtocol;
import org.apache.hadoop.yarn.api.protocolrecords.GetApplicationReportRequest;
import org.apache.hadoop.yarn.api.protocolrecords.GetApplicationReportResponse;
@@ -43,73 +35,13 @@
import org.apache.hadoop.yarn.api.records.ApplicationSubmissionContext;
import org.apache.hadoop.yarn.api.records.ContainerLaunchContext;
import org.apache.hadoop.yarn.api.records.Resource;
-import org.apache.hadoop.yarn.conf.YarnConfiguration;
import org.apache.hadoop.yarn.exceptions.YarnException;
-import org.apache.hadoop.yarn.ipc.YarnRPC;
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMAppState;
import org.apache.hadoop.yarn.server.utils.BuilderUtils;
import org.junit.After;
-import org.junit.Before;
import org.junit.Test;
-public abstract class QueueACLsTestBase {
-
- protected static final String COMMON_USER = "common_user";
- protected static final String QUEUE_A_USER = "queueA_user";
- protected static final String QUEUE_B_USER = "queueB_user";
- protected static final String ROOT_ADMIN = "root_admin";
- protected static final String QUEUE_A_ADMIN = "queueA_admin";
- protected static final String QUEUE_B_ADMIN = "queueB_admin";
-
- protected static final String QUEUEA = "queueA";
- protected static final String QUEUEB = "queueB";
-
- private static final Log LOG = LogFactory.getLog(TestApplicationACLs.class);
-
- MockRM resourceManager;
- Configuration conf;
- YarnRPC rpc;
- InetSocketAddress rmAddress;
-
- @Before
- public void setup() throws InterruptedException, IOException {
- conf = createConfiguration();
- rpc = YarnRPC.create(conf);
- rmAddress = conf.getSocketAddr(
- YarnConfiguration.RM_ADDRESS, YarnConfiguration.DEFAULT_RM_ADDRESS,
- YarnConfiguration.DEFAULT_RM_PORT);
-
- AccessControlList adminACL = new AccessControlList("");
- conf.set(YarnConfiguration.YARN_ADMIN_ACL, adminACL.getAclString());
-
- resourceManager = new MockRM(conf) {
- protected ClientRMService createClientRMService() {
- return new ClientRMService(getRMContext(), this.scheduler,
- this.rmAppManager, this.applicationACLsManager,
- this.queueACLsManager, getRMContext().getRMDelegationTokenSecretManager());
- };
-
- @Override
- protected void doSecureLogin() throws IOException {
- }
- };
- new Thread() {
- public void run() {
- resourceManager.start();
- };
- }.start();
- int waitCount = 0;
- while (resourceManager.getServiceState() == STATE.INITED
- && waitCount++ < 60) {
- LOG.info("Waiting for RM to start...");
- Thread.sleep(1500);
- }
- if (resourceManager.getServiceState() != STATE.STARTED) {
- // RM could have failed.
- throw new IOException("ResourceManager failed to start. Final state is "
- + resourceManager.getServiceState());
- }
- }
+public abstract class QueueACLsTestBase extends ACLsTestBase {
@After
public void tearDown() {
@@ -248,21 +180,4 @@ private ApplicationId submitAppAndGetAppId(String submitter,
acls.put(ApplicationAccessType.MODIFY_APP, modifyACL.getAclString());
return acls;
}
-
- private ApplicationClientProtocol getRMClientForUser(String user)
- throws IOException, InterruptedException {
- UserGroupInformation userUGI = UserGroupInformation.createRemoteUser(user);
- ApplicationClientProtocol userClient =
- userUGI
- .doAs(new PrivilegedExceptionAction() {
- @Override
- public ApplicationClientProtocol run() throws Exception {
- return (ApplicationClientProtocol) rpc.getProxy(
- ApplicationClientProtocol.class, rmAddress, conf);
- }
- });
- return userClient;
- }
-
- protected abstract Configuration createConfiguration() throws IOException;
}
diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/ReservationACLsTestBase.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/ReservationACLsTestBase.java
new file mode 100644
index 0000000..4039f50
--- /dev/null
+++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/ReservationACLsTestBase.java
@@ -0,0 +1,600 @@
+/**
+* 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 java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.security.authorize.AccessControlList;
+import org.apache.hadoop.yarn.api.ApplicationClientProtocol;
+import org.apache.hadoop.yarn.api.protocolrecords.ReservationDeleteRequest;
+import org.apache.hadoop.yarn.api.protocolrecords.ReservationListRequest;
+import org.apache.hadoop.yarn.api.protocolrecords.ReservationListResponse;
+import org.apache.hadoop.yarn.api.protocolrecords.ReservationSubmissionRequest;
+import org.apache.hadoop.yarn.api.protocolrecords.ReservationSubmissionResponse;
+import org.apache.hadoop.yarn.api.protocolrecords.ReservationUpdateRequest;
+import org.apache.hadoop.yarn.api.records.ReservationACL;
+import org.apache.hadoop.yarn.api.records.ReservationId;
+import org.apache.hadoop.yarn.api.records.ReservationDefinition;
+import org.apache.hadoop.yarn.api.records.ReservationRequest;
+import org.apache.hadoop.yarn.api.records.ReservationRequestInterpreter;
+import org.apache.hadoop.yarn.api.records.ReservationRequests;
+import org.apache.hadoop.yarn.conf.YarnConfiguration;
+import org.apache.hadoop.yarn.event.DrainDispatcher;
+import org.apache.hadoop.yarn.exceptions.YarnException;
+import org.apache.hadoop.yarn.server.resourcemanager.reservation.Plan;
+import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler;
+import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacitySchedulerConfiguration;
+import org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler;
+import org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairSchedulerConfiguration;
+import org.apache.hadoop.yarn.server.utils.BuilderUtils;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class ReservationACLsTestBase extends ACLsTestBase {
+
+ private final int defaultDuration = 600000;
+ private final ReservationRequest defaultRequest = ReservationRequest
+ .newInstance(BuilderUtils.newResource(1024, 1), 1, 1,
+ defaultDuration);
+ private final ReservationRequests defaultRequests = ReservationRequests
+ .newInstance(Collections.singletonList(defaultRequest),
+ ReservationRequestInterpreter.R_ALL);
+ private Configuration configuration;
+ private boolean useFullQueuePath;
+
+ public ReservationACLsTestBase(Configuration conf, boolean useFullPath) {
+ configuration = conf;
+ useFullQueuePath = useFullPath;
+ }
+
+ @After
+ public void tearDown() {
+ if (resourceManager != null) {
+ resourceManager.stop();
+ }
+ }
+
+ @Parameterized.Parameters
+ public static Collection