[KYUUBI #5361] [AUTHZ] Support Drop/Truncate Table Commands for Hudi

### _Why are the changes needed?_
To close #5361. Kyuubi authz support hudi drop/repair/truncate table commands

- DropHoodieTableCommand: https://github.com/apache/hudi/blob/master/hudi-spark-datasource/hudi-spark-common/src/main/scala/org/apache/spark/sql/hudi/command/DropHoodieTableCommand.scala
- TruncateHoodieTableCommand: https://github.com/apache/hudi/blob/master/hudi-spark-datasource/hudi-spark-common/src/main/scala/org/apache/spark/sql/hudi/command/TruncateHoodieTableCommand.scala

### _How was this patch tested?_
- [x] Add some test cases that check the changes thoroughly including negative and positive cases if possible

- [ ] Add screenshots for manual tests if appropriate

- [ ] [Run test](https://kyuubi.readthedocs.io/en/master/contributing/code/testing.html#running-tests) locally before make a pull request

### _Was this patch authored or co-authored using generative AI tooling?_
No

Closes #5445 from AngersZhuuuu/KYUUBI-5361.

Closes #5361

ed9d43acd [Angerszhuuuu] update
a08dcaafc [Angerszhuuuu] Update HudiCatalogRangerSparkExtensionSuite.scala
372d1fbed [Angerszhuuuu] Update HudiCatalogRangerSparkExtensionSuite.scala
e0aa8a783 [Bowen Liang] add positive cases
9daf0b4d0 [Bowen Liang] compact code style
7eb0828d7 [Bowen Liang] Update extensions/spark/kyuubi-spark-authz/src/test/scala/org/apache/kyuubi/plugin/spark/authz/ranger/HudiCatalogRangerSparkExtensionSuite.scala
81024ac10 [Angerszhuuuu] update
31d440617 [Angerszhuuuu] Update HudiCatalogRangerSparkExtensionSuite.scala
fae5a64bc [Angerszhuuuu] Merge branch 'master' into KYUUBI-5361
a70617b18 [Angerszhuuuu] [KYUUBI #5361] [AUTHZ] Support Drop/Repair/Truncate Table Commands for Hudi

Lead-authored-by: Angerszhuuuu <angers.zhu@gmail.com>
Co-authored-by: Bowen Liang <liangbowen@gf.com.cn>
Co-authored-by: Bowen Liang <bowenliang@apache.org>
Signed-off-by: Cheng Pan <chengpan@apache.org>
This commit is contained in:
Angerszhuuuu 2023-10-18 13:16:24 +08:00 committed by Cheng Pan
parent 16752164a1
commit c5854f74b2
No known key found for this signature in database
GPG Key ID: 8001952629BCC75D
3 changed files with 132 additions and 10 deletions

View File

@ -1567,6 +1567,24 @@
} ],
"opType" : "CREATETABLE",
"queryDescs" : [ ]
}, {
"classname" : "org.apache.spark.sql.hudi.command.DropHoodieTableCommand",
"tableDescs" : [ {
"fieldName" : "tableIdentifier",
"fieldExtractor" : "TableIdentifierTableExtractor",
"columnDesc" : null,
"actionTypeDesc" : null,
"tableTypeDesc" : {
"fieldName" : "tableIdentifier",
"fieldExtractor" : "TableIdentifierTableTypeExtractor",
"skipTypes" : [ "TEMP_VIEW" ]
},
"catalogDesc" : null,
"isInput" : false,
"setCurrentDatabaseIfMissing" : false
} ],
"opType" : "DROPTABLE",
"queryDescs" : [ ]
}, {
"classname" : "org.apache.spark.sql.hudi.command.Spark31AlterTableCommand",
"tableDescs" : [ {
@ -1581,4 +1599,21 @@
} ],
"opType" : "ALTERTABLE_PROPERTIES",
"queryDescs" : [ ]
}, {
"classname" : "org.apache.spark.sql.hudi.command.TruncateHoodieTableCommand",
"tableDescs" : [ {
"fieldName" : "tableIdentifier",
"fieldExtractor" : "TableIdentifierTableExtractor",
"columnDesc" : {
"fieldName" : "partitionSpec",
"fieldExtractor" : "PartitionOptionColumnExtractor"
},
"actionTypeDesc" : null,
"tableTypeDesc" : null,
"catalogDesc" : null,
"isInput" : false,
"setCurrentDatabaseIfMissing" : false
} ],
"opType" : "TRUNCATETABLE",
"queryDescs" : [ ]
} ]

View File

@ -100,6 +100,33 @@ object HudiCommands {
TableCommandSpec(cmd, Seq(tableDesc1, tableDesc2), CREATETABLE)
}
val DropHoodieTableCommand = {
val cmd = "org.apache.spark.sql.hudi.command.DropHoodieTableCommand"
val tableTypeDesc =
TableTypeDesc(
"tableIdentifier",
classOf[TableIdentifierTableTypeExtractor],
Seq(TEMP_VIEW))
TableCommandSpec(
cmd,
Seq(TableDesc(
"tableIdentifier",
classOf[TableIdentifierTableExtractor],
tableTypeDesc = Some(tableTypeDesc))),
DROPTABLE)
}
val TruncateHoodieTableCommand = {
val cmd = "org.apache.spark.sql.hudi.command.TruncateHoodieTableCommand"
val columnDesc = ColumnDesc("partitionSpec", classOf[PartitionOptionColumnExtractor])
val tableDesc =
TableDesc(
"tableIdentifier",
classOf[TableIdentifierTableExtractor],
columnDesc = Some(columnDesc))
TableCommandSpec(cmd, Seq(tableDesc), TRUNCATETABLE)
}
val data: Array[TableCommandSpec] = Array(
AlterHoodieTableAddColumnsCommand,
AlterHoodieTableChangeColumnCommand,
@ -109,5 +136,7 @@ object HudiCommands {
Spark31AlterTableCommand,
CreateHoodieTableCommand,
CreateHoodieTableAsSelectCommand,
CreateHoodieTableLikeCommand)
CreateHoodieTableLikeCommand,
DropHoodieTableCommand,
TruncateHoodieTableCommand)
}

View File

@ -180,6 +180,67 @@ class HudiCatalogRangerSparkExtensionSuite extends RangerSparkExtensionSuite {
}
test("CreateHoodieTableLikeCommand") {
withCleanTmpResources(Seq(
(s"$namespace1.$table1", "table"),
(s"$namespace1.$table2", "table"),
(namespace1, "database"))) {
doAs(admin, sql(s"CREATE DATABASE IF NOT EXISTS $namespace1"))
doAs(
admin,
sql(
s"""
|CREATE TABLE IF NOT EXISTS $namespace1.$table1(id int, name string, city string)
|USING HUDI
|OPTIONS (
| type = 'cow',
| primaryKey = 'id',
| 'hoodie.datasource.hive_sync.enable' = 'false'
|)
|PARTITIONED BY(city)
|""".stripMargin))
val createTableSql =
s"""
|CREATE TABLE IF NOT EXISTS $namespace1.$table2
|LIKE $namespace1.$table1
|USING HUDI
|""".stripMargin
interceptContains[AccessControlException] {
doAs(
someone,
sql(
createTableSql))
}(s"does not have [select] privilege on [$namespace1/$table1]")
doAs(admin, sql(createTableSql))
}
}
test("DropHoodieTableCommand") {
withCleanTmpResources(Seq((namespace1, "database"))) {
doAs(admin, sql(s"CREATE DATABASE IF NOT EXISTS $namespace1"))
doAs(
admin,
sql(
s"""
|CREATE TABLE IF NOT EXISTS $namespace1.$table1(id int, name string, city string)
|USING HUDI
|OPTIONS (
| type = 'cow',
| primaryKey = 'id',
| 'hoodie.datasource.hive_sync.enable' = 'false'
|)
|PARTITIONED BY(city)
|""".stripMargin))
val dropTableSql = s"DROP TABLE IF EXISTS $namespace1.$table1"
interceptContains[AccessControlException] {
doAs(someone, sql(dropTableSql))
}(s"does not have [drop] privilege on [$namespace1/$table1]")
doAs(admin, sql(dropTableSql))
}
}
test("TruncateHoodieTableCommand") {
withCleanTmpResources(Seq((s"$namespace1.$table1", "table"), (namespace1, "database"))) {
doAs(admin, sql(s"CREATE DATABASE IF NOT EXISTS $namespace1"))
doAs(
@ -195,15 +256,12 @@ class HudiCatalogRangerSparkExtensionSuite extends RangerSparkExtensionSuite {
|)
|PARTITIONED BY(city)
|""".stripMargin))
interceptContains[AccessControlException](
doAs(
someone,
sql(
s"""
|CREATE TABLE IF NOT EXISTS $namespace1.$table2
|LIKE $namespace1.$table1
|USING HUDI
|""".stripMargin)))(s"does not have [select] privilege on [$namespace1/$table1]")
val truncateTableSql = s"TRUNCATE TABLE $namespace1.$table1"
interceptContains[AccessControlException] {
doAs(someone, sql(truncateTableSql))
}(s"does not have [update] privilege on [$namespace1/$table1]")
doAs(admin, sql(truncateTableSql))
}
}
}