You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sentry.apache.org by co...@apache.org on 2017/11/16 09:57:08 UTC

[31/32] sentry git commit: SENTRY-2038 - Some ShellCommand improvements. Colm O hEigeartaigh, reviewed by Sergio Pena.

SENTRY-2038 - Some ShellCommand improvements. Colm O hEigeartaigh, reviewed by Sergio Pena.


Project: http://git-wip-us.apache.org/repos/asf/sentry/repo
Commit: http://git-wip-us.apache.org/repos/asf/sentry/commit/24d82438
Tree: http://git-wip-us.apache.org/repos/asf/sentry/tree/24d82438
Diff: http://git-wip-us.apache.org/repos/asf/sentry/diff/24d82438

Branch: refs/heads/akolb-cli
Commit: 24d8243807cfe274963cf08934515345c7d17eb0
Parents: 151ba53
Author: Colm O hEigeartaigh <co...@apache.org>
Authored: Thu Nov 16 09:53:23 2017 +0000
Committer: Colm O hEigeartaigh <co...@apache.org>
Committed: Thu Nov 16 09:53:23 2017 +0000

----------------------------------------------------------------------
 .../db/generic/tools/SentryShellGeneric.java    | 16 ++++-
 .../tools/command/GenericShellCommand.java      | 63 ++++++++++++++++---
 .../provider/db/tools/SentryShellCommon.java    |  8 +++
 .../provider/db/tools/SentryShellHive.java      | 16 ++++-
 .../sentry/provider/db/tools/ShellCommand.java  | 19 +++---
 .../db/tools/command/hive/HiveShellCommand.java | 64 +++++++++++++++++---
 .../db/generic/tools/TestSentryShellKafka.java  |  9 +++
 .../db/generic/tools/TestSentryShellSolr.java   |  9 +++
 .../db/generic/tools/TestSentryShellSqoop.java  |  9 +++
 .../provider/db/tools/TestSentryShellHive.java  |  9 +++
 10 files changed, 188 insertions(+), 34 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/sentry/blob/24d82438/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/tools/SentryShellGeneric.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/tools/SentryShellGeneric.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/tools/SentryShellGeneric.java
index 49f18c8..1623f38 100644
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/tools/SentryShellGeneric.java
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/tools/SentryShellGeneric.java
@@ -19,6 +19,7 @@
 package org.apache.sentry.provider.db.generic.tools;
 
 import java.util.List;
+import java.util.Set;
 
 import org.apache.commons.lang.StringUtils;
 import org.apache.hadoop.conf.Configuration;
@@ -34,6 +35,8 @@ import org.apache.sentry.provider.db.tools.ShellCommand;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.collect.Sets;
+
 /**
  * SentryShellGeneric is an admin tool, and responsible for the management of repository.
  * The following commands are supported:
@@ -71,15 +74,17 @@ public class SentryShellGeneric extends SentryShellCommon {
       } else if (isDropRole) {
         command.dropRole(requestorName, roleName);
       } else if (isAddRoleGroup) {
-        command.grantRoleToGroups(requestorName, roleName, groupName);
+        Set<String> groups = Sets.newHashSet(groupName.split(SentryShellCommon.GROUP_SPLIT_CHAR));
+        command.grantRoleToGroups(requestorName, roleName, groups);
       } else if (isDeleteRoleGroup) {
-        command.revokeRoleFromGroups(requestorName, roleName, groupName);
+        Set<String> groups = Sets.newHashSet(groupName.split(SentryShellCommon.GROUP_SPLIT_CHAR));
+        command.revokeRoleFromGroups(requestorName, roleName, groups);
       } else if (isGrantPrivilegeRole) {
         command.grantPrivilegeToRole(requestorName, roleName, privilegeStr);
       } else if (isRevokePrivilegeRole) {
         command.revokePrivilegeFromRole(requestorName, roleName, privilegeStr);
       } else if (isListRole) {
-        List<String> roles = command.listRoles(requestorName, roleName, groupName);
+        List<String> roles = command.listRoles(requestorName, groupName);
         for (String role : roles) {
           System.out.println(role);
         }
@@ -88,6 +93,11 @@ public class SentryShellGeneric extends SentryShellCommon {
         for (String privilege : privileges) {
           System.out.println(privilege);
         }
+      } else if (isListGroup) {
+        List<String> groups = command.listGroupRoles(requestorName);
+        for (String group : groups) {
+          System.out.println(group);
+        }
       }
     }
   }

http://git-wip-us.apache.org/repos/asf/sentry/blob/24d82438/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/tools/command/GenericShellCommand.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/tools/command/GenericShellCommand.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/tools/command/GenericShellCommand.java
index 11615ff..a792b5c 100644
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/tools/command/GenericShellCommand.java
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/tools/command/GenericShellCommand.java
@@ -18,7 +18,12 @@
 package org.apache.sentry.provider.db.generic.tools.command;
 
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import org.apache.commons.lang.StringUtils;
@@ -26,11 +31,8 @@ import org.apache.sentry.core.common.exception.SentryUserException;
 import org.apache.sentry.provider.db.generic.service.thrift.SentryGenericServiceClient;
 import org.apache.sentry.provider.db.generic.service.thrift.TSentryPrivilege;
 import org.apache.sentry.provider.db.generic.service.thrift.TSentryRole;
-import org.apache.sentry.provider.db.tools.SentryShellCommon;
 import org.apache.sentry.provider.db.tools.ShellCommand;
 
-import com.google.common.collect.Sets;
-
 /**
  * The ShellCommand implementation for the Generic clients
  */
@@ -62,9 +64,8 @@ public class GenericShellCommand implements ShellCommand {
     client.grantPrivilege(requestorName, roleName, component, sentryPrivilege);
   }
 
-  public void grantRoleToGroups(String requestorName, String roleName, String groups) throws SentryUserException {
-    Set<String> groupSet = Sets.newHashSet(groups.split(SentryShellCommon.GROUP_SPLIT_CHAR));
-    client.grantRoleToGroups(requestorName, roleName, component, groupSet);
+  public void grantRoleToGroups(String requestorName, String roleName, Set<String> groups) throws SentryUserException {
+    client.grantRoleToGroups(requestorName, roleName, component, groups);
   }
 
   public void revokePrivilegeFromRole(String requestorName, String roleName, String privilege) throws SentryUserException {
@@ -72,12 +73,11 @@ public class GenericShellCommand implements ShellCommand {
     client.revokePrivilege(requestorName, roleName, component, sentryPrivilege);
   }
 
-  public void revokeRoleFromGroups(String requestorName, String roleName, String groups) throws SentryUserException {
-    Set<String> groupSet = Sets.newHashSet(groups.split(SentryShellCommon.GROUP_SPLIT_CHAR));
-    client.revokeRoleFromGroups(requestorName, roleName, component, groupSet);
+  public void revokeRoleFromGroups(String requestorName, String roleName, Set<String> groups) throws SentryUserException {
+    client.revokeRoleFromGroups(requestorName, roleName, component, groups);
   }
 
-  public List<String> listRoles(String requestorName, String roleName, String group) throws SentryUserException {
+  public List<String> listRoles(String requestorName, String group) throws SentryUserException {
     Set<TSentryRole> roles;
     if (StringUtils.isEmpty(group)) {
       roles = client.listAllRoles(requestorName, component);
@@ -109,4 +109,47 @@ public class GenericShellCommand implements ShellCommand {
 
     return result;
   }
+
+  public List<String> listGroupRoles(String requestorName) throws SentryUserException {
+    Set<TSentryRole> roles = client.listAllRoles(requestorName, component);
+    if (roles == null || roles.isEmpty()) {
+      return Collections.emptyList();
+    }
+
+    // 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 (String group : role.getGroups()) {
+        groupNames.add(group);
+        Set<String> groupRoles = groupInfo.get(group);
+        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(group, groupRoles);
+      }
+    }
+
+    List<String> groups = new ArrayList<>(groupNames);
+
+    // 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;
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/sentry/blob/24d82438/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
index dd245ea..5fbc961 100644
--- 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
@@ -60,6 +60,7 @@ abstract public class SentryShellCommon {
   protected boolean isRevokePrivilegeRole;
   protected boolean isListRole;
   protected boolean isListPrivilege;
+  protected boolean isListGroup;
   protected boolean isPrintHelp;
   // flag for the parameter check
   protected boolean roleNameRequired;
@@ -80,6 +81,7 @@ abstract public class SentryShellCommon {
    *   -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
+   *   -lg,--list_group                                           list all groups associated with all roles
    *   -t,--type                    <typename>                    the shell for hive model or generic model
    * </pre>
    *
@@ -112,6 +114,9 @@ abstract public class SentryShellCommon {
     Option lpOpt = new Option("lp", "list_privilege", false, "List privilege");
     lpOpt.setRequired(false);
 
+    Option lgOpt = new Option("lg", "list_group", false, "List groups");
+    lgOpt.setRequired(false);
+
     // required args group
     OptionGroup simpleShellOptGroup = new OptionGroup();
     simpleShellOptGroup.addOption(crOpt);
@@ -122,6 +127,7 @@ abstract public class SentryShellCommon {
     simpleShellOptGroup.addOption(rprOpt);
     simpleShellOptGroup.addOption(lrOpt);
     simpleShellOptGroup.addOption(lpOpt);
+    simpleShellOptGroup.addOption(lgOpt);
     simpleShellOptGroup.setRequired(true);
     simpleShellOptions.addOptionGroup(simpleShellOptGroup);
 
@@ -207,6 +213,8 @@ abstract public class SentryShellCommon {
         } else if (opt.getOpt().equals("lp")) {
           isListPrivilege = true;
           roleNameRequired = true;
+        } else if (opt.getOpt().equals("lg")) {
+          isListGroup = true;
         } else if (opt.getOpt().equals("conf")) {
           confPath = opt.getValue();
         } else if (opt.getOpt().equals("t")) {

http://git-wip-us.apache.org/repos/asf/sentry/blob/24d82438/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
index 226d58d..729a518 100644
--- 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
@@ -19,6 +19,7 @@
 package org.apache.sentry.provider.db.tools;
 
 import java.util.List;
+import java.util.Set;
 
 import org.apache.commons.lang.StringUtils;
 import org.apache.hadoop.conf.Configuration;
@@ -30,6 +31,8 @@ import org.apache.sentry.service.thrift.SentryServiceClientFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.collect.Sets;
+
 /**
  * SentryShellHive is an admin tool, and responsible for the management of repository.
  * The following function are supported:
@@ -59,15 +62,17 @@ public class SentryShellHive extends SentryShellCommon {
       } else if (isDropRole) {
         command.dropRole(requestorName, roleName);
       } else if (isAddRoleGroup) {
-        command.grantRoleToGroups(requestorName, roleName, groupName);
+        Set<String> groups = Sets.newHashSet(groupName.split(SentryShellCommon.GROUP_SPLIT_CHAR));
+        command.grantRoleToGroups(requestorName, roleName, groups);
       } else if (isDeleteRoleGroup) {
-        command.revokeRoleFromGroups(requestorName, roleName, groupName);
+        Set<String> groups = Sets.newHashSet(groupName.split(SentryShellCommon.GROUP_SPLIT_CHAR));
+        command.revokeRoleFromGroups(requestorName, roleName, groups);
       } else if (isGrantPrivilegeRole) {
         command.grantPrivilegeToRole(requestorName, roleName, privilegeStr);
       } else if (isRevokePrivilegeRole) {
         command.revokePrivilegeFromRole(requestorName, roleName, privilegeStr);
       } else if (isListRole) {
-        List<String> roles = command.listRoles(requestorName, roleName, groupName);
+        List<String> roles = command.listRoles(requestorName, groupName);
         for (String role : roles) {
           System.out.println(role);
         }
@@ -76,6 +81,11 @@ public class SentryShellHive extends SentryShellCommon {
         for (String privilege : privileges) {
           System.out.println(privilege);
         }
+      } else if (isListGroup) {
+        List<String> groups = command.listGroupRoles(requestorName);
+        for (String group : groups) {
+          System.out.println(group);
+        }
       }
     }
   }

http://git-wip-us.apache.org/repos/asf/sentry/blob/24d82438/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/ShellCommand.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/ShellCommand.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/ShellCommand.java
index ec751ec..eeb3a23 100644
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/ShellCommand.java
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/ShellCommand.java
@@ -18,6 +18,7 @@
 package org.apache.sentry.provider.db.tools;
 
 import java.util.List;
+import java.util.Set;
 
 import org.apache.sentry.core.common.exception.SentryUserException;
 
@@ -26,19 +27,21 @@ import org.apache.sentry.core.common.exception.SentryUserException;
  */
 public interface ShellCommand {
 
-    void createRole(String requestorName, String roleName) throws SentryUserException;
+  void createRole(String requestorName, String roleName) throws SentryUserException;
 
-    void dropRole(String requestorName, String roleName) throws SentryUserException;
+  void dropRole(String requestorName, String roleName) throws SentryUserException;
 
-    void grantPrivilegeToRole(String requestorName, String roleName, String privilege) throws SentryUserException;
+  void grantPrivilegeToRole(String requestorName, String roleName, String privilege) throws SentryUserException;
 
-    void grantRoleToGroups(String requestorName, String roleName, String groups) throws SentryUserException;
+  void grantRoleToGroups(String requestorName, String roleName, Set<String> groups) throws SentryUserException;
 
-    void revokePrivilegeFromRole(String requestorName, String roleName, String privilege) throws SentryUserException;
+  void revokePrivilegeFromRole(String requestorName, String roleName, String privilege) throws SentryUserException;
 
-    void revokeRoleFromGroups(String requestorName, String roleName, String groups) throws SentryUserException;
+  void revokeRoleFromGroups(String requestorName, String roleName, Set<String> groups) throws SentryUserException;
 
-    List<String> listRoles(String requestorName, String roleName, String group) throws SentryUserException;
+  List<String> listRoles(String requestorName, String group) throws SentryUserException;
 
-    List<String> listPrivileges(String requestorName, String roleName) throws SentryUserException;
+  List<String> listPrivileges(String requestorName, String roleName) throws SentryUserException;
+
+  List<String> listGroupRoles(String requestorName) throws SentryUserException;
 }

http://git-wip-us.apache.org/repos/asf/sentry/blob/24d82438/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/HiveShellCommand.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/HiveShellCommand.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/HiveShellCommand.java
index 1e0692b..3abba52 100644
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/HiveShellCommand.java
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/HiveShellCommand.java
@@ -18,20 +18,23 @@
 package org.apache.sentry.provider.db.tools.command.hive;
 
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 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.TSentryPrivilege;
 import org.apache.sentry.provider.db.service.thrift.TSentryRole;
-import org.apache.sentry.provider.db.tools.SentryShellCommon;
 import org.apache.sentry.provider.db.tools.ShellCommand;
 import org.apache.sentry.service.thrift.SentryServiceUtil;
 
-import com.google.common.collect.Sets;
-
 /**
  * The ShellCommand implementation for Hive.
  */
@@ -57,9 +60,8 @@ public class HiveShellCommand implements ShellCommand {
     client.grantPrivilege(requestorName, roleName, tSentryPrivilege);
   }
 
-  public void grantRoleToGroups(String requestorName, String roleName, String groups) throws SentryUserException {
-    Set<String> groupSet = Sets.newHashSet(groups.split(SentryShellCommon.GROUP_SPLIT_CHAR));
-    client.grantRoleToGroups(requestorName, roleName, groupSet);
+  public void grantRoleToGroups(String requestorName, String roleName, Set<String> groups) throws SentryUserException {
+    client.grantRoleToGroups(requestorName, roleName, groups);
   }
 
   public void revokePrivilegeFromRole(String requestorName, String roleName, String privilege) throws SentryUserException {
@@ -68,12 +70,11 @@ public class HiveShellCommand implements ShellCommand {
     client.revokePrivilege(requestorName, roleName, tSentryPrivilege);
   }
 
-  public void revokeRoleFromGroups(String requestorName, String roleName, String groups) throws SentryUserException {
-    Set<String> groupSet = Sets.newHashSet(groups.split(SentryShellCommon.GROUP_SPLIT_CHAR));
-    client.revokeRoleFromGroups(requestorName, roleName, groupSet);
+  public void revokeRoleFromGroups(String requestorName, String roleName, Set<String> groups) throws SentryUserException {
+    client.revokeRoleFromGroups(requestorName, roleName, groups);
   }
 
-  public List<String> listRoles(String requestorName, String roleName, String group) throws SentryUserException {
+  public List<String> listRoles(String requestorName, String group) throws SentryUserException {
     Set<TSentryRole> roles;
     if (StringUtils.isEmpty(group)) {
       roles = client.listAllRoles(requestorName);
@@ -105,4 +106,47 @@ public class HiveShellCommand implements ShellCommand {
     return result;
   }
 
+  public List<String> listGroupRoles(String requestorName) throws SentryUserException {
+    Set<TSentryRole> roles = client.listAllRoles(requestorName);
+    if (roles == null || roles.isEmpty()) {
+      return Collections.emptyList();
+    }
+
+    // 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);
+
+    // 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;
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/sentry/blob/24d82438/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/tools/TestSentryShellKafka.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/tools/TestSentryShellKafka.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/tools/TestSentryShellKafka.java
index 80bbcf1..a9234fa 100644
--- a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/tools/TestSentryShellKafka.java
+++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/tools/TestSentryShellKafka.java
@@ -160,6 +160,15 @@ public class TestSentryShellKafka extends SentryGenericServiceIntegrationBase {
         roleNames = getShellResultWithOSRedirect(sentryShell, args, true);
         validateRoleNames(roleNames, TEST_ROLE_NAME_1);
 
+        // List the groups and roles via listGroups
+        args = new String[] { "--list_group", "-conf", confPath.getAbsolutePath(), "-t", "kafka" };
+        sentryShell = new SentryShellGeneric();
+        Set<String> groups = getShellResultWithOSRedirect(sentryShell, args, true);
+        assertEquals(3, groups.size());
+        assertTrue(groups.contains("testGroup3 = testrole1"));
+        assertTrue(groups.contains("testGroup2 = testrole1"));
+        assertTrue(groups.contains("testGroup1 = testrole2, testrole1"));
+
         // test: delete role from group with -drg
         args = new String[] { "-drg", "-r", TEST_ROLE_NAME_1, "-g", TEST_GROUP_1, "-conf",
             confPath.getAbsolutePath(), "-t", "kafka" };

http://git-wip-us.apache.org/repos/asf/sentry/blob/24d82438/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/tools/TestSentryShellSolr.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/tools/TestSentryShellSolr.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/tools/TestSentryShellSolr.java
index c3a6a9f..0f4bb62 100644
--- a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/tools/TestSentryShellSolr.java
+++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/tools/TestSentryShellSolr.java
@@ -161,6 +161,15 @@ public class TestSentryShellSolr extends SentryGenericServiceIntegrationBase {
         roleNames = getShellResultWithOSRedirect(sentryShell, args, true);
         validateRoleNames(roleNames, TEST_ROLE_NAME_1);
 
+        // List the groups and roles via listGroups
+        args = new String[] { "--list_group", "-conf", confPath.getAbsolutePath(), "-t", "solr" };
+        sentryShell = new SentryShellGeneric();
+        Set<String> groups = getShellResultWithOSRedirect(sentryShell, args, true);
+        assertEquals(3, groups.size());
+        assertTrue(groups.contains("testGroup3 = testrole1"));
+        assertTrue(groups.contains("testGroup2 = testrole1"));
+        assertTrue(groups.contains("testGroup1 = testrole2, testrole1"));
+
         // test: delete role from group with -drg
         args = new String[] { "-drg", "-r", TEST_ROLE_NAME_1, "-g", TEST_GROUP_1, "-conf",
             confPath.getAbsolutePath(), "-t", "solr" };

http://git-wip-us.apache.org/repos/asf/sentry/blob/24d82438/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/tools/TestSentryShellSqoop.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/tools/TestSentryShellSqoop.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/tools/TestSentryShellSqoop.java
index 7bafd8c..cdba442 100644
--- a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/tools/TestSentryShellSqoop.java
+++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/tools/TestSentryShellSqoop.java
@@ -159,6 +159,15 @@ public class TestSentryShellSqoop extends SentryGenericServiceIntegrationBase {
         roleNames = getShellResultWithOSRedirect(sentryShell, args, true);
         validateRoleNames(roleNames, TEST_ROLE_NAME_1);
 
+        // List the groups and roles via listGroups
+        args = new String[] { "--list_group", "-conf", confPath.getAbsolutePath(), "-t", "sqoop" };
+        sentryShell = new SentryShellGeneric();
+        Set<String> groups = getShellResultWithOSRedirect(sentryShell, args, true);
+        assertEquals(3, groups.size());
+        assertTrue(groups.contains("testGroup3 = testrole1"));
+        assertTrue(groups.contains("testGroup2 = testrole1"));
+        assertTrue(groups.contains("testGroup1 = testrole2, testrole1"));
+
         // test: delete role from group with -drg
         args = new String[] { "-drg", "-r", TEST_ROLE_NAME_1, "-g", TEST_GROUP_1, "-conf",
             confPath.getAbsolutePath(), "-t", "sqoop" };

http://git-wip-us.apache.org/repos/asf/sentry/blob/24d82438/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
index adfd102..de8f043 100644
--- 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
@@ -155,6 +155,15 @@ public class TestSentryShellHive extends SentryServiceIntegrationBase {
         roleNames = getShellResultWithOSRedirect(sentryShell, args, true);
         validateRoleNames(roleNames, TEST_ROLE_NAME_1);
 
+        // List the groups and roles via listGroups
+        args = new String[] { "--list_group", "-conf", confPath.getAbsolutePath()};
+        sentryShell = new SentryShellHive();
+        Set<String> groups = getShellResultWithOSRedirect(sentryShell, args, true);
+        assertEquals(3, groups.size());
+        assertTrue(groups.contains("testGroup3 = testrole1"));
+        assertTrue(groups.contains("testGroup2 = testrole1"));
+        assertTrue(groups.contains("testGroup1 = testrole2, testrole1"));
+
         // test: delete role from group with -drg
         args = new String[] { "-drg", "-r", TEST_ROLE_NAME_1, "-g", "testGroup1", "-conf",
             confPath.getAbsolutePath() };