private static void checkAccess(String remoteUser, Application application, Context context) throws YarnException { UserGroupInformation callerUGI = null; if (remoteUser != null) { callerUGI = UserGroupInformation.createRemoteUser(remoteUser); } if (callerUGI != null && !context.getApplicationACLsManager().checkAccess(callerUGI, ApplicationAccessType.VIEW_APP, application.getUser(), application.getAppId())) { throw new YarnException( "User [" + remoteUser + "] is not authorized to view the logs for application " + application.getAppId()); } }
private Map<ApplicationAccessType, String> createACLs(String submitter, boolean setupACLs) { AccessControlList viewACL = new AccessControlList(""); AccessControlList modifyACL = new AccessControlList(""); if (setupACLs) { viewACL.addUser(submitter); viewACL.addUser(COMMON_USER); modifyACL.addUser(submitter); modifyACL.addUser(COMMON_USER); } Map<ApplicationAccessType, String> acls = new HashMap<ApplicationAccessType, String>(); acls.put(ApplicationAccessType.VIEW_APP, viewACL.getAclString()); acls.put(ApplicationAccessType.MODIFY_APP, modifyACL.getAclString()); return acls; }
private void checkAppQueue(MockRM resourceManager, String user, String submissionQueue, String expected) throws Exception { RMApp app = resourceManager.submitApp(200, "name", user, new HashMap<ApplicationAccessType, String>(), false, submissionQueue, -1, null, "MAPREDUCE", false); RMAppState expectedState = expected.isEmpty() ? RMAppState.FAILED : RMAppState.ACCEPTED; resourceManager.waitForState(app.getApplicationId(), expectedState); // get scheduler app CapacityScheduler cs = (CapacityScheduler) resourceManager.getResourceScheduler(); SchedulerApplication schedulerApp = cs.getSchedulerApplications().get(app.getApplicationId()); String queue = ""; if (schedulerApp != null) { queue = schedulerApp.getQueue().getQueueName(); } Assert.assertTrue("expected " + expected + " actual " + queue, expected.equals(queue)); Assert.assertEquals(expected, app.getQueue()); }
private void checkAccess(ApplicationReportExt app) throws YarnException, IOException { if (app.appViewACLs != null) { aclsManager.addApplication( app.appReport.getApplicationId(), app.appViewACLs); try { if (!aclsManager.checkAccess(UserGroupInformation.getCurrentUser(), ApplicationAccessType.VIEW_APP, app.appReport.getUser(), app.appReport.getApplicationId())) { throw new AuthorizationException("User " + UserGroupInformation.getCurrentUser().getShortUserName() + " does not have privilage to see this application " + app.appReport.getApplicationId()); } } finally { aclsManager.removeApplication(app.appReport.getApplicationId()); } } }
/** * Get the single timeline entity that the given user has access to. The * meaning of each argument has been documented with * {@link TimelineReader#getEntity}. * * @see TimelineReader#getEntity */ public TimelineEntity getEntity( String entityType, String entityId, EnumSet<Field> fields, UserGroupInformation callerUGI) throws YarnException, IOException { TimelineEntity entity = null; entity = store.getEntity(entityId, entityType, fields); if (entity != null) { addDefaultDomainIdIfAbsent(entity); // check ACLs if (!timelineACLsManager.checkAccess( callerUGI, ApplicationAccessType.VIEW_APP, entity)) { entity = null; } } return entity; }
@Test public void testYarnACLsNotEnabledForEntity() throws Exception { Configuration conf = new YarnConfiguration(); conf.setBoolean(YarnConfiguration.YARN_ACL_ENABLE, false); TimelineACLsManager timelineACLsManager = new TimelineACLsManager(conf); timelineACLsManager.setTimelineStore(new TestTimelineStore()); TimelineEntity entity = new TimelineEntity(); entity.addPrimaryFilter( TimelineStore.SystemFilter.ENTITY_OWNER .toString(), "owner"); entity.setDomainId("domain_id_1"); Assert.assertTrue( "Always true when ACLs are not enabled", timelineACLsManager.checkAccess( UserGroupInformation.createRemoteUser("user"), ApplicationAccessType.VIEW_APP, entity)); Assert.assertTrue( "Always true when ACLs are not enabled", timelineACLsManager.checkAccess( UserGroupInformation.createRemoteUser("user"), ApplicationAccessType.MODIFY_APP, entity)); }
@Test public void testCorruptedOwnerInfoForEntity() 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); timelineACLsManager.setTimelineStore(new TestTimelineStore()); TimelineEntity entity = new TimelineEntity(); try { timelineACLsManager.checkAccess( UserGroupInformation.createRemoteUser("owner"), ApplicationAccessType.VIEW_APP, entity); Assert.fail("Exception is expected"); } catch (YarnException e) { Assert.assertTrue("It's not the exact expected exception", e.getMessage() .contains("doesn't exist.")); } }
private static void uploadContainerLogIntoRemoteDir(UserGroupInformation ugi, Configuration configuration, List<String> rootLogDirs, NodeId nodeId, ContainerId containerId, Path appDir, FileSystem fs) throws Exception { Path path = new Path(appDir, LogAggregationUtils.getNodeString(nodeId) + System.currentTimeMillis()); AggregatedLogFormat.LogWriter writer = new AggregatedLogFormat.LogWriter(configuration, path, ugi); writer.writeApplicationOwner(ugi.getUserName()); Map<ApplicationAccessType, String> appAcls = new HashMap<ApplicationAccessType, String>(); appAcls.put(ApplicationAccessType.VIEW_APP, ugi.getUserName()); writer.writeApplicationACLs(appAcls); writer.append(new AggregatedLogFormat.LogKey(containerId), new AggregatedLogFormat.LogValue(rootLogDirs, containerId, UserGroupInformation.getCurrentUser().getShortUserName())); writer.close(); }
private static void uploadEmptyContainerLogIntoRemoteDir(UserGroupInformation ugi, Configuration configuration, List<String> rootLogDirs, NodeId nodeId, ContainerId containerId, Path appDir, FileSystem fs) throws Exception { Path path = new Path(appDir, LogAggregationUtils.getNodeString(nodeId) + System.currentTimeMillis()); AggregatedLogFormat.LogWriter writer = new AggregatedLogFormat.LogWriter(configuration, path, ugi); writer.writeApplicationOwner(ugi.getUserName()); Map<ApplicationAccessType, String> appAcls = new HashMap<ApplicationAccessType, String>(); appAcls.put(ApplicationAccessType.VIEW_APP, ugi.getUserName()); writer.writeApplicationACLs(appAcls); DataOutputStream out = writer.getWriter().prepareAppendKey(-1); new AggregatedLogFormat.LogKey(containerId).write(out); out.close(); out = writer.getWriter().prepareAppendValue(-1); new AggregatedLogFormat.LogValue(rootLogDirs, containerId, UserGroupInformation.getCurrentUser().getShortUserName()).write(out, new HashSet<File>()); out.close(); writer.close(); }
@Private @Unstable public static RegisterApplicationMasterResponse newInstance( Resource minCapability, Resource maxCapability, Map<ApplicationAccessType, String> acls, ByteBuffer key, List<Container> containersFromPreviousAttempt, String queue, List<NMToken> nmTokensFromPreviousAttempts) { RegisterApplicationMasterResponse response = Records.newRecord(RegisterApplicationMasterResponse.class); response.setMaximumResourceCapability(maxCapability); response.setApplicationACLs(acls); response.setClientToAMTokenMasterKey(key); response.setContainersFromPreviousAttempts(containersFromPreviousAttempt); response.setNMTokensFromPreviousAttempts(nmTokensFromPreviousAttempts); response.setQueue(queue); return response; }
private TimelineEntity doGetEntity( String entityType, String entityId, EnumSet<Field> fields, UserGroupInformation callerUGI) throws YarnException, IOException { TimelineEntity entity = null; entity = store.getEntity(entityId, entityType, fields); if (entity != null) { addDefaultDomainIdIfAbsent(entity); // check ACLs if (!timelineACLsManager.checkAccess( callerUGI, ApplicationAccessType.VIEW_APP, entity)) { entity = null; } } return entity; }
private void initApplicationACLs() { if (this.applicationACLS != null) { return; } RegisterApplicationMasterResponseProtoOrBuilder p = viaProto ? proto : builder; List<ApplicationACLMapProto> list = p.getApplicationACLsList(); this.applicationACLS = new HashMap<ApplicationAccessType, String>(list .size()); for (ApplicationACLMapProto aclProto : list) { this.applicationACLS.put(ProtoUtils.convertFromProtoFormat(aclProto .getAccessType()), aclProto.getAcl()); } }
private void addApplicationACLs() { maybeInitBuilder(); builder.clearApplicationACLs(); if (applicationACLS == null) { return; } Iterable<? extends ApplicationACLMapProto> values = new Iterable<ApplicationACLMapProto>() { @Override public Iterator<ApplicationACLMapProto> iterator() { return new Iterator<ApplicationACLMapProto>() { Iterator<ApplicationAccessType> aclsIterator = applicationACLS .keySet().iterator(); @Override public boolean hasNext() { return aclsIterator.hasNext(); } @Override public ApplicationACLMapProto next() { ApplicationAccessType key = aclsIterator.next(); return ApplicationACLMapProto.newBuilder().setAcl( applicationACLS.get(key)).setAccessType( ProtoUtils.convertToProtoFormat(key)).build(); } @Override public void remove() { throw new UnsupportedOperationException(); } }; } }; this.builder.addAllApplicationACLs(values); }
@Override public void setApplicationACLs( final Map<ApplicationAccessType, String> appACLs) { if (appACLs == null) return; initApplicationACLs(); this.applicationACLS.clear(); this.applicationACLS.putAll(appACLs); }
private void initApplicationACLs() { if (this.applicationACLS != null) { return; } ContainerLaunchContextProtoOrBuilder p = viaProto ? proto : builder; List<ApplicationACLMapProto> list = p.getApplicationACLsList(); this.applicationACLS = new HashMap<ApplicationAccessType, String>(list .size()); for (ApplicationACLMapProto aclProto : list) { this.applicationACLS.put(ProtoUtils.convertFromProtoFormat(aclProto .getAccessType()), aclProto.getAcl()); } }
public void addApplication(ApplicationId appId, Map<ApplicationAccessType, String> acls) { Map<ApplicationAccessType, AccessControlList> finalMap = new HashMap<ApplicationAccessType, AccessControlList>(acls.size()); for (Entry<ApplicationAccessType, String> acl : acls.entrySet()) { finalMap.put(acl.getKey(), new AccessControlList(acl.getValue())); } this.applicationACLS.put(appId, finalMap); }
public void writeApplicationACLs(Map<ApplicationAccessType, String> appAcls) throws IOException { DataOutputStream out = this.writer.prepareAppendKey(-1); APPLICATION_ACL_KEY.write(out); out.close(); out = this.writer.prepareAppendValue(-1); for (Entry<ApplicationAccessType, String> entry : appAcls.entrySet()) { out.writeUTF(entry.getKey().toString()); out.writeUTF(entry.getValue()); } out.close(); }
@Test public void testCheckAccessWithNullACLS() { Configuration conf = new Configuration(); conf.setBoolean(YarnConfiguration.YARN_ACL_ENABLE, true); conf.set(YarnConfiguration.YARN_ADMIN_ACL, ADMIN_USER); ApplicationACLsManager aclManager = new ApplicationACLsManager(conf); UserGroupInformation appOwner = UserGroupInformation .createRemoteUser(APP_OWNER); ApplicationId appId = ApplicationId.newInstance(1, 1); //Application ACL is not added //Application Owner should have all access even if Application ACL is not added assertTrue(aclManager.checkAccess(appOwner, ApplicationAccessType.MODIFY_APP, APP_OWNER, appId)); assertTrue(aclManager.checkAccess(appOwner, ApplicationAccessType.VIEW_APP, APP_OWNER, appId)); //Admin should have all access UserGroupInformation adminUser = UserGroupInformation .createRemoteUser(ADMIN_USER); assertTrue(aclManager.checkAccess(adminUser, ApplicationAccessType.VIEW_APP, APP_OWNER, appId)); assertTrue(aclManager.checkAccess(adminUser, ApplicationAccessType.MODIFY_APP, APP_OWNER, appId)); // A regular user should Not have access UserGroupInformation testUser1 = UserGroupInformation .createRemoteUser(TESTUSER1); assertFalse(aclManager.checkAccess(testUser1, ApplicationAccessType.VIEW_APP, APP_OWNER, appId)); assertFalse(aclManager.checkAccess(testUser1, ApplicationAccessType.MODIFY_APP, APP_OWNER, appId)); }
private void writeLog(Configuration configuration, String user) throws Exception { ApplicationId appId = ApplicationIdPBImpl.newInstance(0, 1); ApplicationAttemptId appAttemptId = ApplicationAttemptIdPBImpl.newInstance(appId, 1); ContainerId containerId = ContainerIdPBImpl.newContainerId(appAttemptId, 1); String path = "target/logs/" + user + "/logs/application_0_0001/localhost_1234"; File f = new File(path); if (!f.getParentFile().exists()) { assertTrue(f.getParentFile().mkdirs()); } List<String> rootLogDirs = Arrays.asList("target/logs/logs"); UserGroupInformation ugi = UserGroupInformation.getCurrentUser(); AggregatedLogFormat.LogWriter writer = new AggregatedLogFormat.LogWriter( configuration, new Path(path), ugi); writer.writeApplicationOwner(ugi.getUserName()); Map<ApplicationAccessType, String> appAcls = new HashMap<ApplicationAccessType, String>(); appAcls.put(ApplicationAccessType.VIEW_APP, ugi.getUserName()); writer.writeApplicationACLs(appAcls); writer.append(new AggregatedLogFormat.LogKey("container_0_0001_01_000001"), new AggregatedLogFormat.LogValue(rootLogDirs, containerId,UserGroupInformation.getCurrentUser().getShortUserName())); writer.close(); }
public static ContainerLaunchContext newContainerLaunchContext( Map<String, LocalResource> localResources, Map<String, String> environment, List<String> commands, Map<String, ByteBuffer> serviceData, ByteBuffer tokens, Map<ApplicationAccessType, String> acls) { ContainerLaunchContext container = recordFactory .newRecordInstance(ContainerLaunchContext.class); container.setLocalResources(localResources); container.setEnvironment(environment); container.setCommands(commands); container.setServiceData(serviceData); container.setTokens(tokens); container.setApplicationACLs(acls); return container; }
public ApplicationInitEvent(ApplicationId appId, Map<ApplicationAccessType, String> acls, LogAggregationContext logAggregationContext) { super(appId, ApplicationEventType.INIT_APPLICATION); this.applicationACLs = acls; this.logAggregationContext = logAggregationContext; }
public LogHandlerAppStartedEvent(ApplicationId appId, String user, Credentials credentials, ContainerLogsRetentionPolicy retentionPolicy, Map<ApplicationAccessType, String> appAcls, LogAggregationContext logAggregationContext) { super(LogHandlerEventType.APPLICATION_STARTED); this.applicationId = appId; this.user = user; this.credentials = credentials; this.retentionPolicy = retentionPolicy; this.appAcls = appAcls; this.logAggregationContext = logAggregationContext; }
private ContainerManagerApplicationProto buildAppProto(ApplicationId appId, String user, Credentials credentials, Map<ApplicationAccessType, String> appAcls, LogAggregationContext logAggregationContext) { ContainerManagerApplicationProto.Builder builder = ContainerManagerApplicationProto.newBuilder(); builder.setId(((ApplicationIdPBImpl) appId).getProto()); builder.setUser(user); if (logAggregationContext != null) { builder.setLogAggregationContext(( (LogAggregationContextPBImpl)logAggregationContext).getProto()); } builder.clearCredentials(); if (credentials != null) { DataOutputBuffer dob = new DataOutputBuffer(); try { credentials.writeTokenStorageToStream(dob); builder.setCredentials(ByteString.copyFrom(dob.getData())); } catch (IOException e) { // should not occur LOG.error("Cannot serialize credentials", e); } } builder.clearAcls(); if (appAcls != null) { for (Map.Entry<ApplicationAccessType, String> acl : appAcls.entrySet()) { ApplicationACLMapProto p = ApplicationACLMapProto.newBuilder() .setAccessType(ProtoUtils.convertToProtoFormat(acl.getKey())) .setAcl(acl.getValue()) .build(); builder.addAcls(p); } } return builder.build(); }
private Container createMockedContainer(ApplicationId appId, int containerId) { ApplicationAttemptId appAttemptId = BuilderUtils.newApplicationAttemptId(appId, 1); ContainerId cId = BuilderUtils.newContainerId(appAttemptId, containerId); Container c = mock(Container.class); when(c.getContainerId()).thenReturn(cId); ContainerLaunchContext launchContext = mock(ContainerLaunchContext.class); when(c.getLaunchContext()).thenReturn(launchContext); when(launchContext.getApplicationACLs()).thenReturn( new HashMap<ApplicationAccessType, String>()); return c; }
private void verifyAcls(Map<ApplicationAccessType, String> logAcls) { Assert.assertEquals(this.acls.size(), logAcls.size()); for (ApplicationAccessType appAccessType : this.acls.keySet()) { Assert.assertEquals(this.acls.get(appAccessType), logAcls.get(appAccessType)); } }
private Map<ApplicationAccessType, String> createAppAcls() { Map<ApplicationAccessType, String> appAcls = new HashMap<ApplicationAccessType, String>(); appAcls.put(ApplicationAccessType.MODIFY_APP, "user group"); appAcls.put(ApplicationAccessType.VIEW_APP, "*"); return appAcls; }
protected Boolean hasAccess(RMApp app, HttpServletRequest hsr) { // Check for the authorization. UserGroupInformation callerUGI = getCallerUserGroupInformation(hsr, true); if (callerUGI != null && !(this.rm.getApplicationACLsManager().checkAccess(callerUGI, ApplicationAccessType.VIEW_APP, app.getUser(), app.getApplicationId()) || this.rm.getQueueACLsManager().checkAccess(callerUGI, QueueACL.ADMINISTER_QUEUE, app.getQueue()))) { return false; } return true; }
public ContainerLaunchContextInfo() { local_resources = new HashMap<String, LocalResourceInfo>(); environment = new HashMap<String, String>(); commands = new ArrayList<String>(); servicedata = new HashMap<String, String>(); credentials = new CredentialsInfo(); acls = new HashMap<ApplicationAccessType, String>(); }
/** * check if the calling user has the access to application information. * @param callerUGI * @param owner * @param operationPerformed * @param application * @return */ private boolean checkAccess(UserGroupInformation callerUGI, String owner, ApplicationAccessType operationPerformed, RMApp application) { return applicationsACLsManager.checkAccess(callerUGI, operationPerformed, owner, application.getApplicationId()) || queueACLsManager.checkAccess(callerUGI, QueueACL.ADMINISTER_QUEUE, application.getQueue()); }
/** * It gives response which includes application report if the application * present otherwise throws ApplicationNotFoundException. */ @Override public GetApplicationReportResponse getApplicationReport( GetApplicationReportRequest request) throws YarnException { ApplicationId applicationId = request.getApplicationId(); UserGroupInformation callerUGI; try { callerUGI = UserGroupInformation.getCurrentUser(); } catch (IOException ie) { LOG.info("Error getting UGI ", ie); throw RPCUtil.getRemoteException(ie); } RMApp application = this.rmContext.getRMApps().get(applicationId); if (application == null) { // If the RM doesn't have the application, throw // ApplicationNotFoundException and let client to handle. throw new ApplicationNotFoundException("Application with id '" + applicationId + "' doesn't exist in RM."); } boolean allowAccess = checkAccess(callerUGI, application.getUser(), ApplicationAccessType.VIEW_APP, application); ApplicationReport report = application.createAndGetApplicationReport(callerUGI.getUserName(), allowAccess); GetApplicationReportResponse response = recordFactory .newRecordInstance(GetApplicationReportResponse.class); response.setApplicationReport(report); return response; }