YARN-2059. Added admin ACLs support to Timeline Server. Contributed by Zhijie Shen.

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1597207 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Vinod Kumar Vavilapalli 2014-05-23 22:40:52 +00:00
parent 6c56612af5
commit 7f0724dddb
5 changed files with 49 additions and 22 deletions

View File

@ -102,6 +102,9 @@ Release 2.5.0 - UNRELEASED
YARN-2012. Fair Scheduler: allow default queue placement rule to take an
arbitrary queue (Ashwin Shankar via Sandy Ryza)
YARN-2059. Added admin ACLs support to Timeline Server. (Zhijie Shen via
vinodkv)
OPTIMIZATIONS
BUG FIXES

View File

@ -27,8 +27,8 @@ import org.apache.hadoop.classification.InterfaceAudience.Private;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.yarn.api.records.timeline.TimelineEntity;
import org.apache.hadoop.yarn.conf.YarnConfiguration;
import org.apache.hadoop.yarn.exceptions.YarnException;
import org.apache.hadoop.yarn.security.AdminACLsManager;
import org.apache.hadoop.yarn.server.applicationhistoryservice.timeline.EntityIdentifier;
import org.apache.hadoop.yarn.server.applicationhistoryservice.timeline.TimelineStore.SystemFilter;
@ -42,11 +42,10 @@ public class TimelineACLsManager {
private static final Log LOG = LogFactory.getLog(TimelineACLsManager.class);
private boolean aclsEnabled;
private AdminACLsManager adminAclsManager;
public TimelineACLsManager(Configuration conf) {
aclsEnabled = conf.getBoolean(YarnConfiguration.YARN_ACL_ENABLE,
YarnConfiguration.DEFAULT_YARN_ACL_ENABLE);
this.adminAclsManager = new AdminACLsManager(conf);
}
public boolean checkAccess(UserGroupInformation callerUGI,
@ -57,7 +56,7 @@ public class TimelineACLsManager {
+ new EntityIdentifier(entity.getEntityId(), entity.getEntityType()));
}
if (!aclsEnabled) {
if (!adminAclsManager.areACLsEnabled()) {
return true;
}
@ -70,10 +69,12 @@ public class TimelineACLsManager {
+ " is corrupted.");
}
String owner = values.iterator().next().toString();
// TODO: Currently we just check the user is the timeline entity owner. In
// the future, we need to check whether the user is admin or is in the
// TODO: Currently we just check the user is the admin or the timeline
// entity owner. In the future, we need to check whether the user is in the
// allowed user/group list
if (callerUGI != null && callerUGI.getShortUserName().equals(owner)) {
if (callerUGI != null
&& (adminAclsManager.isAdmin(callerUGI) ||
callerUGI.getShortUserName().equals(owner))) {
return true;
}
return false;
@ -81,8 +82,11 @@ public class TimelineACLsManager {
@Private
@VisibleForTesting
public void setACLsEnabled(boolean aclsEnabled) {
this.aclsEnabled = aclsEnabled;
public AdminACLsManager
setAdminACLsManager(AdminACLsManager adminAclsManager) {
AdminACLsManager oldAdminACLsManager = this.adminAclsManager;
this.adminAclsManager = adminAclsManager;
return oldAdminACLsManager;
}
}

View File

@ -346,8 +346,9 @@ public class TimelineWebServices {
new EntityIdentifier(entity.getEntityId(), entity.getEntityType());
// check if there is existing entity
TimelineEntity existingEntity = null;
try {
TimelineEntity existingEntity =
existingEntity =
store.getEntity(entityID.getId(), entityID.getType(),
EnumSet.of(Field.PRIMARY_FILTERS));
if (existingEntity != null
@ -369,10 +370,14 @@ public class TimelineWebServices {
continue;
}
// inject owner information for the access check
// inject owner information for the access check if this is the first
// time to post the entity, in case it's the admin who is updating
// the timeline data.
try {
injectOwnerInfo(entity,
callerUGI == null ? "" : callerUGI.getShortUserName());
if (existingEntity == null) {
injectOwnerInfo(entity,
callerUGI == null ? "" : callerUGI.getShortUserName());
}
} catch (YarnException e) {
// Skip the entity which messes up the primary filter and record the
// error

View File

@ -49,6 +49,7 @@ public class TestTimelineACLsManager {
public void testYarnACLsEnabled() throws Exception {
Configuration conf = new YarnConfiguration();
conf.setBoolean(YarnConfiguration.YARN_ACL_ENABLE, true);
conf.set(YarnConfiguration.YARN_ADMIN_ACL, "admin");
TimelineACLsManager timelineACLsManager =
new TimelineACLsManager(conf);
TimelineEntity entity = new TimelineEntity();
@ -63,12 +64,17 @@ public class TestTimelineACLsManager {
"Other shouldn't be allowed to access",
timelineACLsManager.checkAccess(
UserGroupInformation.createRemoteUser("other"), entity));
Assert.assertTrue(
"Admin should be allowed to access",
timelineACLsManager.checkAccess(
UserGroupInformation.createRemoteUser("admin"), entity));
}
@Test
public void testCorruptedOwnerInfo() throws Exception {
Configuration conf = new YarnConfiguration();
conf.setBoolean(YarnConfiguration.YARN_ACL_ENABLE, true);
conf.set(YarnConfiguration.YARN_ADMIN_ACL, "owner");
TimelineACLsManager timelineACLsManager =
new TimelineACLsManager(conf);
TimelineEntity entity = new TimelineEntity();

View File

@ -40,6 +40,7 @@ import org.apache.hadoop.yarn.api.records.timeline.TimelineEvent;
import org.apache.hadoop.yarn.api.records.timeline.TimelineEvents;
import org.apache.hadoop.yarn.api.records.timeline.TimelinePutResponse;
import org.apache.hadoop.yarn.conf.YarnConfiguration;
import org.apache.hadoop.yarn.security.AdminACLsManager;
import org.apache.hadoop.yarn.server.applicationhistoryservice.timeline.TestMemoryTimelineStore;
import org.apache.hadoop.yarn.server.applicationhistoryservice.timeline.TimelineStore;
import org.apache.hadoop.yarn.server.applicationhistoryservice.timeline.security.TimelineACLsManager;
@ -64,6 +65,7 @@ public class TestTimelineWebServices extends JerseyTest {
private static TimelineStore store;
private static TimelineACLsManager timelineACLsManager;
private static AdminACLsManager adminACLsManager;
private static String remoteUser;
private long beforeTime;
@ -83,6 +85,9 @@ public class TestTimelineWebServices extends JerseyTest {
Configuration conf = new YarnConfiguration();
conf.setBoolean(YarnConfiguration.YARN_ACL_ENABLE, false);
timelineACLsManager = new TimelineACLsManager(conf);
conf.setBoolean(YarnConfiguration.YARN_ACL_ENABLE, true);
conf.set(YarnConfiguration.YARN_ADMIN_ACL, "admin");
adminACLsManager = new AdminACLsManager(conf);
bind(TimelineACLsManager.class).toInstance(timelineACLsManager);
serve("/*").with(GuiceContainer.class);
filter("/*").through(TestFilter.class);
@ -387,7 +392,8 @@ public class TestTimelineWebServices extends JerseyTest {
@Test
public void testPostEntitiesWithYarnACLsEnabled() throws Exception {
timelineACLsManager.setACLsEnabled(true);
AdminACLsManager oldAdminACLsManager =
timelineACLsManager.setAdminACLsManager(adminACLsManager);
remoteUser = "tester";
try {
TimelineEntities entities = new TimelineEntities();
@ -419,14 +425,15 @@ public class TestTimelineWebServices extends JerseyTest {
Assert.assertEquals(TimelinePutResponse.TimelinePutError.ACCESS_DENIED,
putResponse.getErrors().get(0).getErrorCode());
} finally {
timelineACLsManager.setACLsEnabled(false);
timelineACLsManager.setAdminACLsManager(oldAdminACLsManager);
remoteUser = null;
}
}
@Test
public void testGetEntityWithYarnACLsEnabled() throws Exception {
timelineACLsManager.setACLsEnabled(true);
AdminACLsManager oldAdminACLsManager =
timelineACLsManager.setAdminACLsManager(adminACLsManager);
remoteUser = "tester";
try {
TimelineEntities entities = new TimelineEntities();
@ -481,14 +488,15 @@ public class TestTimelineWebServices extends JerseyTest {
assertEquals(ClientResponse.Status.NOT_FOUND,
response.getClientResponseStatus());
} finally {
timelineACLsManager.setACLsEnabled(false);
timelineACLsManager.setAdminACLsManager(oldAdminACLsManager);
remoteUser = null;
}
}
@Test
public void testGetEntitiesWithYarnACLsEnabled() {
timelineACLsManager.setACLsEnabled(true);
AdminACLsManager oldAdminACLsManager =
timelineACLsManager.setAdminACLsManager(adminACLsManager);
remoteUser = "tester";
try {
TimelineEntities entities = new TimelineEntities();
@ -526,14 +534,15 @@ public class TestTimelineWebServices extends JerseyTest {
assertEquals("test type 4", entities.getEntities().get(0).getEntityType());
assertEquals("test id 5", entities.getEntities().get(0).getEntityId());
} finally {
timelineACLsManager.setACLsEnabled(false);
timelineACLsManager.setAdminACLsManager(oldAdminACLsManager);
remoteUser = null;
}
}
@Test
public void testGetEventsWithYarnACLsEnabled() {
timelineACLsManager.setACLsEnabled(true);
AdminACLsManager oldAdminACLsManager =
timelineACLsManager.setAdminACLsManager(adminACLsManager);
remoteUser = "tester";
try {
TimelineEntities entities = new TimelineEntities();
@ -579,7 +588,7 @@ public class TestTimelineWebServices extends JerseyTest {
assertEquals(1, events.getAllEvents().size());
assertEquals("test id 6", events.getAllEvents().get(0).getEntityId());
} finally {
timelineACLsManager.setACLsEnabled(false);
timelineACLsManager.setAdminACLsManager(oldAdminACLsManager);
remoteUser = null;
}
}