HA version of interactive CLI
Project: http://git-wip-us.apache.org/repos/asf/sentry/repo Commit: http://git-wip-us.apache.org/repos/asf/sentry/commit/e5ea89e0 Tree: http://git-wip-us.apache.org/repos/asf/sentry/tree/e5ea89e0 Diff: http://git-wip-us.apache.org/repos/asf/sentry/diff/e5ea89e0 Branch: refs/heads/akolb-ha-cli Commit: e5ea89e09af1cf1edc6747180793e7ddd9b12205 Parents: b7903d0 Author: Alexander Kolbasov <[email protected]> Authored: Mon Dec 12 14:15:26 2016 -0800 Committer: Alexander Kolbasov <[email protected]> Committed: Wed May 10 23:28:29 2017 -0700 ---------------------------------------------------------------------- .../main/java/org/apache/sentry/SentryMain.java | 2 + .../provider/db/tools/cli/GroupShell.java | 65 ++++++ .../provider/db/tools/cli/RolesShell.java | 72 +++++++ .../sentry/provider/db/tools/cli/SentryCli.java | 172 ++++++++++++++++ .../sentry/provider/db/tools/cli/ShellUtil.java | 205 +++++++++++++++++++ .../provider/db/tools/cli/TopLevelShell.java | 93 +++++++++ .../sentry/provider/db/cli/GroupShell.java | 65 ------ .../sentry/provider/db/cli/RolesShell.java | 72 ------- .../sentry/provider/db/cli/SentryCli.java | 172 ---------------- .../sentry/provider/db/cli/ShellUtil.java | 205 ------------------- .../sentry/provider/db/cli/TopLevelShell.java | 93 --------- 11 files changed, 609 insertions(+), 607 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/sentry/blob/e5ea89e0/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/SentryMain.java ---------------------------------------------------------------------- diff --git a/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/SentryMain.java b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/SentryMain.java index 3a981b2..82a7759 100644 --- a/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/SentryMain.java +++ b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/SentryMain.java @@ -79,11 +79,13 @@ public class SentryMain { if (!log4jProperties.containsKey("log4j.category.DataNucleus.Query")) { log4jProperties.setProperty("log4j.category.DataNucleus.Query", "INFO"); + /* // Enable debug log for DataNucleus.Query only when log.threshold is TRACE String logThreshold = log4jProperties.getProperty("log.threshold"); if (logThreshold != null && logThreshold.equalsIgnoreCase("TRACE")) { log4jProperties.setProperty("log4j.category.DataNucleus.Query", "DEBUG"); } + */ } PropertyConfigurator.configure(log4jProperties); http://git-wip-us.apache.org/repos/asf/sentry/blob/e5ea89e0/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/cli/GroupShell.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/cli/GroupShell.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/cli/GroupShell.java new file mode 100644 index 0000000..d4b0bd7 --- /dev/null +++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/cli/GroupShell.java @@ -0,0 +1,65 @@ +/* + * 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.cli; + +import com.budhash.cliche.Command; +import com.budhash.cliche.Shell; +import com.budhash.cliche.ShellDependent; +import org.apache.sentry.provider.db.service.thrift.SentryPolicyServiceClient; + +import java.util.List; + +/** + * Sentry group manipulation for CLI + */ +public class GroupShell implements ShellDependent { + @Command + public List<String> list() { + return tools.listGroups(); + } + + @Command(abbrev = "lr", header = "[groups]", + description = "list groups and their roles") + public List<String> listRoles() { + return tools.listGroupRoles(); + } + + @Command(description = "Grant role to groups") + public void grant(String roleName, String ...groups) { + tools.grantGroupsToRole(roleName, groups); + } + + @Command(description = "Revoke role from groups") + public void revoke(String roleName, String ...groups) { + tools.revokeGroupsFromRole(roleName, groups); + } + + private final ShellUtil tools; + Shell shell; + + + public GroupShell(SentryPolicyServiceClient sentryClient, String authUser) { + this.tools = new ShellUtil(sentryClient, authUser); + } + + @Override + public void cliSetShell(Shell theShell) { + this.shell = theShell; + } +} http://git-wip-us.apache.org/repos/asf/sentry/blob/e5ea89e0/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/cli/RolesShell.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/cli/RolesShell.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/cli/RolesShell.java new file mode 100644 index 0000000..71f0cab --- /dev/null +++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/cli/RolesShell.java @@ -0,0 +1,72 @@ +/* + * 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.cli; + +import com.budhash.cliche.Command; +import com.budhash.cliche.Param; +import com.budhash.cliche.Shell; +import com.budhash.cliche.ShellDependent; +import org.apache.sentry.provider.db.service.thrift.SentryPolicyServiceClient; + +import java.util.List; + +/** + * Sentry roles manipulation for CLI. + */ +public class RolesShell implements ShellDependent { + @Command(description = "List sentry roles. shows all available roles.") + public List<String> list() { + return tools.listRoles(); + } + + @Command(description = "List sentry roles by group") + public List<String> list( + @Param(name = "groupName", description = "group name for roles") + String group) { + return tools.listRoles(group); + } + + @Command(description = "Create Sentry role(s).") + public void create( + @Param(name = "roleName", description = "name of role to create") + String ...roles) { + tools.createRoles(roles); + } + + @Command(description = "remove Sentry role(s).") + public void remove( + @Param(name = "roleName ...", description = "role names to remove") + String ...roles) { + tools.removeRoles(roles); + } + + + @Override + public void cliSetShell(Shell theShell) { + this.shell = theShell; + } + + private final ShellUtil tools; + Shell shell; + + public RolesShell(SentryPolicyServiceClient sentryClient, String authUser) { + this.tools = new ShellUtil(sentryClient, authUser); + } + +} http://git-wip-us.apache.org/repos/asf/sentry/blob/e5ea89e0/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/cli/SentryCli.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/cli/SentryCli.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/cli/SentryCli.java new file mode 100644 index 0000000..f9bbfd3 --- /dev/null +++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/cli/SentryCli.java @@ -0,0 +1,172 @@ +/** + * 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.cli; + +import org.apache.commons.cli.*; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.fs.Path; +import org.apache.hadoop.security.UserGroupInformation; +import org.apache.log4j.PropertyConfigurator; +import org.apache.sentry.provider.db.service.thrift.SentryPolicyServiceClient; +import org.apache.sentry.service.thrift.SentryServiceClientFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.Map; +import java.util.Properties; + +/** + * Sentry interactive tool + */ +public class SentryCli { + private static final Logger log = LoggerFactory.getLogger(SentryCli.class.getName()); + private static final String LOG4J_CONF = "log4jConf"; + private final String[] args; + private Options options = new Options(); + private CommandLine cmd; + + private static final String configOpt = "config"; + private static final String userOpt = "user"; + + private SentryPolicyServiceClient sentryClient; + + public SentryPolicyServiceClient getSentryClient() { + return sentryClient; + } + + public String getRequestorName() { + return requestorName; + } + + private String requestorName; + + public static void main(String[] args) { + SentryCli cli = new SentryCli(args); + // Create interactive shell and run it + TopLevelShell shell = new TopLevelShell(cli.getSentryClient(), + cli.getRequestorName()); + shell.run(); + } + + /** + * Construct SentryCli from arguments + * @param args command-line arguments + */ + public SentryCli(String[] args) { + this.args = args; + options.addOption("h", "help", false, "show help"); + // file path of sentry-site + options.addOption("U", userOpt, true, "auth user"); + options.addOption("c", configOpt, true, "sentry configuration"); + options.addOption("L", LOG4J_CONF, true, "Location of log4j properties file"); + CommandLineParser parser = new GnuParser(); + try { + this.cmd = parser.parse(options, args); + } catch (ParseException e) { + help(); + } + if (cmd.hasOption("h")) { + help(); + } + init(); + } + + /** + * Parse command-line arguments. + */ + public void parse() { + CommandLineParser parser = new GnuParser(); + try { + cmd = parser.parse(options, args); + if (cmd.hasOption("h")) { + help(); + } + } catch (ParseException e) { + log.warn("error in parsing expression", e); + help(); + System.exit(1); + } + } + + /** + * Initialize CLI + */ + private void init() { + Map<String, String> env = System.getenv(); + String pathConf = cmd.getOptionValue(configOpt); + if (pathConf == null) { + pathConf = env.get("SENTRY_CONFIG"); + } + if (pathConf == null) { + System.out.println("Missing config file"); + System.exit(1); + } + + String log4jconf = cmd.getOptionValue(LOG4J_CONF); + if (log4jconf != null && log4jconf.length() > 0) { + Properties log4jProperties = new Properties(); + + // Firstly load log properties from properties file + FileInputStream istream = null; + try { + istream = new FileInputStream(log4jconf); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + try { + log4jProperties.load(istream); + istream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + + PropertyConfigurator.configure(log4jProperties); + } + Configuration conf = new Configuration(); + conf.addResource(new Path(pathConf)); + + requestorName = cmd.getOptionValue(userOpt, ""); + if (requestorName.isEmpty()) { + UserGroupInformation ugi = null; + try { + ugi = UserGroupInformation.getLoginUser(); + } catch (IOException e) { + e.printStackTrace(); + } + requestorName = ugi.getShortUserName(); + } + + try { + sentryClient = SentryServiceClientFactory.create(conf); + } catch (Exception e) { + System.out.println("Failed to connect to Sentry server: " + e.toString()); + } + } + + private void help() { + // This prints out some help + HelpFormatter formater = new HelpFormatter(); + formater.printHelp("sentrycli", options); + System.exit(0); + } + +} http://git-wip-us.apache.org/repos/asf/sentry/blob/e5ea89e0/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/cli/ShellUtil.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/cli/ShellUtil.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/cli/ShellUtil.java new file mode 100644 index 0000000..3d61405 --- /dev/null +++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/cli/ShellUtil.java @@ -0,0 +1,205 @@ +/* + * 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.cli; + +import com.google.common.collect.Sets; +import org.apache.commons.lang.StringUtils; +import org.apache.sentry.core.common.exception.SentryUserException; +import org.apache.sentry.provider.db.service.thrift.SentryPolicyServiceClient; +import org.apache.sentry.provider.db.service.thrift.TSentryGroup; +import org.apache.sentry.provider.db.service.thrift.TSentryRole; + +import java.util.*; + +/** + * ShellUtil implements actual commands + */ +class ShellUtil { + + List<String> listRoles() { + Set<TSentryRole> roles = null; + try { + roles = sentryClient.listRoles(authUser); + } catch (SentryUserException e) { + System.out.println("Error listing roles: " + e.toString()); + } + List<String> result = new ArrayList<>(); + if (roles == null || roles.isEmpty()) { + return result; + } + + for(TSentryRole role: roles) { + result.add(role.getRoleName()); + } + + Collections.sort(result); + return result; + } + + List<String> listRoles(String group) { + Set<TSentryRole> roles = null; + try { + roles = sentryClient.listRolesByGroupName(authUser, group); + } catch (SentryUserException e) { + System.out.println("Error listing roles: " + e.toString()); + } + List<String> result = new ArrayList<>(); + if (roles == null || roles.isEmpty()) { + return result; + } + + for(TSentryRole role: roles) { + result.add(role.getRoleName()); + } + + Collections.sort(result); + return result; + } + + void createRoles(String ...roles) { + for (String role: roles) { + try { + sentryClient.createRole(authUser, role); + } catch (SentryUserException e) { + System.out.printf("failed to create role %s: %s\n", + role, e.toString()); + } + } + } + + void removeRoles(String ...roles) { + for (String role: roles) { + try { + sentryClient.dropRole(authUser, role); + } catch (SentryUserException e) { + System.out.printf("failed to remove role %s: %s\n", + role, e.toString()); + } + } + } + + List<String> listGroups() { + Set<TSentryRole> roles = null; + + try { + roles = sentryClient.listRoles(authUser); + } catch (SentryUserException e) { + System.out.println("Error reading roles: " + e.toString()); + } + + if (roles == null || roles.isEmpty()) { + return new ArrayList<>(); + } + + // Set of all group names + Set<String> groupNames = new HashSet<>(); + + // Get all group names + for (TSentryRole role: roles) { + for (TSentryGroup group: role.getGroups()) { + groupNames.add(group.getGroupName()); + } + } + + List<String> result = new ArrayList<>(groupNames); + + Collections.sort(result); + return result; + } + + List<String> listGroupRoles() { + Set<TSentryRole> roles = null; + + try { + roles = sentryClient.listRoles(authUser); + } catch (SentryUserException e) { + System.out.println("Error reading roles: " + e.toString()); + } + + if (roles == null || roles.isEmpty()) { + return new ArrayList<>(); + } + + // Set of all group names + Set<String> groupNames = new HashSet<>(); + + // Map group to set of roles + Map<String, Set<String>> groupInfo = new HashMap<>(); + + // Get all group names + for (TSentryRole role: roles) { + for (TSentryGroup group: role.getGroups()) { + String groupName = group.getGroupName(); + groupNames.add(groupName); + Set<String> groupRoles = groupInfo.get(groupName); + if (groupRoles != null) { + // Add a new or existing role + groupRoles.add(role.getRoleName()); + continue; + } + // Never seen this group before + groupRoles = new HashSet<>(); + groupRoles.add(role.getRoleName()); + groupInfo.put(groupName, groupRoles); + } + } + + List<String> groups = new ArrayList<>(groupNames); + Collections.sort(groups); + + // Produce printable result as + // group1 = role1, role2, ... + // group2 = ... + List<String> result = new LinkedList<>(); + for(String groupName: groups) { + result.add(groupName + " = " + + StringUtils.join(groupInfo.get(groupName), ", ")); + } + return result; + } + + void grantGroupsToRole(String roleName, String ...groups) { + try { + sentryClient.grantRoleToGroups(authUser, roleName, Sets.newHashSet(groups)); + } catch (SentryUserException e) { + System.out.printf("Failed to gran role %s to groups: %s\n", + roleName, e.toString()); + } + } + + void revokeGroupsFromRole(String roleName, String ...groups) { + try { + sentryClient.revokeRoleFromGroups(authUser, roleName, Sets.newHashSet(groups)); + } catch (SentryUserException e) { + System.out.printf("Failed to revoke role %s to groups: %s\n", + roleName, e.toString()); + } + } + + + + ShellUtil(SentryPolicyServiceClient sentryClient, String authUser) { + this.sentryClient = sentryClient; + this.authUser = authUser; + } + + private final SentryPolicyServiceClient sentryClient; + private final String authUser; + +} http://git-wip-us.apache.org/repos/asf/sentry/blob/e5ea89e0/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/cli/TopLevelShell.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/cli/TopLevelShell.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/cli/TopLevelShell.java new file mode 100644 index 0000000..4bc7512 --- /dev/null +++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/cli/TopLevelShell.java @@ -0,0 +1,93 @@ +/** + * 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.cli; + +import com.budhash.cliche.*; +import org.apache.sentry.provider.db.service.thrift.SentryPolicyServiceClient; + +import java.io.IOException; +import java.util.List; + +/** + * Top level commands + */ +public class TopLevelShell implements ShellDependent, Runnable { + + private final Shell topShell; + private final ShellUtil tools; + private Shell shell; // top level shell object + + private final String authUser; + private final SentryPolicyServiceClient sentryClient; + + TopLevelShell(SentryPolicyServiceClient sentryClient, + String authUser) { + this.authUser = authUser; + this.sentryClient = sentryClient; + this.tools = new ShellUtil(sentryClient, authUser); + topShell = ShellFactory.createConsoleShell("sentry", + "sentry shell\n" + + "Enter ?l to list available commands.", + this); + } + + @Command(description="listRoles, create and remove roles") + public void roles() throws IOException { + ShellFactory.createSubshell("roles", shell, "roles commands", + new RolesShell(sentryClient, authUser)).commandLoop(); + } + + @Command(description = "listRoles, create and remove groups") + public void groups() throws IOException { + ShellFactory.createSubshell("groups", shell, "groups commands", + new GroupShell(sentryClient, authUser)).commandLoop(); + } + + @Command(description = "List sentry roles. shows all available roles.") + public List<String> listRoles() { + return tools.listRoles(); + } + + @Command(description = "List sentry roles by group") + public List<String> listRoles( + @Param(name = "groupName") + String group) { + return tools.listRoles(group); + } + + @Command(abbrev = "lg", header = "[groups]", + description = "list groups and their roles") + public List<String> listGroups() { + return tools.listGroupRoles(); + } + + @Override + public void cliSetShell(Shell theShell) { + this.shell = theShell; + } + + @Override + public void run() { + try { + this.topShell.commandLoop(); + } catch (IOException e) { + System.out.println("error: " + e.toString()); + } + } +} http://git-wip-us.apache.org/repos/asf/sentry/blob/e5ea89e0/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/cli/GroupShell.java ---------------------------------------------------------------------- diff --git a/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/cli/GroupShell.java b/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/cli/GroupShell.java deleted file mode 100644 index fe4e52c..0000000 --- a/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/cli/GroupShell.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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.cli; - -import com.budhash.cliche.Command; -import com.budhash.cliche.Shell; -import com.budhash.cliche.ShellDependent; -import org.apache.sentry.provider.db.service.thrift.SentryPolicyServiceClient; - -import java.util.List; - -/** - * Sentry group manipulation for CLI - */ -public class GroupShell implements ShellDependent { - @Command - public List<String> list() { - return tools.listGroups(); - } - - @Command(abbrev = "lr", header = "[groups]", - description = "list groups and their roles") - public List<String> listRoles() { - return tools.listGroupRoles(); - } - - @Command(description = "Grant role to groups") - public void grant(String roleName, String ...groups) { - tools.grantGroupsToRole(roleName, groups); - } - - @Command(description = "Revoke role from groups") - public void revoke(String roleName, String ...groups) { - tools.revokeGroupsFromRole(roleName, groups); - } - - private final ShellUtil tools; - Shell shell; - - - public GroupShell(SentryPolicyServiceClient sentryClient, String authUser) { - this.tools = new ShellUtil(sentryClient, authUser); - } - - @Override - public void cliSetShell(Shell theShell) { - this.shell = theShell; - } -} http://git-wip-us.apache.org/repos/asf/sentry/blob/e5ea89e0/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/cli/RolesShell.java ---------------------------------------------------------------------- diff --git a/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/cli/RolesShell.java b/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/cli/RolesShell.java deleted file mode 100644 index fbd7ac0..0000000 --- a/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/cli/RolesShell.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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.cli; - -import com.budhash.cliche.Command; -import com.budhash.cliche.Param; -import com.budhash.cliche.Shell; -import com.budhash.cliche.ShellDependent; -import org.apache.sentry.provider.db.service.thrift.SentryPolicyServiceClient; - -import java.util.List; - -/** - * Sentry roles manipulation for CLI. - */ -public class RolesShell implements ShellDependent { - @Command(description = "List sentry roles. shows all available roles.") - public List<String> list() { - return tools.listRoles(); - } - - @Command(description = "List sentry roles by group") - public List<String> list( - @Param(name = "groupName", description = "group name for roles") - String group) { - return tools.listRoles(group); - } - - @Command(description = "Create Sentry role(s).") - public void create( - @Param(name = "roleName", description = "name of role to create") - String ...roles) { - tools.createRoles(roles); - } - - @Command(description = "remove Sentry role(s).") - public void remove( - @Param(name = "roleName ...", description = "role names to remove") - String ...roles) { - tools.removeRoles(roles); - } - - - @Override - public void cliSetShell(Shell theShell) { - this.shell = theShell; - } - - private final ShellUtil tools; - Shell shell; - - public RolesShell(SentryPolicyServiceClient sentryClient, String authUser) { - this.tools = new ShellUtil(sentryClient, authUser); - } - -} http://git-wip-us.apache.org/repos/asf/sentry/blob/e5ea89e0/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/cli/SentryCli.java ---------------------------------------------------------------------- diff --git a/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/cli/SentryCli.java b/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/cli/SentryCli.java deleted file mode 100644 index 001397b..0000000 --- a/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/cli/SentryCli.java +++ /dev/null @@ -1,172 +0,0 @@ -/** - * 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.cli; - -import org.apache.commons.cli.*; -import org.apache.hadoop.conf.Configuration; -import org.apache.hadoop.fs.Path; -import org.apache.hadoop.security.UserGroupInformation; -import org.apache.log4j.PropertyConfigurator; -import org.apache.sentry.provider.db.service.thrift.SentryPolicyServiceClient; -import org.apache.sentry.service.thrift.SentryServiceClientFactory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.Map; -import java.util.Properties; - -/** - * Sentry interactive tool - */ -public class SentryCli { - private static final Logger log = LoggerFactory.getLogger(SentryCli.class.getName()); - private static final String LOG4J_CONF = "log4jConf"; - private final String[] args; - private Options options = new Options(); - private CommandLine cmd; - - private static final String configOpt = "config"; - private static final String userOpt = "user"; - - private SentryPolicyServiceClient sentryClient; - - public SentryPolicyServiceClient getSentryClient() { - return sentryClient; - } - - public String getRequestorName() { - return requestorName; - } - - private String requestorName; - - public static void main(String[] args) { - SentryCli cli = new SentryCli(args); - // Create interactive shell and run it - TopLevelShell shell = new TopLevelShell(cli.getSentryClient(), - cli.getRequestorName()); - shell.run(); - } - - /** - * Construct SentryCli from arguments - * @param args command-line arguments - */ - public SentryCli(String[] args) { - this.args = args; - options.addOption("h", "help", false, "show help"); - // file path of sentry-site - options.addOption("U", userOpt, true, "auth user"); - options.addOption("c", configOpt, true, "sentry configuration"); - options.addOption("L", LOG4J_CONF, true, "Location of log4j properties file"); - CommandLineParser parser = new GnuParser(); - try { - this.cmd = parser.parse(options, args); - } catch (ParseException e) { - help(); - } - if (cmd.hasOption("h")) { - help(); - } - init(); - } - - /** - * Parse command-line arguments. - */ - public void parse() { - CommandLineParser parser = new GnuParser(); - try { - cmd = parser.parse(options, args); - if (cmd.hasOption("h")) { - help(); - } - } catch (ParseException e) { - log.warn("error in parsing expression", e); - help(); - System.exit(1); - } - } - - /** - * Initialize CLI - */ - private void init() { - Map<String, String> env = System.getenv(); - String pathConf = cmd.getOptionValue(configOpt); - if (pathConf == null) { - pathConf = env.get("SENTRY_CONFIG"); - } - if (pathConf == null) { - System.out.println("Missing config file"); - System.exit(1); - } - - String log4jconf = cmd.getOptionValue(LOG4J_CONF); - if (log4jconf != null && log4jconf.length() > 0) { - Properties log4jProperties = new Properties(); - - // Firstly load log properties from properties file - FileInputStream istream = null; - try { - istream = new FileInputStream(log4jconf); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - try { - log4jProperties.load(istream); - istream.close(); - } catch (IOException e) { - e.printStackTrace(); - } - - PropertyConfigurator.configure(log4jProperties); - } - Configuration conf = new Configuration(); - conf.addResource(new Path(pathConf)); - - requestorName = cmd.getOptionValue(userOpt, ""); - if (requestorName.isEmpty()) { - UserGroupInformation ugi = null; - try { - ugi = UserGroupInformation.getLoginUser(); - } catch (IOException e) { - e.printStackTrace(); - } - requestorName = ugi.getShortUserName(); - } - - try { - sentryClient = SentryServiceClientFactory.create(conf); - } catch (Exception e) { - System.out.println("Failed to connect to Sentry server: " + e.toString()); - } - } - - private void help() { - // This prints out some help - HelpFormatter formater = new HelpFormatter(); - formater.printHelp("sentrycli", options); - System.exit(0); - } - -} http://git-wip-us.apache.org/repos/asf/sentry/blob/e5ea89e0/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/cli/ShellUtil.java ---------------------------------------------------------------------- diff --git a/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/cli/ShellUtil.java b/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/cli/ShellUtil.java deleted file mode 100644 index 95d8d4b..0000000 --- a/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/cli/ShellUtil.java +++ /dev/null @@ -1,205 +0,0 @@ -/* - * 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.cli; - -import com.google.common.collect.Sets; -import org.apache.commons.lang.StringUtils; -import org.apache.sentry.core.common.exception.SentryUserException; -import org.apache.sentry.provider.db.service.thrift.SentryPolicyServiceClient; -import org.apache.sentry.provider.db.service.thrift.TSentryGroup; -import org.apache.sentry.provider.db.service.thrift.TSentryRole; - -import java.util.*; - -/** - * ShellUtil implements actual commands - */ -class ShellUtil { - - List<String> listRoles() { - Set<TSentryRole> roles = null; - try { - roles = sentryClient.listRoles(authUser); - } catch (SentryUserException e) { - System.out.println("Error listing roles: " + e.toString()); - } - List<String> result = new ArrayList<>(); - if (roles == null || roles.isEmpty()) { - return result; - } - - for(TSentryRole role: roles) { - result.add(role.getRoleName()); - } - - Collections.sort(result); - return result; - } - - List<String> listRoles(String group) { - Set<TSentryRole> roles = null; - try { - roles = sentryClient.listRolesByGroupName(authUser, group); - } catch (SentryUserException e) { - System.out.println("Error listing roles: " + e.toString()); - } - List<String> result = new ArrayList<>(); - if (roles == null || roles.isEmpty()) { - return result; - } - - for(TSentryRole role: roles) { - result.add(role.getRoleName()); - } - - Collections.sort(result); - return result; - } - - void createRoles(String ...roles) { - for (String role: roles) { - try { - sentryClient.createRole(authUser, role); - } catch (SentryUserException e) { - System.out.printf("failed to create role %s: %s\n", - role, e.toString()); - } - } - } - - void removeRoles(String ...roles) { - for (String role: roles) { - try { - sentryClient.dropRole(authUser, role); - } catch (SentryUserException e) { - System.out.printf("failed to remove role %s: %s\n", - role, e.toString()); - } - } - } - - List<String> listGroups() { - Set<TSentryRole> roles = null; - - try { - roles = sentryClient.listRoles(authUser); - } catch (SentryUserException e) { - System.out.println("Error reading roles: " + e.toString()); - } - - if (roles == null || roles.isEmpty()) { - return new ArrayList<>(); - } - - // Set of all group names - Set<String> groupNames = new HashSet<>(); - - // Get all group names - for (TSentryRole role: roles) { - for (TSentryGroup group: role.getGroups()) { - groupNames.add(group.getGroupName()); - } - } - - List<String> result = new ArrayList<>(groupNames); - - Collections.sort(result); - return result; - } - - List<String> listGroupRoles() { - Set<TSentryRole> roles = null; - - try { - roles = sentryClient.listRoles(authUser); - } catch (SentryUserException e) { - System.out.println("Error reading roles: " + e.toString()); - } - - if (roles == null || roles.isEmpty()) { - return new ArrayList<>(); - } - - // Set of all group names - Set<String> groupNames = new HashSet<>(); - - // Map group to set of roles - Map<String, Set<String>> groupInfo = new HashMap<>(); - - // Get all group names - for (TSentryRole role: roles) { - for (TSentryGroup group: role.getGroups()) { - String groupName = group.getGroupName(); - groupNames.add(groupName); - Set<String> groupRoles = groupInfo.get(groupName); - if (groupRoles != null) { - // Add a new or existing role - groupRoles.add(role.getRoleName()); - continue; - } - // Never seen this group before - groupRoles = new HashSet<>(); - groupRoles.add(role.getRoleName()); - groupInfo.put(groupName, groupRoles); - } - } - - List<String> groups = new ArrayList<>(groupNames); - Collections.sort(groups); - - // Produce printable result as - // group1 = role1, role2, ... - // group2 = ... - List<String> result = new LinkedList<>(); - for(String groupName: groups) { - result.add(groupName + " = " + - StringUtils.join(groupInfo.get(groupName), ", ")); - } - return result; - } - - void grantGroupsToRole(String roleName, String ...groups) { - try { - sentryClient.grantRoleToGroups(authUser, roleName, Sets.newHashSet(groups)); - } catch (SentryUserException e) { - System.out.printf("Failed to gran role %s to groups: %s\n", - roleName, e.toString()); - } - } - - void revokeGroupsFromRole(String roleName, String ...groups) { - try { - sentryClient.revokeRoleFromGroups(authUser, roleName, Sets.newHashSet(groups)); - } catch (SentryUserException e) { - System.out.printf("Failed to revoke role %s to groups: %s\n", - roleName, e.toString()); - } - } - - - - ShellUtil(SentryPolicyServiceClient sentryClient, String authUser) { - this.sentryClient = sentryClient; - this.authUser = authUser; - } - - private final SentryPolicyServiceClient sentryClient; - private final String authUser; - -} http://git-wip-us.apache.org/repos/asf/sentry/blob/e5ea89e0/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/cli/TopLevelShell.java ---------------------------------------------------------------------- diff --git a/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/cli/TopLevelShell.java b/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/cli/TopLevelShell.java deleted file mode 100644 index f940e36..0000000 --- a/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/cli/TopLevelShell.java +++ /dev/null @@ -1,93 +0,0 @@ -/** - * 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.cli; - -import com.budhash.cliche.*; -import org.apache.sentry.provider.db.service.thrift.SentryPolicyServiceClient; - -import java.io.IOException; -import java.util.List; - -/** - * Top level commands - */ -public class TopLevelShell implements ShellDependent, Runnable { - - private final Shell topShell; - private final ShellUtil tools; - private Shell shell; // top level shell object - - private final String authUser; - private final SentryPolicyServiceClient sentryClient; - - TopLevelShell(SentryPolicyServiceClient sentryClient, - String authUser) { - this.authUser = authUser; - this.sentryClient = sentryClient; - this.tools = new ShellUtil(sentryClient, authUser); - topShell = ShellFactory.createConsoleShell("sentry", - "sentry shell\n" + - "Enter ?l to list available commands.", - this); - } - - @Command(description="listRoles, create and remove roles") - public void roles() throws IOException { - ShellFactory.createSubshell("roles", shell, "roles commands", - new RolesShell(sentryClient, authUser)).commandLoop(); - } - - @Command(description = "listRoles, create and remove groups") - public void groups() throws IOException { - ShellFactory.createSubshell("groups", shell, "groups commands", - new GroupShell(sentryClient, authUser)).commandLoop(); - } - - @Command(description = "List sentry roles. shows all available roles.") - public List<String> listRoles() { - return tools.listRoles(); - } - - @Command(description = "List sentry roles by group") - public List<String> listRoles( - @Param(name = "groupName") - String group) { - return tools.listRoles(group); - } - - @Command(abbrev = "lg", header = "[groups]", - description = "list groups and their roles") - public List<String> listGroups() { - return tools.listGroupRoles(); - } - - @Override - public void cliSetShell(Shell theShell) { - this.shell = theShell; - } - - @Override - public void run() { - try { - this.topShell.commandLoop(); - } catch (IOException e) { - System.out.println("error: " + e.toString()); - } - } -}
