Skip to content

Commit

Permalink
Mark /metrics and /jmx as privileged
Browse files Browse the repository at this point in the history
  • Loading branch information
joshelser committed Jan 24, 2020
1 parent 78c5541 commit 1733ec1
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -732,11 +732,11 @@ protected void addDefaultServlets(ContextHandlerCollection contexts) throws IOEx
// Remove when we drop support for hbase on hadoop2.x.
try {
Class<?> clz = Class.forName("org.apache.hadoop.metrics.MetricsServlet");
addUnprivilegedServlet("metrics", "/metrics", clz.asSubclass(HttpServlet.class));
addPrivilegedServlet("metrics", "/metrics", clz.asSubclass(HttpServlet.class));
} catch (Exception e) {
// do nothing
}
addUnprivilegedServlet("jmx", "/jmx", JMXJsonServlet.class);
addPrivilegedServlet("jmx", "/jmx", JMXJsonServlet.class);
addUnprivilegedServlet("conf", "/conf", ConfServlet.class);
final String asyncProfilerHome = ProfileServlet.getAsyncProfilerHome();
if (asyncProfilerHome != null && !asyncProfilerHome.trim().isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,70 @@ public void testStackActionsAvailableForAdmins() throws Exception {
});
}

@Test
public void testJmxAvailableForAdmins() throws Exception {
final String expectedAuthorizedContent = "Hadoop:service=HBase";
UserGroupInformation admin = UserGroupInformation.loginUserFromKeytabAndReturnUGI(
USER_ADMIN_STR, KEYTAB_FILE.getAbsolutePath());
admin.doAs(new PrivilegedExceptionAction<Void>() {
@Override public Void run() throws Exception {
// Check the expected content is present in the http response
Pair<Integer,String> pair = getJmxPage();
assertEquals(HttpURLConnection.HTTP_OK, pair.getFirst().intValue());
assertTrue("expected=" + expectedAuthorizedContent + ", content=" + pair.getSecond(),
pair.getSecond().contains(expectedAuthorizedContent));
return null;
}
});

UserGroupInformation nonAdmin = UserGroupInformation.loginUserFromKeytabAndReturnUGI(
USER_NONE_STR, KEYTAB_FILE.getAbsolutePath());
nonAdmin.doAs(new PrivilegedExceptionAction<Void>() {
@Override public Void run() throws Exception {
Pair<Integer,String> pair = getJmxPage();
assertEquals(HttpURLConnection.HTTP_FORBIDDEN, pair.getFirst().intValue());
return null;
}
});
}

@Test
public void testMetricsAvailableForAdmins() throws Exception {
// Looks like there's nothing exported to this, but leave it since
// it's Hadoop2 only and will eventually be removed due to that.
final String expectedAuthorizedContent = "";
UserGroupInformation admin = UserGroupInformation.loginUserFromKeytabAndReturnUGI(
USER_ADMIN_STR, KEYTAB_FILE.getAbsolutePath());
admin.doAs(new PrivilegedExceptionAction<Void>() {
@Override public Void run() throws Exception {
// Check the expected content is present in the http response
Pair<Integer,String> pair = getMetricsPage();
if (HttpURLConnection.HTTP_NOT_FOUND == pair.getFirst()) {
// Not on hadoop 2
return null;
}
assertEquals(HttpURLConnection.HTTP_OK, pair.getFirst().intValue());
assertTrue("expected=" + expectedAuthorizedContent + ", content=" + pair.getSecond(),
pair.getSecond().contains(expectedAuthorizedContent));
return null;
}
});

UserGroupInformation nonAdmin = UserGroupInformation.loginUserFromKeytabAndReturnUGI(
USER_NONE_STR, KEYTAB_FILE.getAbsolutePath());
nonAdmin.doAs(new PrivilegedExceptionAction<Void>() {
@Override public Void run() throws Exception {
Pair<Integer,String> pair = getMetricsPage();
if (HttpURLConnection.HTTP_NOT_FOUND == pair.getFirst()) {
// Not on hadoop 2
return null;
}
assertEquals(HttpURLConnection.HTTP_FORBIDDEN, pair.getFirst().intValue());
return null;
}
});
}

private String getInfoServerHostAndPort() {
return "http://localhost:" + CLUSTER.getActiveMaster().getInfoServer().getPort();
}
Expand Down Expand Up @@ -327,6 +391,16 @@ private Pair<Integer,String> getStacksPage() throws Exception {
return getUrlContent(url);
}

private Pair<Integer,String> getJmxPage() throws Exception {
URL url = new URL(getInfoServerHostAndPort() + "/jmx");
return getUrlContent(url);
}

private Pair<Integer,String> getMetricsPage() throws Exception {
URL url = new URL(getInfoServerHostAndPort() + "/metrics");
return getUrlContent(url);
}

/**
* Retrieves the content of the specified URL. The content will only be returned if the status
* code for the operation was HTTP 200/OK.
Expand Down

0 comments on commit 1733ec1

Please sign in to comment.