Repository: sentry Updated Branches: refs/heads/sentry-ha-redesign ad929e818 -> ab2c4a3d5
SENTRY-1120: Show role / privileges info in Sentry Service Webpage (Li Li, Reviewed by Anne Yu) Change-Id: I44a733edf2beecfd39d6d15b06d7ad337b73685c Project: http://git-wip-us.apache.org/repos/asf/sentry/repo Commit: http://git-wip-us.apache.org/repos/asf/sentry/commit/ab2c4a3d Tree: http://git-wip-us.apache.org/repos/asf/sentry/tree/ab2c4a3d Diff: http://git-wip-us.apache.org/repos/asf/sentry/diff/ab2c4a3d Branch: refs/heads/sentry-ha-redesign Commit: ab2c4a3d5ac666ec72a13eabd30f29aafd99c053 Parents: ad929e8 Author: lili <[email protected]> Authored: Tue Oct 4 14:45:25 2016 -0700 Committer: lili <[email protected]> Committed: Fri Oct 7 13:39:17 2016 -0700 ---------------------------------------------------------------------- .../db/service/thrift/SentryWebServer.java | 11 +- .../sentry/service/thrift/ServiceConstants.java | 4 + .../db/service/thrift/SentryAdminServlet.java | 132 +++++++++++++++++++ 3 files changed, 144 insertions(+), 3 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/sentry/blob/ab2c4a3d/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryWebServer.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryWebServer.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryWebServer.java index a42f395..01f3a0d 100644 --- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryWebServer.java +++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryWebServer.java @@ -22,8 +22,8 @@ import com.codahale.metrics.servlets.AdminServlet; import com.google.common.base.Preconditions; import java.io.IOException; -import java.util.EnumSet; import java.net.URL; +import java.util.EnumSet; import java.util.EventListener; import java.util.HashMap; import java.util.List; @@ -94,8 +94,13 @@ public class SentryWebServer { servletContextHandler.addEventListener(listener); } - ServletHolder confServletHolder = new ServletHolder(ConfServlet.class); - servletContextHandler.addServlet(confServletHolder, "/conf"); + servletContextHandler.addServlet(new ServletHolder(ConfServlet.class), "/conf"); + + if (conf.getBoolean(ServerConfig.SENTRY_WEB_ADMIN_SERVLET_ENABLED, + ServerConfig.SENTRY_WEB_ADMIN_SERVLET_ENABLED_DEFAULT)) { + servletContextHandler.addServlet( + new ServletHolder(SentryAdminServlet.class), "/admin/*"); + } servletContextHandler.getServletContext() .setAttribute(ConfServlet.CONF_CONTEXT_ATTRIBUTE, conf); http://git-wip-us.apache.org/repos/asf/sentry/blob/ab2c4a3d/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/ServiceConstants.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/ServiceConstants.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/ServiceConstants.java index 31d9d42..f98ebd1 100644 --- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/ServiceConstants.java +++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/ServiceConstants.java @@ -178,6 +178,10 @@ public class ServiceConstants { public static final String SENTRY_WEB_SECURITY_KEYTAB = SENTRY_WEB_SECURITY_PREFIX + ".kerberos.keytab"; public static final String SENTRY_WEB_SECURITY_ALLOW_CONNECT_USERS = SENTRY_WEB_SECURITY_PREFIX + ".allow.connect.users"; + // Flag to enable admin servlet + public static final String SENTRY_WEB_ADMIN_SERVLET_ENABLED = "sentry.web.admin.servlet.enabled"; + public static final boolean SENTRY_WEB_ADMIN_SERVLET_ENABLED_DEFAULT = false; + // max message size for thrift messages public static final String SENTRY_POLICY_SERVER_THRIFT_MAX_MESSAGE_SIZE = "sentry.policy.server.thrift.max.message.size"; public static final long SENTRY_POLICY_SERVER_THRIFT_MAX_MESSAGE_SIZE_DEFAULT = 100 * 1024 * 1024; http://git-wip-us.apache.org/repos/asf/sentry/blob/ab2c4a3d/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryAdminServlet.java ---------------------------------------------------------------------- diff --git a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryAdminServlet.java b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryAdminServlet.java new file mode 100644 index 0000000..8a8bbd3 --- /dev/null +++ b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryAdminServlet.java @@ -0,0 +1,132 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sentry.provider.db.service.thrift; + +import com.google.gson.Gson; +import org.apache.hadoop.conf.Configuration; +import org.apache.sentry.provider.db.service.persistent.SentryStore; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.Writer; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +/** + * Admin Servlet is only used when SENTRY_WEB_ADMIN_SERVLET_ENABLED is true. + */ +public class SentryAdminServlet extends HttpServlet { + private static final String SHOW_ALL = "/showAll"; + // Here we use the same way as in com.codahale.metrics.servlets.AdminServlet, and just + // use the TEMPLATE as a static html with some links referenced to other debug pages. + private static final String TEMPLATE = "<!DOCTYPE HTML>\n"+ + "<html lang=\"en\">\n"+ + "<head>\n"+ + " <meta charset=\"utf-8\">\n"+ + " <title>Sentry Service Admin</title>\n"+ + " <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n"+ + " <meta name=\"description\" content=\"\">\n"+ + " <link href=\"css/bootstrap.min.css\" rel=\"stylesheet\">\n"+ + " <link href=\"css/bootstrap-theme.min.css\" rel=\"stylesheet\">\n"+ + " <link href=\"css/sentry.css\" rel=\"stylesheet\">\n"+ + "</head>\n"+ + "<body>\n"+ + "<nav class=\"navbar navbar-default navbar-fixed-top\">\n"+ + " <div class=\"container\">\n"+ + " <div class=\"navbar-header\">\n"+ + " <a class=\"navbar-brand\" href=\"#\"><img src=\"sentry.png\" alt=\"Sentry Logo\"/></a>\n"+ + " </div>\n"+ + " <div class=\"collapse navbar-collapse\">\n"+ + " <ul class=\"nav navbar-nav\">\n"+ + " <li class=\"active\"><a href=\"#\">Admin</a></li>\n"+ + " <li><a href=\"/metrics?pretty=true\">Metrics</a></li>\n"+ + " <li><a href=\"/threads\">Threads</a></li>\n"+ + " <li><a href=\"/conf\">Configuration</a></li>\n"+ + " <li><a href=\"/admin/showAll\">ShowAllRoles</a></li>\n"+ + " </ul>\n"+ + " </div>\n"+ + " </div>\n"+ + "</nav>\n"+ + "<div class=\"container\">\n"+ + " <ul>\n"+ + " <li><a href=\"/metrics?pretty=true\">Metrics</a></li>\n"+ + " <li><a href=\"/threads\">Threads</a></li>\n"+ + " <li><a href=\"/conf\">Configuration</a></li>\n"+ + " <li><a href=\"/admin/showAll\">ShowAllRoles</a></li>\n"+ + " </ul>\n"+ + "</div>\n"+ + "</body>\n"+ + "</html>"; + + @Override + public void doGet(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + String uri = request.getPathInfo(); + if(uri != null && !uri.equals("/")) { + if (uri.equals(SHOW_ALL)) { + showAll(response); + } else { + response.sendError(404); + } + } else { + response.setStatus(200); + response.setHeader("Cache-Control", "must-revalidate,no-cache,no-store"); + response.setHeader("Pragma", "no-cache"); + response.setDateHeader("Expires", 0); + response.setContentType("text/html"); + PrintWriter writer = response.getWriter(); + try { + writer.println(TEMPLATE); + } finally { + writer.close(); + } + } + } + + /** + * Print out all the roles and privileges information as json format. + */ + private void showAll(HttpServletResponse response) + throws ServletException, IOException { + Configuration conf = (Configuration)getServletContext().getAttribute( + ConfServlet.CONF_CONTEXT_ATTRIBUTE); + assert conf != null; + + Writer out = response.getWriter(); + try { + SentryStore sentrystore = new SentryStore(conf); + Map<String, Set<TSentryPrivilege>> roleMap = new HashMap<>(); + Set<String> roleSet = sentrystore.getAllRoleNames(); + for (String roleName: roleSet) { + roleMap.put(roleName, sentrystore.getAllTSentryPrivilegesByRoleName(roleName)); + } + String json = new Gson().toJson(roleMap); + response.setContentType("application/json"); + response.setCharacterEncoding("UTF-8"); + out.write(json); + } catch (Exception e) { + response.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage()); + } + out.close(); + } +}
