public boolean checkAccess(UserGroupInformation callerUGI, TimelineDomain domain) throws YarnException, IOException { if (LOG.isDebugEnabled()) { LOG.debug("Verifying the access of " + (callerUGI == null ? null : callerUGI.getShortUserName()) + " on the timeline domain " + domain); } if (!adminAclsManager.areACLsEnabled()) { return true; } String owner = domain.getOwner(); if (owner == null || owner.length() == 0) { throw new YarnException("Owner information of the timeline domain " + domain.getId() + " is corrupted."); } if (callerUGI != null && (adminAclsManager.isAdmin(callerUGI) || callerUGI.getShortUserName().equals(owner))) { return true; } return false; }
@Override public TimelineDomain getDomain(String domainId) throws IOException { TimelineDomain domain = domainsById.get(domainId); if (domain == null) { return null; } else { return createTimelineDomain( domain.getId(), domain.getDescription(), domain.getOwner(), domain.getReaders(), domain.getWriters(), domain.getCreatedTime(), domain.getModifiedTime()); } }
public void put(TimelineDomain domain) throws IOException { TimelineDomain domainToReplace = domainsById.get(domain.getId()); Long currentTimestamp = System.currentTimeMillis(); TimelineDomain domainToStore = createTimelineDomain( domain.getId(), domain.getDescription(), domain.getOwner(), domain.getReaders(), domain.getWriters(), (domainToReplace == null ? currentTimestamp : domainToReplace.getCreatedTime()), currentTimestamp); domainsById.put(domainToStore.getId(), domainToStore); Set<TimelineDomain> domainsByOneOwner = domainsByOwner.get(domainToStore.getOwner()); if (domainsByOneOwner == null) { domainsByOneOwner = new HashSet<TimelineDomain>(); domainsByOwner.put(domainToStore.getOwner(), domainsByOneOwner); } if (domainToReplace != null) { domainsByOneOwner.remove(domainToReplace); } domainsByOneOwner.add(domainToStore); }
/** * Add or update an domain. If the domain already exists, only the owner * and the admin can update it. */ public void putDomain(TimelineDomain domain, UserGroupInformation callerUGI) throws YarnException, IOException { TimelineDomain existingDomain = store.getDomain(domain.getId()); if (existingDomain != null) { if (!timelineACLsManager.checkAccess(callerUGI, existingDomain)) { throw new YarnException(callerUGI.getShortUserName() + " is not allowed to override an existing domain " + existingDomain.getId()); } // Set it again in case ACLs are not enabled: The domain can be // modified by every body, but the owner is not changed. domain.setOwner(existingDomain.getOwner()); } store.put(domain); // If the domain exists already, it is likely to be in the cache. // We need to invalidate it. if (existingDomain != null) { timelineACLsManager.replaceIfExist(domain); } }
@Test public void testPutDomains() throws Exception { KerberosTestUtils.doAs(HTTP_USER + "/localhost", new Callable<Void>() { @Override public Void call() throws Exception { TimelineClient client = createTimelineClientForUGI(); TimelineDomain domainToStore = new TimelineDomain(); domainToStore.setId(TestTimelineAuthenticationFilter.class.getName()); domainToStore.setReaders("*"); domainToStore.setWriters("*"); client.putDomain(domainToStore); TimelineDomain domainToRead = testTimelineServer.getTimelineStore().getDomain( TestTimelineAuthenticationFilter.class.getName()); Assert.assertNotNull(domainToRead); return null; } }); }
@Test public void testYarnACLsEnabledForDomain() 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); TimelineDomain domain = new TimelineDomain(); domain.setOwner("owner"); Assert.assertTrue( "Owner should be allowed to access", timelineACLsManager.checkAccess( UserGroupInformation.createRemoteUser("owner"), domain)); Assert.assertFalse( "Other shouldn't be allowed to access", timelineACLsManager.checkAccess( UserGroupInformation.createRemoteUser("other"), domain)); Assert.assertTrue( "Admin should be allowed to access", timelineACLsManager.checkAccess( UserGroupInformation.createRemoteUser("admin"), domain)); }
@Test public void testCorruptedOwnerInfoForDomain() 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); TimelineDomain domain = new TimelineDomain(); try { timelineACLsManager.checkAccess( UserGroupInformation.createRemoteUser("owner"), domain); Assert.fail("Exception is expected"); } catch (YarnException e) { Assert.assertTrue("It's not the exact expected exception", e.getMessage() .contains("is corrupted.")); } }
public void testGetDomain() throws IOException { TimelineDomain actualDomain1 = store.getDomain(domain1.getId()); verifyDomainInfo(domain1, actualDomain1); assertTrue(actualDomain1.getCreatedTime() > 0); assertTrue(actualDomain1.getModifiedTime() > 0); assertEquals( actualDomain1.getCreatedTime(), actualDomain1.getModifiedTime()); TimelineDomain actualDomain2 = store.getDomain(domain2.getId()); verifyDomainInfo(domain2, actualDomain2); assertEquals("domain_id_2", actualDomain2.getId()); assertTrue(actualDomain2.getCreatedTime() > 0); assertTrue(actualDomain2.getModifiedTime() > 0); assertTrue( actualDomain2.getCreatedTime() < actualDomain2.getModifiedTime()); }
public void writeDomainLog(FileSystem fs, Path logPath, ObjectMapper objMapper, TimelineDomain domain, boolean isAppendSupported) throws IOException { try { this.domainFDLocker.lock(); if (this.domainLogFD != null) { this.domainLogFD.writeDomain(domain); } else { this.domainLogFD = new DomainLogFD(fs, logPath, objMapper, isAppendSupported); this.domainLogFD.writeDomain(domain); } } finally { this.domainFDLocker.unlock(); } }
@Test public void testPutDomain() { ApplicationId appId = ApplicationId.newInstance(System.currentTimeMillis(), 1); ApplicationAttemptId attemptId1 = ApplicationAttemptId.newInstance(appId, 1); try { TimelineDomain domain = generateDomain(); client.putDomain(null, domain); verify(spyTimelineWriter, times(1)).putDomain(domain); reset(spyTimelineWriter); client.putDomain(attemptId1, domain); verify(spyTimelineWriter, times(0)).putDomain(domain); Assert.assertTrue(localFS.util().exists( new Path(getAppAttemptDir(attemptId1), "domainlog-" + attemptId1.toString()))); reset(spyTimelineWriter); } catch (Exception e) { Assert.fail("Exception is not expected." + e); } }
private void doPutDomain(TimelineDomain domain, UserGroupInformation callerUGI) throws YarnException, IOException { TimelineDomain existingDomain = store.getDomain(domain.getId()); if (existingDomain != null) { if (!timelineACLsManager.checkAccess(callerUGI, existingDomain)) { throw new YarnException(callerUGI.getShortUserName() + " is not allowed to override an existing domain " + existingDomain.getId()); } // Set it again in case ACLs are not enabled: The domain can be // modified by every body, but the owner is not changed. domain.setOwner(existingDomain.getOwner()); } store.put(domain); // If the domain exists already, it is likely to be in the cache. // We need to invalidate it. if (existingDomain != null) { timelineACLsManager.replaceIfExist(domain); } }
public void put(TimelineDomain domain) throws IOException { TimelineDomain domainToReplace = domainsById.get(domain.getId()); long currentTimestamp = System.currentTimeMillis(); TimelineDomain domainToStore = createTimelineDomain( domain.getId(), domain.getDescription(), domain.getOwner(), domain.getReaders(), domain.getWriters(), (domainToReplace == null ? currentTimestamp : domainToReplace.getCreatedTime()), currentTimestamp); domainsById.put(domainToStore.getId(), domainToStore); Set<TimelineDomain> domainsByOneOwner = domainsByOwner.get(domainToStore.getOwner()); if (domainsByOneOwner == null) { domainsByOneOwner = new HashSet<TimelineDomain>(); domainsByOwner.put(domainToStore.getOwner(), domainsByOneOwner); } if (domainToReplace != null) { domainsByOneOwner.remove(domainToReplace); } domainsByOneOwner.add(domainToStore); }
@Test public void testPutDomains() throws Exception { KerberosTestUtils.doAs(HTTP_USER + "/localhost", new Callable<Void>() { @Override public Void call() throws Exception { TimelineDomain domainToStore = new TimelineDomain(); domainToStore.setId(TestTimelineAuthenticationFilter.class.getName()); domainToStore.setReaders("*"); domainToStore.setWriters("*"); client.putDomain(domainToStore); TimelineDomain domainToRead = testTimelineServer.getTimelineStore().getDomain( TestTimelineAuthenticationFilter.class.getName()); Assert.assertNotNull(domainToRead); return null; } }); }
public void writeDomainLog(FileSystem fs, Path logPath, ObjectMapper objMapper, TimelineDomain domain, boolean isAppendSupported) throws IOException { checkAndStartTimeTasks(); try { this.domainFDLocker.lock(); if (this.domainLogFD != null) { this.domainLogFD.writeDomain(domain); } else { this.domainLogFD = new DomainLogFD(fs, logPath, objMapper, isAppendSupported); this.domainLogFD.writeDomain(domain); } } finally { this.domainFDLocker.unlock(); } }
@Before public void setup() throws Exception { config.set(MiniDFSCluster.HDFS_MINIDFS_BASEDIR, TEST_ROOT_DIR.toString()); HdfsConfiguration hdfsConfig = new HdfsConfiguration(); hdfsCluster = new MiniDFSCluster.Builder(hdfsConfig).numDataNodes(1).build(); fs = hdfsCluster.getFileSystem(); fc = FileContext.getFileContext(hdfsCluster.getURI(0), config); Path testAppDirPath = getTestRootPath(TEST_ATTEMPT_DIR_NAME); fs.mkdirs(testAppDirPath, new FsPermission(FILE_LOG_DIR_PERMISSIONS)); objMapper = PluginStoreTestUtils.createObjectMapper(); TimelineEntities testEntities = PluginStoreTestUtils.generateTestEntities(); writeEntitiesLeaveOpen(testEntities, new Path(testAppDirPath, TEST_ENTITY_FILE_NAME)); testDomain = new TimelineDomain(); testDomain.setId("domain_1"); testDomain.setReaders(UserGroupInformation.getLoginUser().getUserName()); testDomain.setOwner(UserGroupInformation.getLoginUser().getUserName()); testDomain.setDescription("description"); writeDomainLeaveOpen(testDomain, new Path(testAppDirPath, TEST_DOMAIN_FILE_NAME)); writeBrokenFile(new Path(testAppDirPath, TEST_BROKEN_FILE_NAME)); }
@Test public void testParseDomain() throws Exception { // Load test data TimelineDataManager tdm = PluginStoreTestUtils.getTdmWithMemStore(config); DomainLogInfo domainLogInfo = new DomainLogInfo(TEST_ATTEMPT_DIR_NAME, TEST_DOMAIN_FILE_NAME, UserGroupInformation.getLoginUser().getUserName()); domainLogInfo.parseForStore(tdm, getTestRootPath(), true, jsonFactory, objMapper, fs); // Verify domain data TimelineDomain resultDomain = tdm.getDomain("domain_1", UserGroupInformation.getLoginUser()); assertNotNull(resultDomain); assertEquals(testDomain.getReaders(), resultDomain.getReaders()); assertEquals(testDomain.getOwner(), resultDomain.getOwner()); assertEquals(testDomain.getDescription(), resultDomain.getDescription()); }
@Override public TimelineDomain getDomain(String domainId) throws IOException { if (getServiceStopped()) { LOG.info("Service stopped, return null for the storage"); return null; } TimelineDomain domain = domainById.get(domainId); if (domain == null) { return null; } else { return KeyValueBasedTimelineStoreUtils.createTimelineDomain( domain.getId(), domain.getDescription(), domain.getOwner(), domain.getReaders(), domain.getWriters(), domain.getCreatedTime(), domain.getModifiedTime()); } }