diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index 759ea942e..274b02ff3 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -1,53 +1,217 @@
-Release Notes - Sentry - Version v1.2.0
+Release Notes - Sentry - Version 1.7.1
+
+** Improvement
+
+ * [SENTRY-2101] - Upgrade 1.7 branch to use libthrift 0.9.3
+
+
+Release Notes - Sentry - Version 1.7.0
+
+** Sub-task
+ * [SENTRY-505] - Default implementation of SentryAuthorizationValidator to do authorization
+ * [SENTRY-506] - Default implementation of SentryAccessController to do grant/revoke role/privlege
+ * [SENTRY-514] - Enable e2e tests for authorization V2
+ * [SENTRY-532] - Add unit tests for DefaultSentryAuthorizationValidator
+ * [SENTRY-542] - Extend SentryPolicyServiceClient to implement grant wrapped privilege info for V2
+ * [SENTRY-568] - Implement taskFactory V2 to handle special privilege for Sentry
+ * [SENTRY-569] - Workaround some operations for Authorization V2
+ * [SENTRY-589] - Enable dist for authorization V2
+ * [SENTRY-592] - Support column level security for V2
+ * [SENTRY-603] - Execute on failure hooks for V2
+ * [SENTRY-813] - Refactor the AuditMetadataLogEntity to support the audit log for generic mdoel
+ * [SENTRY-814] - Add new log entity for generic model
+ * [SENTRY-815] - Update the util to generate the command for audit log
+ * [SENTRY-816] - Update the util to manage the log entity for audit log
+ * [SENTRY-817] - Update processor for generic model to generate audit log
+ * [SENTRY-916] - Improve TestPrivilegesAtTableScope for keep consistent with Hive metadata.
+ * [SENTRY-917] - Improve TestRuntimeMetadataRetrieval for keeping database policies consistent with Hive metadata
+ * [SENTRY-925] - Improve TestMetadataPermissions for keep consistent with Hive metadata.
+ * [SENTRY-926] - Improve TestMetadataObjectRetrieval for keep consistent with Hive metadata.
+ * [SENTRY-928] - Improve TestDbSentryOnFailureHookLoading for keeping database policies consistent with Hive metadata
+ * [SENTRY-929] - Improve TestDbEndToEnd for keep consistent with Hive metadata.
+ * [SENTRY-930] - Improve TestDbDDLAuditLog for keep consistent with Hive metadata.
+ * [SENTRY-931] - Improve TestDatabaseProvider for keep consistent with Hive metadata.
+ * [SENTRY-987] - Move general (non specific handler) solr-sentry code to solr-sentry-core package
+ * [SENTRY-1011] - Add Kafka binding
+ * [SENTRY-1012] - Add core model for Kafka
+ * [SENTRY-1013] - Add policy engine for Kafka
+ * [SENTRY-1014] - Add end-to-end tests for Kafka
+ * [SENTRY-1023] - Create an initial branch for CI
+ * [SENTRY-1029] - Address review comments for Kafka model that came after patch got committed.
+ * [SENTRY-1030] - Restrict Kafka Cluster authorizable to only have "kafka-cluster" as authorizable's name.
+ * [SENTRY-1056] - Get service name from Kafka's server properties.
+ * [SENTRY-1057] - Add implementations for acls' CRUD
+ * [SENTRY-1098] - Make Kafka dependency as provided
+ * [SENTRY-1102] - Merge kafka branch into trunk
+ * [SENTRY-1113] - Fix test failures due to missing files.
+ * [SENTRY-1126] - Create a email list for jira updates (issues@)
+ * [SENTRY-1137] - Update hive dependence to 2.0.0
+ * [SENTRY-1138] - Extract common classes for binding-hive-v1 and binding-hive-v2
+ * [SENTRY-1142] - Rebase on master
+ * [SENTRY-1143] - Sentry TLP: Update the builds with new git repo
+ * [SENTRY-1144] - Sentry TLP: Update status page
+ * [SENTRY-1147] - Update Home page of Sentry Web
+ * [SENTRY-1148] - Update the maillist of Sentry
+ * [SENTRY-1149] - Update committer list of Sentry
+ * [SENTRY-1150] - Update the website svn directory
+ * [SENTRY-1151] - Update source code host at sentry website
+ * [SENTRY-1152] - Update Sentry wiki after graduation
+ * [SENTRY-1159] - Decouple datanucleus dependences for hive-binding V1 and V2
+ * [SENTRY-1162] - Add shell for Sentry Kafka integration
+ * [SENTRY-1163] - Enable Jenkins for Hive Authz2
+ * [SENTRY-1172] - Update mailing lists page with new issues@ list
+ * [SENTRY-1173] - Sentry TLP: Update pom.xml to new git location
+ * [SENTRY-1186] - Sentry TLP: Update release download links on website
+ * [SENTRY-1188] - Fixes to get kerberos auth work.
+ * [SENTRY-1191] - update history page of Sentry release
+ * [SENTRY-1192] - Add SQL upgrade script for 1.7.0
+ * [SENTRY-1202] - Sentry TLP: Other Common post graduation tasks
+ * [SENTRY-1211] - Home page still has Incubator logo in footer
+
** Bug
- * [SENTRY-15] - log4j.properties file under sentry-tests references the old access package
- * [SENTRY-1] - use default on HiveServer2 fails with invalid privileges exception
- * [SENTRY-2] - Code cleanup in various poms
- * [ACCESS-8] - Log warning if authorization is not used with strong authentication
- * [ACCESS-49] - Modify test cases to restrict LOAD from specific locations
- * [ACCESS-140] - malformatted policy is permitted conditionally
- * [ACCESS-164] - policy file doesn't check non-exist entity mapping
- * [ACCESS-174] - access only throw first error message in HiveServer2 log, and ignore the rest
- * [ACCESS-180] - per DB policy file usability issues
- * [ACCESS-197] - Child authorizeable objects are not inheriting permissions from parent
- * [ACCESS-201] - Bad error message in HiveAuthzBinding
- * [ACCESS-203] - Update trunk version to 1.1 and update dependencies
- * [ACCESS-230] - CREATE TABLE AS works even if user does not have DB-level access
- * [ACCESS-231] - ALTER TABLE SET TBLPROPERTIES allows updates to tables even when the user doesn't have the right privileges
- * [ACCESS-232] - The per-db policy fies can't be accessed if they are not in the same file system as the global policy file.
- * [ACCESS-233] - The URI permission checks should append path separator before checking the parent path
- * [ACCESS-235] - Format unqualified URI as DFS uri by default
+ * [SENTRY-677] - Make the Sentry DB provider RPC methods synchronized
+ * [SENTRY-768] - [Improve error handling] Handle cases when getGroups throws an exception
+ * [SENTRY-769] - [Improve error handling] Make sure groups in list_sentry_privileges_for_provider is not empty
+ * [SENTRY-826] - TRUNCATE on empty partitioned table in Hive fails
+ * [SENTRY-835] - Drop table leaves a connection open when using metastorelistener
+ * [SENTRY-837] - Distributed path update counters in Sentry are indefinitely incremented
+ * [SENTRY-878] - collect_list missing from HIVE_UDF_WHITE_LIST
+ * [SENTRY-881] - Allow some metadata operations with column-level privileges
+ * [SENTRY-884] - Give execute permission by default to paths managed by sentry
+ * [SENTRY-885] - DB name should be case insensitive in HDFS sync plugin
+ * [SENTRY-886] - HDFSIntegration test testAccessToTableDirectory should wait for cache refresh before verification
+ * [SENTRY-888] - Exceptions in Callable tasks in MetaStoreCacheInitializer are being dropped
+ * [SENTRY-890] - Fix TestDbOperations.testAllOnTable on real clusters
+ * [SENTRY-892] - parsePath should handle empty paths well
+ * [SENTRY-893] - Synchronize calls in SentryClient and create sentry client once per request in SimpleDBProvider
+ * [SENTRY-900] - User could access sentry metric info by curl without authorization
+ * [SENTRY-904] - Set max message size for thrift messages
+ * [SENTRY-914] - Sentry default webserver port needs to change out of ephemeral port range
+ * [SENTRY-922] - INSERT OVERWRITE DIRECTORY permission not working correctly
+ * [SENTRY-923] - Fix SentryStore getPrivileges when table require "some"
+ * [SENTRY-932] - TestColumnEndToEnd error check should non-case sensitive
+ * [SENTRY-936] - getGroup and getUser should always return orginal hdfs values for paths in prefix which are not sentry managed
+ * [SENTRY-944] - Setting HDFS rules on Sentry managed hdfs paths should not affect original hdfs rules
+ * [SENTRY-945] - Avoid logging all DataNucleus queries when debug logging is enabled
+ * [SENTRY-953] - External Partitions which are referenced by more than one table can cause some unexpected behavior with Sentry HDFS sync
+ * [SENTRY-960] - Use hive.server2.builtin.udf.blacklist
+ * [SENTRY-962] - Fix SentryStore getPrivileges when column require "some"
+ * [SENTRY-965] - Solr /terms request handler broken because of components declaration
+ * [SENTRY-966] - SqoopAuthBindingSingleton uses bad double check locking idiom
+ * [SENTRY-968] - Uri check needs to be case sensitive
+ * [SENTRY-971] - Add profile to enable Hive AuthZ v2
+ * [SENTRY-974] - create a sentry test data dump to facilite sentry scale tests
+ * [SENTRY-981] - Fix the error in integration tests
+ * [SENTRY-988] - It's better to let SentryAuthorization setter path always fall through and update HDFS
+ * [SENTRY-989] - RealTimeGet with explicit ids can bypass document level authorization
+ * [SENTRY-991] - Roles of Sentry Permission needs to be case insensitive
+ * [SENTRY-994] - SentryAuthorizationInfoX should override isSentryManaged
+ * [SENTRY-997] - Update HiveAuthorizer of Sentry after HiveAuthorizer interface changes
+ * [SENTRY-998] - TestSentryShellHive test failure with JDK 8
+ * [SENTRY-1002] - PathsUpdate.parsePath(path) will throw an NPE when parsing relative paths
+ * [SENTRY-1003] - Support "reload" by updating the classpath of Sentry function aux jar path during runtime
+ * [SENTRY-1007] - Sentry column-level performance for wide tables
+ * [SENTRY-1008] - Path should be not be updated if the create/drop table/partition event fails
+ * [SENTRY-1009] - Improve TestDatabaseProvider to validate test object names instead of validating vague numbers.
+ * [SENTRY-1010] - Sentry column-level performance for wide tables for 1.5.1
+ * [SENTRY-1018] - HiveServer is not properly shutdown cause BindException in TestServerConfiguration
+ * [SENTRY-1027] - Fix PMD error for unused field when enable Hive authz V2
+ * [SENTRY-1035] - Generic service does not handle group name casing correctly
+ * [SENTRY-1037] - Set "hadoop.security.authentication" to "kerberos" in the Generic Client
+ * [SENTRY-1039] - Sentry shell tests assume order of option group privileges
+ * [SENTRY-1044] - Tables with non-hdfs locations breaks HMS startup
+ * [SENTRY-1046] - Hive Auxiliary JARs Directory is not working when Sentry is enabled: Caused by: java.lang.ClassNotFoundException
+ * [SENTRY-1050] - Improve clearAll method to avoid throwing exceptions because of deleting objects created outside of tests.
+ * [SENTRY-1054] - Updated Apache Shiro dependency
+ * [SENTRY-1055] - Sentry service solr constants refer to clusters rather than services
+ * [SENTRY-1058] - Duplicate junit versions in the root pom
+ * [SENTRY-1059] - 'dependencies.dependency.version' for org.apache.sentry:sentry-core-model-kafka:jar is missing. @ line 42, column 17
+ * [SENTRY-1060] - Improve the SentryAuthFilter error message when authentication failure
+ * [SENTRY-1064] - Fix TestDbOperations#testCaseSensitivity
+ * [SENTRY-1066] - Sentry oracle upgrade script failed with ORA-0955 duplicate name issue
+ * [SENTRY-1071] - Update thrift gen-file with maven plugin
+ * [SENTRY-1077] - create a wiki to describe how to run scale script to prepare data and how to run sentry hive e2e tests on the cluster
+ * [SENTRY-1087] - Capture URI when using Hive Serdes
+ * [SENTRY-1095] - Insert into requires URI privilege on partition location under table.
+ * [SENTRY-1096] - Fix TestDbOperations#testCaseSensitivity failure on a real cluster
+ * [SENTRY-1097] - Fix compilation errors from SentryGenericPolicyProcessor
+ * [SENTRY-1099] - JDK8 autoboxing compilation failure
+ * [SENTRY-1105] - Fix unittest TestMetastoreEndToEnd.testAddPartion
+ * [SENTRY-1111] - Apache Sentry should depend on the same version of metrics-core as hadoop
+ * [SENTRY-1112] - Change default value of "sentry.hive.server" to empty string
+ * [SENTRY-1114] - Wrong classname and incorrect _CMD_JAR var in sentryShell
+ * [SENTRY-1116] - Fix PMD violation for Sentry tests after missing commits
+ * [SENTRY-1122] - Allow Solr Audit Log to Read Impersonator Info
+ * [SENTRY-1128] - Add metastore_db to .gitignore
+ * [SENTRY-1155] - Add waiting time for getMetastoreClient for avoiding metastore isn't ready
+ * [SENTRY-1156] - TestDbColumnLevelMetaDataOps should add `use database` for user session created
+ * [SENTRY-1157] - Fix Unit Tests TestAclsCrud&TestAuthorize failed
+ * [SENTRY-1164] - Fix testCaseSensitivity test failure on a real cluster
+ * [SENTRY-1169] - MetastorePlugin#renameAuthzObject log message prints oldpathname as newpathname
+ * [SENTRY-1217] - NPE for list_sentry_privileges_by_authorizable when activeRoleSet is not set
+ * [SENTRY-1234] - JDO exception for list_sentry_privileges_by_authorizable
** Improvement
- * [SENTRY-5] - Normalize the usernames used in the end to end tests
- * [ACCESS-100] - ResourceAuthzProvider should ensure the subject name is non-null before doing the group lookup
- * [ACCESS-157] - Access hard codes hive authentication method none
- * [ACCESS-211] - Add maven profile for compiling access with upstream Apache hadoop/hive
- * [ACCESS-221] - Restrict the URI access granted from a per-database policy file
+ * [SENTRY-520] - Use the twitter Bootstrap kit (or similar) to beautify the Sentry Service webpage
+ * [SENTRY-565] - Improve performance of filtering Hive SHOW commands
+ * [SENTRY-685] - Refactor Sentry HDFS plugin to work with new Hadoop interface
+ * [SENTRY-832] - Clean dependences of sentry-provider-db
+ * [SENTRY-870] - Create UpdateForwarders for paths and permissions
+ * [SENTRY-913] - Thread safe improvement for sqoop binding singleton
+ * [SENTRY-934] - Update plugin versions
+ * [SENTRY-952] - Update source to JDK 7
+ * [SENTRY-957] - Exceptions in MetastoreCacheInitializer should probably not prevent HMS from starting up
+ * [SENTRY-970] - Use random free port for Sqoop tests
+ * [SENTRY-972] - Include sentry-tests-hive hadoop test script in maven project
+ * [SENTRY-973] - Bump hamcrest version
+ * [SENTRY-979] - Speed up the build (a bit)
+ * [SENTRY-986] - Apply PMD plugin to Sentry source
+ * [SENTRY-993] - list_sentry_privileges_by_authorizable() gone in API v2
+ * [SENTRY-1006] - Add user manual for simple shell
+ * [SENTRY-1015] - Improve Sentry + Hive error message when user does not have sufficient privileges to perform an operation
+ * [SENTRY-1021] - Add PMD to Sentry tests
+ * [SENTRY-1036] - Move ProviderConstants from sentry-provider-common to sentry-policy-common
+ * [SENTRY-1048] - Fix "Critical" issues identified by analysis.apache.org
+ * [SENTRY-1051] - The policy Privilege implementations could be consolidated
+ * [SENTRY-1052] - Sentry shell should use kerberos requestor and give better error messages for kerberos failures
+ * [SENTRY-1065] - Make SentryNoSuchObjectException exception error message consistent across all files
+ * [SENTRY-1078] - Add servlet for dumping configurations
+ * [SENTRY-1088] - PathsUpdate should log invalid paths to make troubleshooting easier
+ * [SENTRY-1119] - Allow data engines to specify the ActionFactory from configuration
+ * [SENTRY-1121] - Update Jetty version
+ * [SENTRY-1135] - Remove deprecated junit.framework dependencies
+ * [SENTRY-1136] - Remove /Ping and /HealthCheck from Sentry Service Webpage
+
+** New Feature
+ * [SENTRY-498] - Sentry integration with Hive authorization framework V2
+ * [SENTRY-749] - Create simple shell for sentry
+ * [SENTRY-812] - Generate audit trail for Sentry generic model when authorization metadata change
+ * [SENTRY-906] - Add concurrency sentry client tests
+ * [SENTRY-995] - Simple Solr Shell
+ * [SENTRY-1130] - Upgrade Hive plugin v2 for hive 2.0.0
** Task
- * [ACCESS-16] - Implement the test cases in the test plan
- * [ACCESS-34] - Analyze Path Security
- * [ACCESS-115] - Format all files using a consistent code style formatter for the project
- * [ACCESS-122] - Remove context.close() mid-test
- * [ACCESS-123] - Fix confusing communication mechanism to request if ANY access is exists
- * [ACCESS-125] - TestUserManagement major issues
- * [ACCESS-127] - TestSandboxOps Major issues
- * [ACCESS-130] - TestMovingToProduction major issues
- * [ACCESS-136] - TestCrossDbOps major issues
- * [ACCESS-145] - TestMetadataObjectRetrieval major issues
- * [ACCESS-147] - TestPrivilegeAtTransform major issues
- * [ACCESS-149] - TestPrivilegesAtDatabaseScope major issues
- * [ACCESS-152] - TestPrivilegesAtTableScope minor issues
- * [ACCESS-166] - Policy Engine should do expanded validation of policy file
- * [ACCESS-194] - Explore options for metastore access restriction
- * [ACCESS-195] - Support username mapping at access level
+ * [SENTRY-510] - Metrics collection for Sentry HDFS plugin
+ * [SENTRY-742] - Add describe, show/compute stats tests for column level privileges
+ * [SENTRY-984] - add sentry into analysis.apache.org
+ * [SENTRY-1016] - Update incubator status page with new committer news (Anne) and new resolution (Committer == PPMC during graduation)
+ * [SENTRY-1017] - Update Sentry website "people (commiters)" section with new committer (Anne) and PPMC section with a note on new resolution
+ * [SENTRY-1032] - Implement group/role commands in solr shell
+ * [SENTRY-1038] - More strict checking of SOLR actions in shell
+ * [SENTRY-1047] - Use existing validators in SentryShellSolr
+ * [SENTRY-1110] - Apache Sentry 1.7.0 Release
-** Sub-task
- * [ACCESS-101] - Implement more test cases regarding subquery
- * [ACCESS-209] - be able to run e2e test in cluster mode
- * [ACCESS-225] - Update master branch version to 1.2.0-SNAPSHOT
+
+** Test
+ * [SENTRY-570] - Bug fixing for the test case "TestMetaStoreWithPigHCat"
+ * [SENTRY-748] - Improve test coverage of Sentry + Hive using complex views
+ * [SENTRY-869] - Add a test where we have multiple column level privileges for a given role
+ * [SENTRY-915] - Improve Hive E2E tests for keep consistent with Hive metadata.
+ * [SENTRY-927] - Improve AbstractTestWithStaticConfiguration for keep consistent with Hive metadata.
+ * [SENTRY-955] - Add more meta data operation tests for column level privilege
+ * [SENTRY-958] - TestGrantPrivilege fails on JDK8
+ * [SENTRY-1109] - mvn clean install fails with PMD validation: Unnecessary use of fully qualified name 'org.apache.hadoop.hive.metastore.api.Partition' due to existing import 'org.apache.hadoop.hive.metastore.api.Partition'
diff --git a/DISCLAIMER.txt b/DISCLAIMER.txt
deleted file mode 100644
index ce4c59c23..000000000
--- a/DISCLAIMER.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-Apache Sentry is an effort undergoing incubation at the Apache Software
-Foundation (ASF), sponsored by the Apache Incubator Project Management
-Committee.
-
-Incubation is required for all newly accepted projects until a further review
-indicates that the infrastructure, communications, and decisions making process
-have stabilized in a manner consistent with other successful ASF projects.
-
-While incubation status is not necessarily a reflection of the completeness or
-stability of the code, it does indicate that the project has yet to be fully
-endorsed by the ASF.
-
-For more information about the incubation status of the Sentry project you can
-go to the following page:
-
-http://incubator.apache.org/projects/sentry.html
diff --git a/LICENSE.txt b/LICENSE.txt
index c29b59dda..e6be7872c 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -203,7 +203,7 @@
================================================================================
-The Apache Sentry (incubating) distribution includes the following sources/binaries.
+The Apache Sentry distribution includes the following sources/binaries.
The use of these sources/binaries is subject to the terms and conditions of
their respective licenses.
diff --git a/NOTICE.txt b/NOTICE.txt
index 14fe33daf..4b8c3b75d 100644
--- a/NOTICE.txt
+++ b/NOTICE.txt
@@ -1,5 +1,5 @@
Apache Sentry
-Copyright 2014 The Apache Software Foundation
+Copyright 2017 The Apache Software Foundation
This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).
diff --git a/pom.xml b/pom.xml
index 37db00795..4356fea60 100644
--- a/pom.xml
+++ b/pom.xml
@@ -25,7 +25,7 @@ limitations under the License.
org.apache.sentry
sentry
- 1.7.0-incubating-SNAPSHOT
+ 1.7.1
Sentry component
Sentry
pom
@@ -43,9 +43,9 @@ limitations under the License.
- scm:git:https://git-wip-us.apache.org/repos/asf/incubator-sentry.git
- scm:git:https://git-wip-us.apache.org/repos/asf/incubator-sentry.git
- https://git-wip-us.apache.org/repos/asf/incubator-sentry
+ scm:git:https://git-wip-us.apache.org/repos/asf/sentry.git
+ scm:git:https://git-wip-us.apache.org/repos/asf/sentry.git
+ https://git-wip-us.apache.org/repos/asf/sentry
@@ -74,11 +74,11 @@ limitations under the License.
1.1.0
1.8.8
3.0.1
- 7.6.16.v20140903
+ 8.1.19.v20160209
2.5
4.10
- 0.9.2
- 0.9.2
+ 0.9.3
+ 0.9.3
1.2.16
1.7
2.9
@@ -888,6 +888,33 @@ limitations under the License.
${basedir}/../../build-tools
+
+ sign-artifacts
+
+
+ sign-artifacts
+ true
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-gpg-plugin
+ 1.6
+
+
+ sign-artifacts
+ verify
+
+ sign
+
+
+
+
+
+
+
diff --git a/sentry-binding/pom.xml b/sentry-binding/pom.xml
index 830f0b180..35ec26b72 100644
--- a/sentry-binding/pom.xml
+++ b/sentry-binding/pom.xml
@@ -22,7 +22,7 @@ limitations under the License.
org.apache.sentry
sentry
- 1.7.0-incubating-SNAPSHOT
+ 1.7.1
sentry-binding
diff --git a/sentry-binding/sentry-binding-hive-common/pom.xml b/sentry-binding/sentry-binding-hive-common/pom.xml
index 37485229d..00472a809 100644
--- a/sentry-binding/sentry-binding-hive-common/pom.xml
+++ b/sentry-binding/sentry-binding-hive-common/pom.xml
@@ -22,7 +22,7 @@ limitations under the License.
org.apache.sentry
sentry-binding
- 1.7.0-incubating-SNAPSHOT
+ 1.7.1
sentry-binding-hive-common
diff --git a/sentry-binding/sentry-binding-hive-v2/pom.xml b/sentry-binding/sentry-binding-hive-v2/pom.xml
index f633b6b08..c7a9b9d70 100644
--- a/sentry-binding/sentry-binding-hive-v2/pom.xml
+++ b/sentry-binding/sentry-binding-hive-v2/pom.xml
@@ -22,7 +22,7 @@ limitations under the License.
org.apache.sentry
sentry-binding
- 1.7.0-incubating-SNAPSHOT
+ 1.7.1
sentry-binding-hive-v2
diff --git a/sentry-binding/sentry-binding-hive/pom.xml b/sentry-binding/sentry-binding-hive/pom.xml
index 1a6e42020..838734dcf 100644
--- a/sentry-binding/sentry-binding-hive/pom.xml
+++ b/sentry-binding/sentry-binding-hive/pom.xml
@@ -22,7 +22,7 @@ limitations under the License.
org.apache.sentry
sentry-binding
- 1.7.0-incubating-SNAPSHOT
+ 1.7.1
sentry-binding-hive
diff --git a/sentry-binding/sentry-binding-kafka/pom.xml b/sentry-binding/sentry-binding-kafka/pom.xml
index 27422067a..1133dd348 100644
--- a/sentry-binding/sentry-binding-kafka/pom.xml
+++ b/sentry-binding/sentry-binding-kafka/pom.xml
@@ -23,7 +23,7 @@ limitations under the License.
org.apache.sentry
sentry-binding
- 1.7.0-incubating-SNAPSHOT
+ 1.7.1
sentry-binding-kafka
diff --git a/sentry-binding/sentry-binding-kafka/src/main/java/org/apache/sentry/kafka/authorizer/SentryKafkaAuthorizer.java b/sentry-binding/sentry-binding-kafka/src/main/java/org/apache/sentry/kafka/authorizer/SentryKafkaAuthorizer.java
index 3bce6cc40..03f7b7f5a 100644
--- a/sentry-binding/sentry-binding-kafka/src/main/java/org/apache/sentry/kafka/authorizer/SentryKafkaAuthorizer.java
+++ b/sentry-binding/sentry-binding-kafka/src/main/java/org/apache/sentry/kafka/authorizer/SentryKafkaAuthorizer.java
@@ -117,7 +117,7 @@ public void configure(java.util.Map configs) {
}
LOG.info("Configuring Sentry KafkaAuthorizer: " + sentry_site);
final KafkaAuthBindingSingleton instance = KafkaAuthBindingSingleton.getInstance();
- instance.configure(this.kafkaServiceInstanceName, this.requestorName, sentry_site);
+ instance.configure(this.kafkaServiceInstanceName, this.requestorName, sentry_site, configs);
this.binding = instance.getAuthBinding();
}
diff --git a/sentry-binding/sentry-binding-kafka/src/main/java/org/apache/sentry/kafka/binding/KafkaAuthBinding.java b/sentry-binding/sentry-binding-kafka/src/main/java/org/apache/sentry/kafka/binding/KafkaAuthBinding.java
index 8f4a8c484..c6600a019 100644
--- a/sentry-binding/sentry-binding-kafka/src/main/java/org/apache/sentry/kafka/binding/KafkaAuthBinding.java
+++ b/sentry-binding/sentry-binding-kafka/src/main/java/org/apache/sentry/kafka/binding/KafkaAuthBinding.java
@@ -16,6 +16,7 @@
*/
package org.apache.sentry.kafka.binding;
+import java.io.IOException;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.HashMap;
@@ -34,6 +35,8 @@
import kafka.network.RequestChannel;
import kafka.security.auth.Operation;
import kafka.security.auth.Resource;
+import org.apache.hadoop.security.SecurityUtil;
+import org.apache.hadoop.security.UserGroupInformation;
import org.apache.kafka.common.KafkaException;
import org.apache.kafka.common.security.auth.KafkaPrincipal;
import org.apache.sentry.SentryUserException;
@@ -55,6 +58,7 @@
import org.apache.sentry.provider.db.generic.service.thrift.TAuthorizable;
import org.apache.sentry.provider.db.generic.service.thrift.TSentryPrivilege;
import org.apache.sentry.provider.db.generic.service.thrift.TSentryRole;
+import org.apache.sentry.service.thrift.ServiceConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import scala.Option;
@@ -64,12 +68,16 @@
import scala.collection.JavaConversions;
import scala.collection.immutable.Map;
+import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTHENTICATION;
+
public class KafkaAuthBinding {
private static final Logger LOG = LoggerFactory.getLogger(KafkaAuthBinding.class);
private static final String COMPONENT_TYPE = AuthorizationComponent.KAFKA;
private static final String COMPONENT_NAME = COMPONENT_TYPE;
+ private static Boolean kerberosInit;
+
private final Configuration authConf;
private final AuthorizationProvider authProvider;
private final KafkaActionFactory actionFactory = KafkaActionFactory.getInstance();
@@ -77,12 +85,14 @@ public class KafkaAuthBinding {
private ProviderBackend providerBackend;
private String instanceName;
private String requestorName;
+ private java.util.Map kafkaConfigs;
- public KafkaAuthBinding(String instanceName, String requestorName, Configuration authConf) throws Exception {
+ public KafkaAuthBinding(String instanceName, String requestorName, Configuration authConf, java.util.Map kafkaConfigs) throws Exception {
this.instanceName = instanceName;
this.requestorName = requestorName;
this.authConf = authConf;
+ this.kafkaConfigs = kafkaConfigs;
this.authProvider = createAuthProvider();
}
@@ -118,6 +128,28 @@ private AuthorizationProvider createAuthProvider() throws Exception {
+ providerBackendName);
}
+ // Initiate kerberos via UserGroupInformation if required
+ if (ServiceConstants.ServerConfig.SECURITY_MODE_KERBEROS.equals(authConf.get(ServiceConstants.ServerConfig.SECURITY_MODE))
+ && kafkaConfigs != null) {
+ String keytabProp = kafkaConfigs.get(AuthzConfVars.AUTHZ_KEYTAB_FILE_NAME.getVar()).toString();
+ String principalProp = kafkaConfigs.get(AuthzConfVars.AUTHZ_PRINCIPAL_NAME.getVar()).toString();
+ if (keytabProp != null && principalProp != null) {
+ String actualHost = kafkaConfigs.get(AuthzConfVars.AUTHZ_PRINCIPAL_HOSTNAME.getVar()).toString();
+ if (actualHost != null) {
+ principalProp = SecurityUtil.getServerPrincipal(principalProp, actualHost);
+ }
+ initKerberos(keytabProp, principalProp);
+ } else {
+ LOG.debug("Could not initialize Kerberos.\n" +
+ AuthzConfVars.AUTHZ_KEYTAB_FILE_NAME.getVar() + " set to " + kafkaConfigs.get(AuthzConfVars.AUTHZ_KEYTAB_FILE_NAME.getVar()).toString() + "\n" +
+ AuthzConfVars.AUTHZ_PRINCIPAL_NAME.getVar() + " set to " + kafkaConfigs.get(AuthzConfVars.AUTHZ_PRINCIPAL_NAME.getVar()).toString());
+ }
+ } else {
+ LOG.debug("Could not initialize Kerberos as no kafka config provided. " +
+ AuthzConfVars.AUTHZ_KEYTAB_FILE_NAME.getVar() + " and " + AuthzConfVars.AUTHZ_PRINCIPAL_NAME.getVar() +
+ " are required configs to be able to initialize Kerberos");
+ }
+
// Instantiate the configured providerBackend
Constructor> providerBackendConstructor =
Class.forName(providerBackendName)
@@ -495,4 +527,36 @@ private String getName(RequestChannel.Session session) {
return principalName;
}
}
+
+ /**
+ * Initialize kerberos via UserGroupInformation. Will only attempt to login
+ * during the first request, subsequent calls will have no effect.
+ */
+ private void initKerberos(String keytabFile, String principal) {
+ if (keytabFile == null || keytabFile.length() == 0) {
+ throw new IllegalArgumentException("keytabFile required because kerberos is enabled");
+ }
+ if (principal == null || principal.length() == 0) {
+ throw new IllegalArgumentException("principal required because kerberos is enabled");
+ }
+ synchronized (KafkaAuthBinding.class) {
+ if (kerberosInit == null) {
+ kerberosInit = new Boolean(true);
+ // let's avoid modifying the supplied configuration, just to be conservative
+ final Configuration ugiConf = new Configuration();
+ ugiConf.set(HADOOP_SECURITY_AUTHENTICATION, ServiceConstants.ServerConfig.SECURITY_MODE_KERBEROS);
+ UserGroupInformation.setConfiguration(ugiConf);
+ LOG.info(
+ "Attempting to acquire kerberos ticket with keytab: {}, principal: {} ",
+ keytabFile, principal);
+ try {
+ UserGroupInformation.loginUserFromKeytab(principal, keytabFile);
+ } catch (IOException ioe) {
+ throw new RuntimeException("Failed to login user with Principal: " + principal +
+ " and Keytab file: " + keytabFile, ioe);
+ }
+ LOG.info("Got Kerberos ticket");
+ }
+ }
+ }
}
diff --git a/sentry-binding/sentry-binding-kafka/src/main/java/org/apache/sentry/kafka/binding/KafkaAuthBindingSingleton.java b/sentry-binding/sentry-binding-kafka/src/main/java/org/apache/sentry/kafka/binding/KafkaAuthBindingSingleton.java
index a0007a3e3..6555dae39 100644
--- a/sentry-binding/sentry-binding-kafka/src/main/java/org/apache/sentry/kafka/binding/KafkaAuthBindingSingleton.java
+++ b/sentry-binding/sentry-binding-kafka/src/main/java/org/apache/sentry/kafka/binding/KafkaAuthBindingSingleton.java
@@ -18,6 +18,7 @@
import java.net.MalformedURLException;
import java.net.URL;
+import java.util.Map;
import org.apache.sentry.kafka.conf.KafkaAuthConf;
import org.slf4j.Logger;
@@ -56,10 +57,10 @@ private KafkaAuthConf loadAuthzConf(String sentry_site) {
return kafkaAuthConf;
}
- public void configure(String instanceName, String requestorName, String sentry_site) {
+ public void configure(String instanceName, String requestorName, String sentry_site, Map kafkaConfigs) {
try {
kafkaAuthConf = loadAuthzConf(sentry_site);
- binding = new KafkaAuthBinding(instanceName, requestorName, kafkaAuthConf);
+ binding = new KafkaAuthBinding(instanceName, requestorName, kafkaAuthConf, kafkaConfigs);
log.info("KafkaAuthBinding created successfully");
} catch (Exception ex) {
log.error("Unable to create KafkaAuthBinding", ex);
diff --git a/sentry-binding/sentry-binding-kafka/src/main/java/org/apache/sentry/kafka/conf/KafkaAuthConf.java b/sentry-binding/sentry-binding-kafka/src/main/java/org/apache/sentry/kafka/conf/KafkaAuthConf.java
index e0d767ec3..0a57e2e00 100644
--- a/sentry-binding/sentry-binding-kafka/src/main/java/org/apache/sentry/kafka/conf/KafkaAuthConf.java
+++ b/sentry-binding/sentry-binding-kafka/src/main/java/org/apache/sentry/kafka/conf/KafkaAuthConf.java
@@ -30,6 +30,9 @@ public class KafkaAuthConf extends Configuration {
public static final String KAFKA_SUPER_USERS = "kafka.superusers";
public static final String KAFKA_SERVICE_INSTANCE_NAME = "sentry.kafka.service.instance";
public static final String KAFKA_SERVICE_USER_NAME = "sentry.kafka.service.user.name";
+ public static final String KAFKA_PRINCIPAL_HOSTNAME = "sentry.kafka.principal.hostname";
+ public static final String KAFKA_PRINCIPAL_NAME = "sentry.kafka.kerberos.principal";
+ public static final String KAFKA_KEYTAB_FILE_NAME = "sentry.kafka.keytab.file";
/**
* Config setting definitions
@@ -40,7 +43,10 @@ public static enum AuthzConfVars {
AUTHZ_PROVIDER_BACKEND("sentry.kafka.provider.backend", SentryGenericProviderBackend.class.getName()),
AUTHZ_POLICY_ENGINE("sentry.kafka.policy.engine", SimpleKafkaPolicyEngine.class.getName()),
AUTHZ_INSTANCE_NAME(KAFKA_SERVICE_INSTANCE_NAME, "kafka"),
- AUTHZ_SERVICE_USER_NAME(KAFKA_SERVICE_USER_NAME, "kafka");
+ AUTHZ_SERVICE_USER_NAME(KAFKA_SERVICE_USER_NAME, "kafka"),
+ AUTHZ_PRINCIPAL_HOSTNAME(KAFKA_PRINCIPAL_HOSTNAME, null),
+ AUTHZ_PRINCIPAL_NAME(KAFKA_PRINCIPAL_NAME, null),
+ AUTHZ_KEYTAB_FILE_NAME(KAFKA_KEYTAB_FILE_NAME, null);
private final String varName;
private final String defaultVal;
diff --git a/sentry-binding/sentry-binding-solr/pom.xml b/sentry-binding/sentry-binding-solr/pom.xml
index e8e3013ac..54ed7f110 100644
--- a/sentry-binding/sentry-binding-solr/pom.xml
+++ b/sentry-binding/sentry-binding-solr/pom.xml
@@ -22,7 +22,7 @@ limitations under the License.
org.apache.sentry
sentry-binding
- 1.7.0-incubating-SNAPSHOT
+ 1.7.1
sentry-binding-solr
diff --git a/sentry-binding/sentry-binding-sqoop/pom.xml b/sentry-binding/sentry-binding-sqoop/pom.xml
index 20cbda037..a1d53e471 100644
--- a/sentry-binding/sentry-binding-sqoop/pom.xml
+++ b/sentry-binding/sentry-binding-sqoop/pom.xml
@@ -22,7 +22,7 @@ limitations under the License.
org.apache.sentry
sentry-binding
- 1.7.0-incubating-SNAPSHOT
+ 1.7.1
sentry-binding-sqoop
diff --git a/sentry-core/pom.xml b/sentry-core/pom.xml
index 06d92dea8..fa3ed9cf7 100644
--- a/sentry-core/pom.xml
+++ b/sentry-core/pom.xml
@@ -21,7 +21,7 @@ limitations under the License.
org.apache.sentry
sentry
- 1.7.0-incubating-SNAPSHOT
+ 1.7.1
sentry-core
diff --git a/sentry-core/sentry-core-common/pom.xml b/sentry-core/sentry-core-common/pom.xml
index 21a167745..9fc4e0f87 100644
--- a/sentry-core/sentry-core-common/pom.xml
+++ b/sentry-core/sentry-core-common/pom.xml
@@ -21,7 +21,7 @@ limitations under the License.
org.apache.sentry
sentry-core
- 1.7.0-incubating-SNAPSHOT
+ 1.7.1
sentry-core-common
diff --git a/sentry-core/sentry-core-model-db/pom.xml b/sentry-core/sentry-core-model-db/pom.xml
index 902b129a6..ad0338b1c 100644
--- a/sentry-core/sentry-core-model-db/pom.xml
+++ b/sentry-core/sentry-core-model-db/pom.xml
@@ -21,7 +21,7 @@ limitations under the License.
org.apache.sentry
sentry-core
- 1.7.0-incubating-SNAPSHOT
+ 1.7.1
sentry-core-model-db
diff --git a/sentry-core/sentry-core-model-indexer/pom.xml b/sentry-core/sentry-core-model-indexer/pom.xml
index 68069f4a4..6244dfcf2 100644
--- a/sentry-core/sentry-core-model-indexer/pom.xml
+++ b/sentry-core/sentry-core-model-indexer/pom.xml
@@ -21,7 +21,7 @@ limitations under the License.
org.apache.sentry
sentry-core
- 1.7.0-incubating-SNAPSHOT
+ 1.7.1
sentry-core-model-indexer
diff --git a/sentry-core/sentry-core-model-kafka/pom.xml b/sentry-core/sentry-core-model-kafka/pom.xml
index cadd4ac8e..51024f5dc 100644
--- a/sentry-core/sentry-core-model-kafka/pom.xml
+++ b/sentry-core/sentry-core-model-kafka/pom.xml
@@ -21,7 +21,7 @@ limitations under the License.
org.apache.sentry
sentry-core
- 1.7.0-incubating-SNAPSHOT
+ 1.7.1
sentry-core-model-kafka
diff --git a/sentry-core/sentry-core-model-search/pom.xml b/sentry-core/sentry-core-model-search/pom.xml
index 5f0adc393..757564255 100644
--- a/sentry-core/sentry-core-model-search/pom.xml
+++ b/sentry-core/sentry-core-model-search/pom.xml
@@ -21,7 +21,7 @@ limitations under the License.
org.apache.sentry
sentry-core
- 1.7.0-incubating-SNAPSHOT
+ 1.7.1
sentry-core-model-search
diff --git a/sentry-core/sentry-core-model-sqoop/pom.xml b/sentry-core/sentry-core-model-sqoop/pom.xml
index b5000590a..24ebde3cf 100644
--- a/sentry-core/sentry-core-model-sqoop/pom.xml
+++ b/sentry-core/sentry-core-model-sqoop/pom.xml
@@ -21,7 +21,7 @@ limitations under the License.
org.apache.sentry
sentry-core
- 1.7.0-incubating-SNAPSHOT
+ 1.7.1
sentry-core-model-sqoop
diff --git a/sentry-dist/pom.xml b/sentry-dist/pom.xml
index 4e078f08b..a3a7c968c 100644
--- a/sentry-dist/pom.xml
+++ b/sentry-dist/pom.xml
@@ -20,7 +20,7 @@ limitations under the License.
org.apache.sentry
sentry
- 1.7.0-incubating-SNAPSHOT
+ 1.7.1
sentry-dist
Sentry Distribution
@@ -48,7 +48,7 @@ limitations under the License.
org.apache.sentry
- sentry-binding-hive
+ sentry-core-model-kafka
org.apache.sentry
@@ -58,6 +58,10 @@ limitations under the License.
org.apache.sentry
sentry-binding-sqoop
+
+ org.apache.sentry
+ sentry-binding-kafka
+
org.apache.sentry
solr-sentry-core
@@ -102,10 +106,39 @@ limitations under the License.
org.apache.sentry
sentry-policy-sqoop
+
+ org.apache.sentry
+ sentry-policy-kafka
+
+
+
+ hive-authz1
+
+ true
+
+
+
+ org.apache.sentry
+ sentry-binding-hive
+
+
+
+
+ hive-authz2
+
+ false
+
+
+
+ org.apache.sentry
+ sentry-binding-hive-v2
+
+
+
+
-
org.apache.maven.plugins
maven-assembly-plugin
diff --git a/sentry-hdfs/pom.xml b/sentry-hdfs/pom.xml
index 06081c5e8..f14cbfbae 100644
--- a/sentry-hdfs/pom.xml
+++ b/sentry-hdfs/pom.xml
@@ -22,7 +22,7 @@ limitations under the License.
org.apache.sentry
sentry
- 1.7.0-incubating-SNAPSHOT
+ 1.7.1
sentry-hdfs
diff --git a/sentry-hdfs/sentry-hdfs-common/pom.xml b/sentry-hdfs/sentry-hdfs-common/pom.xml
index c748e5670..451ed1fce 100644
--- a/sentry-hdfs/sentry-hdfs-common/pom.xml
+++ b/sentry-hdfs/sentry-hdfs-common/pom.xml
@@ -21,7 +21,7 @@ limitations under the License.
org.apache.sentry
sentry-hdfs
- 1.7.0-incubating-SNAPSHOT
+ 1.7.1
sentry-hdfs-common
diff --git a/sentry-hdfs/sentry-hdfs-dist/pom.xml b/sentry-hdfs/sentry-hdfs-dist/pom.xml
index 37350c515..ac537bd69 100644
--- a/sentry-hdfs/sentry-hdfs-dist/pom.xml
+++ b/sentry-hdfs/sentry-hdfs-dist/pom.xml
@@ -22,7 +22,7 @@ limitations under the License.
org.apache.sentry
sentry-hdfs
- 1.7.0-incubating-SNAPSHOT
+ 1.7.1
sentry-hdfs-dist
diff --git a/sentry-hdfs/sentry-hdfs-namenode-plugin/pom.xml b/sentry-hdfs/sentry-hdfs-namenode-plugin/pom.xml
index 8d3bdc9fc..270c43edb 100644
--- a/sentry-hdfs/sentry-hdfs-namenode-plugin/pom.xml
+++ b/sentry-hdfs/sentry-hdfs-namenode-plugin/pom.xml
@@ -21,7 +21,7 @@ limitations under the License.
org.apache.sentry
sentry-hdfs
- 1.7.0-incubating-SNAPSHOT
+ 1.7.1
sentry-hdfs-namenode-plugin
@@ -32,7 +32,7 @@ limitations under the License.
org.apache.sentry
sentry-hdfs-common
- 1.7.0-incubating-SNAPSHOT
+ 1.7.1
junit
diff --git a/sentry-hdfs/sentry-hdfs-service/pom.xml b/sentry-hdfs/sentry-hdfs-service/pom.xml
index 78f9da716..6a9b20092 100644
--- a/sentry-hdfs/sentry-hdfs-service/pom.xml
+++ b/sentry-hdfs/sentry-hdfs-service/pom.xml
@@ -21,7 +21,7 @@ limitations under the License.
org.apache.sentry
sentry-hdfs
- 1.7.0-incubating-SNAPSHOT
+ 1.7.1
sentry-hdfs-service
diff --git a/sentry-policy/pom.xml b/sentry-policy/pom.xml
index 45dc675a0..7fa331a7b 100644
--- a/sentry-policy/pom.xml
+++ b/sentry-policy/pom.xml
@@ -22,7 +22,7 @@ limitations under the License.
org.apache.sentry
sentry
- 1.7.0-incubating-SNAPSHOT
+ 1.7.1
sentry-policy
diff --git a/sentry-policy/sentry-policy-common/pom.xml b/sentry-policy/sentry-policy-common/pom.xml
index fbec06f07..6d8ffd720 100644
--- a/sentry-policy/sentry-policy-common/pom.xml
+++ b/sentry-policy/sentry-policy-common/pom.xml
@@ -21,7 +21,7 @@ limitations under the License.
org.apache.sentry
sentry-policy
- 1.7.0-incubating-SNAPSHOT
+ 1.7.1
sentry-policy-common
diff --git a/sentry-policy/sentry-policy-db/pom.xml b/sentry-policy/sentry-policy-db/pom.xml
index 1b1ae43cc..a4ff22af1 100644
--- a/sentry-policy/sentry-policy-db/pom.xml
+++ b/sentry-policy/sentry-policy-db/pom.xml
@@ -21,7 +21,7 @@ limitations under the License.
org.apache.sentry
sentry-policy
- 1.7.0-incubating-SNAPSHOT
+ 1.7.1
sentry-policy-db
diff --git a/sentry-policy/sentry-policy-indexer/pom.xml b/sentry-policy/sentry-policy-indexer/pom.xml
index 1a5058163..59c0f9062 100644
--- a/sentry-policy/sentry-policy-indexer/pom.xml
+++ b/sentry-policy/sentry-policy-indexer/pom.xml
@@ -21,7 +21,7 @@ limitations under the License.
org.apache.sentry
sentry-policy
- 1.7.0-incubating-SNAPSHOT
+ 1.7.1
sentry-policy-indexer
diff --git a/sentry-policy/sentry-policy-kafka/pom.xml b/sentry-policy/sentry-policy-kafka/pom.xml
index 21d34eb40..b95624ad6 100644
--- a/sentry-policy/sentry-policy-kafka/pom.xml
+++ b/sentry-policy/sentry-policy-kafka/pom.xml
@@ -21,7 +21,7 @@ limitations under the License.
org.apache.sentry
sentry-policy
- 1.7.0-incubating-SNAPSHOT
+ 1.7.1
sentry-policy-kafka
diff --git a/sentry-policy/sentry-policy-kafka/src/main/java/org/apache/sentry/policy/kafka/KafkaWildcardPrivilege.java b/sentry-policy/sentry-policy-kafka/src/main/java/org/apache/sentry/policy/kafka/KafkaWildcardPrivilege.java
index bc299b02e..6803a4656 100644
--- a/sentry-policy/sentry-policy-kafka/src/main/java/org/apache/sentry/policy/kafka/KafkaWildcardPrivilege.java
+++ b/sentry-policy/sentry-policy-kafka/src/main/java/org/apache/sentry/policy/kafka/KafkaWildcardPrivilege.java
@@ -121,7 +121,7 @@ private boolean impliesKeyValue(KeyValue policyPart, KeyValue requestPart) {
if (KafkaActionConstant.actionName.equalsIgnoreCase(policyPart.getKey())) { // is action
return policyPart.getValue().equalsIgnoreCase(KafkaActionConstant.ALL) ||
- policyPart.equals(requestPart);
+ policyPart.getValue().equalsIgnoreCase(requestPart.getValue());
} else {
return policyPart.getValue().equals(requestPart.getValue());
}
diff --git a/sentry-policy/sentry-policy-search/pom.xml b/sentry-policy/sentry-policy-search/pom.xml
index 673c615ed..19448a939 100644
--- a/sentry-policy/sentry-policy-search/pom.xml
+++ b/sentry-policy/sentry-policy-search/pom.xml
@@ -21,7 +21,7 @@ limitations under the License.
org.apache.sentry
sentry-policy
- 1.7.0-incubating-SNAPSHOT
+ 1.7.1
sentry-policy-search
diff --git a/sentry-policy/sentry-policy-sqoop/pom.xml b/sentry-policy/sentry-policy-sqoop/pom.xml
index 13112bfa8..14fad8cea 100644
--- a/sentry-policy/sentry-policy-sqoop/pom.xml
+++ b/sentry-policy/sentry-policy-sqoop/pom.xml
@@ -21,7 +21,7 @@ limitations under the License.
org.apache.sentry
sentry-policy
- 1.7.0-incubating-SNAPSHOT
+ 1.7.1
sentry-policy-sqoop
diff --git a/sentry-provider/pom.xml b/sentry-provider/pom.xml
index f26f4d3fa..04eaa0a52 100644
--- a/sentry-provider/pom.xml
+++ b/sentry-provider/pom.xml
@@ -22,7 +22,7 @@ limitations under the License.
org.apache.sentry
sentry
- 1.7.0-incubating-SNAPSHOT
+ 1.7.1
sentry-provider
diff --git a/sentry-provider/sentry-provider-cache/pom.xml b/sentry-provider/sentry-provider-cache/pom.xml
index c67f09429..9922b0647 100644
--- a/sentry-provider/sentry-provider-cache/pom.xml
+++ b/sentry-provider/sentry-provider-cache/pom.xml
@@ -21,7 +21,7 @@ limitations under the License.
org.apache.sentry
sentry-provider
- 1.7.0-incubating-SNAPSHOT
+ 1.7.1
sentry-provider-cache
diff --git a/sentry-provider/sentry-provider-common/pom.xml b/sentry-provider/sentry-provider-common/pom.xml
index de5a2c9bb..da2f5fc96 100644
--- a/sentry-provider/sentry-provider-common/pom.xml
+++ b/sentry-provider/sentry-provider-common/pom.xml
@@ -21,7 +21,7 @@ limitations under the License.
org.apache.sentry
sentry-provider
- 1.7.0-incubating-SNAPSHOT
+ 1.7.1
sentry-provider-common
diff --git a/sentry-provider/sentry-provider-db/pom.xml b/sentry-provider/sentry-provider-db/pom.xml
index b6efd1f2b..2aa6e91bf 100644
--- a/sentry-provider/sentry-provider-db/pom.xml
+++ b/sentry-provider/sentry-provider-db/pom.xml
@@ -21,7 +21,7 @@ limitations under the License.
org.apache.sentry
sentry-provider
- 1.7.0-incubating-SNAPSHOT
+ 1.7.1
sentry-provider-db
@@ -107,6 +107,10 @@ limitations under the License.
org.apache.sentry
sentry-policy-search
+
+ org.apache.sentry
+ sentry-policy-kafka
+
org.apache.hive
hive-shims
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/persistent/DelegateSentryStore.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/persistent/DelegateSentryStore.java
index d51b3baf5..23f6a2ded 100644
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/persistent/DelegateSentryStore.java
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/persistent/DelegateSentryStore.java
@@ -440,14 +440,15 @@ public Set getPrivilegesByAuthorizable(String component, Str
service = toTrimmedLower(service);
Set privileges = Sets.newHashSet();
+
+ if (validActiveRoles == null || validActiveRoles.isEmpty()) {
+ return privileges;
+ }
+
PersistenceManager pm = null;
try {
pm = openTransaction();
- if (validActiveRoles == null || validActiveRoles.size() == 0) {
- return privileges;
- }
-
Set mRoles = Sets.newHashSet();
for (String role : validActiveRoles) {
MSentryRole mRole = getRole(role, pm);
@@ -455,8 +456,19 @@ public Set getPrivilegesByAuthorizable(String component, Str
mRoles.add(mRole);
}
}
+
//get the privileges
- privileges.addAll(privilegeOperator.getPrivilegesByAuthorizable(component, service, mRoles, authorizables, pm));
+ Set mSentryGMPrivileges = privilegeOperator.getPrivilegesByAuthorizable(component, service, mRoles, authorizables, pm);
+
+ for (MSentryGMPrivilege mSentryGMPrivilege : mSentryGMPrivileges) {
+ /**
+ * force to load all roles related this privilege
+ * avoid the lazy-loading
+ */
+ pm.retrieve(mSentryGMPrivilege);
+ privileges.add(mSentryGMPrivilege);
+ }
+
} finally {
commitTransaction(pm);
}
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericPolicyProcessor.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericPolicyProcessor.java
index 58be24dd3..295228037 100644
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericPolicyProcessor.java
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericPolicyProcessor.java
@@ -689,11 +689,12 @@ public TListSentryPrivilegesByAuthResponse list_sentry_privileges_by_authorizabl
requestedGroups = memberGroups;
}
- // Disallow non-admin to lookup roles that they are not part of
+ Set grantedRoles = toTrimmedLower(store.getRolesByGroups(request.getComponent(), requestedGroups));
+
+ // If activeRoleSet is not null, disallow non-admin to lookup roles that they are not part of.
if (activeRoleSet != null && !activeRoleSet.isAll()) {
- Set grantedRoles = toTrimmedLower(store.getRolesByGroups(request.getComponent(), requestedGroups));
- Set activeRoleNames = toTrimmedLower(activeRoleSet.getRoles());
+ Set activeRoleNames = toTrimmedLower(activeRoleSet.getRoles());
for (String activeRole : activeRoleNames) {
if (!grantedRoles.contains(activeRole)) {
throw new SentryAccessDeniedException(ACCESS_DENIAL_MESSAGE
@@ -703,18 +704,23 @@ public TListSentryPrivilegesByAuthResponse list_sentry_privileges_by_authorizabl
// For non-admin, valid active roles are intersection of active roles and granted roles.
validActiveRoles.addAll(activeRoleSet.isAll() ? grantedRoles : Sets.intersection(activeRoleNames, grantedRoles));
+ } else {
+ // For non-admin, if activeRoleSet is null, valid active roles would be the granted roles.
+ validActiveRoles.addAll(grantedRoles);
}
} else {
- Set allRoles = toTrimmedLower(store.getAllRoleNames());
- Set activeRoleNames = toTrimmedLower(activeRoleSet.getRoles());
+ // For admin, if requestedGroups are empty, requested roles will be all roles.
+ Set requestedRoles = toTrimmedLower(store.getAllRoleNames());
+ if (requestedGroups != null && !requestedGroups.isEmpty()) {
+ requestedRoles = toTrimmedLower(store.getRolesByGroups(request.getComponent(), requestedGroups));
+ }
- // For admin, if requestedGroups are empty, valid active roles are intersection of active roles and all roles.
- // Otherwise, valid active roles are intersection of active roles and the roles of requestedGroups.
- if (requestedGroups == null || requestedGroups.isEmpty()) {
- validActiveRoles.addAll(activeRoleSet.isAll() ? allRoles : Sets.intersection(activeRoleNames, allRoles));
+ // If activeRoleSet (which is optional) is not null, valid active role will be intersection
+ // of active roles and requested roles. Otherwise, valid active roles are the requested roles.
+ if (activeRoleSet != null && !activeRoleSet.isAll()) {
+ validActiveRoles.addAll(Sets.intersection(toTrimmedLower(activeRoleSet.getRoles()), requestedRoles));
} else {
- Set requestedRoles = toTrimmedLower(store.getRolesByGroups(request.getComponent(), requestedGroups));
- validActiveRoles.addAll(activeRoleSet.isAll() ? allRoles : Sets.intersection(activeRoleNames, requestedRoles));
+ validActiveRoles.addAll(requestedRoles);
}
}
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericServiceClient.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericServiceClient.java
index 60502895a..76ff15b91 100644
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericServiceClient.java
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericServiceClient.java
@@ -18,6 +18,7 @@
package org.apache.sentry.provider.db.generic.service.thrift;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import org.apache.sentry.SentryUserException;
@@ -173,5 +174,24 @@ Set listPrivilegesForProvider(String component,
String serviceName, ActiveRoleSet roleSet, Set groups,
List extends Authorizable> authorizables) throws SentryUserException;
+ /**
+ * Get sentry privileges based on valid active roles and the authorize objects. Note that
+ * it is client responsibility to ensure the requestor username, etc. is not impersonated.
+ *
+ * @param component: The request respond to which component.
+ * @param serviceName: The name of service.
+ * @param requestorUserName: The requestor user name.
+ * @param authorizablesSet: The set of authorize objects. One authorize object is represented
+ * as a string. e.g resourceType1=resourceName1->resourceType2=resourceName2->resourceType3=resourceName3.
+ * @param groups: The requested groups.
+ * @param roleSet: The active roles set.
+ *
+ * @returns The mapping of authorize objects and TSentryPrivilegeMap().
+ * @throws SentryUserException
+ */
+ Map listPrivilegsbyAuthorizable(String component,
+ String serviceName, String requestorUserName, Set authorizablesSet,
+ Set groups, ActiveRoleSet roleSet) throws SentryUserException;
+
void close();
}
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericServiceClientDefaultImpl.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericServiceClientDefaultImpl.java
index dce3dade7..74b6963ab 100644
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericServiceClientDefaultImpl.java
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericServiceClientDefaultImpl.java
@@ -24,7 +24,6 @@
import javax.security.auth.callback.CallbackHandler;
-import com.google.common.collect.Sets;
import org.apache.hadoop.conf.Configuration;
import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTHENTICATION;
import org.apache.hadoop.net.NetUtils;
@@ -537,14 +536,6 @@ public Set listPrivilegesForProvider(String component,
}
}
- private List fromAuthorizable(List extends Authorizable> authorizables) {
- List tAuthorizables = Lists.newArrayList();
- for (Authorizable authorizable : authorizables) {
- tAuthorizables.add(new TAuthorizable(authorizable.getTypeName(), authorizable.getName()));
- }
- return tAuthorizables;
- }
-
/**
* Get sentry privileges based on valid active roles and the authorize objects. Note that
* it is client responsibility to ensure the requestor username, etc. is not impersonated.
@@ -552,8 +543,8 @@ private List fromAuthorizable(List extends Authorizable> author
* @param component: The request respond to which component.
* @param serviceName: The name of service.
* @param requestorUserName: The requestor user name.
- * @param authorizablesSet: The set of authorize objects. Represented as a string. e.g
- * resourceType1=resourceName1->resourceType2=resourceName2->resourceType3=resourceName3.
+ * @param authorizablesSet: The set of authorize objects. One authorize object is represented
+ * as a string. e.g resourceType1=resourceName1->resourceType2=resourceName2->resourceType3=resourceName3.
* @param groups: The requested groups.
* @param roleSet: The active roles set.
*
@@ -561,20 +552,16 @@ private List fromAuthorizable(List extends Authorizable> author
* @throws SentryUserException
*/
public Map listPrivilegsbyAuthorizable(String component,
- String serviceName, String requestorUserName, Set> authorizablesSet,
+ String serviceName, String requestorUserName, Set authorizablesSet,
Set groups, ActiveRoleSet roleSet) throws SentryUserException {
- Set> authSet = Sets.newHashSet();
- for (List extends Authorizable> authorizables : authorizablesSet) {
- authSet.add(fromAuthorizable(authorizables));
- }
-
TListSentryPrivilegesByAuthRequest request = new TListSentryPrivilegesByAuthRequest();
request.setProtocol_version(sentry_common_serviceConstants.TSENTRY_SERVICE_V2);
request.setComponent(component);
request.setServiceName(serviceName);
request.setRequestorUserName(requestorUserName);
+ request.setAuthorizablesSet(authorizablesSet);
if (groups == null) {
request.setGroups(new HashSet());
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/tools/KafkaTSentryPrivilegeConvertor.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/tools/KafkaTSentryPrivilegeConvertor.java
new file mode 100644
index 000000000..ca88c251c
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/tools/KafkaTSentryPrivilegeConvertor.java
@@ -0,0 +1,109 @@
+/**
+ * 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.generic.tools;
+
+import com.google.common.collect.Lists;
+import org.apache.sentry.core.model.kafka.KafkaAuthorizable;
+import org.apache.sentry.policy.common.KeyValue;
+import org.apache.sentry.policy.common.PolicyConstants;
+import org.apache.sentry.policy.common.PrivilegeValidatorContext;
+import org.apache.sentry.policy.kafka.KafkaModelAuthorizables;
+import org.apache.sentry.policy.kafka.KafkaPrivilegeValidator;
+import org.apache.sentry.provider.common.PolicyFileConstants;
+import org.apache.sentry.provider.db.generic.service.thrift.TAuthorizable;
+import org.apache.sentry.provider.db.generic.service.thrift.TSentryGrantOption;
+import org.apache.sentry.provider.db.generic.service.thrift.TSentryPrivilege;
+import org.apache.sentry.provider.db.generic.tools.command.TSentryPrivilegeConvertor;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+public class KafkaTSentryPrivilegeConvertor implements TSentryPrivilegeConvertor {
+ private String component;
+ private String service;
+
+ public KafkaTSentryPrivilegeConvertor(String component, String service) {
+ this.component = component;
+ this.service = service;
+ }
+
+ public TSentryPrivilege fromString(String privilegeStr) throws Exception {
+ validatePrivilegeHierarchy(privilegeStr);
+ TSentryPrivilege tSentryPrivilege = new TSentryPrivilege();
+ List authorizables = new LinkedList();
+ for (String authorizable : PolicyConstants.AUTHORIZABLE_SPLITTER.split(privilegeStr)) {
+ KeyValue keyValue = new KeyValue(authorizable);
+ String key = keyValue.getKey();
+ String value = keyValue.getValue();
+
+ // is it an authorizable?
+ KafkaAuthorizable authz = KafkaModelAuthorizables.from(keyValue);
+ if (authz != null) {
+ authorizables.add(new TAuthorizable(authz.getTypeName(), authz.getName()));
+
+ } else if (PolicyFileConstants.PRIVILEGE_ACTION_NAME.equalsIgnoreCase(key)) {
+ tSentryPrivilege.setAction(value);
+ }
+ }
+
+ if (tSentryPrivilege.getAction() == null) {
+ throw new IllegalArgumentException("Privilege is invalid: action required but not specified.");
+ }
+ tSentryPrivilege.setComponent(component);
+ tSentryPrivilege.setServiceName(service);
+ tSentryPrivilege.setAuthorizables(authorizables);
+ return tSentryPrivilege;
+ }
+
+ public String toString(TSentryPrivilege tSentryPrivilege) {
+ List privileges = Lists.newArrayList();
+ if (tSentryPrivilege != null) {
+ List authorizables = tSentryPrivilege.getAuthorizables();
+ String action = tSentryPrivilege.getAction();
+ String grantOption = (tSentryPrivilege.getGrantOption() == TSentryGrantOption.TRUE ? "true"
+ : "false");
+
+ Iterator it = authorizables.iterator();
+ if (it != null) {
+ while (it.hasNext()) {
+ TAuthorizable tAuthorizable = it.next();
+ privileges.add(PolicyConstants.KV_JOINER.join(
+ tAuthorizable.getType(), tAuthorizable.getName()));
+ }
+ }
+
+ if (!authorizables.isEmpty()) {
+ privileges.add(PolicyConstants.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(PolicyConstants.KV_JOINER.join(
+ PolicyFileConstants.PRIVILEGE_GRANT_OPTION_NAME, grantOption));
+ }
+ }
+ return PolicyConstants.AUTHORIZABLE_JOINER.join(privileges);
+ }
+
+ private static void validatePrivilegeHierarchy(String privilegeStr) throws Exception {
+ new KafkaPrivilegeValidator().validate(new PrivilegeValidatorContext(privilegeStr));
+ }
+}
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/tools/SentryShellKafka.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/tools/SentryShellKafka.java
new file mode 100644
index 000000000..e15d8d298
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/tools/SentryShellKafka.java
@@ -0,0 +1,112 @@
+/**
+ * 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.generic.tools;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.sentry.provider.db.generic.service.thrift.SentryGenericServiceClient;
+import org.apache.sentry.provider.db.generic.service.thrift.SentryGenericServiceClientFactory;
+import org.apache.sentry.provider.db.generic.tools.command.*;
+import org.apache.sentry.provider.db.tools.SentryShellCommon;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * SentryShellKafka is an admin tool, and responsible for the management of repository.
+ * The following commands are supported:
+ * create role, drop role, add group to role, grant privilege to role,
+ * revoke privilege from role, list roles, list privilege for role.
+ */
+public class SentryShellKafka extends SentryShellCommon {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(SentryShellKafka.class);
+ public static final String KAFKA_SERVICE_NAME = "sentry.service.client.kafka.service.name";
+
+ @Override
+ public void run() throws Exception {
+ Command command = null;
+ String component = "KAFKA";
+ Configuration conf = getSentryConf();
+
+ String service = conf.get(KAFKA_SERVICE_NAME, "kafka1");
+ SentryGenericServiceClient client = SentryGenericServiceClientFactory.create(conf);
+ UserGroupInformation ugi = UserGroupInformation.getLoginUser();
+ String requestorName = ugi.getShortUserName();
+
+ if (isCreateRole) {
+ command = new CreateRoleCmd(roleName, component);
+ } else if (isDropRole) {
+ command = new DropRoleCmd(roleName, component);
+ } else if (isAddRoleGroup) {
+ command = new AddRoleToGroupCmd(roleName, groupName, component);
+ } else if (isDeleteRoleGroup) {
+ command = new DeleteRoleFromGroupCmd(roleName, groupName, component);
+ } else if (isGrantPrivilegeRole) {
+ command = new GrantPrivilegeToRoleCmd(roleName, component,
+ privilegeStr, new KafkaTSentryPrivilegeConvertor(component, service));
+ } else if (isRevokePrivilegeRole) {
+ command = new RevokePrivilegeFromRoleCmd(roleName, component,
+ privilegeStr, new KafkaTSentryPrivilegeConvertor(component, service));
+ } else if (isListRole) {
+ command = new ListRolesCmd(groupName, component);
+ } else if (isListPrivilege) {
+ command = new ListPrivilegesByRoleCmd(roleName, component,
+ service, new KafkaTSentryPrivilegeConvertor(component, service));
+ }
+
+ // check the requestor name
+ if (StringUtils.isEmpty(requestorName)) {
+ // The exception message will be recorded 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 {
+ SentryShellKafka sentryShell = new SentryShellKafka();
+ try {
+ sentryShell.executeShell(args);
+ } catch (Exception e) {
+ LOGGER.error(e.getMessage(), e);
+ Throwable current = e;
+ // find the first printable message;
+ while (current != null && current.getMessage() == null) {
+ current = current.getCause();
+ }
+ String error = "";
+ if (current != null && current.getMessage() != null) {
+ error = "Message: " + current.getMessage();
+ }
+ System.out.println("The operation failed. " + error);
+ System.exit(1);
+ }
+ }
+
+}
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStoreSchemaInfo.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStoreSchemaInfo.java
index fdadcb8ec..a86500de1 100644
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStoreSchemaInfo.java
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStoreSchemaInfo.java
@@ -37,7 +37,7 @@ public class SentryStoreSchemaInfo {
private final String sentrySchemaVersions[];
private final String sentryScriptDir;
- private static final String SENTRY_VERSION = "1.6.0";
+ private static final String SENTRY_VERSION = "1.7.0";
public SentryStoreSchemaInfo(String sentryScriptDir, String dbType)
throws SentryUserException {
diff --git a/sentry-provider/sentry-provider-db/src/main/resources/sentry-db2-1.7.0.sql b/sentry-provider/sentry-provider-db/src/main/resources/sentry-db2-1.7.0.sql
new file mode 100644
index 000000000..b1e86492b
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/main/resources/sentry-db2-1.7.0.sql
@@ -0,0 +1,155 @@
+--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.
+
+-- Table SENTRY_DB_PRIVILEGE for classes [org.apache.sentry.provider.db.service.model.MSentryPrivilege]
+CREATE TABLE SENTRY_DB_PRIVILEGE
+(
+ DB_PRIVILEGE_ID BIGINT NOT NULL generated always as identity (start with 1),
+ URI VARCHAR(4000),
+ "ACTION" VARCHAR(40),
+ CREATE_TIME BIGINT NOT NULL,
+ DB_NAME VARCHAR(4000),
+ PRIVILEGE_SCOPE VARCHAR(40),
+ "SERVER_NAME" VARCHAR(4000),
+ "TABLE_NAME" VARCHAR(4000),
+ "COLUMN_NAME" VARCHAR(4000),
+ WITH_GRANT_OPTION CHAR(1) NOT NULL
+);
+
+ALTER TABLE SENTRY_DB_PRIVILEGE ADD CONSTRAINT SENTRY_DB_PRIVILEGE_PK PRIMARY KEY (DB_PRIVILEGE_ID);
+
+-- Table SENTRY_ROLE for classes [org.apache.sentry.provider.db.service.model.MSentryRole]
+CREATE TABLE SENTRY_ROLE
+(
+ ROLE_ID BIGINT NOT NULL generated always as identity (start with 1),
+ CREATE_TIME BIGINT NOT NULL,
+ ROLE_NAME VARCHAR(128)
+);
+
+ALTER TABLE SENTRY_ROLE ADD CONSTRAINT SENTRY_ROLE_PK PRIMARY KEY (ROLE_ID);
+
+-- Table SENTRY_GROUP for classes [org.apache.sentry.provider.db.service.model.MSentryGroup]
+CREATE TABLE SENTRY_GROUP
+(
+ GROUP_ID BIGINT NOT NULL generated always as identity (start with 1),
+ CREATE_TIME BIGINT NOT NULL,
+ GROUP_NAME VARCHAR(128)
+);
+
+ALTER TABLE SENTRY_GROUP ADD CONSTRAINT SENTRY_GROUP_PK PRIMARY KEY (GROUP_ID);
+
+-- Table SENTRY_ROLE_GROUP_MAP for join relationship
+CREATE TABLE SENTRY_ROLE_GROUP_MAP
+(
+ GROUP_ID BIGINT NOT NULL,
+ ROLE_ID BIGINT NOT NULL,
+ GRANTOR_PRINCIPAL VARCHAR(128)
+);
+
+ALTER TABLE SENTRY_ROLE_GROUP_MAP ADD CONSTRAINT SENTRY_ROLE_GROUP_MAP_PK PRIMARY KEY (GROUP_ID,ROLE_ID);
+
+-- Table SENTRY_ROLE_DB_PRIVILEGE_MAP for join relationship
+CREATE TABLE SENTRY_ROLE_DB_PRIVILEGE_MAP
+(
+ ROLE_ID BIGINT NOT NULL,
+ DB_PRIVILEGE_ID BIGINT NOT NULL,
+ GRANTOR_PRINCIPAL VARCHAR(128)
+);
+
+ALTER TABLE SENTRY_ROLE_DB_PRIVILEGE_MAP ADD CONSTRAINT SENTRY_ROLE_DB_PRIVILEGE_MAP_PK PRIMARY KEY (ROLE_ID,DB_PRIVILEGE_ID);
+
+CREATE TABLE "SENTRY_VERSION" (
+ VER_ID BIGINT NOT NULL,
+ SCHEMA_VERSION VARCHAR(127),
+ VERSION_COMMENT VARCHAR(255)
+);
+
+ALTER TABLE SENTRY_VERSION ADD CONSTRAINT SENTRY_VERSION_PK PRIMARY KEY (VER_ID);
+
+-- Constraints for table SENTRY_DB_PRIVILEGE for class(es) [org.apache.sentry.provider.db.service.model.MSentryPrivilege]
+CREATE UNIQUE INDEX SENTRYPRIVILEGENAME ON SENTRY_DB_PRIVILEGE ("SERVER_NAME",DB_NAME,"TABLE_NAME","COLUMN_NAME",URI,"ACTION",WITH_GRANT_OPTION);
+
+
+-- Constraints for table SENTRY_ROLE for class(es) [org.apache.sentry.provider.db.service.model.MSentryRole]
+CREATE UNIQUE INDEX SENTRYROLENAME ON SENTRY_ROLE (ROLE_NAME);
+
+
+-- Constraints for table SENTRY_GROUP for class(es) [org.apache.sentry.provider.db.service.model.MSentryGroup]
+CREATE UNIQUE INDEX SENTRYGROUPNAME ON SENTRY_GROUP (GROUP_NAME);
+
+
+-- Constraints for table SENTRY_ROLE_GROUP_MAP
+CREATE INDEX SENTRY_ROLE_GROUP_MAP_N49 ON SENTRY_ROLE_GROUP_MAP (GROUP_ID);
+
+CREATE INDEX SENTRY_ROLE_GROUP_MAP_N50 ON SENTRY_ROLE_GROUP_MAP (ROLE_ID);
+
+ALTER TABLE SENTRY_ROLE_GROUP_MAP ADD CONSTRAINT SENTRY_ROLE_GROUP_MAP_FK2 FOREIGN KEY (ROLE_ID) REFERENCES SENTRY_ROLE (ROLE_ID) ;
+
+ALTER TABLE SENTRY_ROLE_GROUP_MAP ADD CONSTRAINT SENTRY_ROLE_GROUP_MAP_FK1 FOREIGN KEY (GROUP_ID) REFERENCES SENTRY_GROUP (GROUP_ID) ;
+
+
+-- Constraints for table SENTRY_ROLE_DB_PRIVILEGE_MAP
+CREATE INDEX SENTRY_ROLE_DB_PRIVILEGE_MAP_N50 ON SENTRY_ROLE_DB_PRIVILEGE_MAP (ROLE_ID);
+
+CREATE INDEX SENTRY_ROLE_DB_PRIVILEGE_MAP_N49 ON SENTRY_ROLE_DB_PRIVILEGE_MAP (DB_PRIVILEGE_ID);
+
+ALTER TABLE SENTRY_ROLE_DB_PRIVILEGE_MAP ADD CONSTRAINT SENTRY_ROLE_DB_PRIVILEGE_MAP_FK2 FOREIGN KEY (DB_PRIVILEGE_ID) REFERENCES SENTRY_DB_PRIVILEGE (DB_PRIVILEGE_ID) ;
+
+ALTER TABLE SENTRY_ROLE_DB_PRIVILEGE_MAP ADD CONSTRAINT SENTRY_ROLE_DB_PRIVILEGE_MAP_FK1 FOREIGN KEY (ROLE_ID) REFERENCES SENTRY_ROLE (ROLE_ID) ;
+
+INSERT INTO SENTRY_VERSION (VER_ID, SCHEMA_VERSION, VERSION_COMMENT) VALUES (1, '1.7.0', 'Sentry release version 1.7.0');
+
+-- Generic model
+-- Table SENTRY_GM_PRIVILEGE for classes [org.apache.sentry.provider.db.service.model.MSentryGMPrivilege]
+CREATE TABLE SENTRY_GM_PRIVILEGE
+(
+ GM_PRIVILEGE_ID BIGINT NOT NULL,
+ "ACTION" VARCHAR(40),
+ COMPONENT_NAME VARCHAR(400),
+ CREATE_TIME BIGINT NOT NULL,
+ WITH_GRANT_OPTION CHAR(1),
+ RESOURCE_NAME_0 VARCHAR(400),
+ RESOURCE_NAME_1 VARCHAR(400),
+ RESOURCE_NAME_2 VARCHAR(400),
+ RESOURCE_NAME_3 VARCHAR(400),
+ RESOURCE_TYPE_0 VARCHAR(400),
+ RESOURCE_TYPE_1 VARCHAR(400),
+ RESOURCE_TYPE_2 VARCHAR(400),
+ RESOURCE_TYPE_3 VARCHAR(400),
+ "SCOPE" VARCHAR(40),
+ SERVICE_NAME VARCHAR(400)
+);
+-- Primary key(GM_PRIVILEGE_ID)
+ALTER TABLE SENTRY_GM_PRIVILEGE ADD CONSTRAINT SENTRY_GM_PRIVILEGE_PK PRIMARY KEY (GM_PRIVILEGE_ID);
+
+-- Constraints for table SENTRY_GM_PRIVILEGE for class(es) [org.apache.sentry.provider.db.service.model.MSentryGMPrivilege]
+CREATE UNIQUE INDEX GM_PRIVILEGE_INDEX ON SENTRY_GM_PRIVILEGE (COMPONENT_NAME,SERVICE_NAME,RESOURCE_NAME_0,RESOURCE_TYPE_0,RESOURCE_NAME_1,RESOURCE_TYPE_1,RESOURCE_NAME_2,RESOURCE_TYPE_2,RESOURCE_NAME_3,RESOURCE_TYPE_3,"ACTION",WITH_GRANT_OPTION);
+
+-- Table SENTRY_ROLE_GM_PRIVILEGE_MAP for join relationship
+CREATE TABLE SENTRY_ROLE_GM_PRIVILEGE_MAP
+(
+ ROLE_ID BIGINT NOT NULL,
+ GM_PRIVILEGE_ID BIGINT NOT NULL
+);
+ALTER TABLE SENTRY_ROLE_GM_PRIVILEGE_MAP ADD CONSTRAINT SENTRY_ROLE_GM_PRIVILEGE_MAP_PK PRIMARY KEY (ROLE_ID,GM_PRIVILEGE_ID);
+
+-- Constraints for table SENTRY_ROLE_GM_PRIVILEGE_MAP
+CREATE INDEX SENTRY_ROLE_GM_PRIVILEGE_MAP_N50 ON SENTRY_ROLE_GM_PRIVILEGE_MAP (ROLE_ID);
+
+CREATE INDEX SENTRY_ROLE_GM_PRIVILEGE_MAP_N49 ON SENTRY_ROLE_GM_PRIVILEGE_MAP (GM_PRIVILEGE_ID);
+
+ALTER TABLE SENTRY_ROLE_GM_PRIVILEGE_MAP ADD CONSTRAINT SENTRY_ROLE_GM_PRIVILEGE_MAP_FK2 FOREIGN KEY (GM_PRIVILEGE_ID) REFERENCES SENTRY_GM_PRIVILEGE (GM_PRIVILEGE_ID);
+
+ALTER TABLE SENTRY_ROLE_GM_PRIVILEGE_MAP ADD CONSTRAINT SENTRY_ROLE_GM_PRIVILEGE_MAP_FK1 FOREIGN KEY (ROLE_ID) REFERENCES SENTRY_ROLE (ROLE_ID);
diff --git a/sentry-provider/sentry-provider-db/src/main/resources/sentry-derby-1.7.0.sql b/sentry-provider/sentry-provider-db/src/main/resources/sentry-derby-1.7.0.sql
new file mode 100644
index 000000000..b06fc4ac5
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/main/resources/sentry-derby-1.7.0.sql
@@ -0,0 +1,155 @@
+--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.
+
+-- Table SENTRY_DB_PRIVILEGE for classes [org.apache.sentry.provider.db.service.model.MSentryPrivilege]
+CREATE TABLE SENTRY_DB_PRIVILEGE
+(
+ DB_PRIVILEGE_ID BIGINT NOT NULL generated always as identity (start with 1),
+ URI VARCHAR(4000) DEFAULT '__NULL__',
+ "ACTION" VARCHAR(40),
+ CREATE_TIME BIGINT NOT NULL,
+ DB_NAME VARCHAR(4000) DEFAULT '__NULL__',
+ PRIVILEGE_SCOPE VARCHAR(40),
+ "SERVER_NAME" VARCHAR(4000),
+ "TABLE_NAME" VARCHAR(4000) DEFAULT '__NULL__',
+ "COLUMN_NAME" VARCHAR(4000) DEFAULT '__NULL__',
+ WITH_GRANT_OPTION CHAR(1) NOT NULL
+);
+
+ALTER TABLE SENTRY_DB_PRIVILEGE ADD CONSTRAINT SENTRY_DB_PRIVILEGE_PK PRIMARY KEY (DB_PRIVILEGE_ID);
+
+-- Table SENTRY_ROLE for classes [org.apache.sentry.provider.db.service.model.MSentryRole]
+CREATE TABLE SENTRY_ROLE
+(
+ ROLE_ID BIGINT NOT NULL generated always as identity (start with 1),
+ CREATE_TIME BIGINT NOT NULL,
+ ROLE_NAME VARCHAR(128)
+);
+
+ALTER TABLE SENTRY_ROLE ADD CONSTRAINT SENTRY_ROLE_PK PRIMARY KEY (ROLE_ID);
+
+-- Table SENTRY_GROUP for classes [org.apache.sentry.provider.db.service.model.MSentryGroup]
+CREATE TABLE SENTRY_GROUP
+(
+ GROUP_ID BIGINT NOT NULL generated always as identity (start with 1),
+ CREATE_TIME BIGINT NOT NULL,
+ GROUP_NAME VARCHAR(128)
+);
+
+ALTER TABLE SENTRY_GROUP ADD CONSTRAINT SENTRY_GROUP_PK PRIMARY KEY (GROUP_ID);
+
+-- Table SENTRY_ROLE_GROUP_MAP for join relationship
+CREATE TABLE SENTRY_ROLE_GROUP_MAP
+(
+ GROUP_ID BIGINT NOT NULL,
+ ROLE_ID BIGINT NOT NULL,
+ GRANTOR_PRINCIPAL VARCHAR(128)
+);
+
+ALTER TABLE SENTRY_ROLE_GROUP_MAP ADD CONSTRAINT SENTRY_ROLE_GROUP_MAP_PK PRIMARY KEY (GROUP_ID,ROLE_ID);
+
+-- Table SENTRY_ROLE_DB_PRIVILEGE_MAP for join relationship
+CREATE TABLE SENTRY_ROLE_DB_PRIVILEGE_MAP
+(
+ ROLE_ID BIGINT NOT NULL,
+ DB_PRIVILEGE_ID BIGINT NOT NULL,
+ GRANTOR_PRINCIPAL VARCHAR(128)
+);
+
+ALTER TABLE SENTRY_ROLE_DB_PRIVILEGE_MAP ADD CONSTRAINT SENTRY_ROLE_DB_PRIVILEGE_MAP_PK PRIMARY KEY (ROLE_ID,DB_PRIVILEGE_ID);
+
+CREATE TABLE "SENTRY_VERSION" (
+ VER_ID BIGINT NOT NULL,
+ SCHEMA_VERSION VARCHAR(127),
+ VERSION_COMMENT VARCHAR(255)
+);
+
+ALTER TABLE SENTRY_VERSION ADD CONSTRAINT SENTRY_VERSION_PK PRIMARY KEY (VER_ID);
+
+-- Constraints for table SENTRY_DB_PRIVILEGE for class(es) [org.apache.sentry.provider.db.service.model.MSentryPrivilege]
+CREATE UNIQUE INDEX SENTRYPRIVILEGENAME ON SENTRY_DB_PRIVILEGE ("SERVER_NAME",DB_NAME,"TABLE_NAME","COLUMN_NAME",URI,"ACTION",WITH_GRANT_OPTION);
+
+
+-- Constraints for table SENTRY_ROLE for class(es) [org.apache.sentry.provider.db.service.model.MSentryRole]
+CREATE UNIQUE INDEX SENTRYROLENAME ON SENTRY_ROLE (ROLE_NAME);
+
+
+-- Constraints for table SENTRY_GROUP for class(es) [org.apache.sentry.provider.db.service.model.MSentryGroup]
+CREATE UNIQUE INDEX SENTRYGROUPNAME ON SENTRY_GROUP (GROUP_NAME);
+
+
+-- Constraints for table SENTRY_ROLE_GROUP_MAP
+CREATE INDEX SENTRY_ROLE_GROUP_MAP_N49 ON SENTRY_ROLE_GROUP_MAP (GROUP_ID);
+
+CREATE INDEX SENTRY_ROLE_GROUP_MAP_N50 ON SENTRY_ROLE_GROUP_MAP (ROLE_ID);
+
+ALTER TABLE SENTRY_ROLE_GROUP_MAP ADD CONSTRAINT SENTRY_ROLE_GROUP_MAP_FK2 FOREIGN KEY (ROLE_ID) REFERENCES SENTRY_ROLE (ROLE_ID) ;
+
+ALTER TABLE SENTRY_ROLE_GROUP_MAP ADD CONSTRAINT SENTRY_ROLE_GROUP_MAP_FK1 FOREIGN KEY (GROUP_ID) REFERENCES SENTRY_GROUP (GROUP_ID) ;
+
+
+-- Constraints for table SENTRY_ROLE_DB_PRIVILEGE_MAP
+CREATE INDEX SENTRY_ROLE_DB_PRIVILEGE_MAP_N50 ON SENTRY_ROLE_DB_PRIVILEGE_MAP (ROLE_ID);
+
+CREATE INDEX SENTRY_ROLE_DB_PRIVILEGE_MAP_N49 ON SENTRY_ROLE_DB_PRIVILEGE_MAP (DB_PRIVILEGE_ID);
+
+ALTER TABLE SENTRY_ROLE_DB_PRIVILEGE_MAP ADD CONSTRAINT SENTRY_ROLE_DB_PRIVILEGE_MAP_FK2 FOREIGN KEY (DB_PRIVILEGE_ID) REFERENCES SENTRY_DB_PRIVILEGE (DB_PRIVILEGE_ID) ;
+
+ALTER TABLE SENTRY_ROLE_DB_PRIVILEGE_MAP ADD CONSTRAINT SENTRY_ROLE_DB_PRIVILEGE_MAP_FK1 FOREIGN KEY (ROLE_ID) REFERENCES SENTRY_ROLE (ROLE_ID) ;
+
+INSERT INTO SENTRY_VERSION (VER_ID, SCHEMA_VERSION, VERSION_COMMENT) VALUES (1, '1.7.0', 'Sentry release version 1.7.0');
+
+-- Generic Model
+-- Table SENTRY_GM_PRIVILEGE for classes [org.apache.sentry.provider.db.service.model.MSentryGMPrivilege]
+CREATE TABLE SENTRY_GM_PRIVILEGE
+(
+ GM_PRIVILEGE_ID BIGINT NOT NULL,
+ "ACTION" VARCHAR(40),
+ COMPONENT_NAME VARCHAR(400),
+ CREATE_TIME BIGINT NOT NULL,
+ WITH_GRANT_OPTION CHAR(1),
+ RESOURCE_NAME_0 VARCHAR(400) DEFAULT '__NULL__',
+ RESOURCE_NAME_1 VARCHAR(400) DEFAULT '__NULL__',
+ RESOURCE_NAME_2 VARCHAR(400) DEFAULT '__NULL__',
+ RESOURCE_NAME_3 VARCHAR(400) DEFAULT '__NULL__',
+ RESOURCE_TYPE_0 VARCHAR(400) DEFAULT '__NULL__',
+ RESOURCE_TYPE_1 VARCHAR(400) DEFAULT '__NULL__',
+ RESOURCE_TYPE_2 VARCHAR(400) DEFAULT '__NULL__',
+ RESOURCE_TYPE_3 VARCHAR(400) DEFAULT '__NULL__',
+ "SCOPE" VARCHAR(40),
+ SERVICE_NAME VARCHAR(400)
+);
+-- Primary key(GM_PRIVILEGE_ID)
+ALTER TABLE SENTRY_GM_PRIVILEGE ADD CONSTRAINT SENTRY_GM_PRIVILEGE_PK PRIMARY KEY (GM_PRIVILEGE_ID);
+
+-- Constraints for table SENTRY_GM_PRIVILEGE for class(es) [org.apache.sentry.provider.db.service.model.MSentryGMPrivilege]
+CREATE UNIQUE INDEX GM_PRIVILEGE_INDEX ON SENTRY_GM_PRIVILEGE (COMPONENT_NAME,SERVICE_NAME,RESOURCE_NAME_0,RESOURCE_TYPE_0,RESOURCE_NAME_1,RESOURCE_TYPE_1,RESOURCE_NAME_2,RESOURCE_TYPE_2,RESOURCE_NAME_3,RESOURCE_TYPE_3,"ACTION",WITH_GRANT_OPTION);
+
+-- Table SENTRY_ROLE_GM_PRIVILEGE_MAP for join relationship
+CREATE TABLE SENTRY_ROLE_GM_PRIVILEGE_MAP
+(
+ ROLE_ID BIGINT NOT NULL,
+ GM_PRIVILEGE_ID BIGINT NOT NULL
+);
+ALTER TABLE SENTRY_ROLE_GM_PRIVILEGE_MAP ADD CONSTRAINT SENTRY_ROLE_GM_PRIVILEGE_MAP_PK PRIMARY KEY (ROLE_ID,GM_PRIVILEGE_ID);
+
+-- Constraints for table SENTRY_ROLE_GM_PRIVILEGE_MAP
+CREATE INDEX SENTRY_ROLE_GM_PRIVILEGE_MAP_N50 ON SENTRY_ROLE_GM_PRIVILEGE_MAP (ROLE_ID);
+
+CREATE INDEX SENTRY_ROLE_GM_PRIVILEGE_MAP_N49 ON SENTRY_ROLE_GM_PRIVILEGE_MAP (GM_PRIVILEGE_ID);
+
+ALTER TABLE SENTRY_ROLE_GM_PRIVILEGE_MAP ADD CONSTRAINT SENTRY_ROLE_GM_PRIVILEGE_MAP_FK2 FOREIGN KEY (GM_PRIVILEGE_ID) REFERENCES SENTRY_GM_PRIVILEGE (GM_PRIVILEGE_ID);
+
+ALTER TABLE SENTRY_ROLE_GM_PRIVILEGE_MAP ADD CONSTRAINT SENTRY_ROLE_GM_PRIVILEGE_MAP_FK1 FOREIGN KEY (ROLE_ID) REFERENCES SENTRY_ROLE (ROLE_ID);
diff --git a/sentry-provider/sentry-provider-db/src/main/resources/sentry-mysql-1.7.0.sql b/sentry-provider/sentry-provider-db/src/main/resources/sentry-mysql-1.7.0.sql
new file mode 100644
index 000000000..faff34895
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/main/resources/sentry-mysql-1.7.0.sql
@@ -0,0 +1,193 @@
+-- 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.
+
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
+/*!40103 SET TIME_ZONE='+00:00' */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+
+CREATE TABLE `SENTRY_DB_PRIVILEGE` (
+ `DB_PRIVILEGE_ID` BIGINT NOT NULL,
+ `PRIVILEGE_SCOPE` VARCHAR(32) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+ `SERVER_NAME` VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+ `DB_NAME` VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT '__NULL__',
+ `TABLE_NAME` VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT '__NULL__',
+ `COLUMN_NAME` VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT '__NULL__',
+ `URI` VARCHAR(4000) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT '__NULL__',
+ `ACTION` VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+ `CREATE_TIME` BIGINT NOT NULL,
+ `WITH_GRANT_OPTION` CHAR(1) NOT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+CREATE TABLE `SENTRY_ROLE` (
+ `ROLE_ID` BIGINT NOT NULL,
+ `ROLE_NAME` VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+ `CREATE_TIME` BIGINT NOT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+CREATE TABLE `SENTRY_GROUP` (
+ `GROUP_ID` BIGINT NOT NULL,
+ `GROUP_NAME` VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+ `CREATE_TIME` BIGINT NOT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+CREATE TABLE `SENTRY_ROLE_DB_PRIVILEGE_MAP` (
+ `ROLE_ID` BIGINT NOT NULL,
+ `DB_PRIVILEGE_ID` BIGINT NOT NULL,
+ `GRANTOR_PRINCIPAL` VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_bin
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+CREATE TABLE `SENTRY_ROLE_GROUP_MAP` (
+ `ROLE_ID` BIGINT NOT NULL,
+ `GROUP_ID` BIGINT NOT NULL,
+ `GRANTOR_PRINCIPAL` VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_bin
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+CREATE TABLE IF NOT EXISTS `SENTRY_VERSION` (
+ `VER_ID` BIGINT NOT NULL,
+ `SCHEMA_VERSION` VARCHAR(127) NOT NULL,
+ `VERSION_COMMENT` VARCHAR(255) NOT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+ALTER TABLE `SENTRY_DB_PRIVILEGE`
+ ADD CONSTRAINT `SENTRY_DB_PRIV_PK` PRIMARY KEY (`DB_PRIVILEGE_ID`);
+
+ALTER TABLE `SENTRY_ROLE`
+ ADD CONSTRAINT `SENTRY_ROLE_PK` PRIMARY KEY (`ROLE_ID`);
+
+ALTER TABLE `SENTRY_GROUP`
+ ADD CONSTRAINT `SENTRY_GROUP_PK` PRIMARY KEY (`GROUP_ID`);
+
+ALTER TABLE `SENTRY_VERSION`
+ ADD CONSTRAINT `SENTRY_VERSION` PRIMARY KEY (`VER_ID`);
+
+ALTER TABLE `SENTRY_DB_PRIVILEGE`
+ ADD UNIQUE `SENTRY_DB_PRIV_PRIV_NAME_UNIQ` (`SERVER_NAME`,`DB_NAME`,`TABLE_NAME`,`COLUMN_NAME`,`URI`(250),`ACTION`,`WITH_GRANT_OPTION`);
+
+ALTER TABLE `SENTRY_DB_PRIVILEGE`
+ ADD INDEX `SENTRY_PRIV_SERV_IDX` (`SERVER_NAME`);
+
+ALTER TABLE `SENTRY_DB_PRIVILEGE`
+ ADD INDEX `SENTRY_PRIV_DB_IDX` (`DB_NAME`);
+
+ALTER TABLE `SENTRY_DB_PRIVILEGE`
+ ADD INDEX `SENTRY_PRIV_TBL_IDX` (`TABLE_NAME`);
+
+ALTER TABLE `SENTRY_DB_PRIVILEGE`
+ ADD INDEX `SENTRY_PRIV_COL_IDX` (`COLUMN_NAME`);
+
+ALTER TABLE `SENTRY_DB_PRIVILEGE`
+ ADD INDEX `SENTRY_PRIV_URI_IDX` (`URI`);
+
+ALTER TABLE `SENTRY_ROLE`
+ ADD CONSTRAINT `SENTRY_ROLE_ROLE_NAME_UNIQUE` UNIQUE (`ROLE_NAME`);
+
+ALTER TABLE `SENTRY_GROUP`
+ ADD CONSTRAINT `SENTRY_GRP_GRP_NAME_UNIQUE` UNIQUE (`GROUP_NAME`);
+
+ALTER TABLE `SENTRY_ROLE_DB_PRIVILEGE_MAP`
+ ADD CONSTRAINT `SENTRY_ROLE_DB_PRIVILEGE_MAP_PK` PRIMARY KEY (`ROLE_ID`,`DB_PRIVILEGE_ID`);
+
+ALTER TABLE `SENTRY_ROLE_GROUP_MAP`
+ ADD CONSTRAINT `SENTRY_ROLE_GROUP_MAP_PK` PRIMARY KEY (`ROLE_ID`,`GROUP_ID`);
+
+ALTER TABLE `SENTRY_ROLE_DB_PRIVILEGE_MAP`
+ ADD CONSTRAINT `SEN_RLE_DB_PRV_MAP_SN_RLE_FK`
+ FOREIGN KEY (`ROLE_ID`) REFERENCES `SENTRY_ROLE`(`ROLE_ID`);
+
+ALTER TABLE `SENTRY_ROLE_DB_PRIVILEGE_MAP`
+ ADD CONSTRAINT `SEN_RL_DB_PRV_MAP_SN_DB_PRV_FK`
+ FOREIGN KEY (`DB_PRIVILEGE_ID`) REFERENCES `SENTRY_DB_PRIVILEGE`(`DB_PRIVILEGE_ID`);
+
+ALTER TABLE `SENTRY_ROLE_GROUP_MAP`
+ ADD CONSTRAINT `SEN_ROLE_GROUP_MAP_SEN_ROLE_FK`
+ FOREIGN KEY (`ROLE_ID`) REFERENCES `SENTRY_ROLE`(`ROLE_ID`);
+
+ALTER TABLE `SENTRY_ROLE_GROUP_MAP`
+ ADD CONSTRAINT `SEN_ROLE_GROUP_MAP_SEN_GRP_FK`
+ FOREIGN KEY (`GROUP_ID`) REFERENCES `SENTRY_GROUP`(`GROUP_ID`);
+
+INSERT INTO SENTRY_VERSION (VER_ID, SCHEMA_VERSION, VERSION_COMMENT) VALUES (1, '1.7.0', 'Sentry release version 1.7.0');
+
+-- Generic Model
+-- Table SENTRY_GM_PRIVILEGE for classes [org.apache.sentry.provider.db.service.model.MSentryGMPrivilege]
+CREATE TABLE `SENTRY_GM_PRIVILEGE`
+(
+ `GM_PRIVILEGE_ID` BIGINT NOT NULL,
+ `ACTION` VARCHAR(32) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+ `COMPONENT_NAME` VARCHAR(32) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+ `CREATE_TIME` BIGINT NOT NULL,
+ `WITH_GRANT_OPTION` CHAR(1) NOT NULL,
+ `RESOURCE_NAME_0` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT '__NULL__',
+ `RESOURCE_NAME_1` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT '__NULL__',
+ `RESOURCE_NAME_2` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT '__NULL__',
+ `RESOURCE_NAME_3` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT '__NULL__',
+ `RESOURCE_TYPE_0` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT '__NULL__',
+ `RESOURCE_TYPE_1` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT '__NULL__',
+ `RESOURCE_TYPE_2` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT '__NULL__',
+ `RESOURCE_TYPE_3` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT '__NULL__',
+ `SCOPE` VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+ `SERVICE_NAME` VARCHAR(64) BINARY CHARACTER SET utf8 COLLATE utf8_bin NOT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+ALTER TABLE `SENTRY_GM_PRIVILEGE`
+ ADD CONSTRAINT `SENTRY_GM_PRIVILEGE_PK` PRIMARY KEY (`GM_PRIVILEGE_ID`);
+-- Constraints for table SENTRY_GM_PRIVILEGE for class(es) [org.apache.sentry.provider.db.service.model.MSentryGMPrivilege]
+ALTER TABLE `SENTRY_GM_PRIVILEGE`
+ ADD UNIQUE `GM_PRIVILEGE_UNIQUE` (`COMPONENT_NAME`,`SERVICE_NAME`,`RESOURCE_NAME_0`,`RESOURCE_TYPE_0`,`RESOURCE_NAME_1`,`RESOURCE_TYPE_1`,`RESOURCE_NAME_2`,`RESOURCE_TYPE_2`,`RESOURCE_NAME_3`,`RESOURCE_TYPE_3`,`ACTION`,`WITH_GRANT_OPTION`);
+
+ALTER TABLE `SENTRY_GM_PRIVILEGE`
+ ADD INDEX `SENTRY_GM_PRIV_COMP_IDX` (`COMPONENT_NAME`);
+
+ALTER TABLE `SENTRY_GM_PRIVILEGE`
+ ADD INDEX `SENTRY_GM_PRIV_SERV_IDX` (`SERVICE_NAME`);
+
+ALTER TABLE `SENTRY_GM_PRIVILEGE`
+ ADD INDEX `SENTRY_GM_PRIV_RES0_IDX` (`RESOURCE_NAME_0`,`RESOURCE_TYPE_0`);
+
+ALTER TABLE `SENTRY_GM_PRIVILEGE`
+ ADD INDEX `SENTRY_GM_PRIV_RES1_IDX` (`RESOURCE_NAME_1`,`RESOURCE_TYPE_1`);
+
+ALTER TABLE `SENTRY_GM_PRIVILEGE`
+ ADD INDEX `SENTRY_GM_PRIV_RES2_IDX` (`RESOURCE_NAME_2`,`RESOURCE_TYPE_2`);
+
+ALTER TABLE `SENTRY_GM_PRIVILEGE`
+ ADD INDEX `SENTRY_GM_PRIV_RES3_IDX` (`RESOURCE_NAME_3`,`RESOURCE_TYPE_3`);
+
+-- Table SENTRY_ROLE_GM_PRIVILEGE_MAP for join relationship
+CREATE TABLE `SENTRY_ROLE_GM_PRIVILEGE_MAP`
+(
+ `ROLE_ID` BIGINT NOT NULL,
+ `GM_PRIVILEGE_ID` BIGINT NOT NULL
+) ENGINE=INNODB DEFAULT CHARSET=utf8;
+
+ALTER TABLE `SENTRY_ROLE_GM_PRIVILEGE_MAP`
+ ADD CONSTRAINT `SENTRY_ROLE_GM_PRIVILEGE_MAP_PK` PRIMARY KEY (`ROLE_ID`,`GM_PRIVILEGE_ID`);
+
+-- Constraints for table SENTRY_ROLE_GM_PRIVILEGE_MAP
+ALTER TABLE `SENTRY_ROLE_GM_PRIVILEGE_MAP`
+ ADD CONSTRAINT `SEN_RLE_GM_PRV_MAP_SN_RLE_FK`
+ FOREIGN KEY (`ROLE_ID`) REFERENCES `SENTRY_ROLE`(`ROLE_ID`);
+
+ALTER TABLE `SENTRY_ROLE_GM_PRIVILEGE_MAP`
+ ADD CONSTRAINT `SEN_RL_GM_PRV_MAP_SN_DB_PRV_FK`
+ FOREIGN KEY (`GM_PRIVILEGE_ID`) REFERENCES `SENTRY_GM_PRIVILEGE`(`GM_PRIVILEGE_ID`);
diff --git a/sentry-provider/sentry-provider-db/src/main/resources/sentry-oracle-1.7.0.sql b/sentry-provider/sentry-provider-db/src/main/resources/sentry-oracle-1.7.0.sql
new file mode 100644
index 000000000..ae9cd0626
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/main/resources/sentry-oracle-1.7.0.sql
@@ -0,0 +1,168 @@
+--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.
+
+CREATE TABLE "SENTRY_DB_PRIVILEGE" (
+ "DB_PRIVILEGE_ID" NUMBER NOT NULL,
+ "PRIVILEGE_SCOPE" VARCHAR2(32) NOT NULL,
+ "SERVER_NAME" VARCHAR2(128) NOT NULL,
+ "DB_NAME" VARCHAR2(128) DEFAULT '__NULL__',
+ "TABLE_NAME" VARCHAR2(128) DEFAULT '__NULL__',
+ "COLUMN_NAME" VARCHAR2(128) DEFAULT '__NULL__',
+ "URI" VARCHAR2(4000) DEFAULT '__NULL__',
+ "ACTION" VARCHAR2(128) NOT NULL,
+ "CREATE_TIME" NUMBER NOT NULL,
+ "WITH_GRANT_OPTION" CHAR(1) DEFAULT 'N' NOT NULL
+);
+
+CREATE TABLE "SENTRY_ROLE" (
+ "ROLE_ID" NUMBER NOT NULL,
+ "ROLE_NAME" VARCHAR2(128) NOT NULL,
+ "CREATE_TIME" NUMBER NOT NULL
+);
+
+CREATE TABLE "SENTRY_GROUP" (
+ "GROUP_ID" NUMBER NOT NULL,
+ "GROUP_NAME" VARCHAR2(128) NOT NULL,
+ "CREATE_TIME" NUMBER NOT NULL
+);
+
+CREATE TABLE "SENTRY_ROLE_DB_PRIVILEGE_MAP" (
+ "ROLE_ID" NUMBER NOT NULL,
+ "DB_PRIVILEGE_ID" NUMBER NOT NULL,
+ "GRANTOR_PRINCIPAL" VARCHAR2(128)
+);
+
+CREATE TABLE "SENTRY_ROLE_GROUP_MAP" (
+ "ROLE_ID" NUMBER NOT NULL,
+ "GROUP_ID" NUMBER NOT NULL,
+ "GRANTOR_PRINCIPAL" VARCHAR2(128)
+);
+
+CREATE TABLE "SENTRY_VERSION" (
+ "VER_ID" NUMBER NOT NULL,
+ "SCHEMA_VERSION" VARCHAR(127) NOT NULL,
+ "VERSION_COMMENT" VARCHAR(255) NOT NULL
+);
+
+ALTER TABLE "SENTRY_DB_PRIVILEGE"
+ ADD CONSTRAINT "SENTRY_DB_PRIV_PK" PRIMARY KEY ("DB_PRIVILEGE_ID");
+
+ALTER TABLE "SENTRY_ROLE"
+ ADD CONSTRAINT "SENTRY_ROLE_PK" PRIMARY KEY ("ROLE_ID");
+
+ALTER TABLE "SENTRY_GROUP"
+ ADD CONSTRAINT "SENTRY_GROUP_PK" PRIMARY KEY ("GROUP_ID");
+
+ALTER TABLE "SENTRY_VERSION" ADD CONSTRAINT "SENTRY_VERSION_PK" PRIMARY KEY ("VER_ID");
+
+ALTER TABLE "SENTRY_DB_PRIVILEGE"
+ ADD CONSTRAINT "SENTRY_DB_PRIV_PRIV_NAME_UNIQ" UNIQUE ("SERVER_NAME","DB_NAME","TABLE_NAME","COLUMN_NAME","URI","ACTION","WITH_GRANT_OPTION");
+
+CREATE INDEX "SENTRY_SERV_PRIV_IDX" ON "SENTRY_DB_PRIVILEGE" ("SERVER_NAME");
+
+CREATE INDEX "SENTRY_DB_PRIV_IDX" ON "SENTRY_DB_PRIVILEGE" ("DB_NAME");
+
+CREATE INDEX "SENTRY_TBL_PRIV_IDX" ON "SENTRY_DB_PRIVILEGE" ("TABLE_NAME");
+
+CREATE INDEX "SENTRY_COL_PRIV_IDX" ON "SENTRY_DB_PRIVILEGE" ("COLUMN_NAME");
+
+CREATE INDEX "SENTRY_URI_PRIV_IDX" ON "SENTRY_DB_PRIVILEGE" ("URI");
+
+ALTER TABLE "SENTRY_ROLE"
+ ADD CONSTRAINT "SENTRY_ROLE_ROLE_NAME_UNIQUE" UNIQUE ("ROLE_NAME");
+
+ALTER TABLE "SENTRY_GROUP"
+ ADD CONSTRAINT "SENTRY_GRP_GRP_NAME_UNIQUE" UNIQUE ("GROUP_NAME");
+
+ALTER TABLE "SENTRY_ROLE_DB_PRIVILEGE_MAP"
+ ADD CONSTRAINT "SEN_RLE_PRIV_MAP_PK" PRIMARY KEY ("ROLE_ID","DB_PRIVILEGE_ID");
+
+ALTER TABLE "SENTRY_ROLE_GROUP_MAP"
+ ADD CONSTRAINT "SENTRY_ROLE_GROUP_MAP_PK" PRIMARY KEY ("ROLE_ID","GROUP_ID");
+
+ALTER TABLE "SENTRY_ROLE_DB_PRIVILEGE_MAP"
+ ADD CONSTRAINT "SEN_RLE_DB_PRV_MAP_SN_RLE_FK"
+ FOREIGN KEY ("ROLE_ID") REFERENCES "SENTRY_ROLE"("ROLE_ID") INITIALLY DEFERRED;
+
+ALTER TABLE "SENTRY_ROLE_DB_PRIVILEGE_MAP"
+ ADD CONSTRAINT "SEN_RL_DB_PRV_MAP_SN_DB_PRV_FK"
+ FOREIGN KEY ("DB_PRIVILEGE_ID") REFERENCES "SENTRY_DB_PRIVILEGE"("DB_PRIVILEGE_ID") INITIALLY DEFERRED;
+
+ALTER TABLE "SENTRY_ROLE_GROUP_MAP"
+ ADD CONSTRAINT "SEN_ROLE_GROUP_MAP_SEN_ROLE_FK"
+ FOREIGN KEY ("ROLE_ID") REFERENCES "SENTRY_ROLE"("ROLE_ID") INITIALLY DEFERRED;
+
+ALTER TABLE "SENTRY_ROLE_GROUP_MAP"
+ ADD CONSTRAINT "SEN_ROLE_GROUP_MAP_SEN_GRP_FK"
+ FOREIGN KEY ("GROUP_ID") REFERENCES "SENTRY_GROUP"("GROUP_ID") INITIALLY DEFERRED;
+
+INSERT INTO SENTRY_VERSION (VER_ID, SCHEMA_VERSION, VERSION_COMMENT) VALUES (1, '1.7.0', 'Sentry release version 1.7.0');
+
+-- Generic Model
+-- Table SENTRY_GM_PRIVILEGE for classes [org.apache.sentry.provider.db.service.model.MSentryGMPrivilege]
+CREATE TABLE "SENTRY_GM_PRIVILEGE" (
+ "GM_PRIVILEGE_ID" NUMBER NOT NULL,
+ "COMPONENT_NAME" VARCHAR2(32) NOT NULL,
+ "SERVICE_NAME" VARCHAR2(64) NOT NULL,
+ "RESOURCE_NAME_0" VARCHAR2(64) DEFAULT '__NULL__',
+ "RESOURCE_NAME_1" VARCHAR2(64) DEFAULT '__NULL__',
+ "RESOURCE_NAME_2" VARCHAR2(64) DEFAULT '__NULL__',
+ "RESOURCE_NAME_3" VARCHAR2(64) DEFAULT '__NULL__',
+ "RESOURCE_TYPE_0" VARCHAR2(64) DEFAULT '__NULL__',
+ "RESOURCE_TYPE_1" VARCHAR2(64) DEFAULT '__NULL__',
+ "RESOURCE_TYPE_2" VARCHAR2(64) DEFAULT '__NULL__',
+ "RESOURCE_TYPE_3" VARCHAR2(64) DEFAULT '__NULL__',
+ "ACTION" VARCHAR2(32) NOT NULL,
+ "SCOPE" VARCHAR2(128) NOT NULL,
+ "CREATE_TIME" NUMBER NOT NULL,
+ "WITH_GRANT_OPTION" CHAR(1) DEFAULT 'N' NOT NULL
+);
+
+ALTER TABLE "SENTRY_GM_PRIVILEGE"
+ ADD CONSTRAINT "SENTRY_GM_PRIV_PK" PRIMARY KEY ("GM_PRIVILEGE_ID");
+-- Constraints for table SENTRY_GM_PRIVILEGE for class(es) [org.apache.sentry.provider.db.service.model.MSentryGMPrivilege]
+ALTER TABLE "SENTRY_GM_PRIVILEGE"
+ ADD CONSTRAINT "SENTRY_GM_PRIV_PRIV_NAME_UNIQ" UNIQUE ("COMPONENT_NAME","SERVICE_NAME","RESOURCE_NAME_0","RESOURCE_NAME_1","RESOURCE_NAME_2",
+ "RESOURCE_NAME_3","RESOURCE_TYPE_0","RESOURCE_TYPE_1","RESOURCE_TYPE_2","RESOURCE_TYPE_3","ACTION","WITH_GRANT_OPTION");
+
+CREATE INDEX "SENTRY_GM_PRIV_COMP_IDX" ON "SENTRY_GM_PRIVILEGE" ("COMPONENT_NAME");
+
+CREATE INDEX "SENTRY_GM_PRIV_SERV_IDX" ON "SENTRY_GM_PRIVILEGE" ("SERVICE_NAME");
+
+CREATE INDEX "SENTRY_GM_PRIV_RES0_IDX" ON "SENTRY_GM_PRIVILEGE" ("RESOURCE_NAME_0","RESOURCE_TYPE_0");
+
+CREATE INDEX "SENTRY_GM_PRIV_RES1_IDX" ON "SENTRY_GM_PRIVILEGE" ("RESOURCE_NAME_1","RESOURCE_TYPE_1");
+
+CREATE INDEX "SENTRY_GM_PRIV_RES2_IDX" ON "SENTRY_GM_PRIVILEGE" ("RESOURCE_NAME_2","RESOURCE_TYPE_2");
+
+CREATE INDEX "SENTRY_GM_PRIV_RES3_IDX" ON "SENTRY_GM_PRIVILEGE" ("RESOURCE_NAME_3","RESOURCE_TYPE_3");
+
+-- Table SENTRY_ROLE_GM_PRIVILEGE_MAP for join relationship
+CREATE TABLE "SENTRY_ROLE_GM_PRIVILEGE_MAP" (
+ "ROLE_ID" NUMBER NOT NULL,
+ "GM_PRIVILEGE_ID" NUMBER NOT NULL
+);
+
+ALTER TABLE "SENTRY_ROLE_GM_PRIVILEGE_MAP"
+ ADD CONSTRAINT "SEN_RLE_GM_PRIV_MAP_PK" PRIMARY KEY ("ROLE_ID","GM_PRIVILEGE_ID");
+
+-- Constraints for table SENTRY_ROLE_GM_PRIVILEGE_MAP
+ALTER TABLE "SENTRY_ROLE_GM_PRIVILEGE_MAP"
+ ADD CONSTRAINT "SEN_RLE_GM_PRV_MAP_SN_RLE_FK"
+ FOREIGN KEY ("ROLE_ID") REFERENCES "SENTRY_ROLE"("ROLE_ID") INITIALLY DEFERRED;
+
+ALTER TABLE "SENTRY_ROLE_GM_PRIVILEGE_MAP"
+ ADD CONSTRAINT "SEN_RL_GM_PRV_MAP_SN_DB_PRV_FK"
+ FOREIGN KEY ("GM_PRIVILEGE_ID") REFERENCES "SENTRY_GM_PRIVILEGE"("GM_PRIVILEGE_ID") INITIALLY DEFERRED;
diff --git a/sentry-provider/sentry-provider-db/src/main/resources/sentry-postgres-1.7.0.sql b/sentry-provider/sentry-provider-db/src/main/resources/sentry-postgres-1.7.0.sql
new file mode 100644
index 000000000..9f4f85b02
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/main/resources/sentry-postgres-1.7.0.sql
@@ -0,0 +1,182 @@
+--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.
+
+START TRANSACTION;
+
+SET statement_timeout = 0;
+SET client_encoding = 'UTF8';
+SET standard_conforming_strings = off;
+SET check_function_bodies = false;
+SET client_min_messages = warning;
+SET escape_string_warning = off;
+SET search_path = public, pg_catalog;
+SET default_tablespace = '';
+SET default_with_oids = false;
+
+CREATE TABLE "SENTRY_DB_PRIVILEGE" (
+ "DB_PRIVILEGE_ID" BIGINT NOT NULL,
+ "PRIVILEGE_SCOPE" character varying(32) NOT NULL,
+ "SERVER_NAME" character varying(128) NOT NULL,
+ "DB_NAME" character varying(128) DEFAULT '__NULL__',
+ "TABLE_NAME" character varying(128) DEFAULT '__NULL__',
+ "COLUMN_NAME" character varying(128) DEFAULT '__NULL__',
+ "URI" character varying(4000) DEFAULT '__NULL__',
+ "ACTION" character varying(128) NOT NULL,
+ "CREATE_TIME" BIGINT NOT NULL,
+ "WITH_GRANT_OPTION" CHAR(1) NOT NULL
+);
+
+CREATE TABLE "SENTRY_ROLE" (
+ "ROLE_ID" BIGINT NOT NULL,
+ "ROLE_NAME" character varying(128) NOT NULL,
+ "CREATE_TIME" BIGINT NOT NULL
+);
+
+CREATE TABLE "SENTRY_GROUP" (
+ "GROUP_ID" BIGINT NOT NULL,
+ "GROUP_NAME" character varying(128) NOT NULL,
+ "CREATE_TIME" BIGINT NOT NULL
+);
+
+CREATE TABLE "SENTRY_ROLE_DB_PRIVILEGE_MAP" (
+ "ROLE_ID" BIGINT NOT NULL,
+ "DB_PRIVILEGE_ID" BIGINT NOT NULL,
+ "GRANTOR_PRINCIPAL" character varying(128)
+);
+
+CREATE TABLE "SENTRY_ROLE_GROUP_MAP" (
+ "ROLE_ID" BIGINT NOT NULL,
+ "GROUP_ID" BIGINT NOT NULL,
+ "GRANTOR_PRINCIPAL" character varying(128)
+);
+
+CREATE TABLE "SENTRY_VERSION" (
+ "VER_ID" bigint,
+ "SCHEMA_VERSION" character varying(127) NOT NULL,
+ "VERSION_COMMENT" character varying(255) NOT NULL
+);
+
+
+ALTER TABLE ONLY "SENTRY_DB_PRIVILEGE"
+ ADD CONSTRAINT "SENTRY_DB_PRIV_PK" PRIMARY KEY ("DB_PRIVILEGE_ID");
+
+ALTER TABLE ONLY "SENTRY_ROLE"
+ ADD CONSTRAINT "SENTRY_ROLE_PK" PRIMARY KEY ("ROLE_ID");
+
+ALTER TABLE ONLY "SENTRY_GROUP"
+ ADD CONSTRAINT "SENTRY_GROUP_PK" PRIMARY KEY ("GROUP_ID");
+
+ALTER TABLE ONLY "SENTRY_VERSION" ADD CONSTRAINT "SENTRY_VERSION_PK" PRIMARY KEY ("VER_ID");
+
+ALTER TABLE ONLY "SENTRY_DB_PRIVILEGE"
+ ADD CONSTRAINT "SENTRY_DB_PRIV_PRIV_NAME_UNIQ" UNIQUE ("SERVER_NAME","DB_NAME","TABLE_NAME","COLUMN_NAME","URI", "ACTION","WITH_GRANT_OPTION");
+
+CREATE INDEX "SENTRY_PRIV_SERV_IDX" ON "SENTRY_DB_PRIVILEGE" USING btree ("SERVER_NAME");
+
+CREATE INDEX "SENTRY_PRIV_DB_IDX" ON "SENTRY_DB_PRIVILEGE" USING btree ("DB_NAME");
+
+CREATE INDEX "SENTRY_PRIV_TBL_IDX" ON "SENTRY_DB_PRIVILEGE" USING btree ("TABLE_NAME");
+
+CREATE INDEX "SENTRY_PRIV_COL_IDX" ON "SENTRY_DB_PRIVILEGE" USING btree ("COLUMN_NAME");
+
+CREATE INDEX "SENTRY_PRIV_URI_IDX" ON "SENTRY_DB_PRIVILEGE" USING btree ("URI");
+
+ALTER TABLE ONLY "SENTRY_ROLE"
+ ADD CONSTRAINT "SENTRY_ROLE_ROLE_NAME_UNIQUE" UNIQUE ("ROLE_NAME");
+
+ALTER TABLE ONLY "SENTRY_GROUP"
+ ADD CONSTRAINT "SENTRY_GRP_GRP_NAME_UNIQUE" UNIQUE ("GROUP_NAME");
+
+ALTER TABLE "SENTRY_ROLE_DB_PRIVILEGE_MAP"
+ ADD CONSTRAINT "SENTRY_ROLE_DB_PRIVILEGE_MAP_PK" PRIMARY KEY ("ROLE_ID","DB_PRIVILEGE_ID");
+
+ALTER TABLE "SENTRY_ROLE_GROUP_MAP"
+ ADD CONSTRAINT "SENTRY_ROLE_GROUP_MAP_PK" PRIMARY KEY ("ROLE_ID","GROUP_ID");
+
+ALTER TABLE ONLY "SENTRY_ROLE_DB_PRIVILEGE_MAP"
+ ADD CONSTRAINT "SEN_RLE_DB_PRV_MAP_SN_RLE_FK"
+ FOREIGN KEY ("ROLE_ID") REFERENCES "SENTRY_ROLE"("ROLE_ID") DEFERRABLE;
+
+ALTER TABLE ONLY "SENTRY_ROLE_DB_PRIVILEGE_MAP"
+ ADD CONSTRAINT "SEN_RL_DB_PRV_MAP_SN_DB_PRV_FK"
+ FOREIGN KEY ("DB_PRIVILEGE_ID") REFERENCES "SENTRY_DB_PRIVILEGE"("DB_PRIVILEGE_ID") DEFERRABLE;
+
+ALTER TABLE ONLY "SENTRY_ROLE_GROUP_MAP"
+ ADD CONSTRAINT "SEN_ROLE_GROUP_MAP_SEN_ROLE_FK"
+ FOREIGN KEY ("ROLE_ID") REFERENCES "SENTRY_ROLE"("ROLE_ID") DEFERRABLE;
+
+ALTER TABLE ONLY "SENTRY_ROLE_GROUP_MAP"
+ ADD CONSTRAINT "SEN_ROLE_GROUP_MAP_SEN_GRP_FK"
+ FOREIGN KEY ("GROUP_ID") REFERENCES "SENTRY_GROUP"("GROUP_ID") DEFERRABLE;
+
+INSERT INTO "SENTRY_VERSION" ("VER_ID", "SCHEMA_VERSION", "VERSION_COMMENT") VALUES (1, '1.7.0', 'Sentry release version 1.7.0');
+
+-- Generic Model
+-- Table SENTRY_GM_PRIVILEGE for classes [org.apache.sentry.provider.db.service.model.MSentryGMPrivilege]
+CREATE TABLE "SENTRY_GM_PRIVILEGE" (
+ "GM_PRIVILEGE_ID" BIGINT NOT NULL,
+ "COMPONENT_NAME" character varying(32) NOT NULL,
+ "SERVICE_NAME" character varying(64) NOT NULL,
+ "RESOURCE_NAME_0" character varying(64) DEFAULT '__NULL__',
+ "RESOURCE_NAME_1" character varying(64) DEFAULT '__NULL__',
+ "RESOURCE_NAME_2" character varying(64) DEFAULT '__NULL__',
+ "RESOURCE_NAME_3" character varying(64) DEFAULT '__NULL__',
+ "RESOURCE_TYPE_0" character varying(64) DEFAULT '__NULL__',
+ "RESOURCE_TYPE_1" character varying(64) DEFAULT '__NULL__',
+ "RESOURCE_TYPE_2" character varying(64) DEFAULT '__NULL__',
+ "RESOURCE_TYPE_3" character varying(64) DEFAULT '__NULL__',
+ "ACTION" character varying(32) NOT NULL,
+ "SCOPE" character varying(128) NOT NULL,
+ "CREATE_TIME" BIGINT NOT NULL,
+ "WITH_GRANT_OPTION" CHAR(1) NOT NULL
+);
+ALTER TABLE ONLY "SENTRY_GM_PRIVILEGE"
+ ADD CONSTRAINT "SENTRY_GM_PRIV_PK" PRIMARY KEY ("GM_PRIVILEGE_ID");
+-- Constraints for table SENTRY_GM_PRIVILEGE for class(es) [org.apache.sentry.provider.db.service.model.MSentryGMPrivilege]
+ALTER TABLE ONLY "SENTRY_GM_PRIVILEGE"
+ ADD CONSTRAINT "SENTRY_GM_PRIV_PRIV_NAME_UNIQ" UNIQUE ("COMPONENT_NAME","SERVICE_NAME","RESOURCE_NAME_0","RESOURCE_NAME_1","RESOURCE_NAME_2",
+ "RESOURCE_NAME_3","RESOURCE_TYPE_0","RESOURCE_TYPE_1","RESOURCE_TYPE_2","RESOURCE_TYPE_3","ACTION","WITH_GRANT_OPTION");
+
+CREATE INDEX "SENTRY_GM_PRIV_COMP_IDX" ON "SENTRY_GM_PRIVILEGE" USING btree ("COMPONENT_NAME");
+
+CREATE INDEX "SENTRY_GM_PRIV_SERV_IDX" ON "SENTRY_GM_PRIVILEGE" USING btree ("SERVICE_NAME");
+
+CREATE INDEX "SENTRY_GM_PRIV_RES0_IDX" ON "SENTRY_GM_PRIVILEGE" USING btree ("RESOURCE_NAME_0","RESOURCE_TYPE_0");
+
+CREATE INDEX "SENTRY_GM_PRIV_RES1_IDX" ON "SENTRY_GM_PRIVILEGE" USING btree ("RESOURCE_NAME_1","RESOURCE_TYPE_1");
+
+CREATE INDEX "SENTRY_GM_PRIV_RES2_IDX" ON "SENTRY_GM_PRIVILEGE" USING btree ("RESOURCE_NAME_2","RESOURCE_TYPE_2");
+
+CREATE INDEX "SENTRY_GM_PRIV_RES3_IDX" ON "SENTRY_GM_PRIVILEGE" USING btree ("RESOURCE_NAME_3","RESOURCE_TYPE_3");
+
+-- Table SENTRY_ROLE_GM_PRIVILEGE_MAP for join relationship
+CREATE TABLE "SENTRY_ROLE_GM_PRIVILEGE_MAP" (
+ "ROLE_ID" BIGINT NOT NULL,
+ "GM_PRIVILEGE_ID" BIGINT NOT NULL
+);
+
+ALTER TABLE "SENTRY_ROLE_GM_PRIVILEGE_MAP"
+ ADD CONSTRAINT "SENTRY_ROLE_GM_PRIVILEGE_MAP_PK" PRIMARY KEY ("ROLE_ID","GM_PRIVILEGE_ID");
+
+-- Constraints for table SENTRY_ROLE_GM_PRIVILEGE_MAP
+ALTER TABLE ONLY "SENTRY_ROLE_GM_PRIVILEGE_MAP"
+ ADD CONSTRAINT "SEN_RLE_GM_PRV_MAP_SN_RLE_FK"
+ FOREIGN KEY ("ROLE_ID") REFERENCES "SENTRY_ROLE"("ROLE_ID") DEFERRABLE;
+
+ALTER TABLE ONLY "SENTRY_ROLE_GM_PRIVILEGE_MAP"
+ ADD CONSTRAINT "SEN_RL_GM_PRV_MAP_SN_DB_PRV_FK"
+ FOREIGN KEY ("GM_PRIVILEGE_ID") REFERENCES "SENTRY_GM_PRIVILEGE"("GM_PRIVILEGE_ID") DEFERRABLE;
+
+COMMIT;
diff --git a/sentry-provider/sentry-provider-db/src/main/resources/sentry-upgrade-db2-1.6.0-to-1.7.0.sql b/sentry-provider/sentry-provider-db/src/main/resources/sentry-upgrade-db2-1.6.0-to-1.7.0.sql
new file mode 100644
index 000000000..e2494a26f
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/main/resources/sentry-upgrade-db2-1.6.0-to-1.7.0.sql
@@ -0,0 +1,2 @@
+-- Version update
+UPDATE SENTRY_VERSION SET SCHEMA_VERSION='1.7.0', VERSION_COMMENT='Sentry release version 1.7.0' WHERE VER_ID=1;
\ No newline at end of file
diff --git a/sentry-provider/sentry-provider-db/src/main/resources/sentry-upgrade-derby-1.6.0-to-1.7.0.sql b/sentry-provider/sentry-provider-db/src/main/resources/sentry-upgrade-derby-1.6.0-to-1.7.0.sql
new file mode 100644
index 000000000..e2494a26f
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/main/resources/sentry-upgrade-derby-1.6.0-to-1.7.0.sql
@@ -0,0 +1,2 @@
+-- Version update
+UPDATE SENTRY_VERSION SET SCHEMA_VERSION='1.7.0', VERSION_COMMENT='Sentry release version 1.7.0' WHERE VER_ID=1;
\ No newline at end of file
diff --git a/sentry-provider/sentry-provider-db/src/main/resources/sentry-upgrade-mysql-1.6.0-to-1.7.0.sql b/sentry-provider/sentry-provider-db/src/main/resources/sentry-upgrade-mysql-1.6.0-to-1.7.0.sql
new file mode 100644
index 000000000..3413edee7
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/main/resources/sentry-upgrade-mysql-1.6.0-to-1.7.0.sql
@@ -0,0 +1,5 @@
+SELECT 'Upgrading Sentry store schema from 1.6.0 to 1.7.0' AS ' ';
+
+UPDATE SENTRY_VERSION SET SCHEMA_VERSION='1.7.0', VERSION_COMMENT='Sentry release version 1.7.0' WHERE VER_ID=1;
+
+SELECT 'Finish upgrading Sentry store schema from 1.6.0 to 1.7.0' AS ' ';
\ No newline at end of file
diff --git a/sentry-provider/sentry-provider-db/src/main/resources/sentry-upgrade-oracle-1.6.0-to-1.7.0.sql b/sentry-provider/sentry-provider-db/src/main/resources/sentry-upgrade-oracle-1.6.0-to-1.7.0.sql
new file mode 100644
index 000000000..fa82c87ae
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/main/resources/sentry-upgrade-oracle-1.6.0-to-1.7.0.sql
@@ -0,0 +1,5 @@
+SELECT 'Upgrading Sentry store schema from 1.6.0 to 1.7.0' AS Status from dual;
+
+UPDATE SENTRY_VERSION SET SCHEMA_VERSION='1.7.0', VERSION_COMMENT='Sentry release version 1.7.0' WHERE VER_ID=1;
+
+SELECT 'Finished upgrading Sentry store schema from 1.6.0 to 1.7.0' AS Status from dual;
\ No newline at end of file
diff --git a/sentry-provider/sentry-provider-db/src/main/resources/sentry-upgrade-postgres-1.6.0-to-1.7.0.sql b/sentry-provider/sentry-provider-db/src/main/resources/sentry-upgrade-postgres-1.6.0-to-1.7.0.sql
new file mode 100644
index 000000000..ff10e106b
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/main/resources/sentry-upgrade-postgres-1.6.0-to-1.7.0.sql
@@ -0,0 +1,5 @@
+SELECT 'Upgrading Sentry store schema from 1.6.0 to 1.7.0';
+
+UPDATE "SENTRY_VERSION" SET "SCHEMA_VERSION"='1.7.0', "VERSION_COMMENT"='Sentry release version 1.7.0' WHERE "VER_ID"=1;
+
+SELECT 'Finished upgrading Sentry store schema from 1.6.0 to 1.7.0';
\ No newline at end of file
diff --git a/sentry-provider/sentry-provider-db/src/main/resources/upgrade.order.db2 b/sentry-provider/sentry-provider-db/src/main/resources/upgrade.order.db2
index 8473c4cdc..789a8ca61 100644
--- a/sentry-provider/sentry-provider-db/src/main/resources/upgrade.order.db2
+++ b/sentry-provider/sentry-provider-db/src/main/resources/upgrade.order.db2
@@ -1,2 +1,3 @@
1.4.0-to-1.5.0
1.5.0-to-1.6.0
+1.6.0-to-1.7.0
diff --git a/sentry-provider/sentry-provider-db/src/main/resources/upgrade.order.derby b/sentry-provider/sentry-provider-db/src/main/resources/upgrade.order.derby
index 8473c4cdc..789a8ca61 100644
--- a/sentry-provider/sentry-provider-db/src/main/resources/upgrade.order.derby
+++ b/sentry-provider/sentry-provider-db/src/main/resources/upgrade.order.derby
@@ -1,2 +1,3 @@
1.4.0-to-1.5.0
1.5.0-to-1.6.0
+1.6.0-to-1.7.0
diff --git a/sentry-provider/sentry-provider-db/src/main/resources/upgrade.order.mysql b/sentry-provider/sentry-provider-db/src/main/resources/upgrade.order.mysql
index 8473c4cdc..789a8ca61 100644
--- a/sentry-provider/sentry-provider-db/src/main/resources/upgrade.order.mysql
+++ b/sentry-provider/sentry-provider-db/src/main/resources/upgrade.order.mysql
@@ -1,2 +1,3 @@
1.4.0-to-1.5.0
1.5.0-to-1.6.0
+1.6.0-to-1.7.0
diff --git a/sentry-provider/sentry-provider-db/src/main/resources/upgrade.order.oracle b/sentry-provider/sentry-provider-db/src/main/resources/upgrade.order.oracle
index 8473c4cdc..789a8ca61 100644
--- a/sentry-provider/sentry-provider-db/src/main/resources/upgrade.order.oracle
+++ b/sentry-provider/sentry-provider-db/src/main/resources/upgrade.order.oracle
@@ -1,2 +1,3 @@
1.4.0-to-1.5.0
1.5.0-to-1.6.0
+1.6.0-to-1.7.0
diff --git a/sentry-provider/sentry-provider-db/src/main/resources/upgrade.order.postgres b/sentry-provider/sentry-provider-db/src/main/resources/upgrade.order.postgres
index 8473c4cdc..789a8ca61 100644
--- a/sentry-provider/sentry-provider-db/src/main/resources/upgrade.order.postgres
+++ b/sentry-provider/sentry-provider-db/src/main/resources/upgrade.order.postgres
@@ -1,2 +1,3 @@
1.4.0-to-1.5.0
1.5.0-to-1.6.0
+1.6.0-to-1.7.0
diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/service/persistent/TestPrivilegeOperatePersistence.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/service/persistent/TestPrivilegeOperatePersistence.java
index 9cbd1bd98..deefefa72 100644
--- a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/service/persistent/TestPrivilegeOperatePersistence.java
+++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/service/persistent/TestPrivilegeOperatePersistence.java
@@ -966,6 +966,8 @@ public void testGetPrivilegesByAuthorizable() throws Exception {
assertEquals(0, sentryStore.getPrivilegesByAuthorizable(SEARCH, service1, null,
Arrays.asList(new Collection(COLLECTION_NAME), new Field(FIELD_NAME))).size());
+ assertEquals(1, sentryStore.getPrivilegesByAuthorizable(SEARCH, service1, Sets.newHashSet(roleName1),
+ Arrays.asList(new Collection(COLLECTION_NAME), new Field(FIELD_NAME))).size());
assertEquals(2, sentryStore.getPrivilegesByAuthorizable(SEARCH, service1,
Sets.newHashSet(roleName1), null).size());
assertEquals(2, sentryStore.getPrivilegesByAuthorizable(SEARCH, service1,
diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/service/thrift/TestSentryGenericPolicyProcessor.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/service/thrift/TestSentryGenericPolicyProcessor.java
index 84eeb8216..cc0b28ecd 100644
--- a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/service/thrift/TestSentryGenericPolicyProcessor.java
+++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/service/thrift/TestSentryGenericPolicyProcessor.java
@@ -300,17 +300,27 @@ public void testGetRolesAndPrivileges() throws Exception {
assertEquals(Status.OK, fromTSentryStatus(response3.getStatus()));
assertEquals(2, response3.getPrivileges().size());
+ // Optional parameters activeRoleSet and requested group name are both provided.
TListSentryPrivilegesByAuthRequest request4 = new TListSentryPrivilegesByAuthRequest();
request4.setGroups(Sets.newHashSet(groupName));
request4.setRoleSet(new TSentryActiveRoleSet(true, null));
request4.setRequestorUserName(ADMIN_USER);
-
Set authorizablesSet = Sets.newHashSet("Collection=c1->Field=f1");
request4.setAuthorizablesSet(authorizablesSet);
TListSentryPrivilegesByAuthResponse response4 = processor.list_sentry_privileges_by_authorizable(request4);
assertEquals(Status.OK, fromTSentryStatus(response4.getStatus()));
assertEquals(1, response4.getPrivilegesMapByAuth().size());
+
+ // Optional parameters activeRoleSet and requested group name are both not provided.
+ TListSentryPrivilegesByAuthRequest request5 = new TListSentryPrivilegesByAuthRequest();
+ request5.setRequestorUserName("not_" + ADMIN_USER);
+ authorizablesSet = Sets.newHashSet("Collection=c1->Field=f2");
+ request5.setAuthorizablesSet(authorizablesSet);
+
+ TListSentryPrivilegesByAuthResponse response5 = processor.list_sentry_privileges_by_authorizable(request5);
+ assertEquals(Status.OK, fromTSentryStatus(response5.getStatus()));
+ assertEquals(1, response5.getPrivilegesMapByAuth().size());
}
@Test(expected=SentryConfigurationException.class)
diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/service/thrift/TestSentryGenericServiceIntegration.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/service/thrift/TestSentryGenericServiceIntegration.java
index fcf0e7b9d..e23050573 100644
--- a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/service/thrift/TestSentryGenericServiceIntegration.java
+++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/service/thrift/TestSentryGenericServiceIntegration.java
@@ -23,6 +23,7 @@
import java.util.Arrays;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import org.apache.sentry.SentryUserException;
@@ -385,6 +386,69 @@ public void runTestAsSubject() throws Exception {
}});
}
+ @Test
+ public void testGetPrivilegeByAuthorizable() throws Exception {
+ runTestAsSubject(new TestOperation(){
+ @Override
+ public void runTestAsSubject() throws Exception {
+ String adminUser = ADMIN_USER;
+ Set adminGroup = Sets.newHashSet(ADMIN_GROUP);
+ String testRole = "role1";
+ Set testGroup = Sets.newHashSet("group1");
+ String testUser = "user1";
+ setLocalGroupMapping(adminUser, adminGroup);
+ setLocalGroupMapping(testUser, testGroup);
+ writePolicyFile();
+
+ client.createRole(adminUser, testRole, SOLR);
+ client.addRoleToGroups(adminUser, testRole, SOLR, adminGroup);
+
+ TSentryPrivilege queryPrivilege = new TSentryPrivilege(SOLR, "service1",
+ fromAuthorizable(Arrays.asList(new Collection("c1"), new Field("f1"))),
+ SearchConstants.QUERY);
+
+ TSentryPrivilege updatePrivilege = new TSentryPrivilege(SOLR, "service1",
+ fromAuthorizable(Arrays.asList(new Collection("c1"), new Field("f2"))),
+ SearchConstants.UPDATE);
+
+ client.grantPrivilege(adminUser, testRole, SOLR, queryPrivilege);
+ client.grantPrivilege(adminUser, testRole, SOLR, updatePrivilege);
+
+ //test listPrivilegsbyAuthorizable without requested group and active role set.
+ assertEquals(1, client.listPrivilegsbyAuthorizable(SOLR, "service1", adminUser,
+ Sets.newHashSet(new String("Collection=c1->Field=f1")), null, null).size());
+
+ //test listPrivilegsbyAuthorizable with requested group (testGroup)
+ Map privilegeMap = client.listPrivilegsbyAuthorizable(SOLR,
+ "service1", adminUser, Sets.newHashSet(new String("Collection=c1->Field=f1")), testGroup, null);
+ TSentryPrivilegeMap actualMap = privilegeMap.get(new String("Collection=c1->Field=f1"));
+ assertEquals(0, actualMap.getPrivilegeMap().size());
+
+ //test listPrivilegsbyAuthorizable with active role set.
+ ActiveRoleSet roleSet = ActiveRoleSet.ALL;
+ assertEquals(1, client.listPrivilegsbyAuthorizable(SOLR, "service1", adminUser,
+ Sets.newHashSet(new String("Collection=c1->Field=f1")), null, roleSet).size());
+ privilegeMap = client.listPrivilegsbyAuthorizable(SOLR,
+ "service1", adminUser, Sets.newHashSet(new String("Collection=c1->Field=f1")), null, roleSet);
+ actualMap = privilegeMap.get(new String("Collection=c1->Field=f1"));
+ assertEquals(1, actualMap.getPrivilegeMap().size());
+
+ privilegeMap = client.listPrivilegsbyAuthorizable(SOLR,
+ "service1", testUser, Sets.newHashSet(new String("Collection=c1->Field=f1")), null, roleSet);
+ actualMap = privilegeMap.get(new String("Collection=c1->Field=f1"));
+ assertEquals(0, actualMap.getPrivilegeMap().size());
+
+ // grant tesRole to testGroup.
+ client.addRoleToGroups(adminUser, testRole, SOLR, testGroup);
+
+ privilegeMap = client.listPrivilegsbyAuthorizable(SOLR,
+ "service1", testUser, Sets.newHashSet(new String("Collection=c1")), null, roleSet);
+ actualMap = privilegeMap.get(new String("Collection=c1"));
+ assertEquals(1, actualMap.getPrivilegeMap().size());
+ assertEquals(2, actualMap.getPrivilegeMap().get(testRole).size());
+ }});
+ }
+
@Test
public void testDropAndRenamePrivilege() throws Exception {
runTestAsSubject(new TestOperation(){
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
new file mode 100644
index 000000000..7d25ae11c
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/tools/TestSentryShellKafka.java
@@ -0,0 +1,540 @@
+/**
+ * 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.generic.tools;
+
+import com.google.common.collect.Sets;
+import com.google.common.io.Files;
+import org.apache.commons.io.FileUtils;
+import org.apache.sentry.SentryUserException;
+import org.apache.sentry.policy.kafka.KafkaPrivilegeValidator;
+import org.apache.sentry.provider.db.generic.service.thrift.SentryGenericServiceIntegrationBase;
+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.shiro.config.ConfigurationException;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.PrintStream;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import static org.junit.Assert.*;
+
+public class TestSentryShellKafka extends SentryGenericServiceIntegrationBase {
+ private File confDir;
+ private File confPath;
+ private static String TEST_ROLE_NAME_1 = "testRole1";
+ private static String TEST_ROLE_NAME_2 = "testRole2";
+ private static String KAFKA = "KAFKA";
+ private String requestorName = "";
+ private String service = "kafka1";
+
+ @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 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() };
+ SentryShellKafka.main(args);
+ // test: create role with --create_role
+ args = new String[] { "--create_role", "-r", TEST_ROLE_NAME_2, "-conf",
+ confPath.getAbsolutePath() };
+ SentryShellKafka.main(args);
+
+ // validate the result, list roles with -lr
+ args = new String[] { "-lr", "-conf", confPath.getAbsolutePath() };
+ SentryShellKafka sentryShell = new SentryShellKafka();
+ Set roleNames = getShellResultWithOSRedirect(sentryShell, args, true);
+ validateRoleNames(roleNames, TEST_ROLE_NAME_1, TEST_ROLE_NAME_2);
+
+ // validate the result, list roles with --list_role
+ args = new String[] { "--list_role", "-conf", confPath.getAbsolutePath() };
+ sentryShell = new SentryShellKafka();
+ roleNames = getShellResultWithOSRedirect(sentryShell, args, true);
+ validateRoleNames(roleNames, TEST_ROLE_NAME_1, TEST_ROLE_NAME_2);
+
+ // test: drop role with -dr
+ args = new String[] { "-dr", "-r", TEST_ROLE_NAME_1, "-conf", confPath.getAbsolutePath() };
+ SentryShellKafka.main(args);
+ // test: drop role with --drop_role
+ args = new String[] { "--drop_role", "-r", TEST_ROLE_NAME_2, "-conf",
+ confPath.getAbsolutePath() };
+ SentryShellKafka.main(args);
+
+ // validate the result
+ Set roles = client.listAllRoles(requestorName, KAFKA);
+ assertEquals("Incorrect number of roles", 0, roles.size());
+ }
+ });
+ }
+
+ @Test
+ public void testAddDeleteRoleForGroup() throws Exception {
+ runTestAsSubject(new TestOperation() {
+ @Override
+ public void runTestAsSubject() throws Exception {
+ // Group names are case sensitive - mixed case names should work
+ String TEST_GROUP_1 = "testGroup1";
+ String TEST_GROUP_2 = "testGroup2";
+ String TEST_GROUP_3 = "testGroup3";
+
+ // create the role for test
+ client.createRole(requestorName, TEST_ROLE_NAME_1, KAFKA);
+ client.createRole(requestorName, TEST_ROLE_NAME_2, KAFKA);
+ // test: add role to group with -arg
+ String[] args = { "-arg", "-r", TEST_ROLE_NAME_1, "-g", TEST_GROUP_1, "-conf",
+ confPath.getAbsolutePath() };
+ SentryShellKafka.main(args);
+ // test: add role to multiple groups
+ args = new String[] { "-arg", "-r", TEST_ROLE_NAME_1, "-g", TEST_GROUP_2 + "," + TEST_GROUP_3,
+ "-conf",
+ confPath.getAbsolutePath() };
+ SentryShellKafka.main(args);
+ // test: add role to group with --add_role_group
+ args = new String[] { "--add_role_group", "-r", TEST_ROLE_NAME_2, "-g", TEST_GROUP_1,
+ "-conf",
+ confPath.getAbsolutePath() };
+ SentryShellKafka.main(args);
+
+ // validate the result list roles with -lr and -g
+ args = new String[] { "-lr", "-g", TEST_GROUP_1, "-conf", confPath.getAbsolutePath() };
+ SentryShellKafka sentryShell = new SentryShellKafka();
+ Set roleNames = getShellResultWithOSRedirect(sentryShell, args, true);
+ validateRoleNames(roleNames, TEST_ROLE_NAME_1, TEST_ROLE_NAME_2);
+
+ // list roles with --list_role and -g
+ args = new String[] { "--list_role", "-g", TEST_GROUP_2, "-conf",
+ confPath.getAbsolutePath() };
+ sentryShell = new SentryShellKafka();
+ roleNames = getShellResultWithOSRedirect(sentryShell, args, true);
+ validateRoleNames(roleNames, TEST_ROLE_NAME_1);
+
+ args = new String[] { "--list_role", "-g", TEST_GROUP_3, "-conf",
+ confPath.getAbsolutePath() };
+ sentryShell = new SentryShellKafka();
+ roleNames = getShellResultWithOSRedirect(sentryShell, args, true);
+ validateRoleNames(roleNames, TEST_ROLE_NAME_1);
+
+ // test: delete role from group with -drg
+ args = new String[] { "-drg", "-r", TEST_ROLE_NAME_1, "-g", TEST_GROUP_1, "-conf",
+ confPath.getAbsolutePath() };
+ SentryShellKafka.main(args);
+ // test: delete role to multiple groups
+ args = new String[] { "-drg", "-r", TEST_ROLE_NAME_1, "-g", TEST_GROUP_2 + "," + TEST_GROUP_3,
+ "-conf",
+ confPath.getAbsolutePath() };
+ SentryShellKafka.main(args);
+ // test: delete role from group with --delete_role_group
+ args = new String[] { "--delete_role_group", "-r", TEST_ROLE_NAME_2, "-g", TEST_GROUP_1,
+ "-conf", confPath.getAbsolutePath() };
+ SentryShellKafka.main(args);
+
+ // validate the result
+ Set roles = client.listRolesByGroupName(requestorName, TEST_GROUP_1, KAFKA);
+ assertEquals("Incorrect number of roles", 0, roles.size());
+ roles = client.listRolesByGroupName(requestorName, TEST_GROUP_2, KAFKA);
+ assertEquals("Incorrect number of roles", 0, roles.size());
+ roles = client.listRolesByGroupName(requestorName, TEST_GROUP_3, KAFKA);
+ assertEquals("Incorrect number of roles", 0, roles.size());
+ // clear the test data
+ client.dropRole(requestorName, TEST_ROLE_NAME_1, KAFKA);
+ client.dropRole(requestorName, TEST_ROLE_NAME_2, KAFKA);
+ }
+ });
+ }
+
+ @Test
+ public void testCaseSensitiveGroupName() throws Exception {
+ runTestAsSubject(new TestOperation() {
+ @Override
+ public void runTestAsSubject() throws Exception {
+
+ // create the role for test
+ client.createRole(requestorName, TEST_ROLE_NAME_1, KAFKA);
+ // add role to a group (lower case)
+ String[] args = {"-arg", "-r", TEST_ROLE_NAME_1, "-g", "group1", "-conf",
+ confPath.getAbsolutePath()};
+ SentryShellKafka.main(args);
+
+ // validate the roles when group name is same case as above
+ args = new String[]{"-lr", "-g", "group1", "-conf", confPath.getAbsolutePath()};
+ SentryShellKafka sentryShell = new SentryShellKafka();
+ Set roleNames = getShellResultWithOSRedirect(sentryShell, args, true);
+ validateRoleNames(roleNames, TEST_ROLE_NAME_1);
+
+ // roles should be empty when group name is different case than above
+ args = new String[]{"-lr", "-g", "GROUP1", "-conf", confPath.getAbsolutePath()};
+ roleNames = getShellResultWithOSRedirect(sentryShell, args, true);
+ validateRoleNames(roleNames);
+ }
+ });
+ }
+
+ public static String grant(boolean shortOption) {
+ return shortOption ? "-gpr" : "--grant_privilege_role";
+ }
+
+ public static String revoke(boolean shortOption) {
+ return shortOption ? "-rpr" : "--revoke_privilege_role";
+ }
+
+ public static String list(boolean shortOption) {
+ return shortOption ? "-lp" : "--list_privilege";
+ }
+
+ private void assertGrantRevokePrivilege(final boolean shortOption) throws Exception {
+ runTestAsSubject(new TestOperation() {
+ @Override
+ public void runTestAsSubject() throws Exception {
+ // create the role for test
+ client.createRole(requestorName, TEST_ROLE_NAME_1, KAFKA);
+ client.createRole(requestorName, TEST_ROLE_NAME_2, KAFKA);
+
+ String [] privs = {
+ "HOST=*->CLUSTER=kafka-cluster->action=read",
+ "HOST=h1->TOPIC=t1->action=write",
+ "HOST=*->CONSUMERGROUP=cg1->action=read",
+ };
+ for (int i = 0; i < privs.length; ++i) {
+ // test: grant privilege to role
+ String [] args = new String [] { grant(shortOption), "-r", TEST_ROLE_NAME_1, "-p",
+ privs[ i ],
+ "-conf", confPath.getAbsolutePath() };
+ SentryShellKafka.main(args);
+ }
+
+ // test the list privilege
+ String [] args = new String[] { list(shortOption), "-r", TEST_ROLE_NAME_1, "-conf", confPath.getAbsolutePath() };
+ SentryShellKafka sentryShell = new SentryShellKafka();
+ Set privilegeStrs = getShellResultWithOSRedirect(sentryShell, args, true);
+
+ assertEquals("Incorrect number of privileges", privs.length, privilegeStrs.size());
+ for (int i = 0; i < privs.length; ++i) {
+ assertTrue("Expected privilege: " + privs[i] + " in " + Arrays.toString(privilegeStrs.toArray()), privilegeStrs.contains(privs[i]));
+ }
+
+ for (int i = 0; i < privs.length; ++i) {
+ args = new String[] { revoke(shortOption), "-r", TEST_ROLE_NAME_1, "-p",
+ privs[ i ], "-conf",
+ confPath.getAbsolutePath() };
+ SentryShellKafka.main(args);
+ Set privileges = client.listPrivilegesByRoleName(requestorName,
+ TEST_ROLE_NAME_1, KAFKA, service);
+ assertEquals("Incorrect number of privileges. Received privileges: " + Arrays.toString(privileges.toArray()), privs.length - (i + 1), privileges.size());
+ }
+
+ // clear the test data
+ client.dropRole(requestorName, TEST_ROLE_NAME_1, KAFKA);
+ client.dropRole(requestorName, TEST_ROLE_NAME_2, KAFKA);
+ }
+ });
+ }
+
+
+ @Test
+ public void testGrantRevokePrivilegeWithShortOption() throws Exception {
+ assertGrantRevokePrivilege(true);
+ }
+
+ @Test
+ public void testGrantRevokePrivilegeWithLongOption() throws Exception {
+ assertGrantRevokePrivilege(false);
+ }
+
+
+ @Test
+ public void testNegativeCaseWithInvalidArgument() throws Exception {
+ runTestAsSubject(new TestOperation() {
+ @Override
+ public void runTestAsSubject() throws Exception {
+ client.createRole(requestorName, TEST_ROLE_NAME_1, KAFKA);
+ // test: create duplicate role with -cr
+ String[] args = { "-cr", "-r", TEST_ROLE_NAME_1, "-conf", confPath.getAbsolutePath() };
+ SentryShellKafka sentryShell = new SentryShellKafka();
+ try {
+ sentryShell.executeShell(args);
+ fail("Exception should be thrown for creating duplicate role");
+ } catch (SentryUserException e) {
+ // expected exception
+ } catch (Exception e) {
+ fail ("Unexpected exception received. " + e);
+ }
+
+ // test: drop non-exist role with -dr
+ args = new String[] { "-dr", "-r", TEST_ROLE_NAME_2, "-conf", confPath.getAbsolutePath() };
+ sentryShell = new SentryShellKafka();
+ try {
+ sentryShell.executeShell(args);
+ fail("Exception should be thrown for dropping non-exist role");
+ } catch (SentryUserException e) {
+ // excepted exception
+ } catch (Exception e) {
+ fail ("Unexpected exception received. " + e);
+ }
+
+ // test: add non-exist role to group with -arg
+ args = new String[] { "-arg", "-r", TEST_ROLE_NAME_2, "-g", "testGroup1", "-conf",
+ confPath.getAbsolutePath() };
+ sentryShell = new SentryShellKafka();
+ try {
+ sentryShell.executeShell(args);
+ fail("Exception should be thrown for granting non-exist role to group");
+ } catch (SentryUserException e) {
+ // excepted exception
+ } catch (Exception e) {
+ fail ("Unexpected exception received. " + e);
+ }
+
+ // 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 SentryShellKafka();
+ try {
+ sentryShell.executeShell(args);
+ fail("Exception should be thrown for drop group from non-exist role");
+ } catch (SentryUserException e) {
+ // excepted exception
+ } catch (Exception e) {
+ fail ("Unexpected exception received. " + e);
+ }
+
+ // test: grant privilege to role with the error privilege format
+ args = new String[] { "-gpr", "-r", TEST_ROLE_NAME_1, "-p", "serverserver1->action=all",
+ "-conf", confPath.getAbsolutePath() };
+ sentryShell = new SentryShellKafka();
+ try {
+ sentryShell.executeShell(args);
+ fail("Exception should be thrown for the error privilege format, invalid key value.");
+ } catch (IllegalArgumentException e) {
+ // excepted exception
+ } catch (Exception e) {
+ fail ("Unexpected exception received. " + e);
+ }
+
+ // test: grant privilege to role with the error privilege hierarchy
+ args = new String[] { "-gpr", "-r", TEST_ROLE_NAME_1, "-p",
+ "consumergroup=cg1->host=h1->action=create", "-conf",
+ confPath.getAbsolutePath() };
+ sentryShell = new SentryShellKafka();
+ try {
+ sentryShell.executeShell(args);
+ fail("Exception should be thrown for the error privilege format, invalid key value.");
+ } catch (ConfigurationException e) {
+ // expected exception
+ } catch (Exception e) {
+ fail ("Unexpected exception received. " + e);
+ }
+
+ // clear the test data
+ client.dropRole(requestorName, TEST_ROLE_NAME_1, KAFKA);
+ }
+ });
+ }
+
+ @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, KAFKA);
+ // test: the conf is required argument
+ String[] args = { "-cr", "-r", TEST_ROLE_NAME_1 };
+ SentryShellKafka sentryShell = new SentryShellKafka();
+ 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 SentryShellKafka();
+ 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 SentryShellKafka();
+ validateMissingParameterMsg(sentryShell, args,
+ SentryShellCommon.PREFIX_MESSAGE_MISSING_OPTION + SentryShellCommon.OPTION_DESC_ROLE_NAME);
+
+ // test: -r is required when add role to group
+ args = new String[] { "-arg", "-g", "testGroup1", "-conf", confPath.getAbsolutePath() };
+ sentryShell = new SentryShellKafka();
+ validateMissingParameterMsg(sentryShell, args,
+ SentryShellCommon.PREFIX_MESSAGE_MISSING_OPTION + SentryShellCommon.OPTION_DESC_ROLE_NAME);
+
+ // test: -g is required when add role to group
+ args = new String[] { "-arg", "-r", TEST_ROLE_NAME_2, "-conf", confPath.getAbsolutePath() };
+ sentryShell = new SentryShellKafka();
+ validateMissingParameterMsg(sentryShell, args,
+ SentryShellCommon.PREFIX_MESSAGE_MISSING_OPTION + SentryShellCommon.OPTION_DESC_GROUP_NAME);
+
+ // test: -r is required when delete role from group
+ args = new String[] { "-drg", "-g", "testGroup1", "-conf", confPath.getAbsolutePath() };
+ sentryShell = new SentryShellKafka();
+ validateMissingParameterMsg(sentryShell, args,
+ SentryShellCommon.PREFIX_MESSAGE_MISSING_OPTION + SentryShellCommon.OPTION_DESC_ROLE_NAME);
+
+ // test: -g is required when delete role from group
+ args = new String[] { "-drg", "-r", TEST_ROLE_NAME_2, "-conf", confPath.getAbsolutePath() };
+ sentryShell = new SentryShellKafka();
+ 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 SentryShellKafka();
+ 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 SentryShellKafka();
+ validateMissingParameterMsg(sentryShell, args,
+ SentryShellCommon.PREFIX_MESSAGE_MISSING_OPTION + SentryShellCommon.OPTION_DESC_PRIVILEGE);
+
+ // test: action is required in privilege
+ args = new String[] { "-gpr", "-r", TEST_ROLE_NAME_1, "-conf", confPath.getAbsolutePath(), "-p", "host=*->topic=t1" };
+ sentryShell = new SentryShellKafka();
+ try {
+ getShellResultWithOSRedirect(sentryShell, args, false);
+ fail("Expected IllegalArgumentException");
+ } catch (ConfigurationException e) {
+ assert(("Kafka privilege must end with a valid action.\n" + KafkaPrivilegeValidator.KafkaPrivilegeHelpMsg).equals(e.getMessage()));
+ } catch (Exception e) {
+ fail ("Unexpected exception received. " + e);
+ }
+
+ // test: -r is required when revoke privilege from role
+ args = new String[] { "-rpr", "-p", "host=h1", "-conf", confPath.getAbsolutePath() };
+ sentryShell = new SentryShellKafka();
+ 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 SentryShellKafka();
+ 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 SentryShellKafka();
+ validateMissingParameterMsgsContains(sentryShell, args,
+ SentryShellCommon.PREFIX_MESSAGE_MISSING_OPTION + "[",
+ "-arg Add role to group",
+ "-cr Create role",
+ "-rpr Revoke privilege from role",
+ "-drg Delete role from group",
+ "-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, KAFKA);
+ }
+ });
+ }
+
+ // redirect the System.out to ByteArrayOutputStream, then execute the command and parse the result.
+ private Set getShellResultWithOSRedirect(SentryShellKafka sentryShell,
+ String[] args, boolean expectedExecuteResult) throws Exception {
+ PrintStream oldOut = System.out;
+ ByteArrayOutputStream outContent = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(outContent));
+ assertEquals(expectedExecuteResult, sentryShell.executeShell(args));
+ Set resultSet = Sets.newHashSet(outContent.toString().split("\n"));
+ System.setOut(oldOut);
+ return resultSet;
+ }
+
+ private void validateRoleNames(Set roleNames, String ... expectedRoleNames) {
+ if (expectedRoleNames != null && expectedRoleNames.length > 0) {
+ assertEquals("Found: " + roleNames.size() + " roles, expected: " + expectedRoleNames.length,
+ expectedRoleNames.length, roleNames.size());
+ Set lowerCaseRoles = new HashSet();
+ for (String role : roleNames) {
+ lowerCaseRoles.add(role.toLowerCase());
+ }
+
+ for (String expectedRole : expectedRoleNames) {
+ assertTrue("Expected role: " + expectedRole,
+ lowerCaseRoles.contains(expectedRole.toLowerCase()));
+ }
+ }
+ }
+
+ private void validateMissingParameterMsg(SentryShellKafka sentryShell, String[] args,
+ String expectedErrorMsg) throws Exception {
+ Set errorMsgs = getShellResultWithOSRedirect(sentryShell, args, false);
+ assertTrue("Expected error message: " + expectedErrorMsg, errorMsgs.contains(expectedErrorMsg));
+ }
+
+ private void validateMissingParameterMsgsContains(SentryShellKafka sentryShell, String[] args,
+ String ... expectedErrorMsgsContains) throws Exception {
+ Set errorMsgs = getShellResultWithOSRedirect(sentryShell, args, false);
+ boolean foundAllMessages = false;
+ Iterator it = errorMsgs.iterator();
+ while (it.hasNext()) {
+ String errorMessage = it.next();
+ boolean missingExpected = false;
+ for (String expectedContains : expectedErrorMsgsContains) {
+ if (!errorMessage.contains(expectedContains)) {
+ missingExpected = true;
+ break;
+ }
+ }
+ if (!missingExpected) {
+ foundAllMessages = true;
+ break;
+ }
+ }
+ assertTrue(foundAllMessages);
+ }
+}
diff --git a/sentry-provider/sentry-provider-file/pom.xml b/sentry-provider/sentry-provider-file/pom.xml
index 1f3f7e67e..3b84884bf 100644
--- a/sentry-provider/sentry-provider-file/pom.xml
+++ b/sentry-provider/sentry-provider-file/pom.xml
@@ -21,7 +21,7 @@ limitations under the License.
org.apache.sentry
sentry-provider
- 1.7.0-incubating-SNAPSHOT
+ 1.7.1
sentry-provider-file
diff --git a/sentry-solr/pom.xml b/sentry-solr/pom.xml
index 43798c974..c86d6adba 100644
--- a/sentry-solr/pom.xml
+++ b/sentry-solr/pom.xml
@@ -22,7 +22,7 @@ limitations under the License.
org.apache.sentry
sentry
- 1.7.0-incubating-SNAPSHOT
+ 1.7.1
sentry-solr
diff --git a/sentry-solr/solr-sentry-core/pom.xml b/sentry-solr/solr-sentry-core/pom.xml
index 44fbb864a..168ca1c2d 100644
--- a/sentry-solr/solr-sentry-core/pom.xml
+++ b/sentry-solr/solr-sentry-core/pom.xml
@@ -22,7 +22,7 @@ limitations under the License.
org.apache.sentry
sentry-solr
- 1.7.0-incubating-SNAPSHOT
+ 1.7.1
solr-sentry-core
diff --git a/sentry-solr/solr-sentry-handlers/pom.xml b/sentry-solr/solr-sentry-handlers/pom.xml
index 07d95faf1..a8e3aa9e0 100644
--- a/sentry-solr/solr-sentry-handlers/pom.xml
+++ b/sentry-solr/solr-sentry-handlers/pom.xml
@@ -22,7 +22,7 @@ limitations under the License.
org.apache.sentry
sentry-solr
- 1.7.0-incubating-SNAPSHOT
+ 1.7.1
solr-sentry-handlers
diff --git a/sentry-tests/pom.xml b/sentry-tests/pom.xml
index 86a1409af..ca63223ac 100644
--- a/sentry-tests/pom.xml
+++ b/sentry-tests/pom.xml
@@ -20,7 +20,7 @@ limitations under the License.
org.apache.sentry
sentry
- 1.7.0-incubating-SNAPSHOT
+ 1.7.1
sentry-tests
Sentry Tests
diff --git a/sentry-tests/sentry-tests-hive-v2/pom.xml b/sentry-tests/sentry-tests-hive-v2/pom.xml
index b6590bd71..4706fcb0e 100644
--- a/sentry-tests/sentry-tests-hive-v2/pom.xml
+++ b/sentry-tests/sentry-tests-hive-v2/pom.xml
@@ -21,7 +21,7 @@ limitations under the License.
org.apache.sentry
sentry-tests
- 1.7.0-incubating-SNAPSHOT
+ 1.7.1
sentry-tests-hive-v2
Sentry Hive Tests v2
diff --git a/sentry-tests/sentry-tests-hive/pom.xml b/sentry-tests/sentry-tests-hive/pom.xml
index 7a32ba37c..0ed217045 100644
--- a/sentry-tests/sentry-tests-hive/pom.xml
+++ b/sentry-tests/sentry-tests-hive/pom.xml
@@ -21,7 +21,7 @@ limitations under the License.
org.apache.sentry
sentry-tests
- 1.7.0-incubating-SNAPSHOT
+ 1.7.1
sentry-tests-hive
Sentry Hive Tests
diff --git a/sentry-tests/sentry-tests-kafka/pom.xml b/sentry-tests/sentry-tests-kafka/pom.xml
index 58dc0b081..89db14c6f 100644
--- a/sentry-tests/sentry-tests-kafka/pom.xml
+++ b/sentry-tests/sentry-tests-kafka/pom.xml
@@ -21,7 +21,7 @@ limitations under the License.
sentry-tests
org.apache.sentry
- 1.7.0-incubating-SNAPSHOT
+ 1.7.1
4.0.0
diff --git a/sentry-tests/sentry-tests-solr/pom.xml b/sentry-tests/sentry-tests-solr/pom.xml
index c88ca8549..18673930d 100644
--- a/sentry-tests/sentry-tests-solr/pom.xml
+++ b/sentry-tests/sentry-tests-solr/pom.xml
@@ -22,7 +22,7 @@ limitations under the License.
org.apache.sentry
sentry-tests
- 1.7.0-incubating-SNAPSHOT
+ 1.7.1
sentry-tests-solr
diff --git a/sentry-tests/sentry-tests-sqoop/pom.xml b/sentry-tests/sentry-tests-sqoop/pom.xml
index 34fe83146..5e8471fb9 100644
--- a/sentry-tests/sentry-tests-sqoop/pom.xml
+++ b/sentry-tests/sentry-tests-sqoop/pom.xml
@@ -22,7 +22,7 @@ limitations under the License.
org.apache.sentry
sentry-tests
- 1.7.0-incubating-SNAPSHOT
+ 1.7.1
sentry-tests-sqoop