SUBMARINE-488. DCL Framework: SHOW ROLES syntax
### What is this PR for?
Part of DCL framework, this PR adds the show roles syntax support
### What type of PR is it?
Feature
### Todos
* [ ] - Task
### What is the Jira issue?
https://issues.apache.org/jira/browse/SUBMARINE-488
### How should this be tested?
add new unit tests
### Screenshots (if appropriate)
### Questions:
* Does the licenses files need update? No
* Is there breaking changes for older versions? No
* Does this needs documentation? No
Author: Kent Yao <yaooqinn@hotmail.com>
Closes #274 from yaooqinn/SUBMARINE-488 and squashes the following commits:
0edd58e [Kent Yao] SUBMARINE-488. DCL Framework: SHOW ROLES syntax
diff --git a/submarine-security/spark-security/ranger-1/src/main/scala/org.apache.submarine.spark.security.command/ShowRolesCommand.scala b/submarine-security/spark-security/ranger-1/src/main/scala/org.apache.submarine.spark.security.command/ShowRolesCommand.scala
new file mode 100644
index 0000000..ab4fc10
--- /dev/null
+++ b/submarine-security/spark-security/ranger-1/src/main/scala/org.apache.submarine.spark.security.command/ShowRolesCommand.scala
@@ -0,0 +1,29 @@
+/*
+ * 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.submarine.spark.security.command
+
+import org.apache.spark.sql.{Row, SparkSession}
+import org.apache.spark.sql.execution.command.RunnableCommand
+
+case class ShowRolesCommand () extends RunnableCommand {
+ override def run(sparkSession: SparkSession): Seq[Row] = {
+ throw new UnsupportedOperationException("SHOW ROLES")
+ }
+}
diff --git a/submarine-security/spark-security/ranger-2/src/main/scala/org.apache.submarine.spark.security.command/ShowRolesCommand.scala b/submarine-security/spark-security/ranger-2/src/main/scala/org.apache.submarine.spark.security.command/ShowRolesCommand.scala
new file mode 100644
index 0000000..73d0ab1
--- /dev/null
+++ b/submarine-security/spark-security/ranger-2/src/main/scala/org.apache.submarine.spark.security.command/ShowRolesCommand.scala
@@ -0,0 +1,50 @@
+/*
+ * 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.submarine.spark.security.command
+
+import scala.collection.JavaConverters._
+import scala.util.control.NonFatal
+
+import org.apache.hadoop.security.UserGroupInformation
+import org.apache.spark.sql.{Row, SparkSession}
+import org.apache.spark.sql.catalyst.expressions.{Attribute, AttributeReference}
+import org.apache.spark.sql.execution.command.RunnableCommand
+import org.apache.spark.sql.types.StringType
+
+import org.apache.submarine.spark.security.{RangerSparkAuditHandler, RangerSparkPlugin, SparkAccessControlException}
+
+case class ShowRolesCommand () extends RunnableCommand {
+
+ override def output: Seq[Attribute] =
+ Seq(AttributeReference("Role Name", StringType, nullable = false)())
+
+ override def run(sparkSession: SparkSession): Seq[Row] = {
+ try {
+ val auditHandler = RangerSparkAuditHandler()
+ val currentUser = UserGroupInformation.getCurrentUser.getShortUserName
+ val roles = RangerSparkPlugin.getAllRoles(currentUser, auditHandler)
+ roles.asScala.map(Row(_))
+ } catch {
+ case NonFatal(e) => throw new SparkAccessControlException(e.getMessage, e)
+ } finally {
+ // TODO: support auditHandler.flushAudit()
+ }
+ }
+}
diff --git a/submarine-security/spark-security/src/main/antlr4/org/apache/submarine/spark/security/parser/SubmarineSqlBase.g4 b/submarine-security/spark-security/src/main/antlr4/org/apache/submarine/spark/security/parser/SubmarineSqlBase.g4
index 34f0d3d..a63f847 100644
--- a/submarine-security/spark-security/src/main/antlr4/org/apache/submarine/spark/security/parser/SubmarineSqlBase.g4
+++ b/submarine-security/spark-security/src/main/antlr4/org/apache/submarine/spark/security/parser/SubmarineSqlBase.g4
@@ -31,6 +31,7 @@
statement
: CREATE ROLE identifier #createRole
| DROP ROLE identifier #dropRole
+ | SHOW ROLES #showRoles
;
identifier
@@ -54,7 +55,9 @@
| PRIVILEGES
| READ
| ROLE
+ | ROLES
| SELECT
+ | SHOW
| UPDATE
| USE
| WRITE
@@ -73,7 +76,9 @@
PRIVILEGES: 'PRIVILEGES';
READ: 'READ';
ROLE: 'ROLE';
+ROLES: 'ROLES';
SELECT: 'SELECT';
+SHOW: 'SHOW';
UPDATE: 'UPDATE';
USE: 'USE';
WRITE: 'WRITE';
diff --git a/submarine-security/spark-security/src/main/scala/org/apache/submarine/spark/security/parser/SubmarineSqlAstBuilder.scala b/submarine-security/spark-security/src/main/scala/org/apache/submarine/spark/security/parser/SubmarineSqlAstBuilder.scala
index 0b32db3..c2e3a11 100644
--- a/submarine-security/spark-security/src/main/scala/org/apache/submarine/spark/security/parser/SubmarineSqlAstBuilder.scala
+++ b/submarine-security/spark-security/src/main/scala/org/apache/submarine/spark/security/parser/SubmarineSqlAstBuilder.scala
@@ -21,8 +21,8 @@
import org.apache.spark.sql.catalyst.plans.logical.LogicalPlan
-import org.apache.submarine.spark.security.command.{CreateRoleCommand, DropRoleCommand}
-import org.apache.submarine.spark.security.parser.SubmarineSqlBaseParser.{CreateRoleContext, DropRoleContext, SingleStatementContext}
+import org.apache.submarine.spark.security.command.{CreateRoleCommand, DropRoleCommand, ShowRolesCommand}
+import org.apache.submarine.spark.security.parser.SubmarineSqlBaseParser.{CreateRoleContext, DropRoleContext, ShowRolesContext, SingleStatementContext}
class SubmarineSqlAstBuilder extends SubmarineSqlBaseBaseVisitor[AnyRef] {
@@ -37,4 +37,8 @@
override def visitDropRole(ctx: DropRoleContext): AnyRef = {
DropRoleCommand(ctx.identifier().getText)
}
+
+ override def visitShowRoles(ctx: ShowRolesContext): AnyRef = {
+ ShowRolesCommand()
+ }
}
diff --git a/submarine-security/spark-security/src/test/scala/org/apache/submarine/spark/security/parser/SubmarineSqlParserTest.scala b/submarine-security/spark-security/src/test/scala/org/apache/submarine/spark/security/parser/SubmarineSqlParserTest.scala
index 9adfa32..6204572 100644
--- a/submarine-security/spark-security/src/test/scala/org/apache/submarine/spark/security/parser/SubmarineSqlParserTest.scala
+++ b/submarine-security/spark-security/src/test/scala/org/apache/submarine/spark/security/parser/SubmarineSqlParserTest.scala
@@ -23,7 +23,7 @@
import org.apache.spark.sql.hive.test.TestHive
import org.scalatest.FunSuite
-import org.apache.submarine.spark.security.command.{CreateRoleCommand, DropRoleCommand}
+import org.apache.submarine.spark.security.command.{CreateRoleCommand, DropRoleCommand, ShowRolesCommand}
class SubmarineSqlParserTest extends FunSuite {
@@ -56,4 +56,9 @@
assert(p3.asInstanceOf[DropRoleCommand].roleName === "`bob`")
intercept[ParseException](parser.parsePlan("drop role 'bob'"))
}
+
+ test("show roles") {
+ val p1 = parser.parsePlan("show roles")
+ assert(p1.isInstanceOf[ShowRolesCommand])
+ }
}