Repository: incubator-sentry Updated Branches: refs/heads/master a661c1828 -> 0adfc7384
SENTRY-749: Create simple shell for sentry(Colin Ma, reviewed by Hao Hao, Gregory Chanan, Lenni Kuff) Project: http://git-wip-us.apache.org/repos/asf/incubator-sentry/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-sentry/commit/0adfc738 Tree: http://git-wip-us.apache.org/repos/asf/incubator-sentry/tree/0adfc738 Diff: http://git-wip-us.apache.org/repos/asf/incubator-sentry/diff/0adfc738 Branch: refs/heads/master Commit: 0adfc7384f531f93ff0a5d2a0b1470876fc10855 Parents: a661c18 Author: Colin Ma <co...@apache.org> Authored: Mon Jan 4 14:56:50 2016 +0800 Committer: Colin Ma <co...@apache.org> Committed: Mon Jan 4 14:56:50 2016 +0800 ---------------------------------------------------------------------- bin/sentryShell | 71 +++ .../provider/db/tools/SentryShellCommon.java | 242 ++++++++ .../provider/db/tools/SentryShellHive.java | 92 +++ .../provider/db/tools/command/hive/Command.java | 27 + .../db/tools/command/hive/CommandUtil.java | 114 ++++ .../db/tools/command/hive/CreateRoleCmd.java | 37 ++ .../db/tools/command/hive/DropRoleCmd.java | 37 ++ .../command/hive/GrantPrivilegeToRoleCmd.java | 61 ++ .../command/hive/GrantRoleToGroupsCmd.java | 43 ++ .../tools/command/hive/ListPrivilegesCmd.java | 97 +++ .../db/tools/command/hive/ListRolesCmd.java | 51 ++ .../hive/RevokePrivilegeFromRoleCmd.java | 62 ++ .../command/hive/RevokeRoleFromGroupsCmd.java | 43 ++ .../provider/db/tools/TestSentryShellHive.java | 583 +++++++++++++++++++ .../thrift/SentryServiceIntegrationBase.java | 6 - 15 files changed, 1560 insertions(+), 6 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/0adfc738/bin/sentryShell ---------------------------------------------------------------------- diff --git a/bin/sentryShell b/bin/sentryShell new file mode 100755 index 0000000..d6e8055 --- /dev/null +++ b/bin/sentryShell @@ -0,0 +1,71 @@ +#!/usr/bin/env bash + +# 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. + +bin=`dirname "$0"` +myhome=`cd "$bin/.."; pwd` + +if [[ -z $SENTRY_HOME ]] ; then + export SENTRY_HOME=$myhome +fi + +# check for hadoop in the path +HADOOP_IN_PATH=`which hadoop 2>/dev/null` +if [ -f ${HADOOP_IN_PATH} ]; then + HADOOP_DIR=`dirname "$HADOOP_IN_PATH"`/.. +fi +# HADOOP_HOME env variable overrides hadoop in the path +HADOOP_HOME=${HADOOP_HOME:-${HADOOP_PREFIX:-$HADOOP_DIR}} +if [ "$HADOOP_HOME" == "" ]; then + echo "Cannot find hadoop installation: \$HADOOP_HOME or \$HADOOP_PREFIX must be set or hadoop must be in the path"; + exit 4; +fi + +HADOOP=$HADOOP_HOME/bin/hadoop +if [ ! -f ${HADOOP} ]; then + echo "Cannot find hadoop installation: \$HADOOP_HOME or \$HADOOP_PREFIX must be set or hadoop must be in the path"; + exit 4; +fi + +export _CMD_JAR=${SENTRY_SHELL_JAR}:sentry-provider-db-*.jar +for f in ${SENTRY_HOME}/lib/*.jar; do + HADOOP_CLASSPATH=${HADOOP_CLASSPATH}:${f} +done +export HADOOP_CLASSPATH + +for f in ${SENTRY_HOME}/lib/server/*.jar; do + HADOOP_CLASSPATH=${HADOOP_CLASSPATH}:${f} +done +for f in ${SENTRY_HOME}/lib/plugins/*.jar; do + HADOOP_CLASSPATH=${HADOOP_CLASSPATH}:${f} +done + +args=() +# get the type argument for the command, and check use the shell for hive model or for generic model. +# todo: currently, supoort hive only, need add generic model support +while [ $# -gt 0 ]; do # Until you run out of parameters . . . + if [[ "$1" = "-t" || "$1" = "--type" ]]; then + # currently, only support the hive model + if ! [[ $2 =~ ^[H|h][I|i][V|v][E|e]$ ]]; then + echo "Doesn't support the type $2!" + exit 1 + fi + fi + args+=" $1" + shift +done + +exec $HADOOP jar ${SENTRY_HOME}/lib/${_CMD_JAR} org.apache.sentry.SentryShellHive ${args[@]} http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/0adfc738/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/SentryShellCommon.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/SentryShellCommon.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/SentryShellCommon.java new file mode 100644 index 0000000..b1353c5 --- /dev/null +++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/SentryShellCommon.java @@ -0,0 +1,242 @@ +/** + * 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.tools; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.GnuParser; +import org.apache.commons.cli.HelpFormatter; +import org.apache.commons.cli.Option; +import org.apache.commons.cli.OptionGroup; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.ParseException; +import org.apache.commons.cli.Parser; +import org.apache.commons.lang.StringUtils; + +/** + * SentryShellCommon provides the function for parsing the argument. + * For hive model and generic model, child class should be implemented as a sentry admin tool. + */ +abstract public class SentryShellCommon { + + protected String roleName; + protected String groupName; + protected String privilegeStr; + protected String confPath; + // flag for the command + protected boolean isCreateRole = false; + protected boolean isDropRole = false; + protected boolean isAddRoleGroup = false; + protected boolean isDeleteRoleGroup = false; + protected boolean isGrantPrivilegeRole = false; + protected boolean isRevokePrivilegeRole = false; + protected boolean isListRole = false; + protected boolean isListPrivilege = false; + protected boolean isPrintHelp = false; + // flag for the parameter check + protected boolean roleNameRequired = false; + protected boolean groupNameRequired = false; + protected boolean privilegeStrRequired = false; + + public final static String OPTION_DESC_HELP = "Shell usage"; + public final static String OPTION_DESC_CONF = "sentry-site file path"; + public final static String OPTION_DESC_ROLE_NAME = "Role name"; + public final static String OPTION_DESC_GROUP_NAME = "Group name"; + public final static String OPTION_DESC_PRIVILEGE = "Privilege string"; + public final static String PREFIX_MESSAGE_MISSING_OPTION = "Missing required option: "; + + /** + * parse arguments + * + * <pre> + * -conf,--sentry_conf <filepath> sentry config file path + * -cr,--create_role -r <rolename> create role + * -dr,--drop_role -r <rolename> drop role + * -arg,--add_role_group -r <rolename> -g <groupname> add group to role + * -drg,--delete_role_group -r <rolename> -g <groupname> delete group from role + * -gpr,--grant_privilege_role -r <rolename> -p <privilege> grant privilege to role + * -rpr,--revoke_privilege_role -r <rolename> -p <privilege> revoke privilege from role + * -lr,--list_role -g <groupname> list roles for group + * -lp,--list_privilege -r <rolename> list privilege for role + * -t,--type <typeame> the shell for hive model or generic model + * </pre> + * + * @param args + */ + protected boolean parseArgs(String[] args) { + Options simpleShellOptions = new Options(); + + Option crOpt = new Option("cr", "create_role", false, "Create role"); + crOpt.setRequired(false); + + Option drOpt = new Option("dr", "drop_role", false, "Drop role"); + drOpt.setRequired(false); + + Option argOpt = new Option("arg", "add_role_group", false, "Add group to role"); + argOpt.setRequired(false); + + Option drgOpt = new Option("drg", "delete_role_group", false, "Delete group from role"); + drgOpt.setRequired(false); + + Option gprOpt = new Option("gpr", "grant_privilege_role", false, "Grant privilege to role"); + gprOpt.setRequired(false); + + Option rprOpt = new Option("rpr", "revoke_privilege_role", false, "Revoke privilege from role"); + rprOpt.setRequired(false); + + Option lrOpt = new Option("lr", "list_role", false, "List role"); + lrOpt.setRequired(false); + + Option lpOpt = new Option("lp", "list_privilege", false, "List privilege"); + lpOpt.setRequired(false); + + // required args group + OptionGroup simpleShellOptGroup = new OptionGroup(); + simpleShellOptGroup.addOption(crOpt); + simpleShellOptGroup.addOption(drOpt); + simpleShellOptGroup.addOption(argOpt); + simpleShellOptGroup.addOption(drgOpt); + simpleShellOptGroup.addOption(gprOpt); + simpleShellOptGroup.addOption(rprOpt); + simpleShellOptGroup.addOption(lrOpt); + simpleShellOptGroup.addOption(lpOpt); + simpleShellOptGroup.setRequired(true); + simpleShellOptions.addOptionGroup(simpleShellOptGroup); + + // optional args + Option pOpt = new Option("p", "privilege", true, OPTION_DESC_PRIVILEGE); + pOpt.setRequired(false); + simpleShellOptions.addOption(pOpt); + + Option gOpt = new Option("g", "groupname", true, OPTION_DESC_GROUP_NAME); + gOpt.setRequired(false); + simpleShellOptions.addOption(gOpt); + + Option rOpt = new Option("r", "rolename", true, OPTION_DESC_ROLE_NAME); + rOpt.setRequired(false); + simpleShellOptions.addOption(rOpt); + + // this argument should be parsed in the bin/sentryShell + Option tOpt = new Option("t", "type", true, "[hive|solr|sqoop|.....]"); + tOpt.setRequired(false); + simpleShellOptions.addOption(tOpt); + + // file path of sentry-site + Option sentrySitePathOpt = new Option("conf", "sentry_conf", true, OPTION_DESC_CONF); + sentrySitePathOpt.setRequired(true); + simpleShellOptions.addOption(sentrySitePathOpt); + + // help option + Option helpOpt = new Option("h", "help", false, OPTION_DESC_HELP); + helpOpt.setRequired(false); + simpleShellOptions.addOption(helpOpt); + + // this Options is parsed first for help option + Options helpOptions = new Options(); + helpOptions.addOption(helpOpt); + + try { + Parser parser = new GnuParser(); + + // parse help option first + CommandLine cmd = parser.parse(helpOptions, args, true); + for (Option opt : cmd.getOptions()) { + if (opt.getOpt().equals("h")) { + // get the help option, print the usage and exit + usage(simpleShellOptions); + return false; + } + } + + // without help option + cmd = parser.parse(simpleShellOptions, args); + + for (Option opt : cmd.getOptions()) { + if (opt.getOpt().equals("p")) { + privilegeStr = opt.getValue(); + } else if (opt.getOpt().equals("g")) { + groupName = opt.getValue(); + } else if (opt.getOpt().equals("r")) { + roleName = opt.getValue(); + } else if (opt.getOpt().equals("cr")) { + isCreateRole = true; + roleNameRequired = true; + } else if (opt.getOpt().equals("dr")) { + isDropRole = true; + roleNameRequired = true; + } else if (opt.getOpt().equals("arg")) { + isAddRoleGroup = true; + roleNameRequired = true; + groupNameRequired = true; + } else if (opt.getOpt().equals("drg")) { + isDeleteRoleGroup = true; + roleNameRequired = true; + groupNameRequired = true; + } else if (opt.getOpt().equals("gpr")) { + isGrantPrivilegeRole = true; + roleNameRequired = true; + privilegeStrRequired = true; + } else if (opt.getOpt().equals("rpr")) { + isRevokePrivilegeRole = true; + roleNameRequired = true; + privilegeStrRequired = true; + } else if (opt.getOpt().equals("lr")) { + isListRole = true; + } else if (opt.getOpt().equals("lp")) { + isListPrivilege = true; + roleNameRequired = true; + } else if (opt.getOpt().equals("conf")) { + confPath = opt.getValue(); + } + } + checkRequiredParameter(roleNameRequired, roleName, OPTION_DESC_ROLE_NAME); + checkRequiredParameter(groupNameRequired, groupName, OPTION_DESC_GROUP_NAME); + checkRequiredParameter(privilegeStrRequired, privilegeStr, OPTION_DESC_PRIVILEGE); + } catch (ParseException pe) { + System.out.println(pe.getMessage()); + usage(simpleShellOptions); + return false; + } + return true; + } + + private void checkRequiredParameter(boolean isRequired, String paramValue, String paramName) throws ParseException { + if (isRequired && StringUtils.isEmpty(paramValue)) { + throw new ParseException(PREFIX_MESSAGE_MISSING_OPTION + paramName); + } + } + + // print usage + private void usage(Options sentryOptions) { + HelpFormatter formatter = new HelpFormatter(); + formatter.printHelp("sentryShell", sentryOptions); + } + + // hive model and generic model should implement this method + abstract void run() throws Exception; + + protected boolean executeShell(String[] args) throws Exception { + boolean result = true; + if (parseArgs(args)) { + run(); + } else { + result = false; + } + return result; + } +} http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/0adfc738/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/SentryShellHive.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/SentryShellHive.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/SentryShellHive.java new file mode 100644 index 0000000..80c8442 --- /dev/null +++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/SentryShellHive.java @@ -0,0 +1,92 @@ +/** + * 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.tools; + +import org.apache.commons.lang.StringUtils; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.fs.Path; +import org.apache.sentry.provider.db.service.thrift.SentryPolicyServiceClient; +import org.apache.sentry.provider.db.tools.command.hive.*; +import org.apache.sentry.service.thrift.SentryServiceClientFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * SentryShellHive is an admin tool, and responsible for the management of repository. + * The following function are supported: + * create role, drop role, add group to role, delete group from role, grant privilege to role, + * revoke privilege from role, list roles for group, list privilege for role. + */ +public class SentryShellHive extends SentryShellCommon { + + private static final Logger LOGGER = LoggerFactory.getLogger(SentryShellHive.class); + + public void run() throws Exception { + Command command = null; + String requestorName = System.getProperty("user.name", ""); + SentryPolicyServiceClient client = SentryServiceClientFactory.create(getSentryConf()); + + if (isCreateRole) { + command = new CreateRoleCmd(roleName); + } else if (isDropRole) { + command = new DropRoleCmd(roleName); + } else if (isAddRoleGroup) { + command = new GrantRoleToGroupsCmd(roleName, groupName); + } else if (isDeleteRoleGroup) { + command = new RevokeRoleFromGroupsCmd(roleName, groupName); + } else if (isGrantPrivilegeRole) { + command = new GrantPrivilegeToRoleCmd(roleName, privilegeStr); + } else if (isRevokePrivilegeRole) { + command = new RevokePrivilegeFromRoleCmd(roleName, privilegeStr); + } else if (isListRole) { + command = new ListRolesCmd(groupName); + } else if (isListPrivilege) { + command = new ListPrivilegesCmd(roleName); + } + + // check the requestor name + if (StringUtils.isEmpty(requestorName)) { + // The exception message will be recoreded in log file. + throw new Exception("The requestor name is empty."); + } + + if (command != null) { + command.execute(client, requestorName); + } + } + + private Configuration getSentryConf() { + Configuration conf = new Configuration(); + conf.addResource(new Path(confPath)); + return conf; + } + + public static void main(String[] args) throws Exception { + SentryShellHive sentryShell = new SentryShellHive(); + try { + if (sentryShell.executeShell(args)) { + System.out.println("The operation is compeleted successfully."); + } + } catch (Exception e) { + LOGGER.error(e.getMessage(), e); + System.out.println("The operation is failed, please refer to log file for the root cause."); + } + } + +} http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/0adfc738/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/Command.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/Command.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/Command.java new file mode 100644 index 0000000..ae9809a --- /dev/null +++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/Command.java @@ -0,0 +1,27 @@ +/** + * 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.tools.command.hive; + +import org.apache.sentry.provider.db.service.thrift.SentryPolicyServiceClient; + +/** + * The interface for all admin commands, eg, CreateRoleCmd. + */ +public interface Command { + abstract void execute(SentryPolicyServiceClient client, String requestorName) throws Exception; +} http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/0adfc738/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/CommandUtil.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/CommandUtil.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/CommandUtil.java new file mode 100644 index 0000000..0a73d9f --- /dev/null +++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/CommandUtil.java @@ -0,0 +1,114 @@ +/** + * 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.tools.command.hive; + +import org.apache.commons.lang.StringUtils; +import org.apache.sentry.provider.common.KeyValue; +import org.apache.sentry.provider.common.PolicyFileConstants; +import org.apache.sentry.provider.common.ProviderConstants; +import org.apache.sentry.provider.db.service.thrift.TSentryGrantOption; +import org.apache.sentry.provider.db.service.thrift.TSentryPrivilege; +import org.apache.sentry.service.thrift.ServiceConstants; + +public class CommandUtil { + + public static final String SPLIT_CHAR = ","; + + // parse the privilege in String and get the TSentryPrivilege as result + public static TSentryPrivilege convertToTSentryPrivilege(String privilegeStr) throws Exception { + TSentryPrivilege tSentryPrivilege = new TSentryPrivilege(); + for (String authorizable : ProviderConstants.AUTHORIZABLE_SPLITTER.split(privilegeStr)) { + KeyValue tempKV = new KeyValue(authorizable); + String key = tempKV.getKey(); + String value = tempKV.getValue(); + + if (PolicyFileConstants.PRIVILEGE_SERVER_NAME.equalsIgnoreCase(key)) { + tSentryPrivilege.setServerName(value); + } else if (PolicyFileConstants.PRIVILEGE_DATABASE_NAME.equalsIgnoreCase(key)) { + tSentryPrivilege.setDbName(value); + } else if (PolicyFileConstants.PRIVILEGE_TABLE_NAME.equalsIgnoreCase(key)) { + tSentryPrivilege.setTableName(value); + } else if (PolicyFileConstants.PRIVILEGE_COLUMN_NAME.equalsIgnoreCase(key)) { + tSentryPrivilege.setColumnName(value); + } else if (PolicyFileConstants.PRIVILEGE_URI_NAME.equalsIgnoreCase(key)) { + tSentryPrivilege.setURI(value); + } else if (PolicyFileConstants.PRIVILEGE_ACTION_NAME.equalsIgnoreCase(key)) { + tSentryPrivilege.setAction(value); + } else if (PolicyFileConstants.PRIVILEGE_GRANT_OPTION_NAME.equalsIgnoreCase(key)) { + TSentryGrantOption grantOption = "true".equalsIgnoreCase(value) ? TSentryGrantOption.TRUE + : TSentryGrantOption.FALSE; + tSentryPrivilege.setGrantOption(grantOption); + } + } + tSentryPrivilege.setPrivilegeScope(getPrivilegeScope(tSentryPrivilege)); + validatePrivilegeHierarchy(tSentryPrivilege); + return tSentryPrivilege; + } + + // for the different hierarchy for hive: + // 1: server->url + // 2: server->database->table->column + // if both of them are found in the privilege string, the privilege scope will be set as + // PrivilegeScope.URI + private static String getPrivilegeScope(TSentryPrivilege tSentryPrivilege) { + ServiceConstants.PrivilegeScope privilegeScope = ServiceConstants.PrivilegeScope.SERVER; + if (!StringUtils.isEmpty(tSentryPrivilege.getURI())) { + privilegeScope = ServiceConstants.PrivilegeScope.URI; + } else if (!StringUtils.isEmpty(tSentryPrivilege.getColumnName())) { + privilegeScope = ServiceConstants.PrivilegeScope.COLUMN; + } else if (!StringUtils.isEmpty(tSentryPrivilege.getTableName())) { + privilegeScope = ServiceConstants.PrivilegeScope.TABLE; + } else if (!StringUtils.isEmpty(tSentryPrivilege.getDbName())) { + privilegeScope = ServiceConstants.PrivilegeScope.DATABASE; + } + return privilegeScope.toString(); + } + + // check the privilege value for the specific privilege scope + // eg, for the table scope, server and database can't be empty + private static void validatePrivilegeHierarchy(TSentryPrivilege tSentryPrivilege) throws Exception { + String serverName = tSentryPrivilege.getServerName(); + String dbName = tSentryPrivilege.getDbName(); + String tableName = tSentryPrivilege.getTableName(); + String columnName = tSentryPrivilege.getColumnName(); + String uri = tSentryPrivilege.getURI(); + if (ServiceConstants.PrivilegeScope.SERVER.toString().equals(tSentryPrivilege.getPrivilegeScope())) { + if (StringUtils.isEmpty(serverName)) { + throw new IllegalArgumentException("The hierarchy of privilege is not correct."); + } + } else if (ServiceConstants.PrivilegeScope.URI.toString().equals(tSentryPrivilege.getPrivilegeScope())) { + if (StringUtils.isEmpty(serverName) || StringUtils.isEmpty(uri)) { + throw new IllegalArgumentException("The hierarchy of privilege is not correct."); + } + } else if (ServiceConstants.PrivilegeScope.DATABASE.toString().equals(tSentryPrivilege.getPrivilegeScope())) { + if (StringUtils.isEmpty(serverName) || StringUtils.isEmpty(dbName)) { + throw new IllegalArgumentException("The hierarchy of privilege is not correct."); + } + } else if (ServiceConstants.PrivilegeScope.TABLE.toString().equals(tSentryPrivilege.getPrivilegeScope())) { + if (StringUtils.isEmpty(serverName) || StringUtils.isEmpty(dbName) + || StringUtils.isEmpty(tableName)) { + throw new IllegalArgumentException("The hierarchy of privilege is not correct."); + } + } else if (ServiceConstants.PrivilegeScope.COLUMN.toString().equals(tSentryPrivilege.getPrivilegeScope())) { + if (StringUtils.isEmpty(serverName) || StringUtils.isEmpty(dbName) + || StringUtils.isEmpty(tableName) || StringUtils.isEmpty(columnName)) { + throw new IllegalArgumentException("The hierarchy of privilege is not correct."); + } + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/0adfc738/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/CreateRoleCmd.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/CreateRoleCmd.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/CreateRoleCmd.java new file mode 100644 index 0000000..5a4834a --- /dev/null +++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/CreateRoleCmd.java @@ -0,0 +1,37 @@ +/** + * 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.tools.command.hive; + +import org.apache.sentry.provider.db.service.thrift.SentryPolicyServiceClient; + +/** + * The class for admin command to create role. + */ +public class CreateRoleCmd implements Command { + + private String roleName; + + public CreateRoleCmd(String roleName) { + this.roleName = roleName; + } + + @Override + public void execute(SentryPolicyServiceClient client, String requestorName) throws Exception { + client.createRole(requestorName, roleName); + } +} http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/0adfc738/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/DropRoleCmd.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/DropRoleCmd.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/DropRoleCmd.java new file mode 100644 index 0000000..facec0e --- /dev/null +++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/DropRoleCmd.java @@ -0,0 +1,37 @@ +/** + * 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.tools.command.hive; + +import org.apache.sentry.provider.db.service.thrift.SentryPolicyServiceClient; + +/** + * The class for admin command to drop role. + */ +public class DropRoleCmd implements Command { + + private String roleName; + + public DropRoleCmd(String roleName) { + this.roleName = roleName; + } + + @Override + public void execute(SentryPolicyServiceClient client, String requestorName) throws Exception { + client.dropRole(requestorName, roleName); + } +} http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/0adfc738/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/GrantPrivilegeToRoleCmd.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/GrantPrivilegeToRoleCmd.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/GrantPrivilegeToRoleCmd.java new file mode 100644 index 0000000..a1ef2f9 --- /dev/null +++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/GrantPrivilegeToRoleCmd.java @@ -0,0 +1,61 @@ +/** + * 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.tools.command.hive; + +import org.apache.sentry.provider.db.service.thrift.SentryPolicyServiceClient; +import org.apache.sentry.provider.db.service.thrift.TSentryGrantOption; +import org.apache.sentry.provider.db.service.thrift.TSentryPrivilege; +import org.apache.sentry.service.thrift.ServiceConstants; + +/** + * The class for admin command to grant privilege to role. + */ +public class GrantPrivilegeToRoleCmd implements Command { + + private String roleName; + private String privilegeStr; + + public GrantPrivilegeToRoleCmd(String roleName, String privilegeStr) { + this.roleName = roleName; + this.privilegeStr = privilegeStr; + } + + @Override + public void execute(SentryPolicyServiceClient client, String requestorName) throws Exception { + TSentryPrivilege tSentryPrivilege = CommandUtil.convertToTSentryPrivilege(privilegeStr); + boolean grantOption = tSentryPrivilege.getGrantOption().equals(TSentryGrantOption.TRUE) ? true : false; + if (ServiceConstants.PrivilegeScope.SERVER.toString().equals(tSentryPrivilege.getPrivilegeScope())) { + client.grantServerPrivilege(requestorName, roleName, tSentryPrivilege.getServerName(), + tSentryPrivilege.getAction(), grantOption); + } else if (ServiceConstants.PrivilegeScope.DATABASE.toString().equals(tSentryPrivilege.getPrivilegeScope())) { + client.grantDatabasePrivilege(requestorName, roleName, tSentryPrivilege.getServerName(), + tSentryPrivilege.getDbName(), tSentryPrivilege.getAction(), grantOption); + } else if (ServiceConstants.PrivilegeScope.TABLE.toString().equals(tSentryPrivilege.getPrivilegeScope())) { + client.grantTablePrivilege(requestorName, roleName, tSentryPrivilege.getServerName(), + tSentryPrivilege.getDbName(), tSentryPrivilege.getTableName(), + tSentryPrivilege.getAction(), grantOption); + } else if (ServiceConstants.PrivilegeScope.COLUMN.toString().equals(tSentryPrivilege.getPrivilegeScope())) { + client.grantColumnPrivilege(requestorName, roleName, tSentryPrivilege.getServerName(), + tSentryPrivilege.getDbName(), tSentryPrivilege.getTableName(), + tSentryPrivilege.getColumnName(), tSentryPrivilege.getAction(), grantOption); + } else if (ServiceConstants.PrivilegeScope.URI.toString().equals(tSentryPrivilege.getPrivilegeScope())) { + client.grantURIPrivilege(requestorName, roleName, tSentryPrivilege.getServerName(), + tSentryPrivilege.getURI(), grantOption); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/0adfc738/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/GrantRoleToGroupsCmd.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/GrantRoleToGroupsCmd.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/GrantRoleToGroupsCmd.java new file mode 100644 index 0000000..39d3591 --- /dev/null +++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/GrantRoleToGroupsCmd.java @@ -0,0 +1,43 @@ +/** + * 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.tools.command.hive; + +import com.google.common.collect.Sets; +import org.apache.sentry.provider.db.service.thrift.SentryPolicyServiceClient; + +import java.util.Set; + +/** + * The class for admin command to grant role to group. + */ +public class GrantRoleToGroupsCmd implements Command { + + private String roleName; + private String groupNamesStr; + + public GrantRoleToGroupsCmd(String roleName, String groupNamesStr) { + this.roleName = roleName; + this.groupNamesStr = groupNamesStr; + } + + @Override + public void execute(SentryPolicyServiceClient client, String requestorName) throws Exception { + Set<String> groups = Sets.newHashSet(groupNamesStr.split(CommandUtil.SPLIT_CHAR)); + client.grantRoleToGroups(requestorName, roleName, groups); + } +} http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/0adfc738/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/ListPrivilegesCmd.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/ListPrivilegesCmd.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/ListPrivilegesCmd.java new file mode 100644 index 0000000..98fae95 --- /dev/null +++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/ListPrivilegesCmd.java @@ -0,0 +1,97 @@ +/** + * 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.tools.command.hive; + +import com.google.common.collect.Lists; +import org.apache.commons.lang.StringUtils; +import org.apache.sentry.provider.common.PolicyFileConstants; +import org.apache.sentry.provider.common.ProviderConstants; +import org.apache.sentry.provider.db.service.thrift.SentryPolicyServiceClient; +import org.apache.sentry.provider.db.service.thrift.TSentryGrantOption; +import org.apache.sentry.provider.db.service.thrift.TSentryPrivilege; + +import java.util.List; +import java.util.Set; + +/** + * The class for admin command to list privileges. + */ +public class ListPrivilegesCmd implements Command { + + private String roleName; + + public ListPrivilegesCmd(String roleName) { + this.roleName = roleName; + } + + @Override + public void execute(SentryPolicyServiceClient client, String requestorName) throws Exception { + Set<TSentryPrivilege> privileges = client + .listAllPrivilegesByRoleName(requestorName, roleName); + if (privileges != null) { + for (TSentryPrivilege privilege : privileges) { + String privilegeStr = convertToPrivilegeStr(privilege); + System.out.println(privilegeStr); + } + } + } + + // convert TSentryPrivilege to privilege in string + private String convertToPrivilegeStr(TSentryPrivilege tSentryPrivilege) { + List<String> privileges = Lists.newArrayList(); + if (tSentryPrivilege != null) { + String serverName = tSentryPrivilege.getServerName(); + String dbName = tSentryPrivilege.getDbName(); + String tableName = tSentryPrivilege.getTableName(); + String columnName = tSentryPrivilege.getColumnName(); + String uri = tSentryPrivilege.getURI(); + String action = tSentryPrivilege.getAction(); + String grantOption = (tSentryPrivilege.getGrantOption() == TSentryGrantOption.TRUE ? "true" + : "false"); + if (!StringUtils.isEmpty(serverName)) { + privileges.add(ProviderConstants.KV_JOINER.join(PolicyFileConstants.PRIVILEGE_SERVER_NAME, + serverName)); + if (!StringUtils.isEmpty(uri)) { + privileges.add(ProviderConstants.KV_JOINER.join(PolicyFileConstants.PRIVILEGE_URI_NAME, + uri)); + } else if (!StringUtils.isEmpty(dbName)) { + privileges.add(ProviderConstants.KV_JOINER.join( + PolicyFileConstants.PRIVILEGE_DATABASE_NAME, dbName)); + if (!StringUtils.isEmpty(tableName)) { + privileges.add(ProviderConstants.KV_JOINER.join( + PolicyFileConstants.PRIVILEGE_TABLE_NAME, tableName)); + if (!StringUtils.isEmpty(columnName)) { + privileges.add(ProviderConstants.KV_JOINER.join( + PolicyFileConstants.PRIVILEGE_COLUMN_NAME, columnName)); + } + } + } + if (!StringUtils.isEmpty(action)) { + privileges.add(ProviderConstants.KV_JOINER.join( + PolicyFileConstants.PRIVILEGE_ACTION_NAME, action)); + } + } + // only append the grant option to privilege string if it's true + if ("true".equals(grantOption)) { + privileges.add(ProviderConstants.KV_JOINER.join( + PolicyFileConstants.PRIVILEGE_GRANT_OPTION_NAME, grantOption)); + } + } + return ProviderConstants.AUTHORIZABLE_JOINER.join(privileges); + } +} http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/0adfc738/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/ListRolesCmd.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/ListRolesCmd.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/ListRolesCmd.java new file mode 100644 index 0000000..283f2c0 --- /dev/null +++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/ListRolesCmd.java @@ -0,0 +1,51 @@ +/** + * 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.tools.command.hive; + +import org.apache.commons.lang.StringUtils; +import org.apache.sentry.provider.db.service.thrift.SentryPolicyServiceClient; +import org.apache.sentry.provider.db.service.thrift.TSentryRole; + +import java.util.Set; + +/** + * The class for admin command to list roles. + */ +public class ListRolesCmd implements Command { + + private String groupName; + + public ListRolesCmd(String groupName) { + this.groupName = groupName; + } + + @Override + public void execute(SentryPolicyServiceClient client, String requestorName) throws Exception { + Set<TSentryRole> roles; + if (StringUtils.isEmpty(groupName)) { + roles = client.listRoles(requestorName); + } else { + roles = client.listRolesByGroupName(requestorName, groupName); + } + if (roles != null) { + for (TSentryRole role : roles) { + System.out.println(role.getRoleName()); + } + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/0adfc738/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/RevokePrivilegeFromRoleCmd.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/RevokePrivilegeFromRoleCmd.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/RevokePrivilegeFromRoleCmd.java new file mode 100644 index 0000000..9405037 --- /dev/null +++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/RevokePrivilegeFromRoleCmd.java @@ -0,0 +1,62 @@ +/** + * 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.tools.command.hive; + +import org.apache.sentry.provider.db.service.thrift.SentryPolicyServiceClient; +import org.apache.sentry.provider.db.service.thrift.TSentryGrantOption; +import org.apache.sentry.provider.db.service.thrift.TSentryPrivilege; +import org.apache.sentry.service.thrift.ServiceConstants; + +/** + * The class for admin command to revoke privileges from role. + */ +public class RevokePrivilegeFromRoleCmd implements Command { + + private String roleName; + String privilegeStr; + + public RevokePrivilegeFromRoleCmd(String roleName, String privilegeStr) { + this.roleName = roleName; + this.privilegeStr = privilegeStr; + } + + @Override + public void execute(SentryPolicyServiceClient client, String requestorName) throws Exception { + TSentryPrivilege tSentryPrivilege = CommandUtil.convertToTSentryPrivilege(privilegeStr); + boolean grantOption = tSentryPrivilege.getGrantOption().equals(TSentryGrantOption.TRUE) ? true : false; + if (ServiceConstants.PrivilegeScope.SERVER.toString().equals(tSentryPrivilege.getPrivilegeScope())) { + client.revokeServerPrivilege(requestorName, roleName, tSentryPrivilege.getServerName(), + grantOption); + } else if (ServiceConstants.PrivilegeScope.DATABASE.toString().equals(tSentryPrivilege.getPrivilegeScope())) { + client.revokeDatabasePrivilege(requestorName, roleName, tSentryPrivilege.getServerName(), + tSentryPrivilege.getDbName(), tSentryPrivilege.getAction(), grantOption); + } else if (ServiceConstants.PrivilegeScope.TABLE.toString().equals(tSentryPrivilege.getPrivilegeScope())) { + client.revokeTablePrivilege(requestorName, roleName, tSentryPrivilege.getServerName(), + tSentryPrivilege.getDbName(), tSentryPrivilege.getTableName(), + tSentryPrivilege.getAction(), grantOption); + } else if (ServiceConstants.PrivilegeScope.COLUMN.toString().equals(tSentryPrivilege.getPrivilegeScope())) { + client.revokeColumnPrivilege(requestorName, roleName, tSentryPrivilege.getServerName(), + tSentryPrivilege.getDbName(), tSentryPrivilege.getTableName(), + tSentryPrivilege.getColumnName(), tSentryPrivilege.getAction(), grantOption); + } else if (ServiceConstants.PrivilegeScope.URI.toString().equals(tSentryPrivilege.getPrivilegeScope())) { + client.revokeURIPrivilege(requestorName, roleName, tSentryPrivilege.getServerName(), + tSentryPrivilege.getURI(), grantOption); + } + } + +} http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/0adfc738/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/RevokeRoleFromGroupsCmd.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/RevokeRoleFromGroupsCmd.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/RevokeRoleFromGroupsCmd.java new file mode 100644 index 0000000..86773ca --- /dev/null +++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/RevokeRoleFromGroupsCmd.java @@ -0,0 +1,43 @@ +/** + * 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.tools.command.hive; + +import com.google.common.collect.Sets; +import org.apache.sentry.provider.db.service.thrift.SentryPolicyServiceClient; + +import java.util.Set; + +/** + * The class for admin command to revoke role from group. + */ +public class RevokeRoleFromGroupsCmd implements Command { + + private String roleName; + private String groupNamesStr; + + public RevokeRoleFromGroupsCmd(String roleName, String groupNamesStr) { + this.roleName = roleName; + this.groupNamesStr = groupNamesStr; + } + + @Override + public void execute(SentryPolicyServiceClient client, String requestorName) throws Exception { + Set<String> groups = Sets.newHashSet(groupNamesStr.split(CommandUtil.SPLIT_CHAR)); + client.revokeRoleFromGroups(requestorName, roleName, groups); + } +} http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/0adfc738/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/tools/TestSentryShellHive.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/tools/TestSentryShellHive.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/tools/TestSentryShellHive.java new file mode 100644 index 0000000..3907200 --- /dev/null +++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/tools/TestSentryShellHive.java @@ -0,0 +1,583 @@ +/** + * 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.tools; + +import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.PrintStream; +import java.util.Set; + +import junit.framework.Assert; +import org.apache.commons.io.FileUtils; +import org.apache.sentry.SentryUserException; +import org.apache.sentry.provider.db.service.thrift.TSentryPrivilege; +import org.apache.sentry.provider.db.service.thrift.TSentryRole; +import org.apache.sentry.service.thrift.SentryServiceIntegrationBase; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.collect.Sets; +import com.google.common.io.Files; + +public class TestSentryShellHive extends SentryServiceIntegrationBase { + + private static final Logger LOGGER = LoggerFactory.getLogger(TestSentryShellHive.class); + private File confDir; + private File confPath; + private static String TEST_ROLE_NAME_1 = "testRole1"; + private static String TEST_ROLE_NAME_2 = "testRole2"; + private String requestorName = ""; + + @Before + public void prepareForTest() throws Exception { + confDir = Files.createTempDir(); + confPath = new File(confDir, "sentry-site.xml"); + if (confPath.createNewFile()) { + FileOutputStream to = new FileOutputStream(confPath); + conf.writeXml(to); + to.close(); + } + requestorName = System.getProperty("user.name", ""); + Set<String> requestorUserGroupNames = Sets.newHashSet(ADMIN_GROUP); + setLocalGroupMapping(requestorName, requestorUserGroupNames); + // add ADMIN_USER for the after() in SentryServiceIntegrationBase + setLocalGroupMapping(ADMIN_USER, requestorUserGroupNames); + writePolicyFile(); + } + + @After + public void clearTestData() throws Exception { + FileUtils.deleteQuietly(confDir); + } + + @Test + public void testCreateDropRole() throws Exception { + runTestAsSubject(new TestOperation() { + @Override + public void runTestAsSubject() throws Exception { + // test: create role with -cr + String[] args = { "-cr", "-r", TEST_ROLE_NAME_1, "-conf", confPath.getAbsolutePath() }; + SentryShellHive.main(args); + // test: create role with --create_role + args = new String[] { "--create_role", "-r", TEST_ROLE_NAME_2, "-conf", + confPath.getAbsolutePath() }; + SentryShellHive.main(args); + + // validate the result, list roles with -lr + args = new String[] { "-lr", "-conf", confPath.getAbsolutePath() }; + SentryShellHive sentryShell = new SentryShellHive(); + Set<String> roleNames = getShellResultWithOSRedirect(sentryShell, args, true); + assertEquals("Incorrect number of roles", 2, roleNames.size()); + for (String roleName : roleNames) { + assertTrue(TEST_ROLE_NAME_1.equalsIgnoreCase(roleName) + || TEST_ROLE_NAME_2.equalsIgnoreCase(roleName)); + } + + // validate the result, list roles with --list_role + args = new String[] { "--list_role", "-conf", confPath.getAbsolutePath() }; + sentryShell = new SentryShellHive(); + roleNames = getShellResultWithOSRedirect(sentryShell, args, true); + assertEquals("Incorrect number of roles", 2, roleNames.size()); + for (String roleName : roleNames) { + assertTrue(TEST_ROLE_NAME_1.equalsIgnoreCase(roleName) + || TEST_ROLE_NAME_2.equalsIgnoreCase(roleName)); + } + + // test: drop role with -dr + args = new String[] { "-dr", "-r", TEST_ROLE_NAME_1, "-conf", confPath.getAbsolutePath() }; + SentryShellHive.main(args); + // test: drop role with --drop_role + args = new String[] { "--drop_role", "-r", TEST_ROLE_NAME_2, "-conf", + confPath.getAbsolutePath() }; + SentryShellHive.main(args); + + // validate the result + Set<TSentryRole> roles = client.listRoles(requestorName); + assertEquals("Incorrect number of roles", 0, roles.size()); + } + }); + } + + @Test + public void testAddDeleteRoleForGroup() throws Exception { + runTestAsSubject(new TestOperation() { + @Override + public void runTestAsSubject() throws Exception { + // create the role for test + client.createRole(requestorName, TEST_ROLE_NAME_1); + client.createRole(requestorName, TEST_ROLE_NAME_2); + // test: add group to role with -arg + String[] args = { "-arg", "-r", TEST_ROLE_NAME_1, "-g", "testGroup1", "-conf", + confPath.getAbsolutePath() }; + SentryShellHive.main(args); + // test: add role to multiple groups + args = new String[] { "-arg", "-r", TEST_ROLE_NAME_1, "-g", "testGroup2,testGroup3", + "-conf", + confPath.getAbsolutePath() }; + SentryShellHive.main(args); + // test: add role to group with --add_role_group + args = new String[] { "--add_role_group", "-r", TEST_ROLE_NAME_2, "-g", "testGroup1", + "-conf", + confPath.getAbsolutePath() }; + SentryShellHive.main(args); + + // validate the result list roles with -lr and -g + args = new String[] { "-lr", "-g", "testGroup1", "-conf", confPath.getAbsolutePath() }; + SentryShellHive sentryShell = new SentryShellHive(); + Set<String> roleNames = getShellResultWithOSRedirect(sentryShell, args, true); + assertEquals("Incorrect number of roles", 2, roleNames.size()); + for (String roleName : roleNames) { + assertTrue(TEST_ROLE_NAME_1.equalsIgnoreCase(roleName) + || TEST_ROLE_NAME_2.equalsIgnoreCase(roleName)); + } + + // list roles with --list_role and -g + args = new String[] { "--list_role", "-g", "testGroup2", "-conf", + confPath.getAbsolutePath() }; + sentryShell = new SentryShellHive(); + roleNames = getShellResultWithOSRedirect(sentryShell, args, true); + assertEquals("Incorrect number of roles", 1, roleNames.size()); + for (String roleName : roleNames) { + assertTrue(TEST_ROLE_NAME_1.equalsIgnoreCase(roleName)); + } + + args = new String[] { "--list_role", "-g", "testGroup3", "-conf", + confPath.getAbsolutePath() }; + sentryShell = new SentryShellHive(); + roleNames = getShellResultWithOSRedirect(sentryShell, args, true); + assertEquals("Incorrect number of roles", 1, roleNames.size()); + for (String roleName : roleNames) { + assertTrue(TEST_ROLE_NAME_1.equalsIgnoreCase(roleName)); + } + + // test: delete group from role with -drg + args = new String[] { "-drg", "-r", TEST_ROLE_NAME_1, "-g", "testGroup1", "-conf", + confPath.getAbsolutePath() }; + SentryShellHive.main(args); + // test: delete role to multiple groups + args = new String[] { "-drg", "-r", TEST_ROLE_NAME_1, "-g", "testGroup2,testGroup3", + "-conf", + confPath.getAbsolutePath() }; + SentryShellHive.main(args); + // test: delete group from role with --delete_role_group + args = new String[] { "--delete_role_group", "-r", TEST_ROLE_NAME_2, "-g", "testGroup1", + "-conf", confPath.getAbsolutePath() }; + SentryShellHive.main(args); + + // validate the result + Set<TSentryRole> roles = client.listRolesByGroupName(requestorName, "testGroup1"); + assertEquals("Incorrect number of roles", 0, roles.size()); + roles = client.listRolesByGroupName(requestorName, "testGroup2"); + assertEquals("Incorrect number of roles", 0, roles.size()); + roles = client.listRolesByGroupName(requestorName, "testGroup3"); + assertEquals("Incorrect number of roles", 0, roles.size()); + // clear the test data + client.dropRole(requestorName, TEST_ROLE_NAME_1); + client.dropRole(requestorName, TEST_ROLE_NAME_2); + } + }); + } + + @Test + public void testGrantRevokePrivilegeWithShortOption() throws Exception { + runTestAsSubject(new TestOperation() { + @Override + public void runTestAsSubject() throws Exception { + // create the role for test + client.createRole(requestorName, TEST_ROLE_NAME_1); + client.createRole(requestorName, TEST_ROLE_NAME_2); + + // test: grant privilege to role with -gpr + String[] args = { "-gpr", "-r", TEST_ROLE_NAME_1, "-p", + "server=server1->action=*", + "-conf", confPath.getAbsolutePath() }; + SentryShellHive.main(args); + args = new String[] { "-gpr", "-r", TEST_ROLE_NAME_1, "-p", + "server=server1->db=db1->action=select", "-conf", confPath.getAbsolutePath() }; + SentryShellHive.main(args); + args = new String[] { "-gpr", "-r", TEST_ROLE_NAME_1, "-p", + "server=server1->db=db1->table=tbl1->action=insert", "-conf", + confPath.getAbsolutePath() }; + SentryShellHive.main(args); + args = new String[] { "-gpr", "-r", TEST_ROLE_NAME_1, "-p", + "server=server1->db=db1->table=tbl1->column=col1->action=insert", "-conf", + confPath.getAbsolutePath() }; + SentryShellHive.main(args); + args = new String[] { "-gpr", "-r", TEST_ROLE_NAME_1, "-p", + "server=server1->db=db1->table=tbl1->column=col2->action=insert->grantoption=true", + "-conf", confPath.getAbsolutePath() }; + SentryShellHive.main(args); + // for the uri privilege, the action will be awalys * + args = new String[] { "-gpr", "-r", TEST_ROLE_NAME_1, "-p", + "server=server1->uri=hdfs://path/testuri", "-conf", confPath.getAbsolutePath() }; + SentryShellHive.main(args); + + // test the list privilege with -lp + args = new String[] { "-lp", "-r", TEST_ROLE_NAME_1, "-conf", confPath.getAbsolutePath() }; + SentryShellHive sentryShell = new SentryShellHive(); + Set<String> privilegeStrs = getShellResultWithOSRedirect(sentryShell, args, true); + // validate the result for -lp + assertEquals("Incorrect number of privileges", 6, privilegeStrs.size()); + assertTrue(privilegeStrs.contains("server=server1->action=*")); + assertTrue(privilegeStrs.contains("server=server1->db=db1->action=select")); + assertTrue(privilegeStrs.contains("server=server1->db=db1->table=tbl1->action=insert")); + assertTrue(privilegeStrs + .contains("server=server1->db=db1->table=tbl1->column=col1->action=insert")); + assertTrue(privilegeStrs + .contains("server=server1->db=db1->table=tbl1->column=col2->action=insert->grantoption=true")); + // for the uri privilege, the action will be awalys * + assertTrue(privilegeStrs.contains("server=server1->uri=hdfs://path/testuri->action=*")); + + // test: revoke privilege from role with -rpr + args = new String[] { "-rpr", "-r", TEST_ROLE_NAME_1, "-p", + "server=server1->db=db1->table=tbl1->column=col1->action=insert", "-conf", + confPath.getAbsolutePath() }; + SentryShellHive.main(args); + Set<TSentryPrivilege> privileges = client.listAllPrivilegesByRoleName(requestorName, + TEST_ROLE_NAME_1); + assertEquals("Incorrect number of privileges", 5, privileges.size()); + + args = new String[] { "-rpr", "-r", TEST_ROLE_NAME_1, "-p", + "server=server1->db=db1->table=tbl1->column=col2->action=insert->grantoption=true", + "-conf", confPath.getAbsolutePath() }; + SentryShellHive.main(args); + privileges = client.listAllPrivilegesByRoleName(requestorName, TEST_ROLE_NAME_1); + assertEquals("Incorrect number of privileges", 4, privileges.size()); + + args = new String[] { "-rpr", "-r", TEST_ROLE_NAME_1, "-p", + "server=server1->uri=hdfs://path/testuri", "-conf", confPath.getAbsolutePath() }; + SentryShellHive.main(args); + privileges = client.listAllPrivilegesByRoleName(requestorName, TEST_ROLE_NAME_1); + assertEquals("Incorrect number of privileges", 3, privileges.size()); + + args = new String[] { "-rpr", "-r", TEST_ROLE_NAME_1, "-p", + "server=server1->db=db1->table=tbl1->action=insert", "-conf", + confPath.getAbsolutePath() }; + SentryShellHive.main(args); + privileges = client.listAllPrivilegesByRoleName(requestorName, TEST_ROLE_NAME_1); + assertEquals("Incorrect number of privileges", 2, privileges.size()); + + args = new String[] { "-rpr", "-r", TEST_ROLE_NAME_1, "-p", + "server=server1->db=db1->action=select", "-conf", confPath.getAbsolutePath() }; + SentryShellHive.main(args); + privileges = client.listAllPrivilegesByRoleName(requestorName, TEST_ROLE_NAME_1); + assertEquals("Incorrect number of privileges", 1, privileges.size()); + + args = new String[] { "-rpr", "-r", TEST_ROLE_NAME_1, "-p", "server=server1->action=*", + "-conf", + confPath.getAbsolutePath() }; + SentryShellHive.main(args); + privileges = client.listAllPrivilegesByRoleName(requestorName, TEST_ROLE_NAME_1); + assertEquals("Incorrect number of privileges", 0, privileges.size()); + + // clear the test data + client.dropRole(requestorName, TEST_ROLE_NAME_1); + client.dropRole(requestorName, TEST_ROLE_NAME_2); + } + }); + } + + @Test + public void testGrantRevokePrivilegeWithLongOption() throws Exception { + runTestAsSubject(new TestOperation() { + @Override + public void runTestAsSubject() throws Exception { + // create the role for test + client.createRole(requestorName, TEST_ROLE_NAME_1); + client.createRole(requestorName, TEST_ROLE_NAME_2); + + // test: grant privilege to role with -gpr + String[] args = { "--grant_privilege_role", "-r", TEST_ROLE_NAME_1, "-p", + "server=server1->action=*", "-conf", confPath.getAbsolutePath() }; + SentryShellHive.main(args); + args = new String[] { "--grant_privilege_role", "-r", TEST_ROLE_NAME_1, "-p", + "server=server1->db=db1->action=select", "-conf", confPath.getAbsolutePath() }; + SentryShellHive.main(args); + args = new String[] { "--grant_privilege_role", "-r", TEST_ROLE_NAME_1, "-p", + "server=server1->db=db1->table=tbl1->action=insert", "-conf", + confPath.getAbsolutePath() }; + SentryShellHive.main(args); + args = new String[] { "--grant_privilege_role", "-r", TEST_ROLE_NAME_1, "-p", + "server=server1->db=db1->table=tbl1->column=col1->action=insert", "-conf", + confPath.getAbsolutePath() }; + SentryShellHive.main(args); + args = new String[] { "--grant_privilege_role", "-r", TEST_ROLE_NAME_1, "-p", + "server=server1->db=db1->table=tbl1->column=col2->action=insert->grantoption=true", + "-conf", confPath.getAbsolutePath() }; + SentryShellHive.main(args); + // for the uri privilege, the action will be awalys * + args = new String[] { "--grant_privilege_role", "-r", TEST_ROLE_NAME_1, "-p", + "server=server1->uri=hdfs://path/testuri", "-conf", confPath.getAbsolutePath() }; + SentryShellHive.main(args); + + // test the list privilege with -lp + args = new String[] { "--list_privilege", "-r", TEST_ROLE_NAME_1, "-conf", + confPath.getAbsolutePath() }; + SentryShellHive sentryShell = new SentryShellHive(); + Set<String> privilegeStrs = getShellResultWithOSRedirect(sentryShell, args, true); + // validate the result for -lp + assertEquals("Incorrect number of privileges", 6, privilegeStrs.size()); + assertTrue(privilegeStrs.contains("server=server1->action=*")); + assertTrue(privilegeStrs.contains("server=server1->db=db1->action=select")); + assertTrue(privilegeStrs.contains("server=server1->db=db1->table=tbl1->action=insert")); + assertTrue(privilegeStrs + .contains("server=server1->db=db1->table=tbl1->column=col1->action=insert")); + assertTrue(privilegeStrs + .contains("server=server1->db=db1->table=tbl1->column=col2->action=insert->grantoption=true")); + // for the uri privilege, the action will be awalys * + assertTrue(privilegeStrs.contains("server=server1->uri=hdfs://path/testuri->action=*")); + + // test: revoke privilege from role with -rpr + args = new String[] { "--revoke_privilege_role", "-r", TEST_ROLE_NAME_1, "-p", + "server=server1->db=db1->table=tbl1->column=col1->action=insert", "-conf", + confPath.getAbsolutePath() }; + SentryShellHive.main(args); + Set<TSentryPrivilege> privileges = client.listAllPrivilegesByRoleName(requestorName, + TEST_ROLE_NAME_1); + assertEquals("Incorrect number of privileges", 5, privileges.size()); + + args = new String[] { "--revoke_privilege_role", "-r", TEST_ROLE_NAME_1, "-p", + "server=server1->db=db1->table=tbl1->column=col2->action=insert->grantoption=true", + "-conf", confPath.getAbsolutePath() }; + SentryShellHive.main(args); + privileges = client.listAllPrivilegesByRoleName(requestorName, TEST_ROLE_NAME_1); + assertEquals("Incorrect number of privileges", 4, privileges.size()); + + args = new String[] { "--revoke_privilege_role", "-r", TEST_ROLE_NAME_1, "-p", + "server=server1->uri=hdfs://path/testuri", "-conf", confPath.getAbsolutePath() }; + SentryShellHive.main(args); + privileges = client.listAllPrivilegesByRoleName(requestorName, TEST_ROLE_NAME_1); + assertEquals("Incorrect number of privileges", 3, privileges.size()); + + args = new String[] { "--revoke_privilege_role", "-r", TEST_ROLE_NAME_1, "-p", + "server=server1->db=db1->table=tbl1->action=insert", "-conf", + confPath.getAbsolutePath() }; + SentryShellHive.main(args); + privileges = client.listAllPrivilegesByRoleName(requestorName, TEST_ROLE_NAME_1); + assertEquals("Incorrect number of privileges", 2, privileges.size()); + + args = new String[] { "--revoke_privilege_role", "-r", TEST_ROLE_NAME_1, "-p", + "server=server1->db=db1->action=select", "-conf", confPath.getAbsolutePath() }; + SentryShellHive.main(args); + privileges = client.listAllPrivilegesByRoleName(requestorName, TEST_ROLE_NAME_1); + assertEquals("Incorrect number of privileges", 1, privileges.size()); + + args = new String[] { "--revoke_privilege_role", "-r", TEST_ROLE_NAME_1, "-p", + "server=server1->action=*", "-conf", confPath.getAbsolutePath() }; + SentryShellHive.main(args); + privileges = client.listAllPrivilegesByRoleName(requestorName, TEST_ROLE_NAME_1); + assertEquals("Incorrect number of privileges", 0, privileges.size()); + + // clear the test data + client.dropRole(requestorName, TEST_ROLE_NAME_1); + client.dropRole(requestorName, TEST_ROLE_NAME_2); + } + }); + } + + @Test + public void testNegativeCaseWithInvalidArgument() throws Exception { + runTestAsSubject(new TestOperation() { + @Override + public void runTestAsSubject() throws Exception { + client.createRole(requestorName, TEST_ROLE_NAME_1); + // test: create duplicate role with -cr + String[] args = { "-cr", "-r", TEST_ROLE_NAME_1, "-conf", confPath.getAbsolutePath() }; + SentryShellHive sentryShell = new SentryShellHive(); + try { + sentryShell.executeShell(args); + fail("Exception should be thrown for creating duplicate role"); + } catch (SentryUserException e) { + // excepted exception + } + + // test: drop non-exist role with -dr + args = new String[] { "-dr", "-r", TEST_ROLE_NAME_2, "-conf", confPath.getAbsolutePath() }; + sentryShell = new SentryShellHive(); + try { + sentryShell.executeShell(args); + fail("Exception should be thrown for dropping non-exist role"); + } catch (SentryUserException e) { + // excepted exception + } + + // test: add group to non-exist role with -arg + args = new String[] { "-arg", "-r", TEST_ROLE_NAME_2, "-g", "testGroup1", "-conf", + confPath.getAbsolutePath() }; + sentryShell = new SentryShellHive(); + try { + sentryShell.executeShell(args); + fail("Exception should be thrown for granting non-exist role to group"); + } catch (SentryUserException e) { + // excepted exception + } + + // test: drop group from non-exist role with -drg + args = new String[] { "-drg", "-r", TEST_ROLE_NAME_2, "-g", "testGroup1", "-conf", + confPath.getAbsolutePath() }; + sentryShell = new SentryShellHive(); + try { + sentryShell.executeShell(args); + fail("Exception should be thrown for drop group from non-exist role"); + } catch (SentryUserException e) { + // excepted exception + } + + // test: grant privilege to role with the error privilege format + args = new String[] { "-gpr", "-r", TEST_ROLE_NAME_1, "-p", "serverserver1->action=*", + "-conf", confPath.getAbsolutePath() }; + sentryShell = new SentryShellHive(); + try { + sentryShell.executeShell(args); + fail("Exception should be thrown for the error privilege format, invalid key value."); + } catch (IllegalArgumentException e) { + // excepted exception + } + + // test: grant privilege to role with the error privilege hierarchy + args = new String[] { "-gpr", "-r", TEST_ROLE_NAME_1, "-p", + "server=server1->table=tbl1->column=col2->action=insert", "-conf", + confPath.getAbsolutePath() }; + sentryShell = new SentryShellHive(); + try { + sentryShell.executeShell(args); + fail("Exception should be thrown for the error privilege format, invalid key value."); + } catch (IllegalArgumentException e) { + // excepted exception + } + + // clear the test data + client.dropRole(requestorName, TEST_ROLE_NAME_1); + } + }); + } + + @Test + public void testNegativeCaseWithoutRequiredArgument() throws Exception { + runTestAsSubject(new TestOperation() { + @Override + public void runTestAsSubject() throws Exception { + String strOptionConf = "conf"; + client.createRole(requestorName, TEST_ROLE_NAME_1); + // test: the conf is required argument + String[] args = { "-cr", "-r", TEST_ROLE_NAME_1 }; + SentryShellHive sentryShell = new SentryShellHive(); + validateMissingParameterMsg(sentryShell, args, + SentryShellCommon.PREFIX_MESSAGE_MISSING_OPTION + strOptionConf); + + // test: -r is required when create role + args = new String[] { "-cr", "-conf", confPath.getAbsolutePath() }; + sentryShell = new SentryShellHive(); + validateMissingParameterMsg(sentryShell, args, + SentryShellCommon.PREFIX_MESSAGE_MISSING_OPTION + SentryShellCommon.OPTION_DESC_ROLE_NAME); + + // test: -r is required when drop role + args = new String[] { "-dr", "-conf", confPath.getAbsolutePath() }; + sentryShell = new SentryShellHive(); + validateMissingParameterMsg(sentryShell, args, + SentryShellCommon.PREFIX_MESSAGE_MISSING_OPTION + SentryShellCommon.OPTION_DESC_ROLE_NAME); + + // test: -r is required when add group to role + args = new String[] { "-arg", "-g", "testGroup1", "-conf", confPath.getAbsolutePath() }; + sentryShell = new SentryShellHive(); + validateMissingParameterMsg(sentryShell, args, + SentryShellCommon.PREFIX_MESSAGE_MISSING_OPTION + SentryShellCommon.OPTION_DESC_ROLE_NAME); + + // test: -g is required when add group to role + args = new String[] { "-arg", "-r", TEST_ROLE_NAME_2, "-conf", confPath.getAbsolutePath() }; + sentryShell = new SentryShellHive(); + validateMissingParameterMsg(sentryShell, args, + SentryShellCommon.PREFIX_MESSAGE_MISSING_OPTION + SentryShellCommon.OPTION_DESC_GROUP_NAME); + + // test: -r is required when delete group from role + args = new String[] { "-drg", "-g", "testGroup1", "-conf", confPath.getAbsolutePath() }; + sentryShell = new SentryShellHive(); + validateMissingParameterMsg(sentryShell, args, + SentryShellCommon.PREFIX_MESSAGE_MISSING_OPTION + SentryShellCommon.OPTION_DESC_ROLE_NAME); + + // test: -g is required when delete group from role + args = new String[] { "-drg", "-r", TEST_ROLE_NAME_2, "-conf", confPath.getAbsolutePath() }; + sentryShell = new SentryShellHive(); + validateMissingParameterMsg(sentryShell, args, + SentryShellCommon.PREFIX_MESSAGE_MISSING_OPTION + SentryShellCommon.OPTION_DESC_GROUP_NAME); + + // test: -r is required when grant privilege to role + args = new String[] { "-gpr", "-p", "server=server1", "-conf", confPath.getAbsolutePath() }; + sentryShell = new SentryShellHive(); + validateMissingParameterMsg(sentryShell, args, + SentryShellCommon.PREFIX_MESSAGE_MISSING_OPTION + SentryShellCommon.OPTION_DESC_ROLE_NAME); + + // test: -p is required when grant privilege to role + args = new String[] { "-gpr", "-r", TEST_ROLE_NAME_1, "-conf", confPath.getAbsolutePath() }; + sentryShell = new SentryShellHive(); + validateMissingParameterMsg(sentryShell, args, + SentryShellCommon.PREFIX_MESSAGE_MISSING_OPTION + SentryShellCommon.OPTION_DESC_PRIVILEGE); + + // test: -r is required when revoke privilege from role + args = new String[] { "-rpr", "-p", "server=server1", "-conf", confPath.getAbsolutePath() }; + sentryShell = new SentryShellHive(); + validateMissingParameterMsg(sentryShell, args, + SentryShellCommon.PREFIX_MESSAGE_MISSING_OPTION + SentryShellCommon.OPTION_DESC_ROLE_NAME); + + // test: -p is required when revoke privilege from role + args = new String[] { "-rpr", "-r", TEST_ROLE_NAME_1, "-conf", confPath.getAbsolutePath() }; + sentryShell = new SentryShellHive(); + validateMissingParameterMsg(sentryShell, args, + SentryShellCommon.PREFIX_MESSAGE_MISSING_OPTION + SentryShellCommon.OPTION_DESC_PRIVILEGE); + + // test: command option is required for shell + args = new String[] {"-conf", confPath.getAbsolutePath() }; + sentryShell = new SentryShellHive(); + validateMissingParameterMsg(sentryShell, args, + SentryShellCommon.PREFIX_MESSAGE_MISSING_OPTION + "[-arg Add group to role," + + " -cr Create role, -rpr Revoke privilege from role, -drg Delete group from role," + + " -lr List role, -lp List privilege, -gpr Grant privilege to role, -dr Drop role]"); + + // clear the test data + client.dropRole(requestorName, TEST_ROLE_NAME_1); + } + }); + } + + // redirect the System.out to ByteArrayOutputStream, then execute the command and parse the result. + private Set<String> getShellResultWithOSRedirect(SentryShellHive sentryShell, + String[] args, boolean exceptedExecuteResult) throws Exception { + PrintStream oldOut = System.out; + ByteArrayOutputStream outContent = new ByteArrayOutputStream(); + System.setOut(new PrintStream(outContent)); + assertEquals(exceptedExecuteResult, sentryShell.executeShell(args)); + Set<String> resultSet = Sets.newHashSet(outContent.toString().split("\n")); + System.setOut(oldOut); + return resultSet; + } + + private void validateMissingParameterMsg(SentryShellHive sentryShell, String[] args, + String exceptedErrorMsg) throws Exception { + Set<String> errorMsgs = getShellResultWithOSRedirect(sentryShell, args, false); + Assert.assertTrue(errorMsgs.contains(exceptedErrorMsg)); + } +} http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/0adfc738/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/service/thrift/SentryServiceIntegrationBase.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/service/thrift/SentryServiceIntegrationBase.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/service/thrift/SentryServiceIntegrationBase.java index 6bc9f75..124293a 100644 --- a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/service/thrift/SentryServiceIntegrationBase.java +++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/service/thrift/SentryServiceIntegrationBase.java @@ -56,12 +56,6 @@ import com.google.common.io.Files; public abstract class SentryServiceIntegrationBase extends SentryMiniKdcTestcase { private static final Logger LOGGER = LoggerFactory.getLogger(SentryServiceIntegrationBase.class); - static { - if (System.getProperty("sun.security.krb5.debug", "").trim().isEmpty()) { - System.setProperty("sun.security.krb5.debug", String.valueOf("true")); - } - } - protected static final String SERVER_HOST = NetUtils.createSocketAddr("localhost:80").getAddress().getCanonicalHostName(); protected static final String REALM = "EXAMPLE.COM"; protected static final String SERVER_PRINCIPAL = "sentry/" + SERVER_HOST;