Skip to content

Commit d5e69d8

Browse files
MapReduce JHS should honor yarn.webapp.filter-entity-list-by-user(addendum). Contributed by Sunil Govindan.
1 parent e11d674 commit d5e69d8

File tree

4 files changed

+56
-39
lines changed

4 files changed

+56
-39
lines changed

hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-hs/src/main/java/org/apache/hadoop/mapreduce/v2/hs/webapp/HsJobBlock.java

+1-17
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@
2727
import java.util.Date;
2828
import java.util.List;
2929

30-
import org.apache.hadoop.conf.Configuration;
31-
import org.apache.hadoop.mapreduce.JobACL;
3230
import org.apache.hadoop.mapreduce.TaskID;
3331
import org.apache.hadoop.mapreduce.v2.api.records.AMInfo;
3432
import org.apache.hadoop.mapreduce.v2.api.records.JobId;
@@ -41,10 +39,8 @@
4139
import org.apache.hadoop.mapreduce.v2.jobhistory.JHAdminConfig;
4240
import org.apache.hadoop.mapreduce.v2.util.MRApps;
4341
import org.apache.hadoop.mapreduce.v2.util.MRApps.TaskAttemptStateUI;
44-
import org.apache.hadoop.security.UserGroupInformation;
4542
import org.apache.hadoop.mapreduce.v2.util.MRWebAppUtil;
4643
import org.apache.hadoop.util.StringUtils;
47-
import org.apache.hadoop.yarn.conf.YarnConfiguration;
4844
import org.apache.hadoop.yarn.util.Times;
4945
import org.apache.hadoop.yarn.webapp.ResponseInfo;
5046
import org.apache.hadoop.yarn.webapp.hamlet2.Hamlet;
@@ -60,14 +56,9 @@
6056
*/
6157
public class HsJobBlock extends HtmlBlock {
6258
final AppContext appContext;
63-
private UserGroupInformation ugi;
64-
private boolean isFilterAppListByUserEnabled;
6559

66-
@Inject HsJobBlock(Configuration conf, AppContext appctx, ViewContext ctx) {
67-
super(ctx);
60+
@Inject HsJobBlock(AppContext appctx) {
6861
appContext = appctx;
69-
isFilterAppListByUserEnabled = conf
70-
.getBoolean(YarnConfiguration.FILTER_ENTITY_LIST_BY_USER, false);
7162
}
7263

7364
/*
@@ -87,13 +78,6 @@ public class HsJobBlock extends HtmlBlock {
8778
html.p().__("Sorry, ", jid, " not found.").__();
8879
return;
8980
}
90-
ugi = getCallerUGI();
91-
if (isFilterAppListByUserEnabled && ugi != null
92-
&& !j.checkAccess(ugi, JobACL.VIEW_JOB)) {
93-
html.p().__("Sorry, ", jid, " could not be viewed for '",
94-
ugi.getUserName(), "'.").__();
95-
return;
96-
}
9781
if(j instanceof UnparsedJob) {
9882
final int taskCount = j.getTotalMaps() + j.getTotalReduces();
9983
UnparsedJob oversizedJob = (UnparsedJob) j;

hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-hs/src/main/java/org/apache/hadoop/mapreduce/v2/hs/webapp/HsJobsBlock.java

+39-1
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,15 @@
2222
import java.util.Date;
2323

2424
import org.apache.commons.lang3.StringEscapeUtils;
25+
import org.apache.hadoop.conf.Configuration;
26+
import org.apache.hadoop.mapreduce.MRConfig;
2527
import org.apache.hadoop.mapreduce.v2.app.AppContext;
2628
import org.apache.hadoop.mapreduce.v2.app.job.Job;
2729
import org.apache.hadoop.mapreduce.v2.hs.webapp.dao.JobInfo;
30+
import org.apache.hadoop.security.UserGroupInformation;
31+
import org.apache.hadoop.security.authorize.AccessControlList;
2832
import org.apache.hadoop.util.StringUtils;
33+
import org.apache.hadoop.yarn.conf.YarnConfiguration;
2934
import org.apache.hadoop.yarn.util.Times;
3035
import org.apache.hadoop.yarn.webapp.hamlet2.Hamlet;
3136
import org.apache.hadoop.yarn.webapp.hamlet2.Hamlet.TABLE;
@@ -42,9 +47,19 @@ public class HsJobsBlock extends HtmlBlock {
4247
final AppContext appContext;
4348
final SimpleDateFormat dateFormat =
4449
new SimpleDateFormat("yyyy.MM.dd HH:mm:ss z");
50+
private UserGroupInformation ugi;
51+
private boolean isFilterAppListByUserEnabled;
52+
private boolean areAclsEnabled;
53+
private AccessControlList adminAclList;
4554

46-
@Inject HsJobsBlock(AppContext appCtx) {
55+
@Inject
56+
HsJobsBlock(Configuration conf, AppContext appCtx, ViewContext ctx) {
57+
super(ctx);
4758
appContext = appCtx;
59+
isFilterAppListByUserEnabled = conf
60+
.getBoolean(YarnConfiguration.FILTER_ENTITY_LIST_BY_USER, false);
61+
areAclsEnabled = conf.getBoolean(MRConfig.MR_ACLS_ENABLED, false);
62+
adminAclList = new AccessControlList(conf.get(MRConfig.MR_ADMINS, " "));
4863
}
4964

5065
/*
@@ -77,6 +92,12 @@ public class HsJobsBlock extends HtmlBlock {
7792
StringBuilder jobsTableData = new StringBuilder("[\n");
7893
for (Job j : appContext.getAllJobs().values()) {
7994
JobInfo job = new JobInfo(j);
95+
ugi = getCallerUGI();
96+
// Allow to list only per-user apps if incoming ugi has permission.
97+
if (isFilterAppListByUserEnabled && ugi != null
98+
&& !checkAccess(job.getUserName())) {
99+
continue;
100+
}
80101
jobsTableData.append("[\"")
81102
.append(dateFormat.format(new Date(job.getSubmitTime()))).append("\",\"")
82103
.append(job.getFormattedStartTimeStr(dateFormat)).append("\",\"")
@@ -139,4 +160,21 @@ public class HsJobsBlock extends HtmlBlock {
139160
__().
140161
__();
141162
}
163+
164+
private boolean checkAccess(String userName) {
165+
if(!areAclsEnabled) {
166+
return true;
167+
}
168+
169+
// User could see its own job.
170+
if (ugi.getShortUserName().equals(userName)) {
171+
return true;
172+
}
173+
174+
// Admin could also see all jobs
175+
if (adminAclList != null && adminAclList.isUserAllowed(ugi)) {
176+
return true;
177+
}
178+
return false;
179+
}
142180
}

hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-hs/src/test/java/org/apache/hadoop/mapreduce/v2/hs/webapp/TestBlocks.java

+14-3
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@
5959
import org.apache.hadoop.yarn.api.records.impl.pb.ApplicationIdPBImpl;
6060
import org.apache.hadoop.yarn.api.records.impl.pb.ContainerIdPBImpl;
6161
import org.apache.hadoop.yarn.webapp.Controller.RequestContext;
62+
import org.apache.hadoop.yarn.webapp.View.ViewContext;
63+
import org.apache.hadoop.yarn.webapp.Controller;
6264
import org.apache.hadoop.yarn.webapp.Params;
6365
import org.apache.hadoop.yarn.webapp.View;
6466
import org.apache.hadoop.yarn.webapp.log.AggregatedLogsPage;
@@ -223,7 +225,14 @@ public void testHsJobsBlock() {
223225
jobs.put(job.getID(), job);
224226
when(ctx.getAllJobs()).thenReturn(jobs);
225227

226-
HsJobsBlock block = new HsJobsBlockForTest(ctx);
228+
Controller.RequestContext rc = mock(Controller.RequestContext.class);
229+
ViewContext view = mock(ViewContext.class);
230+
HttpServletRequest req =mock(HttpServletRequest.class);
231+
when(rc.getRequest()).thenReturn(req);
232+
when(view.requestContext()).thenReturn(rc);
233+
234+
Configuration conf = new Configuration();
235+
HsJobsBlock block = new HsJobsBlockForTest(conf, ctx, view);
227236
PrintWriter pWriter = new PrintWriter(data);
228237
Block html = new BlockForTest(new HtmlBlockForTest(), pWriter, 0, false);
229238
block.render(html);
@@ -400,8 +409,10 @@ private Task getTask(long timestamp) {
400409
}
401410

402411
private class HsJobsBlockForTest extends HsJobsBlock {
403-
HsJobsBlockForTest(AppContext appCtx) {
404-
super(appCtx);
412+
413+
HsJobsBlockForTest(Configuration conf, AppContext appCtx,
414+
ViewContext view) {
415+
super(conf, appCtx, view);
405416
}
406417

407418
@Override

hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-hs/src/test/java/org/apache/hadoop/mapreduce/v2/hs/webapp/TestHsJobBlock.java

+2-18
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,8 @@
3333
import org.apache.hadoop.mapreduce.v2.jobhistory.JHAdminConfig;
3434
import org.apache.hadoop.yarn.api.records.ApplicationId;
3535
import org.apache.hadoop.yarn.util.StringHelper;
36-
import org.apache.hadoop.yarn.webapp.Controller;
3736
import org.apache.hadoop.yarn.webapp.ResponseInfo;
3837
import org.apache.hadoop.yarn.webapp.SubView;
39-
import org.apache.hadoop.yarn.webapp.View.ViewContext;
4038
import org.apache.hadoop.yarn.webapp.view.BlockForTest;
4139
import org.apache.hadoop.yarn.webapp.view.HtmlBlock;
4240
import org.apache.hadoop.yarn.webapp.view.HtmlBlockForTest;
@@ -51,8 +49,6 @@
5149
import java.util.HashMap;
5250
import java.util.Map;
5351

54-
import javax.servlet.http.HttpServletRequest;
55-
5652
import static org.mockito.Matchers.any;
5753
import static org.mockito.Mockito.mock;
5854
import static org.mockito.Mockito.when;
@@ -73,13 +69,7 @@ public void testHsJobBlockForOversizeJobShouldDisplayWarningMessage() {
7369
new JobHistoryStubWithAllOversizeJobs(maxAllowedTaskNum);
7470
jobHistory.init(config);
7571

76-
Controller.RequestContext rc = mock(Controller.RequestContext.class);
77-
ViewContext view = mock(ViewContext.class);
78-
HttpServletRequest req =mock(HttpServletRequest.class);
79-
when(rc.getRequest()).thenReturn(req);
80-
when(view.requestContext()).thenReturn(rc);
81-
82-
HsJobBlock jobBlock = new HsJobBlock(config, jobHistory, view) {
72+
HsJobBlock jobBlock = new HsJobBlock(jobHistory) {
8373
// override this so that job block can fetch a job id.
8474
@Override
8575
public Map<String, String> moreParams() {
@@ -111,13 +101,7 @@ public void testHsJobBlockForNormalSizeJobShouldNotDisplayWarningMessage() {
111101
JobHistory jobHistory = new JobHitoryStubWithAllNormalSizeJobs();
112102
jobHistory.init(config);
113103

114-
Controller.RequestContext rc = mock(Controller.RequestContext.class);
115-
ViewContext view = mock(ViewContext.class);
116-
HttpServletRequest req =mock(HttpServletRequest.class);
117-
when(rc.getRequest()).thenReturn(req);
118-
when(view.requestContext()).thenReturn(rc);
119-
120-
HsJobBlock jobBlock = new HsJobBlock(config, jobHistory, view) {
104+
HsJobBlock jobBlock = new HsJobBlock(jobHistory) {
121105
// override this so that the job block can fetch a job id.
122106
@Override
123107
public Map<String, String> moreParams() {

0 commit comments

Comments
 (0)