diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java index a6d3360..0946fbc 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java @@ -309,6 +309,12 @@ public static boolean isAclEnabled(Configuration conf) { public static final String YARN_ADMIN_ACL = YARN_PREFIX + "admin.acl"; public static final String DEFAULT_YARN_ADMIN_ACL = "*"; + + // ACL of who can be viewer of YARN cluster, + // it has all application view permissions. + public static final String YARN_VIEWER_ACL = + YARN_PREFIX + "viewer.acl"; + public static final String DEFAULT_YARN_VIEWER_ACL = "*"; /** ACL used in case none is found. Allows nothing. */ public static final String DEFAULT_YARN_APP_ACL = " "; diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/server/security/ApplicationACLsManager.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/server/security/ApplicationACLsManager.java index 97b4163..572657b 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/server/security/ApplicationACLsManager.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/server/security/ApplicationACLsManager.java @@ -46,6 +46,7 @@ private static AccessControlList DEFAULT_YARN_APP_ACL = new AccessControlList(YarnConfiguration.DEFAULT_YARN_APP_ACL); private final Configuration conf; + private static AccessControlList viewerACL; private final AdminACLsManager adminAclsManager; private final ConcurrentMap> applicationACLS = new ConcurrentHashMap>(); @@ -57,6 +58,9 @@ public ApplicationACLsManager() { public ApplicationACLsManager(Configuration conf) { this.conf = conf; + viewerACL = new AccessControlList( + conf.get(YarnConfiguration.YARN_VIEWER_ACL, + YarnConfiguration.DEFAULT_YARN_VIEWER_ACL)); this.adminAclsManager = new AdminACLsManager(this.conf); } @@ -108,6 +112,10 @@ public boolean checkAccess(UserGroupInformation callerUGI, if (!areACLsEnabled()) { return true; } + if (applicationAccessType.equals(ApplicationAccessType.VIEW_APP) + && viewerACL.isUserAllowed(callerUGI)) { + return true; + } AccessControlList applicationACL = DEFAULT_YARN_APP_ACL; Map acls = this.applicationACLS .get(applicationId); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/server/security/TestApplicationACLsManager.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/server/security/TestApplicationACLsManager.java index 2db1da9..dd0366a 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/server/security/TestApplicationACLsManager.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/server/security/TestApplicationACLsManager.java @@ -33,6 +33,7 @@ public class TestApplicationACLsManager { private static final String ADMIN_USER = "adminuser"; + private static final String VIEWER = "viewer"; private static final String APP_OWNER = "appuser"; private static final String TESTUSER1 = "testuser1"; private static final String TESTUSER2 = "testuser2"; @@ -45,6 +46,8 @@ public void testCheckAccess() { true); conf.set(YarnConfiguration.YARN_ADMIN_ACL, ADMIN_USER); + conf.set(YarnConfiguration.YARN_VIEWER_ACL, + VIEWER); ApplicationACLsManager aclManager = new ApplicationACLsManager(conf); Map aclMap = new HashMap(); @@ -92,6 +95,21 @@ public void testCheckAccess() { APP_OWNER, appId)); assertTrue(aclManager.checkAccess(adminUser, ApplicationAccessType.MODIFY_APP, APP_OWNER, appId)); + + // viewer has view access, but not modify access + UserGroupInformation viewer = UserGroupInformation + .createRemoteUser(VIEWER); + assertTrue(aclManager.checkAccess(viewer, ApplicationAccessType.VIEW_APP, + APP_OWNER, appId)); + assertFalse(aclManager.checkAccess(viewer, ApplicationAccessType.MODIFY_APP, + APP_OWNER, appId)); + + // all user has view access. + conf.set(YarnConfiguration.YARN_VIEWER_ACL, + YarnConfiguration.DEFAULT_YARN_VIEWER_ACL); + aclManager = new ApplicationACLsManager(conf); + assertTrue(aclManager.checkAccess(testUser2, + ApplicationAccessType.VIEW_APP, APP_OWNER, appId)); } @Test @@ -101,6 +119,8 @@ public void testCheckAccessWithNullACLS() { true); conf.set(YarnConfiguration.YARN_ADMIN_ACL, ADMIN_USER); + conf.set(YarnConfiguration.YARN_VIEWER_ACL, + VIEWER); ApplicationACLsManager aclManager = new ApplicationACLsManager(conf); UserGroupInformation appOwner = UserGroupInformation .createRemoteUser(APP_OWNER); @@ -137,6 +157,8 @@ public void testCheckAccessWithPartialACLS() { true); conf.set(YarnConfiguration.YARN_ADMIN_ACL, ADMIN_USER); + conf.set(YarnConfiguration.YARN_VIEWER_ACL, + VIEWER); ApplicationACLsManager aclManager = new ApplicationACLsManager(conf); UserGroupInformation appOwner = UserGroupInformation .createRemoteUser(APP_OWNER);