This is an automated email from the ASF dual-hosted git repository.
stigahuang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/impala.git
The following commit(s) were added to refs/heads/master by this push:
new 20c0de101 IMPALA-10436: Support storage handler privileges for
external Kudu table creation
20c0de101 is described below
commit 20c0de1017f6c17068cbb302e181b947a337975f
Author: Fang-Yu Rao <[email protected]>
AuthorDate: Mon Dec 6 10:14:59 2021 -0800
IMPALA-10436: Support storage handler privileges for external Kudu table
creation
This patch lowers the privilege requirement for external Kudu table
creation. Before this patch, a user was required to have the ALL
privilege on SERVER if the user wanted to create an external Kudu table.
In this patch we introduce a new type of resources called storage
handler URI and a new access type called RWSTORAGE that will be
supported by Apache Ranger once RANGER-3281 is resolved, which in turn
depends on the release of Apache Hive 4.0 that consists of HIVE-24705.
Specifically, after this patch, a user will be allowed to create an
external Kudu table as long as the user is granted the RWSTORAGE
privilege on the resource specified by a storage handler URI that points
to an existing Kudu table.
For instance, in order for a user 'non_owner' to create an external Kudu
table based on an existing Kudu table 'impala::tpch_kudu.nation', it
suffices to execute the following command as an administrator to grant
the necessary privilege to the requesting user, where "localhost" is the
default address of Kudu master host assuming there is only one single
master host in this example.
GRANT RWSTORAGE ON
STORAGEHANDLER_URI 'kudu://localhost/impala::tpch_kudu.nation'
TO USER non_owner
One may be wondering why we do not simply cancel the privilege check
that required the ALL privilege on SERVER for external Kudu table
creation. One scenario in which such relaxation is not secure is when
the owner or the creator of the existing Kudu table is different from
the requesting user who wants to create an external Kudu table in
Impala. Not requiring any additional privilege check would allow a user
without any privilege to retrieve the contents of the existing Kudu
table.
On the other hand, after this patch we still require a user to have the
ALL privilege on SERVER when the table property of
'kudu.master_addresses' is specified in a query that tries to create a
Kudu table whether or not the table is external. To be more specific,
the user 'non_owner' would be able to create an external Kudu table
using the following statement once being granted the RWSTORAGE privilege
on the specified storage handler URI above.
CREATE EXTERNAL TABLE default.kudu_tbl STORED AS KUDU
TBLPROPERTIES ('kudu.table_name'='impala::tpch_kudu.nation')
However, the following query submitted by the same user would be
rejected due to the user 'non_owner' not being granted the ALL privilege
on SERVER.
CREATE EXTERNAL TABLE default.kudu_tbl STORED AS KUDU
TBLPROPERTIES ('kudu.table_name'='impala::tpch_kudu.nation',
'kudu.master_addresses'='localhost')
We do not relax such a requirement in that specifying the addresses of
Kudu master hosts to connect should still be considered as an
administrative operation.
Testing:
- Added various FE and E2E tests to verify Impala's behavior after this
patch with respect to external Kudu table creation.
- Verified that this patch passes the core tests in the DEBUG build.
Change-Id: I7936e1d8c48696169f7ad7ad92abe44a26eea3c4
Reviewed-on: http://gerrit.cloudera.org:8080/17640
Reviewed-by: Impala Public Jenkins <[email protected]>
Tested-by: Impala Public Jenkins <[email protected]>
---
common/thrift/CatalogObjects.thrift | 7 +
fe/src/main/cup/sql-parser.cup | 22 +-
.../apache/impala/analysis/CreateTableStmt.java | 45 ++--
.../org/apache/impala/analysis/PrivilegeSpec.java | 40 +++-
.../impala/analysis/ShowGrantPrincipalStmt.java | 6 +
.../apache/impala/analysis/StorageHandlerUri.java | 78 +++++++
.../apache/impala/authorization/Authorizable.java | 7 +-
.../impala/authorization/AuthorizableFactory.java | 2 +
.../AuthorizableStorageHandlerUri.java | 54 +++++
.../authorization/DefaultAuthorizableFactory.java | 7 +
.../org/apache/impala/authorization/Privilege.java | 2 +
.../authorization/PrivilegeRequestBuilder.java | 12 +
.../ranger/RangerAuthorizationChecker.java | 39 +++-
.../ranger/RangerCatalogdAuthorizationManager.java | 40 +++-
.../ranger/RangerImpalaResourceBuilder.java | 12 +
.../ranger/RangerImpaladAuthorizationManager.java | 28 ++-
.../impala/authorization/ranger/RangerUtil.java | 12 +
fe/src/main/jflex/sql-scanner.flex | 2 +
.../impala/analysis/AnalyzeAuthStmtsTest.java | 48 ++++
.../java/org/apache/impala/analysis/ToSqlTest.java | 12 +
.../authorization/AuthorizationStmtTest.java | 71 +++++-
.../authorization/AuthorizationTestBase.java | 23 ++
.../queries/QueryTest/grant_revoke.test | 242 +++++++++++----------
tests/authorization/test_ranger.py | 210 ++++++++++++------
24 files changed, 784 insertions(+), 237 deletions(-)
diff --git a/common/thrift/CatalogObjects.thrift
b/common/thrift/CatalogObjects.thrift
index ef2666f02..846baa0dc 100644
--- a/common/thrift/CatalogObjects.thrift
+++ b/common/thrift/CatalogObjects.thrift
@@ -709,6 +709,8 @@ enum TPrivilegeScope {
DATABASE = 2
TABLE = 3
COLUMN = 4
+ STORAGE_TYPE = 5
+ STORAGEHANDLER_URI = 6
}
// The privilege level allowed.
@@ -721,6 +723,7 @@ enum TPrivilegeLevel {
ALTER = 5
DROP = 6
OWNER = 7
+ RWSTORAGE = 8
}
// Represents a privilege in an authorization policy. Privileges contain the
level
@@ -771,6 +774,10 @@ struct TPrivilege {
// Set if scope is COLUMN
12: optional string column_name
+
+ 13: optional string storage_type
+
+ 14: optional string storage_url
}
// Thrift representation of an HdfsCachePool.
diff --git a/fe/src/main/cup/sql-parser.cup b/fe/src/main/cup/sql-parser.cup
index 52e4412bb..99fe7f007 100755
--- a/fe/src/main/cup/sql-parser.cup
+++ b/fe/src/main/cup/sql-parser.cup
@@ -307,9 +307,9 @@ terminal
KW_PARTITIONS, KW_PRECEDING, KW_PREPARE_FN, KW_PRIMARY, KW_PRODUCED,
KW_PURGE,
KW_RANGE, KW_RCFILE, KW_RECOVER, KW_REFERENCES, KW_REFRESH, KW_REGEXP,
KW_RELY,
KW_RENAME, KW_REPEATABLE, KW_REPLACE, KW_REPLICATION, KW_RESTRICT,
KW_RETURNS,
- KW_REVOKE, KW_RIGHT, KW_RLIKE, KW_ROLE, KW_ROLES, KW_ROLLUP, KW_ROW,
KW_ROWS, KW_SCHEMA,
+ KW_REVOKE, KW_RIGHT, KW_RLIKE, KW_ROLE, KW_ROLES, KW_ROLLUP, KW_ROW,
KW_ROWS, KW_RWSTORAGE, KW_SCHEMA,
KW_SCHEMAS, KW_SELECT, KW_SEMI, KW_SEQUENCEFILE, KW_SERDEPROPERTIES,
KW_SERIALIZE_FN,
- KW_SET, KW_SHOW, KW_SMALLINT, KW_SETS, KW_SORT, KW_SPEC, KW_STORED,
KW_STRAIGHT_JOIN,
+ KW_SET, KW_SHOW, KW_SMALLINT, KW_SETS, KW_SORT, KW_SPEC,
KW_STORAGE_HANDLER_URI, KW_STORED, KW_STRAIGHT_JOIN,
KW_STRING, KW_STRUCT, KW_SYMBOL, KW_SYSTEM_TIME, KW_SYSTEM_VERSION,
KW_TABLE, KW_TABLES, KW_TABLESAMPLE, KW_TBLPROPERTIES,
KW_TERMINATED, KW_TEXTFILE, KW_THEN, KW_TIMESTAMP, KW_TINYINT, KW_TRUNCATE,
KW_STATS,
@@ -1021,6 +1021,13 @@ show_grant_principal_stmt ::=
RESULT = new ShowGrantPrincipalStmt(name, type,
PrivilegeSpec.createUriScopedPriv(TPrivilegeLevel.ALL, new
HdfsUri(uri)));
:}
+ | KW_SHOW KW_GRANT principal_type:type ident_or_default:name KW_ON
KW_STORAGE_HANDLER_URI
+ STRING_LITERAL:storage_handler_uri
+ {:
+ RESULT = new ShowGrantPrincipalStmt(name, type,
+
PrivilegeSpec.createStorageHandlerUriScopedPriv(TPrivilegeLevel.RWSTORAGE,
+ new StorageHandlerUri(storage_handler_uri)));
+ :}
;
create_drop_role_stmt ::=
@@ -1093,6 +1100,11 @@ privilege_spec ::=
{: RESULT = PrivilegeSpec.createColumnScopedPriv(priv, tbl_name, cols); :}
| privilege:priv KW_ON uri_ident:uri_kw STRING_LITERAL:uri
{: RESULT = PrivilegeSpec.createUriScopedPriv(priv, new HdfsUri(uri)); :}
+ | privilege:priv KW_ON KW_STORAGE_HANDLER_URI
STRING_LITERAL:storage_handler_uri
+ {:
+ RESULT = PrivilegeSpec.createStorageHandlerUriScopedPriv(priv,
+ new StorageHandlerUri(storage_handler_uri));
+ :}
;
privilege ::=
@@ -1110,6 +1122,8 @@ privilege ::=
{: RESULT = TPrivilegeLevel.DROP; :}
| KW_ALL
{: RESULT = TPrivilegeLevel.ALL; :}
+ | KW_RWSTORAGE
+ {: RESULT = TPrivilegeLevel.RWSTORAGE; :}
;
principal_type ::=
@@ -4371,6 +4385,8 @@ word ::=
{: RESULT = r.toString(); :}
| KW_ROWS:r
{: RESULT = r.toString(); :}
+ | KW_RWSTORAGE:r
+ {: RESULT = r.toString(); :}
| KW_SCHEMA:r
{: RESULT = r.toString(); :}
| KW_SCHEMAS:r
@@ -4397,6 +4413,8 @@ word ::=
{: RESULT = r.toString(); :}
| KW_SPEC:r
{: RESULT = r.toString(); :}
+ | KW_STORAGE_HANDLER_URI:r
+ {: RESULT = r.toString(); :}
| KW_STORED:r
{: RESULT = r.toString(); :}
| KW_STRAIGHT_JOIN:r
diff --git a/fe/src/main/java/org/apache/impala/analysis/CreateTableStmt.java
b/fe/src/main/java/org/apache/impala/analysis/CreateTableStmt.java
index 819981a84..242ba70a8 100644
--- a/fe/src/main/java/org/apache/impala/analysis/CreateTableStmt.java
+++ b/fe/src/main/java/org/apache/impala/analysis/CreateTableStmt.java
@@ -56,6 +56,7 @@ import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
+import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.primitives.Ints;
import com.google.common.primitives.Longs;
@@ -355,16 +356,33 @@ public class CreateTableStmt extends StatementBase {
* Kudu tables.
*/
private void analyzeKuduTableProperties(Analyzer analyzer) throws
AnalysisException {
+ String kuduMasters = getKuduMasters(analyzer);
+ if (kuduMasters.isEmpty()) {
+ throw new AnalysisException(String.format(
+ "Table property '%s' is required when the impalad startup flag " +
+ "-kudu_master_hosts is not used.", KuduTable.KEY_MASTER_HOSTS));
+ }
+ putGeneratedProperty(KuduTable.KEY_MASTER_HOSTS, kuduMasters);
+
AuthorizationConfig authzConfig = analyzer.getAuthzConfig();
if (authzConfig.isEnabled()) {
- // Today there is no comprehensive way of enforcing a Ranger
authorization policy
- // against tables stored in Kudu. This is why only users with ALL
privileges on
- // SERVER may create external Kudu tables or set the master addresses.
- // See IMPALA-4000 for details.
boolean isExternal = tableDef_.isExternal() ||
MetaStoreUtil.findTblPropKeyCaseInsensitive(
getTblProperties(), "EXTERNAL") != null;
- if (getTblProperties().containsKey(KuduTable.KEY_MASTER_HOSTS) ||
isExternal) {
+ if (isExternal) {
+ String externalTableName =
getTblProperties().get(KuduTable.KEY_TABLE_NAME);
+ AnalysisUtils.throwIfNull(externalTableName,
+ String.format("Table property %s must be specified when creating "
+
+ "an external Kudu table.", KuduTable.KEY_TABLE_NAME));
+ List<String> storageUris = getUrisForAuthz(kuduMasters,
externalTableName);
+ for (String storageUri : storageUris) {
+ analyzer.registerPrivReq(builder -> builder
+ .onStorageHandlerUri("kudu", storageUri)
+ .rwstorage().build());
+ }
+ }
+
+ if (getTblProperties().containsKey(KuduTable.KEY_MASTER_HOSTS)) {
String authzServer = authzConfig.getServerName();
Preconditions.checkNotNull(authzServer);
analyzer.registerPrivReq(builder ->
builder.onServer(authzServer).all().build());
@@ -380,14 +398,6 @@ public class CreateTableStmt extends StatementBase {
putGeneratedProperty(KuduTable.KEY_STORAGE_HANDLER,
KuduTable.KUDU_STORAGE_HANDLER);
- String kuduMasters = getKuduMasters(analyzer);
- if (kuduMasters.isEmpty()) {
- throw new AnalysisException(String.format(
- "Table property '%s' is required when the impalad startup flag " +
- "-kudu_master_hosts is not used.", KuduTable.KEY_MASTER_HOSTS));
- }
- putGeneratedProperty(KuduTable.KEY_MASTER_HOSTS, kuduMasters);
-
// TODO: Find out what is creating a directory in HDFS and stop doing
that. Kudu
// tables shouldn't have HDFS dirs: IMPALA-3570
AnalysisUtils.throwIfNotNull(getCachingOp(),
@@ -401,6 +411,15 @@ public class CreateTableStmt extends StatementBase {
"Kudu table.", KuduTable.KEY_TABLE_ID));
}
+ private List<String> getUrisForAuthz(String kuduMasterAddresses, String
kuduTableName) {
+ List<String> masterAddresses =
Lists.newArrayList(kuduMasterAddresses.split(","));
+ List<String> uris = new ArrayList<>();
+ for (String masterAddress : masterAddresses) {
+ uris.add(masterAddress + "/" + kuduTableName);
+ }
+ return uris;
+ }
+
/**
* Populates Kudu master addresses either from table property or
* the -kudu_master_hosts flag.
diff --git a/fe/src/main/java/org/apache/impala/analysis/PrivilegeSpec.java
b/fe/src/main/java/org/apache/impala/analysis/PrivilegeSpec.java
index af578c740..3910cf69a 100644
--- a/fe/src/main/java/org/apache/impala/analysis/PrivilegeSpec.java
+++ b/fe/src/main/java/org/apache/impala/analysis/PrivilegeSpec.java
@@ -46,6 +46,8 @@ public class PrivilegeSpec extends StmtNode {
private final TPrivilegeLevel privilegeLevel_;
private final TableName tableName_;
private final HdfsUri uri_;
+ private final String storageType_;
+ private final String storageUri_;
private final List<String> columnNames_;
// Set/modified during analysis
@@ -54,7 +56,7 @@ public class PrivilegeSpec extends StmtNode {
private PrivilegeSpec(TPrivilegeLevel privilegeLevel, TPrivilegeScope scope,
String serverName, String dbName, TableName tableName, HdfsUri uri,
- List<String> columnNames) {
+ String storageType, String storageUri, List<String> columnNames) {
Preconditions.checkNotNull(scope);
Preconditions.checkNotNull(privilegeLevel);
privilegeLevel_ = privilegeLevel;
@@ -63,6 +65,8 @@ public class PrivilegeSpec extends StmtNode {
tableName_ = tableName;
dbName_ = (tableName_ != null ? tableName_.getDb() : dbName);
uri_ = uri;
+ storageType_ = storageType;
+ storageUri_ = storageUri;
columnNames_ = columnNames;
}
@@ -73,21 +77,21 @@ public class PrivilegeSpec extends StmtNode {
public static PrivilegeSpec createServerScopedPriv(TPrivilegeLevel
privilegeLevel,
String serverName) {
return new PrivilegeSpec(privilegeLevel, TPrivilegeScope.SERVER,
serverName, null,
- null, null, null);
+ null, null, null, null, null);
}
public static PrivilegeSpec createDbScopedPriv(TPrivilegeLevel
privilegeLevel,
String dbName) {
Preconditions.checkNotNull(dbName);
return new PrivilegeSpec(privilegeLevel, TPrivilegeScope.DATABASE, null,
dbName,
- null, null, null);
+ null, null, null, null, null);
}
public static PrivilegeSpec createTableScopedPriv(TPrivilegeLevel
privilegeLevel,
TableName tableName) {
Preconditions.checkNotNull(tableName);
- return new PrivilegeSpec(privilegeLevel, TPrivilegeScope.TABLE, null,
null, tableName,
- null, null);
+ return new PrivilegeSpec(privilegeLevel, TPrivilegeScope.TABLE, null, null,
+ tableName, null, null, null, null);
}
public static PrivilegeSpec createColumnScopedPriv(TPrivilegeLevel
privilegeLevel,
@@ -95,14 +99,22 @@ public class PrivilegeSpec extends StmtNode {
Preconditions.checkNotNull(tableName);
Preconditions.checkNotNull(columnNames);
return new PrivilegeSpec(privilegeLevel, TPrivilegeScope.COLUMN, null,
null,
- tableName, null, columnNames);
+ tableName, null, null, null, columnNames);
}
public static PrivilegeSpec createUriScopedPriv(TPrivilegeLevel
privilegeLevel,
HdfsUri uri) {
Preconditions.checkNotNull(uri);
return new PrivilegeSpec(privilegeLevel, TPrivilegeScope.URI, null, null,
null, uri,
- null);
+ null, null, null);
+ }
+
+ public static PrivilegeSpec createStorageHandlerUriScopedPriv(
+ TPrivilegeLevel privilegeLevel, StorageHandlerUri storageHandlerUri) {
+ Preconditions.checkNotNull(storageHandlerUri);
+ return new PrivilegeSpec(privilegeLevel,
TPrivilegeScope.STORAGEHANDLER_URI, null,
+ null, null, null, storageHandlerUri.getStorageType(),
+ storageHandlerUri.getStoreUrl(), null);
}
public List<TPrivilege> toThrift() {
@@ -133,6 +145,8 @@ public class PrivilegeSpec extends StmtNode {
if (dbName_ != null) privilege.setDb_name(dbName_);
if (tableName_ != null) privilege.setTable_name(tableName_.getTbl());
if (uri_ != null) privilege.setUri(uri_.toString());
+ if (storageType_ != null) privilege.setStorage_type(storageType_);
+ if (storageUri_ != null) privilege.setStorage_url(storageUri_);
if (columnName != null) privilege.setColumn_name(columnName);
privilege.setCreate_time_ms(-1);
return privilege;
@@ -174,6 +188,8 @@ public class PrivilegeSpec extends StmtNode {
sb.append(" ON TABLE " + tableName_.toString());
} else if (scope_ == TPrivilegeScope.URI) {
sb.append(" '" + uri_.getLocation() + "'");
+ } else if (scope_ == TPrivilegeScope.STORAGEHANDLER_URI) {
+ sb.append(" '" + storageType_ + "://" + storageUri_ + "'");
}
return sb.toString();
}
@@ -214,6 +230,12 @@ public class PrivilegeSpec extends StmtNode {
}
uri_.analyze(analyzer, Privilege.ALL, false);
break;
+ case STORAGEHANDLER_URI:
+ if (privilegeLevel_ != TPrivilegeLevel.RWSTORAGE) {
+ throw new AnalysisException("Only 'RWSTORAGE' privilege may be
applied at " +
+ "storage handler URI scope in privilege spec.");
+ }
+ break;
case TABLE:
analyzeTargetTable(analyzer);
break;
@@ -298,6 +320,10 @@ public class PrivilegeSpec extends StmtNode {
public HdfsUri getUri() { return uri_; }
+ public String getStorageType() { return storageType_; }
+
+ public String getStorageUri() { return storageUri_; }
+
public String getDbName() { return dbName_; }
public String getServerName() { return serverName_; }
diff --git
a/fe/src/main/java/org/apache/impala/analysis/ShowGrantPrincipalStmt.java
b/fe/src/main/java/org/apache/impala/analysis/ShowGrantPrincipalStmt.java
index 103dde626..86f1b4960 100644
--- a/fe/src/main/java/org/apache/impala/analysis/ShowGrantPrincipalStmt.java
+++ b/fe/src/main/java/org/apache/impala/analysis/ShowGrantPrincipalStmt.java
@@ -77,6 +77,12 @@ public class ShowGrantPrincipalStmt extends
AuthorizationStmt {
case URI:
sb.append(String.format(" '%s'", privilegeSpec_.getUri()));
break;
+ case STORAGE_TYPE:
+ sb.append(String.format(" '%s'", privilegeSpec_.getStorageType()));
+ break;
+ case STORAGEHANDLER_URI:
+ sb.append(String.format(" '%s'", privilegeSpec_.getStorageUri()));
+ break;
default:
throw new IllegalStateException("Unexpected privilege spec scope: " +
privilegeSpec_.getScope());
diff --git a/fe/src/main/java/org/apache/impala/analysis/StorageHandlerUri.java
b/fe/src/main/java/org/apache/impala/analysis/StorageHandlerUri.java
new file mode 100644
index 000000000..fcdd8c05b
--- /dev/null
+++ b/fe/src/main/java/org/apache/impala/analysis/StorageHandlerUri.java
@@ -0,0 +1,78 @@
+// 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.impala.analysis;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import org.apache.impala.common.AnalysisException;
+
+import com.google.common.collect.ImmutableSet;
+
+public class StorageHandlerUri {
+ public static final ImmutableSet<String> supportedStorageTypes =
ImmutableSet.of(
+ "kudu");
+
+ private String storageType_;
+ private String storageUrl_;
+
+ public StorageHandlerUri(String storageHandlerUri) throws AnalysisException,
+ URISyntaxException {
+ // We consider "*://*" as a valid URI since it is supported by Ranger.
+ if (storageHandlerUri.equals("*://*")) {
+ storageType_ = "*";
+ storageUrl_ = "*";
+ return;
+ }
+
+ // We consider "<storage_type>://*" as a valid URI since it is supported
by Ranger.
+ String res[] = storageHandlerUri.split(":\\/\\/", 2);
+ if (res.length == 2) {
+ if (supportedStorageTypes.contains(res[0].toLowerCase()) &&
+ res[1].equals("*")) {
+ storageType_ = res[0];
+ storageUrl_ = "*";
+ return;
+ }
+ }
+
+ URI uri = new URI(storageHandlerUri);
+ if (!supportedStorageTypes.contains(uri.getScheme())) {
+ throw new AnalysisException("The storage type \"" + uri.getScheme() +
+ "\" is not supported. A storage handler URI should be in the form of
" +
+ "<storage_type>://<hostname>[:<port>]/<path_to_resource>.");
+ }
+
+ if (uri.getHost() == null) {
+ throw new AnalysisException("A storage handler URI should be in the form
of " +
+ "<storage_type>://<hostname>[:<port>]/<path_to_resource>.");
+ }
+
+ storageType_ = uri.getScheme();
+ storageUrl_ = uri.getHost() + (uri.getPort() == -1 ? "" : ":" +
uri.getPort())
+ + uri.getPath();
+ }
+
+ String getStorageType() {
+ return storageType_;
+ }
+
+ String getStoreUrl() {
+ return storageUrl_;
+ }
+}
diff --git a/fe/src/main/java/org/apache/impala/authorization/Authorizable.java
b/fe/src/main/java/org/apache/impala/authorization/Authorizable.java
index 75f437d39..fe0f9d168 100644
--- a/fe/src/main/java/org/apache/impala/authorization/Authorizable.java
+++ b/fe/src/main/java/org/apache/impala/authorization/Authorizable.java
@@ -31,7 +31,8 @@ public abstract class Authorizable {
TABLE,
COLUMN,
FUNCTION,
- URI
+ URI,
+ STORAGEHANDLER_URI
}
// Returns the name of the object.
@@ -55,6 +56,10 @@ public abstract class Authorizable {
// Returns the function name if applicable, null otherwise.
public String getFnName() { return null; }
+ public String getStorageType() { return null; }
+
+ public String getStorageUri() { return null; }
+
// Returns the owner for this authorizable if applicable, null otherwise.
// Currently, ownership is applicable only for database and table objects.
// Only used by RangerAuthorizationChecker.
diff --git
a/fe/src/main/java/org/apache/impala/authorization/AuthorizableFactory.java
b/fe/src/main/java/org/apache/impala/authorization/AuthorizableFactory.java
index 1a27663b4..750c1a8e7 100644
--- a/fe/src/main/java/org/apache/impala/authorization/AuthorizableFactory.java
+++ b/fe/src/main/java/org/apache/impala/authorization/AuthorizableFactory.java
@@ -72,4 +72,6 @@ public interface AuthorizableFactory {
* function names.
*/
Authorizable newFunction(String dbName, String fnName);
+
+ Authorizable newStorageHandlerUri(String storageType, String storageUri);
}
diff --git
a/fe/src/main/java/org/apache/impala/authorization/AuthorizableStorageHandlerUri.java
b/fe/src/main/java/org/apache/impala/authorization/AuthorizableStorageHandlerUri.java
new file mode 100644
index 000000000..25a8c3c52
--- /dev/null
+++
b/fe/src/main/java/org/apache/impala/authorization/AuthorizableStorageHandlerUri.java
@@ -0,0 +1,54 @@
+// 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.impala.authorization;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+
+/**
+ * A class to authorize access to a storage handler URI.
+ */
+public class AuthorizableStorageHandlerUri extends Authorizable {
+ private final String storageType_;
+ private final String storageUri_;
+
+ public AuthorizableStorageHandlerUri(String storageType, String
storageUri) {
+ Preconditions.checkArgument(!Strings.isNullOrEmpty(storageType));
+ Preconditions.checkArgument(!Strings.isNullOrEmpty(storageUri));
+ storageType_ = storageType;
+ storageUri_ = storageUri;
+ }
+
+ @Override
+ public String getName() {
+ return storageType_ + "://" + storageUri_;
+ }
+
+ @Override
+ public String getStorageType() {
+ return storageType_;
+ }
+
+ @Override
+ public String getStorageUri() {
+ return storageUri_;
+ }
+
+ @Override
+ public Type getType() { return Type.STORAGEHANDLER_URI; }
+}
diff --git
a/fe/src/main/java/org/apache/impala/authorization/DefaultAuthorizableFactory.java
b/fe/src/main/java/org/apache/impala/authorization/DefaultAuthorizableFactory.java
index 94afaccab..7cee989fa 100644
---
a/fe/src/main/java/org/apache/impala/authorization/DefaultAuthorizableFactory.java
+++
b/fe/src/main/java/org/apache/impala/authorization/DefaultAuthorizableFactory.java
@@ -78,4 +78,11 @@ public class DefaultAuthorizableFactory implements
AuthorizableFactory {
Preconditions.checkNotNull(fnName);
return new AuthorizableFn(dbName, fnName);
}
+
+ @Override
+ public Authorizable newStorageHandlerUri(String storageType, String
storageUri) {
+ Preconditions.checkNotNull(storageType);
+ Preconditions.checkNotNull(storageUri);
+ return new AuthorizableStorageHandlerUri(storageType, storageUri);
+ }
}
diff --git a/fe/src/main/java/org/apache/impala/authorization/Privilege.java
b/fe/src/main/java/org/apache/impala/authorization/Privilege.java
index eb4594740..f5177874a 100644
--- a/fe/src/main/java/org/apache/impala/authorization/Privilege.java
+++ b/fe/src/main/java/org/apache/impala/authorization/Privilege.java
@@ -35,6 +35,7 @@ public enum Privilege {
DROP,
CREATE,
ALL,
+ RWSTORAGE,
OWNER,
// Privileges required to view metadata on a server object.
VIEW_METADATA(true),
@@ -51,6 +52,7 @@ public enum Privilege {
INSERT.implied_ = EnumSet.of(INSERT);
SELECT.implied_ = EnumSet.of(SELECT);
REFRESH.implied_ = EnumSet.of(REFRESH);
+ RWSTORAGE.implied_ = EnumSet.of(RWSTORAGE);
VIEW_METADATA.implied_ = EnumSet.of(INSERT, SELECT, REFRESH);
ANY.implied_ = EnumSet.of(ALL, OWNER, ALTER, DROP, CREATE, INSERT, SELECT,
REFRESH);
diff --git
a/fe/src/main/java/org/apache/impala/authorization/PrivilegeRequestBuilder.java
b/fe/src/main/java/org/apache/impala/authorization/PrivilegeRequestBuilder.java
index 6fc55e2a0..402a01178 100644
---
a/fe/src/main/java/org/apache/impala/authorization/PrivilegeRequestBuilder.java
+++
b/fe/src/main/java/org/apache/impala/authorization/PrivilegeRequestBuilder.java
@@ -67,6 +67,13 @@ public class PrivilegeRequestBuilder {
return this;
}
+ public PrivilegeRequestBuilder onStorageHandlerUri(String storageType,
+ String storageUri) {
+ Preconditions.checkState(authorizable_ == null);
+ authorizable_ = authzFactory_.newStorageHandlerUri(storageType,
storageUri);
+ return this;
+ }
+
/**
* Determines whether the given FeTable corresponds to a view that was
created by a
* non-superuser in HiveMetaStore.
@@ -209,6 +216,11 @@ public class PrivilegeRequestBuilder {
return this;
}
+ public PrivilegeRequestBuilder rwstorage() {
+ privilege_ = Privilege.RWSTORAGE;
+ return this;
+ }
+
/**
* Specifies that any privileges are sufficient.
*/
diff --git
a/fe/src/main/java/org/apache/impala/authorization/ranger/RangerAuthorizationChecker.java
b/fe/src/main/java/org/apache/impala/authorization/ranger/RangerAuthorizationChecker.java
index 668d904a1..046e3e99e 100644
---
a/fe/src/main/java/org/apache/impala/authorization/ranger/RangerAuthorizationChecker.java
+++
b/fe/src/main/java/org/apache/impala/authorization/ranger/RangerAuthorizationChecker.java
@@ -102,6 +102,11 @@ public class RangerAuthorizationChecker extends
BaseAuthorizationChecker {
resources.add(new RangerImpalaResourceBuilder()
.database("*").function("*").build());
resources.add(new RangerImpalaResourceBuilder().uri("*").build());
+ if (privilege == Privilege.ALL || privilege == Privilege.OWNER ||
+ privilege == Privilege.RWSTORAGE) {
+ resources.add(new RangerImpalaResourceBuilder()
+ .storageType("*").storageUri("*").build());
+ }
break;
case DB:
resources.add(new RangerImpalaResourceBuilder()
@@ -153,6 +158,12 @@ public class RangerAuthorizationChecker extends
BaseAuthorizationChecker {
.uri(authorizable.getName())
.build());
break;
+ case STORAGEHANDLER_URI:
+ resources.add(new RangerImpalaResourceBuilder()
+ .storageType(authorizable.getStorageType())
+ .storageUri(authorizable.getStorageUri())
+ .build());
+ break;
default:
throw new IllegalArgumentException(String.format("Invalid authorizable
type: %s",
authorizable.getType()));
@@ -594,9 +605,16 @@ public class RangerAuthorizationChecker extends
BaseAuthorizationChecker {
}
// 'tmpAuditHandler' could be null if 'originalAuditHandler' is null or
// authzCtx.getRetainAudits() is false.
+ // Moreover, when 'resource' is associated with a storage handler URI, we
pass
+ // Privilege.RWSTORAGE to updateAuditEvents() since RWSTORAGE is the only
valid
+ // access type on a storage handler URI. Otherwise, we may update
+ // 'originalAuditHandler' incorrectly since the audit log entries produced
by Ranger
+ // corresponding to a command like REFRESH/INVALIDATE METADATA has a entry
with
+ // access type being RWSTORAGE instead of REFRESH.
if (originalAuditHandler != null && tmpAuditHandler != null) {
updateAuditEvents(tmpAuditHandler, originalAuditHandler, false /*not
any*/,
- privilege);
+
resource.getKeys().contains(RangerImpalaResourceBuilder.STORAGE_TYPE) ?
+ Privilege.RWSTORAGE : privilege);
}
return authorized;
}
@@ -633,13 +651,20 @@ public class RangerAuthorizationChecker extends
BaseAuthorizationChecker {
RangerAccessResourceImpl resource, Authorizable authorizable, Privilege
privilege,
RangerBufferAuditHandler auditHandler) throws InternalException {
String accessType;
- if (privilege == Privilege.ANY) {
- accessType = RangerPolicyEngine.ANY_ACCESS;
- } else if (privilege == Privilege.INSERT) {
- // Ranger plugin for Hive considers INSERT to be UPDATE.
- accessType = UPDATE_ACCESS_TYPE;
+ // If 'resource' is associated with a storage handler URI, then
'accessType' can only
+ // be RWSTORAGE since RWSTORAGE is the only valid privilege that could be
applied on
+ // a storage handler URI.
+ if (resource.getKeys().contains(RangerImpalaResourceBuilder.STORAGE_TYPE))
{
+ accessType = Privilege.RWSTORAGE.name().toLowerCase();
} else {
- accessType = privilege.name().toLowerCase();
+ if (privilege == Privilege.ANY) {
+ accessType = RangerPolicyEngine.ANY_ACCESS;
+ } else if (privilege == Privilege.INSERT) {
+ // Ranger plugin for Hive considers INSERT to be UPDATE.
+ accessType = UPDATE_ACCESS_TYPE;
+ } else {
+ accessType = privilege.name().toLowerCase();
+ }
}
RangerAccessRequestImpl request = new RangerAccessRequestImpl(resource,
accessType, user.getShortName(), getUserGroups(user));
diff --git
a/fe/src/main/java/org/apache/impala/authorization/ranger/RangerCatalogdAuthorizationManager.java
b/fe/src/main/java/org/apache/impala/authorization/ranger/RangerCatalogdAuthorizationManager.java
index 0fc750231..2597ce4a6 100644
---
a/fe/src/main/java/org/apache/impala/authorization/ranger/RangerCatalogdAuthorizationManager.java
+++
b/fe/src/main/java/org/apache/impala/authorization/ranger/RangerCatalogdAuthorizationManager.java
@@ -21,6 +21,7 @@ import com.google.common.annotations.VisibleForTesting;
import org.apache.hadoop.hive.metastore.api.PrincipalType;
import org.apache.impala.authorization.AuthorizationDelta;
import org.apache.impala.authorization.AuthorizationManager;
+import org.apache.impala.authorization.Privilege;
import org.apache.impala.authorization.User;
import
org.apache.impala.authorization.ranger.RangerBufferAuditHandler.AutoFlush;
import org.apache.impala.catalog.AuthzCacheInvalidation;
@@ -383,10 +384,11 @@ public class RangerCatalogdAuthorizationManager
implements AuthorizationManager
createGrantRevokeRequest(grantor, user, groups, roles, clusterName,
p.has_grant_opt, isGrant, p.privilege_level, resource, clientIp);
- // Ranger Impala service definition defines 3 resources:
+ // Ranger Impala service definition defines 4 resources:
// [DB -> Table -> Column]
// [DB -> Function]
// [URI]
+ // [Storage Type -> Storage URI]
// What it means is if we grant a particular privilege on a resource that
// is common to other resources, we need to grant that privilege to those
// resources.
@@ -398,11 +400,14 @@ public class RangerCatalogdAuthorizationManager
implements AuthorizationManager
// DB is used by column and function resources.
requests.add(createRequest.apply(RangerUtil.createColumnResource(p)));
requests.add(createRequest.apply(RangerUtil.createFunctionResource(p)));
+ } else if (p.getStorage_url() != null || p.getStorage_type() != null) {
+
requests.add(createRequest.apply(RangerUtil.createStorageHandlerUriResource(p)));
} else {
- // Server is used by column, function, and URI resources.
+ // Server is used by column, function, URI, and storage handler URI
resources.
requests.add(createRequest.apply(RangerUtil.createColumnResource(p)));
requests.add(createRequest.apply(RangerUtil.createFunctionResource(p)));
requests.add(createRequest.apply(RangerUtil.createUriResource(p)));
+
requests.add(createRequest.apply(RangerUtil.createStorageHandlerUriResource(p)));
}
}
@@ -431,10 +436,35 @@ public class RangerCatalogdAuthorizationManager
implements AuthorizationManager
// For revoke grant option, omit the privilege
if (!(!isGrant && withGrantOpt)) {
- if (level == TPrivilegeLevel.INSERT) {
-
request.getAccessTypes().add(RangerAuthorizationChecker.UPDATE_ACCESS_TYPE);
+ if (resource.containsKey(RangerImpalaResourceBuilder.STORAGE_TYPE)) {
+ // We consider TPrivilegeLevel.ALL and TPrivilegeLevel.OWNER because
for a
+ // statement that grants or revokes the ALL or OWNER privileges on
SERVER,
+ // 'resource' could also correspond to a storage handler URI.
+ // For such a statement, we add the RWSTORAGE privilege on the
wildcard storage
+ // handler URI. On the other hand, we won't ask Ranger to add a policy
associated
+ // with the RWSTORAGE privilege on the wildcard storage handler URI in
a
+ // query that grants or revokes a privilege other than ALL or OWNER.
For
+ // instance, we won't ask Ranger to add a policy granting the
RWSTORAGE privilege
+ // on the wildcard storage handler URI for "GRANT SELECT ON SERVER TO
USER
+ // non_owner".
+ // Recall that no new Ranger policy will be added if we do not add a
Privilege
+ // to 'accessTypes' of 'request'.
+ if (level == TPrivilegeLevel.ALL || level == TPrivilegeLevel.OWNER ||
+ level == TPrivilegeLevel.RWSTORAGE) {
+
request.getAccessTypes().add(Privilege.RWSTORAGE.name().toLowerCase());
+ }
} else {
- request.getAccessTypes().add(level.name().toLowerCase());
+ if (level == TPrivilegeLevel.INSERT) {
+
request.getAccessTypes().add(RangerAuthorizationChecker.UPDATE_ACCESS_TYPE);
+ } else if (level != TPrivilegeLevel.RWSTORAGE) {
+ // When 'resource' does not correspond to a storage handler URI, we
add the
+ // specified 'level' as is to 'accessTypes' of 'request' only if
'level' is not
+ // TPrivilegeLevel.RWSTORAGE since TPrivilegeLevel.RWSTORAGE is not
+ // well-defined with respect to other types of resources, e.g.,
table. This
+ // way we won't add a policy that grants or revokes the privilege of
RWSTORAGE
+ // on a 'resource' that is incompatible.
+ request.getAccessTypes().add(level.name().toLowerCase());
+ }
}
}
diff --git
a/fe/src/main/java/org/apache/impala/authorization/ranger/RangerImpalaResourceBuilder.java
b/fe/src/main/java/org/apache/impala/authorization/ranger/RangerImpalaResourceBuilder.java
index 97170dc6f..e743c0c5f 100644
---
a/fe/src/main/java/org/apache/impala/authorization/ranger/RangerImpalaResourceBuilder.java
+++
b/fe/src/main/java/org/apache/impala/authorization/ranger/RangerImpalaResourceBuilder.java
@@ -29,6 +29,8 @@ public class RangerImpalaResourceBuilder {
public static final String COLUMN = "column";
public static final String UDF = "udf";
public static final String URL = "url";
+ public static final String STORAGE_TYPE = "storage-type";
+ public static final String STORAGE_URL = "storage-url";
private final RangerAccessResourceImpl rangerAccessResource =
new RangerAccessResourceImpl();
@@ -58,6 +60,16 @@ public class RangerImpalaResourceBuilder {
return this;
}
+ public RangerImpalaResourceBuilder storageType(String storageType) {
+ rangerAccessResource.setValue(STORAGE_TYPE,
Preconditions.checkNotNull(storageType));
+ return this;
+ }
+
+ public RangerImpalaResourceBuilder storageUri(String storageUri) {
+ rangerAccessResource.setValue(STORAGE_URL,
Preconditions.checkNotNull(storageUri));
+ return this;
+ }
+
public RangerImpalaResourceBuilder owner(String ownerUser) {
rangerAccessResource.setOwnerUser(ownerUser);
return this;
diff --git
a/fe/src/main/java/org/apache/impala/authorization/ranger/RangerImpaladAuthorizationManager.java
b/fe/src/main/java/org/apache/impala/authorization/ranger/RangerImpaladAuthorizationManager.java
index 42f2be2c6..216d81a21 100644
---
a/fe/src/main/java/org/apache/impala/authorization/ranger/RangerImpaladAuthorizationManager.java
+++
b/fe/src/main/java/org/apache/impala/authorization/ranger/RangerImpaladAuthorizationManager.java
@@ -288,11 +288,18 @@ public class RangerImpaladAuthorizationManager implements
AuthorizationManager {
privilege.getColumn_name(), accessResult);
Optional<String> uri = getResourceName(RangerImpalaResourceBuilder.URL,
privilege.getUri(), accessResult);
+ Optional<String> storageType = getResourceName(
+ RangerImpalaResourceBuilder.STORAGE_TYPE, privilege.getStorage_type(),
+ accessResult);
+ Optional<String> storageUri = getResourceName(
+ RangerImpalaResourceBuilder.STORAGE_URL, privilege.getStorage_url(),
+ accessResult);
Optional<String> udf = getResourceName(RangerImpalaResourceBuilder.UDF,
ANY,
accessResult);
return new RangerResultRow(type, principal, database.orElse(""),
table.orElse(""),
- column.orElse(""), uri.orElse(""), udf.orElse(""), level, grantOption,
longTime);
+ column.orElse(""), uri.orElse(""), storageType.orElse(""),
storageUri.orElse(""),
+ udf.orElse(""), level, grantOption, longTime);
}
private static List<RangerAccessRequest> buildAccessRequests(TPrivilege
privilege) {
@@ -311,10 +318,14 @@ public class RangerImpaladAuthorizationManager implements
AuthorizationManager {
// DB is used by column and function resources.
resources.add(RangerUtil.createColumnResource(privilege));
resources.add(RangerUtil.createFunctionResource(privilege));
+ } else if (privilege.getStorage_url() != null ||
+ privilege.getStorage_type() != null) {
+ resources.add(RangerUtil.createStorageHandlerUriResource(privilege));
} else {
- // Server is used by column, function, and URI resources.
+ // Server is used by column, function, URI, and storage handler URI
resources.
resources.add(RangerUtil.createColumnResource(privilege));
resources.add(RangerUtil.createUriResource(privilege));
+ resources.add(RangerUtil.createStorageHandlerUriResource(privilege));
resources.add(RangerUtil.createFunctionResource(privilege));
}
@@ -489,20 +500,25 @@ public class RangerImpaladAuthorizationManager implements
AuthorizationManager {
private final String table_;
private final String column_;
private final String uri_;
+ private final String storageType_;
+ private final String storageUri_;
private final String udf_;
private final TPrivilegeLevel privilege_;
private final boolean grantOption_;
private final Long createTime_;
public RangerResultRow(TPrincipalType principalType, String principalName,
- String database, String table, String column, String uri, String udf,
- TPrivilegeLevel privilege, boolean grantOption, Long createTime) {
+ String database, String table, String column, String uri, String
storageType,
+ String storageUri, String udf, TPrivilegeLevel privilege, boolean
grantOption,
+ Long createTime) {
this.principalType_ = principalType;
this.principalName_ = principalName;
this.database_ = database;
this.table_ = table;
this.column_ = column;
this.uri_ = uri;
+ this.storageType_ = storageType;
+ this.storageUri_ = storageUri;
this.udf_ = udf;
this.privilege_ = privilege;
this.grantOption_ = grantOption;
@@ -518,6 +534,8 @@ public class RangerImpaladAuthorizationManager implements
AuthorizationManager {
schema.addToColumns(new TColumn("table", Type.STRING.toThrift()));
schema.addToColumns(new TColumn("column", Type.STRING.toThrift()));
schema.addToColumns(new TColumn("uri", Type.STRING.toThrift()));
+ schema.addToColumns(new TColumn("storage_type", Type.STRING.toThrift()));
+ schema.addToColumns(new TColumn("storage_uri", Type.STRING.toThrift()));
schema.addToColumns(new TColumn("udf", Type.STRING.toThrift()));
schema.addToColumns(new TColumn("privilege", Type.STRING.toThrift()));
schema.addToColumns(new TColumn("grant_option",
Type.BOOLEAN.toThrift()));
@@ -535,6 +553,8 @@ public class RangerImpaladAuthorizationManager implements
AuthorizationManager {
rowBuilder.add(table_);
rowBuilder.add(column_);
rowBuilder.add(uri_);
+ rowBuilder.add(storageType_);
+ rowBuilder.add(storageUri_);
rowBuilder.add(udf_);
rowBuilder.add(privilege_.name().toLowerCase());
rowBuilder.add(grantOption_);
diff --git
a/fe/src/main/java/org/apache/impala/authorization/ranger/RangerUtil.java
b/fe/src/main/java/org/apache/impala/authorization/ranger/RangerUtil.java
index 9abccf0e4..36004a1ac 100644
--- a/fe/src/main/java/org/apache/impala/authorization/ranger/RangerUtil.java
+++ b/fe/src/main/java/org/apache/impala/authorization/ranger/RangerUtil.java
@@ -72,6 +72,18 @@ public class RangerUtil {
return resource;
}
+ public static Map<String, String> createStorageHandlerUriResource(
+ TPrivilege privilege) {
+ Map<String, String> resource = new HashMap<>();
+
+ resource.put(RangerImpalaResourceBuilder.STORAGE_TYPE,
+ getOrAll(privilege.getStorage_type()));
+ resource.put(RangerImpalaResourceBuilder.STORAGE_URL,
+ getOrAll(privilege.getStorage_url()));
+
+ return resource;
+ }
+
private static String getOrAll(String resource) {
return (resource == null) ? "*" : resource;
}
diff --git a/fe/src/main/jflex/sql-scanner.flex
b/fe/src/main/jflex/sql-scanner.flex
index 79786ed41..48eb00d83 100644
--- a/fe/src/main/jflex/sql-scanner.flex
+++ b/fe/src/main/jflex/sql-scanner.flex
@@ -233,6 +233,7 @@ import org.apache.impala.thrift.TReservedWordsVersion;
keywordMap.put("rollup", new Integer(SqlParserSymbols.KW_ROLLUP));
keywordMap.put("row", SqlParserSymbols.KW_ROW);
keywordMap.put("rows", SqlParserSymbols.KW_ROWS);
+ keywordMap.put("rwstorage", SqlParserSymbols.KW_RWSTORAGE);
keywordMap.put("schema", SqlParserSymbols.KW_SCHEMA);
keywordMap.put("schemas", SqlParserSymbols.KW_SCHEMAS);
keywordMap.put("select", SqlParserSymbols.KW_SELECT);
@@ -248,6 +249,7 @@ import org.apache.impala.thrift.TReservedWordsVersion;
keywordMap.put("spec", SqlParserSymbols.KW_SPEC);
keywordMap.put("stats", SqlParserSymbols.KW_STATS);
keywordMap.put("stored", SqlParserSymbols.KW_STORED);
+ keywordMap.put("storagehandler_uri",
SqlParserSymbols.KW_STORAGE_HANDLER_URI);
keywordMap.put("straight_join", SqlParserSymbols.KW_STRAIGHT_JOIN);
keywordMap.put("string", SqlParserSymbols.KW_STRING);
keywordMap.put("struct", SqlParserSymbols.KW_STRUCT);
diff --git
a/fe/src/test/java/org/apache/impala/analysis/AnalyzeAuthStmtsTest.java
b/fe/src/test/java/org/apache/impala/analysis/AnalyzeAuthStmtsTest.java
index 8f3427e0f..727c510ae 100644
--- a/fe/src/test/java/org/apache/impala/analysis/AnalyzeAuthStmtsTest.java
+++ b/fe/src/test/java/org/apache/impala/analysis/AnalyzeAuthStmtsTest.java
@@ -190,6 +190,10 @@ public class AnalyzeAuthStmtsTest extends FrontendTestBase
{
formatArgs));
AnalysisError(String.format("%s ALL ON URI 'xxxx:////abc//123' %s %s",
formatArgs), "No FileSystem for scheme: xxxx");
+ AnalysisError(String.format(
+ "%s ALL ON STORAGEHANDLER_URI 'kudu://localhost/tbl' %s %s",
formatArgs),
+ "Only 'RWSTORAGE' privilege may be applied at storage handler URI
scope " +
+ "in privilege spec.");
AnalysisError(String.format("%s ALL ON DATABASE does_not_exist %s %s",
formatArgs), "Error setting/showing privileges for " +
"database 'does_not_exist'. Verify that the database exists and
that you " +
@@ -215,6 +219,10 @@ public class AnalyzeAuthStmtsTest extends FrontendTestBase
{
AnalysisError(String.format("%s INSERT ON URI 'hdfs:////abc//123' %s
%s",
formatArgs), "Only 'ALL' privilege may be applied at URI scope in
" +
"privilege spec.");
+ AnalysisError(String.format(
+ "%s INSERT ON STORAGEHANDLER_URI 'kudu://localhost/tbl' %s %s",
formatArgs),
+ "Only 'RWSTORAGE' privilege may be applied at storage handler URI
scope " +
+ "in privilege spec.");
// SELECT privilege
AnalyzesOk(String.format("%s SELECT ON TABLE alltypessmall %s %s",
formatArgs),
@@ -229,6 +237,10 @@ public class AnalyzeAuthStmtsTest extends FrontendTestBase
{
AnalysisError(String.format("%s SELECT ON URI 'hdfs:////abc//123' %s
%s",
formatArgs), "Only 'ALL' privilege may be applied at URI scope in
" +
"privilege spec.");
+ AnalysisError(String.format(
+ "%s SELECT ON STORAGEHANDLER_URI 'kudu://localhost/tbl' %s %s",
formatArgs),
+ "Only 'RWSTORAGE' privilege may be applied at storage handler URI
scope " +
+ "in privilege spec.");
// SELECT privileges on columns
AnalyzesOk(String.format("%s SELECT (id, int_col) ON TABLE
functional.alltypes " +
@@ -276,6 +288,10 @@ public class AnalyzeAuthStmtsTest extends FrontendTestBase
{
AnalysisError(String.format(
"%s REFRESH ON URI 'hdfs:////abc//123' %s %s", formatArgs),
"Only 'ALL' privilege may be applied at URI scope in privilege
spec.");
+ AnalysisError(String.format(
+ "%s REFRESH ON STORAGEHANDLER_URI 'kudu://localhost/tbl' %s %s",
formatArgs),
+ "Only 'RWSTORAGE' privilege may be applied at storage handler URI
scope " +
+ "in privilege spec.");
// CREATE privilege
AnalyzesOk(String.format("%s CREATE ON SERVER %s %s", formatArgs));
@@ -288,6 +304,10 @@ public class AnalyzeAuthStmtsTest extends FrontendTestBase
{
AnalysisError(String.format(
"%s CREATE ON URI 'hdfs:////abc//123' %s %s", formatArgs),
"Only 'ALL' privilege may be applied at URI scope in privilege
spec.");
+ AnalysisError(String.format(
+ "%s CREATE ON STORAGEHANDLER_URI 'kudu://localhost/tbl' %s %s",
formatArgs),
+ "Only 'RWSTORAGE' privilege may be applied at storage handler URI
scope " +
+ "in privilege spec.");
// ALTER privilege
AnalyzesOk(String.format("%s ALTER ON SERVER %s %s", formatArgs));
@@ -298,6 +318,10 @@ public class AnalyzeAuthStmtsTest extends FrontendTestBase
{
AnalysisError(String.format(
"%s ALTER ON URI 'hdfs:////abc/123' %s %s", formatArgs),
"Only 'ALL' privilege may be applied at URI scope in privilege
spec.");
+ AnalysisError(String.format(
+ "%s ALTER ON STORAGEHANDLER_URI 'kudu://localhost/tbl' %s %s",
formatArgs),
+ "Only 'RWSTORAGE' privilege may be applied at storage handler URI
scope " +
+ "in privilege spec.");
// DROP privilege
AnalyzesOk(String.format("%s DROP ON SERVER %s %s", formatArgs));
@@ -308,6 +332,30 @@ public class AnalyzeAuthStmtsTest extends FrontendTestBase
{
AnalysisError(String.format(
"%s DROP ON URI 'hdfs:////abc/123' %s %s", formatArgs),
"Only 'ALL' privilege may be applied at URI scope in privilege
spec.");
+ AnalysisError(String.format(
+ "%s DROP ON STORAGEHANDLER_URI 'kudu://localhost/tbl' %s %s",
formatArgs),
+ "Only 'RWSTORAGE' privilege may be applied at storage handler URI
scope " +
+ "in privilege spec.");
+
+ // RWSTORAGE privilege
+ AnalyzesOk(String.format(
+ "%s RWSTORAGE ON STORAGEHANDLER_URI 'kudu://localhost/tbl' %s %s",
+ formatArgs));
+ AnalyzesOk(String.format(
+ "%s RWSTORAGE ON STORAGEHANDLER_URI '*://*' %s %s", formatArgs));
+ AnalyzesOk(String.format(
+ "%s RWSTORAGE ON STORAGEHANDLER_URI 'kudu://*' %s %s",
formatArgs));
+ AnalyzesOk(String.format(
+ "%s RWSTORAGE ON STORAGEHANDLER_URI 'kudu://localhost/*' %s %s",
formatArgs));
+ AnalysisError(String.format(
+ "%s DROP ON STORAGEHANDLER_URI 'abc://localhost/tbl' %s %s",
formatArgs),
+ "The storage type \"abc\" is not supported. " +
+ "A storage handler URI should be in the form of " +
+ "<storage_type>://<hostname>[:<port>]/<path_to_resource>.");
+ AnalysisError(String.format(
+ "%s RWSTORAGE ON STORAGEHANDLER_URI 'kudu://*/*' %s %s",
formatArgs),
+ "A storage handler URI should be in the form of " +
+ "<storage_type>://<hostname>[:<port>]/<path_to_resource>.");
}
AnalysisContext authDisabledCtx = createAuthDisabledAnalysisCtx();
diff --git a/fe/src/test/java/org/apache/impala/analysis/ToSqlTest.java
b/fe/src/test/java/org/apache/impala/analysis/ToSqlTest.java
index 83873b302..865a72d20 100644
--- a/fe/src/test/java/org/apache/impala/analysis/ToSqlTest.java
+++ b/fe/src/test/java/org/apache/impala/analysis/ToSqlTest.java
@@ -1671,6 +1671,7 @@ public class ToSqlTest extends FrontendTestBase {
List<String> principalTypes = Arrays.asList("USER", "ROLE", "GROUP");
String testRole = System.getProperty("user.name");
String testUri = "hdfs://localhost:20500/test-warehouse";
+ String testStorageHandlerUri = "kudu://localhost/tbl";
for (String pt : principalTypes) {
try {
@@ -1746,6 +1747,17 @@ public class ToSqlTest extends FrontendTestBase {
testToSql(ctx, String.format("REVOKE GRANT OPTION FOR ALL ON URI '%s'
FROM %s %s",
testUri, pt, testRole));
+ // Storage handler URI (Only RWSTORAGE is supported)
+ testToSql(ctx, String.format(
+ "GRANT RWSTORAGE ON STORAGEHANDLER_URI '%s' TO %s %s",
+ testStorageHandlerUri, pt, testRole));
+ testToSql(ctx, String.format("GRANT RWSTORAGE ON STORAGEHANDLER_URI
'%s' " +
+ "TO %s %s WITH GRANT OPTION", testStorageHandlerUri, pt,
testRole));
+ testToSql(ctx, String.format("REVOKE RWSTORAGE ON STORAGEHANDLER_URI
'%s' " +
+ "FROM %s %s", testStorageHandlerUri, pt, testRole));
+ testToSql(ctx, String.format("REVOKE GRANT OPTION FOR RWSTORAGE ON " +
+ "STORAGEHANDLER_URI '%s' FROM %s %s", testStorageHandlerUri, pt,
testRole));
+
// Column (Only SELECT is supported)
testToSql(ctx, String.format(
"GRANT SELECT (id) ON TABLE functional.alltypes TO %s %s", pt,
diff --git
a/fe/src/test/java/org/apache/impala/authorization/AuthorizationStmtTest.java
b/fe/src/test/java/org/apache/impala/authorization/AuthorizationStmtTest.java
index b1b27ee2b..af25f0b50 100644
---
a/fe/src/test/java/org/apache/impala/authorization/AuthorizationStmtTest.java
+++
b/fe/src/test/java/org/apache/impala/authorization/AuthorizationStmtTest.java
@@ -1025,7 +1025,11 @@ public class AuthorizationStmtTest extends
AuthorizationTestBase {
@Test
public void testUseDb() throws ImpalaException {
AuthzTest test = authorize("use functional");
- for (TPrivilegeLevel privilege: TPrivilegeLevel.values()) {
+ // We exclude TPrivilegeLevel.RWSTORAGE because we do not ask Ranger
service to grant
+ // the RWSTORAGE privilege on a resource if the resource is not a storage
handler
+ // URI. Refer to
RangerCatalogdAuthorizationManager#createGrantRevokeRequest() for
+ // further details.
+ for (TPrivilegeLevel privilege: allExcept(TPrivilegeLevel.RWSTORAGE)) {
test.ok(onServer(privilege))
.ok(onDatabase("functional", privilege))
.ok(onTable("functional", "alltypes", privilege))
@@ -1213,7 +1217,11 @@ public class AuthorizationStmtTest extends
AuthorizationTestBase {
// Show tables.
AuthzTest test = authorize("show tables in functional");
- for (TPrivilegeLevel privilege: TPrivilegeLevel.values()) {
+ // We exclude TPrivilegeLevel.RWSTORAGE because we do not ask Ranger
service to grant
+ // the RWSTORAGE privilege on a resource if the resource is not a storage
handler
+ // URI. Refer to
RangerCatalogdAuthorizationManager#createGrantRevokeRequest() for
+ // further details.
+ for (TPrivilegeLevel privilege: allExcept(TPrivilegeLevel.RWSTORAGE)) {
test.ok(onServer(privilege))
.ok(onDatabase("functional", privilege))
.ok(onTable("functional", "alltypes", privilege));
@@ -1831,8 +1839,8 @@ public class AuthorizationStmtTest extends
AuthorizationTestBase {
.error(systemDbError(), onServer(TPrivilegeLevel.ALL))
.error(systemDbError(), onServer(TPrivilegeLevel.OWNER));
- // IMPALA-4000: Only users with ALL/OWNER privileges on SERVER may create
external
- // Kudu tables.
+ // Only users with ALL/OWNER privileges on SERVER may create external Kudu
tables
+ // when 'kudu.master_addresses' is specified.
authorize("create external table functional.kudu_tbl stored as kudu " +
"tblproperties ('kudu.master_addresses'='127.0.0.1',
'kudu.table_name'='tbl')")
.ok(onServer(TPrivilegeLevel.ALL))
@@ -1840,10 +1848,59 @@ public class AuthorizationStmtTest extends
AuthorizationTestBase {
.error(createError("functional"))
.error(accessError("server1"), onServer(allExcept(TPrivilegeLevel.ALL,
TPrivilegeLevel.OWNER)))
- .error(accessError("server1"), onDatabase("functional",
TPrivilegeLevel.ALL))
- .error(accessError("server1"), onDatabase("functional",
TPrivilegeLevel.OWNER));
+ .error(accessError("server1"), onDatabase("functional",
TPrivilegeLevel.ALL),
+ onStorageHandlerUri("kudu", "127.0.0.1/tbl",
TPrivilegeLevel.RWSTORAGE))
+ .error(accessError("server1"), onDatabase("functional",
TPrivilegeLevel.OWNER),
+ onStorageHandlerUri("kudu", "127.0.0.1/tbl",
TPrivilegeLevel.RWSTORAGE));
- // IMPALA-4000: ALL/OWNER privileges on SERVER are not required to create
managed
+
+ // ALL/OWNER privileges on SERVER are not required to create external Kudu
tables
+ // when 'kudu.master_addresses' is not specified as long as the RWSTORAGE
privilege
+ // is granted on the storage handler URI.
+ authorize("create external table functional.kudu_tbl stored as kudu " +
+ "tblproperties ('kudu.table_name'='tbl')")
+ .ok(onDatabase("functional", TPrivilegeLevel.ALL),
+ onStorageHandlerUri("kudu", "127.0.0.1/tbl",
TPrivilegeLevel.RWSTORAGE))
+ .ok(onDatabase("functional", TPrivilegeLevel.OWNER),
+ onStorageHandlerUri("kudu", "127.0.0.1/tbl",
TPrivilegeLevel.RWSTORAGE))
+ .ok(onDatabase("functional", TPrivilegeLevel.CREATE),
+ onStorageHandlerUri("kudu", "127.0.0.1/tbl",
TPrivilegeLevel.RWSTORAGE))
+ .error(rwstorageError("kudu://127.0.0.1/tbl"),
+ onDatabase("functional", TPrivilegeLevel.ALL))
+ .error(rwstorageError("kudu://127.0.0.1/tbl"),
+ onDatabase("functional", TPrivilegeLevel.OWNER))
+ .error(rwstorageError("kudu://127.0.0.1/tbl"),
+ onDatabase("functional", TPrivilegeLevel.CREATE))
+ .error(createError("functional"), onDatabase("functional", allExcept(
+ TPrivilegeLevel.ALL, TPrivilegeLevel.OWNER,
TPrivilegeLevel.CREATE)))
+ .error(createError("functional"));
+
+ // Wildcard is supported when a storage handler URI is specified.
+ authorize("create external table functional.kudu_tbl stored as kudu " +
+ "tblproperties ('kudu.table_name'='impala::tpch_kudu.nation')")
+ .ok(onDatabase("functional", TPrivilegeLevel.CREATE),
+ onStorageHandlerUri("*", "*", TPrivilegeLevel.RWSTORAGE))
+ .ok(onDatabase("functional", TPrivilegeLevel.CREATE),
+ onStorageHandlerUri("kudu", "*", TPrivilegeLevel.RWSTORAGE))
+ .ok(onDatabase("functional", TPrivilegeLevel.CREATE),
+ onStorageHandlerUri("kudu", "127.0.0.1/impala::tpch_kudu.*",
+ TPrivilegeLevel.RWSTORAGE));
+
+ // The authorization will fail if the wildcard storage handler URI on
which the
+ // privilege is granted does not cover the storage handler URI of the Kudu
table used
+ // to create the external table whether or not the Kudu table exists.
+ for (String tableName : new String[]{"alltypes", "alltypestiny",
"non_existing"}) {
+ authorize(String.format("create external table functional.kudu_tbl " +
+ "stored as kudu tblproperties " +
+ "('kudu.table_name'='impala::functional_kudu.%s')", tableName))
+ .error(rwstorageError(
+ String.format("kudu://127.0.0.1/impala::functional_kudu.%s",
tableName)),
+ onDatabase("functional", TPrivilegeLevel.CREATE),
+ onStorageHandlerUri("kudu", "127.0.0.1/impala::tpch_kudu.*",
+ TPrivilegeLevel.RWSTORAGE));
+ }
+
+ // ALL/OWNER privileges on SERVER are not required to create managed
// tables.
authorize("create table functional.kudu_tbl (i int, j int, primary key
(i))" +
" partition by hash (i) partitions 9 stored as kudu")
diff --git
a/fe/src/test/java/org/apache/impala/authorization/AuthorizationTestBase.java
b/fe/src/test/java/org/apache/impala/authorization/AuthorizationTestBase.java
index bd65f9b8b..32f237550 100644
---
a/fe/src/test/java/org/apache/impala/authorization/AuthorizationTestBase.java
+++
b/fe/src/test/java/org/apache/impala/authorization/AuthorizationTestBase.java
@@ -491,6 +491,25 @@ public abstract class AuthorizationTestBase extends
FrontendTestBase {
return privileges;
}
+ protected TPrivilege[] onStorageHandlerUri(String storageType, String
storageUri,
+ TPrivilegeLevel... levels) {
+ return onStorageHandlerUri(false, storageType, storageUri, levels);
+ }
+
+ protected TPrivilege[] onStorageHandlerUri(boolean grantOption, String
storageType,
+ String storageUri, TPrivilegeLevel... levels) {
+ TPrivilege[] privileges = new TPrivilege[levels.length];
+ for (int i = 0; i < levels.length; i++) {
+ privileges[i] = new TPrivilege(levels[i],
TPrivilegeScope.STORAGEHANDLER_URI,
+ false);
+ privileges[i].setServer_name(SERVER_NAME);
+ privileges[i].setStorage_type(storageType);
+ privileges[i].setStorage_url(storageUri);
+ privileges[i].setHas_grant_opt(grantOption);
+ }
+ return privileges;
+ }
+
private void authzOk(String stmt, WithPrincipal withPrincipal) throws
ImpalaException {
authzOk(authzCtx_, stmt, withPrincipal, /* expectAnalysisOk */ true);
}
@@ -633,6 +652,10 @@ public abstract class AuthorizationTestBase extends
FrontendTestBase {
return "User '%s' does not have privileges to execute 'CREATE' on: " +
object;
}
+ protected static String rwstorageError(String object) {
+ return "User '%s' does not have privileges to execute 'RWSTORAGE' on: " +
object;
+ }
+
protected static String alterError(String object) {
return "User '%s' does not have privileges to execute 'ALTER' on: " +
object;
}
diff --git
a/testdata/workloads/functional-query/queries/QueryTest/grant_revoke.test
b/testdata/workloads/functional-query/queries/QueryTest/grant_revoke.test
index 191b1bd55..8019b9ab3 100644
--- a/testdata/workloads/functional-query/queries/QueryTest/grant_revoke.test
+++ b/testdata/workloads/functional-query/queries/QueryTest/grant_revoke.test
@@ -85,13 +85,14 @@ STRING
# without a defined resource in Ranger.
show grant role grant_revoke_test_ALL_SERVER on server
---- RESULTS: VERIFY_IS_EQUAL_SORTED
-'ROLE','grant_revoke_test_ALL_SERVER','','','','*','','all',false,regex:.+
-'ROLE','grant_revoke_test_ALL_SERVER','*','','','','*','all',false,regex:.+
-'ROLE','grant_revoke_test_ALL_SERVER','*','*','*','','','all',false,regex:.+
+'ROLE','grant_revoke_test_ALL_SERVER','','','','','*','*','','rwstorage',false,regex:.+
+'ROLE','grant_revoke_test_ALL_SERVER','','','','*','','','','all',false,regex:.+
+'ROLE','grant_revoke_test_ALL_SERVER','*','','','','','','*','all',false,regex:.+
+'ROLE','grant_revoke_test_ALL_SERVER','*','*','*','','','','','all',false,regex:.+
---- LABELS
-principal_type, principal_name, database, table, column, uri, udf, privilege,
grant_option, create_time
+principal_type, principal_name, database, table, column, uri, storage_type,
storage_uri, udf, privilege, grant_option, create_time
---- TYPES
-STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, BOOLEAN, STRING
+STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING,
STRING, BOOLEAN, STRING
====
---- USER
does_not_exist
@@ -315,33 +316,33 @@ STRING, BIGINT, BIGINT, STRING, STRING, STRING, STRING,
STRING, STRING
# without a defined resource in Ranger.
show grant role grant_revoke_test_ALL_URI on uri
'$NAMENODE/test-warehouse/grant_rev_test_tbl2'
---- RESULTS
-'ROLE','grant_revoke_test_ALL_URI','','','','$NAMENODE/test-warehouse/grant_rev_test_tbl2','','all',false,regex:.+
+'ROLE','grant_revoke_test_ALL_URI','','','','$NAMENODE/test-warehouse/grant_rev_test_tbl2','','','','all',false,regex:.+
---- LABELS
-principal_type, principal_name, database, table, column, uri, udf, privilege,
grant_option, create_time
+principal_type, principal_name, database, table, column, uri, storage_type,
storage_uri, udf, privilege, grant_option, create_time
---- TYPES
-STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, BOOLEAN, STRING
+STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING,
STRING, BOOLEAN, STRING
====
---- QUERY
# We have to specify the resource for SHOW GRANT since SHOW GRANT is not
supported
# without a defined resource in Ranger.
show grant role grant_revoke_test_ALL_URI on uri
'$NAMENODE/test-warehouse/GRANT_REV_TEST_TBL3'
---- RESULTS
-'ROLE','grant_revoke_test_ALL_URI','','','','$NAMENODE/test-warehouse/GRANT_REV_TEST_TBL3','','all',false,regex:.+
+'ROLE','grant_revoke_test_ALL_URI','','','','$NAMENODE/test-warehouse/GRANT_REV_TEST_TBL3','','','','all',false,regex:.+
---- LABELS
-principal_type, principal_name, database, table, column, uri, udf, privilege,
grant_option, create_time
+principal_type, principal_name, database, table, column, uri, storage_type,
storage_uri, udf, privilege, grant_option, create_time
---- TYPES
-STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, BOOLEAN, STRING
+STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING,
STRING, BOOLEAN, STRING
====
---- QUERY
# We have to specify the resource for SHOW GRANT since SHOW GRANT is not
supported
# without a defined resource in Ranger.
show grant role grant_revoke_test_ALL_URI on uri
'$NAMENODE/test-warehouse/grant_rev_test_prt'
---- RESULTS
-'ROLE','grant_revoke_test_ALL_URI','','','','$NAMENODE/test-warehouse/grant_rev_test_prt','','all',false,regex:.+
+'ROLE','grant_revoke_test_ALL_URI','','','','$NAMENODE/test-warehouse/grant_rev_test_prt','','','','all',false,regex:.+
---- LABELS
-principal_type, principal_name, database, table, column, uri, udf, privilege,
grant_option, create_time
+principal_type, principal_name, database, table, column, uri, storage_type,
storage_uri, udf, privilege, grant_option, create_time
---- TYPES
-STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, BOOLEAN, STRING
+STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING,
STRING, BOOLEAN, STRING
====
---- QUERY
# Does not result in an AuthorizationException since '$GROUP_NAME' is still
assigned the
@@ -444,12 +445,12 @@ GRANT INSERT ON TABLE grant_rev_db.test_tbl1 TO
grant_revoke_test_SELECT_INSERT_
---- QUERY
show grant role grant_revoke_test_SELECT_INSERT_TEST_TBL on table
grant_rev_db.test_tbl1
---- RESULTS: VERIFY_IS_EQUAL_SORTED
-'ROLE','grant_revoke_test_SELECT_INSERT_TEST_TBL','grant_rev_db','test_tbl1','*','','','insert',false,regex:.+
-'ROLE','grant_revoke_test_SELECT_INSERT_TEST_TBL','grant_rev_db','test_tbl1','*','','','select',false,regex:.+
+'ROLE','grant_revoke_test_SELECT_INSERT_TEST_TBL','grant_rev_db','test_tbl1','*','','','','','insert',false,regex:.+
+'ROLE','grant_revoke_test_SELECT_INSERT_TEST_TBL','grant_rev_db','test_tbl1','*','','','','','select',false,regex:.+
---- LABELS
-principal_type, principal_name, database, table, column, uri, udf, privilege,
grant_option, create_time
+principal_type, principal_name, database, table, column, uri, storage_type,
storage_uri, udf, privilege, grant_option, create_time
---- TYPES
-STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, BOOLEAN, STRING
+STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING,
STRING, BOOLEAN, STRING
====
---- QUERY
insert overwrite grant_rev_db.test_tbl1 select 1
@@ -564,12 +565,12 @@ non_owner
# without a defined resource in Ranger.
show grant role grant_revoke_test_NON_OWNER on database functional
---- RESULTS: VERIFY_IS_EQUAL_SORTED
-'ROLE','grant_revoke_test_NON_OWNER','functional','','','','*','all',true,regex:.+
-'ROLE','grant_revoke_test_NON_OWNER','functional','*','*','','','all',true,regex:.+
+'ROLE','grant_revoke_test_NON_OWNER','functional','','','','','','*','all',true,regex:.+
+'ROLE','grant_revoke_test_NON_OWNER','functional','*','*','','','','','all',true,regex:.+
---- LABELS
-principal_type, principal_name, database, table, column, uri, udf, privilege,
grant_option, create_time
+principal_type, principal_name, database, table, column, uri, storage_type,
storage_uri, udf, privilege, grant_option, create_time
---- TYPES
-STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, BOOLEAN, STRING
+STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING,
STRING, BOOLEAN, STRING
====
---- USER
non_owner
@@ -579,11 +580,11 @@ non_owner
# Note that the column of 'grant_option' is false for this privilege.
show grant role grant_revoke_test_NON_OWNER on table functional.alltypes
---- RESULTS: VERIFY_IS_EQUAL_SORTED
-'ROLE','grant_revoke_test_NON_OWNER','functional','alltypes','*','','','all',false,regex:.+
+'ROLE','grant_revoke_test_NON_OWNER','functional','alltypes','*','','','','','all',false,regex:.+
---- LABELS
-principal_type, principal_name, database, table, column, uri, udf, privilege,
grant_option, create_time
+principal_type, principal_name, database, table, column, uri, storage_type,
storage_uri, udf, privilege, grant_option, create_time
---- TYPES
-STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, BOOLEAN, STRING
+STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING,
STRING, BOOLEAN, STRING
====
---- USER
admin
@@ -648,12 +649,12 @@ non_owner
# Also, privilege still exists, but grant option is set to false.
show grant role grant_revoke_test_NON_OWNER on database functional
---- RESULTS: VERIFY_IS_EQUAL_SORTED
-'ROLE','grant_revoke_test_NON_OWNER','functional','','','','*','all',false,regex:.+
-'ROLE','grant_revoke_test_NON_OWNER','functional','*','*','','','all',false,regex:.+
+'ROLE','grant_revoke_test_NON_OWNER','functional','','','','','','*','all',false,regex:.+
+'ROLE','grant_revoke_test_NON_OWNER','functional','*','*','','','','','all',false,regex:.+
---- LABELS
-principal_type, principal_name, database, table, column, uri, udf, privilege,
grant_option, create_time
+principal_type, principal_name, database, table, column, uri, storage_type,
storage_uri, udf, privilege, grant_option, create_time
---- TYPES
-STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, BOOLEAN, STRING
+STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING,
STRING, BOOLEAN, STRING
====
---- USER
admin
@@ -699,36 +700,36 @@ GRANT SELECT (a, b, x) ON TABLE grant_rev_db.test_tbl3 TO
grant_revoke_test_ALL_
# resource will be shown as well.
show grant role grant_revoke_test_ALL_SERVER on column grant_rev_db.test_tbl3.a
---- RESULTS: VERIFY_IS_EQUAL_SORTED
-'ROLE','grant_revoke_test_ALL_SERVER','*','*','*','','','all',false,regex:.+
-'ROLE','grant_revoke_test_ALL_SERVER','grant_rev_db','test_tbl3','a','','','select',false,regex:.+
+'ROLE','grant_revoke_test_ALL_SERVER','*','*','*','','','','','all',false,regex:.+
+'ROLE','grant_revoke_test_ALL_SERVER','grant_rev_db','test_tbl3','a','','','','','select',false,regex:.+
---- LABELS
-principal_type, principal_name, database, table, column, uri, udf, privilege,
grant_option, create_time
+principal_type, principal_name, database, table, column, uri, storage_type,
storage_uri, udf, privilege, grant_option, create_time
---- TYPES
-STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, BOOLEAN, STRING
+STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING,
STRING, BOOLEAN, STRING
====
---- QUERY
# We have to specify the resource for SHOW GRANT since SHOW GRANT is not
supported
# without a defined resource in Ranger.
show grant role grant_revoke_test_ALL_SERVER on column grant_rev_db.test_tbl3.b
---- RESULTS: VERIFY_IS_EQUAL_SORTED
-'ROLE','grant_revoke_test_ALL_SERVER','*','*','*','','','all',false,regex:.+
-'ROLE','grant_revoke_test_ALL_SERVER','grant_rev_db','test_tbl3','b','','','select',false,regex:.+
+'ROLE','grant_revoke_test_ALL_SERVER','*','*','*','','','','','all',false,regex:.+
+'ROLE','grant_revoke_test_ALL_SERVER','grant_rev_db','test_tbl3','b','','','','','select',false,regex:.+
---- LABELS
-principal_type, principal_name, database, table, column, uri, udf, privilege,
grant_option, create_time
+principal_type, principal_name, database, table, column, uri, storage_type,
storage_uri, udf, privilege, grant_option, create_time
---- TYPES
-STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, BOOLEAN, STRING
+STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING,
STRING, BOOLEAN, STRING
====
---- QUERY
# We have to specify the resource for SHOW GRANT since SHOW GRANT is not
supported
# without a defined resource in Ranger.
show grant role grant_revoke_test_ALL_SERVER on column grant_rev_db.test_tbl3.x
---- RESULTS: VERIFY_IS_EQUAL_SORTED
-'ROLE','grant_revoke_test_ALL_SERVER','*','*','*','','','all',false,regex:.+
-'ROLE','grant_revoke_test_ALL_SERVER','grant_rev_db','test_tbl3','x','','','select',false,regex:.+
+'ROLE','grant_revoke_test_ALL_SERVER','*','*','*','','','','','all',false,regex:.+
+'ROLE','grant_revoke_test_ALL_SERVER','grant_rev_db','test_tbl3','x','','','','','select',false,regex:.+
---- LABELS
-principal_type, principal_name, database, table, column, uri, udf, privilege,
grant_option, create_time
+principal_type, principal_name, database, table, column, uri, storage_type,
storage_uri, udf, privilege, grant_option, create_time
---- TYPES
-STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, BOOLEAN, STRING
+STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING,
STRING, BOOLEAN, STRING
====
---- USER
admin
@@ -744,36 +745,36 @@ GRANT SELECT (c, d, y) ON TABLE grant_rev_db.test_tbl3 TO
grant_revoke_test_ALL_
# without a defined resource in Ranger.
show grant role grant_revoke_test_ALL_SERVER on column grant_rev_db.test_tbl3.c
---- RESULTS: VERIFY_IS_EQUAL_SORTED
-'ROLE','grant_revoke_test_ALL_SERVER','*','*','*','','','all',false,regex:.+
-'ROLE','grant_revoke_test_ALL_SERVER','grant_rev_db','test_tbl3','c','','','select',false,regex:.+
+'ROLE','grant_revoke_test_ALL_SERVER','*','*','*','','','','','all',false,regex:.+
+'ROLE','grant_revoke_test_ALL_SERVER','grant_rev_db','test_tbl3','c','','','','','select',false,regex:.+
---- LABELS
-principal_type, principal_name, database, table, column, uri, udf, privilege,
grant_option, create_time
+principal_type, principal_name, database, table, column, uri, storage_type,
storage_uri, udf, privilege, grant_option, create_time
---- TYPES
-STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, BOOLEAN, STRING
+STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING,
STRING, BOOLEAN, STRING
====
---- QUERY
# We have to specify the resource for SHOW GRANT since SHOW GRANT is not
supported
# without a defined resource in Ranger.
show grant role grant_revoke_test_ALL_SERVER on column grant_rev_db.test_tbl3.d
---- RESULTS: VERIFY_IS_EQUAL_SORTED
-'ROLE','grant_revoke_test_ALL_SERVER','*','*','*','','','all',false,regex:.+
-'ROLE','grant_revoke_test_ALL_SERVER','grant_rev_db','test_tbl3','d','','','select',false,regex:.+
+'ROLE','grant_revoke_test_ALL_SERVER','*','*','*','','','','','all',false,regex:.+
+'ROLE','grant_revoke_test_ALL_SERVER','grant_rev_db','test_tbl3','d','','','','','select',false,regex:.+
---- LABELS
-principal_type, principal_name, database, table, column, uri, udf, privilege,
grant_option, create_time
+principal_type, principal_name, database, table, column, uri, storage_type,
storage_uri, udf, privilege, grant_option, create_time
---- TYPES
-STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, BOOLEAN, STRING
+STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING,
STRING, BOOLEAN, STRING
====
---- QUERY
# We have to specify the resource for SHOW GRANT since SHOW GRANT is not
supported
# without a defined resource in Ranger.
show grant role grant_revoke_test_ALL_SERVER on column grant_rev_db.test_tbl3.y
---- RESULTS: VERIFY_IS_EQUAL_SORTED
-'ROLE','grant_revoke_test_ALL_SERVER','*','*','*','','','all',false,regex:.+
-'ROLE','grant_revoke_test_ALL_SERVER','grant_rev_db','test_tbl3','y','','','select',false,regex:.+
+'ROLE','grant_revoke_test_ALL_SERVER','*','*','*','','','','','all',false,regex:.+
+'ROLE','grant_revoke_test_ALL_SERVER','grant_rev_db','test_tbl3','y','','','','','select',false,regex:.+
---- LABELS
-principal_type, principal_name, database, table, column, uri, udf, privilege,
grant_option, create_time
+principal_type, principal_name, database, table, column, uri, storage_type,
storage_uri, udf, privilege, grant_option, create_time
---- TYPES
-STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, BOOLEAN, STRING
+STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING,
STRING, BOOLEAN, STRING
====
---- USER
admin
@@ -788,12 +789,12 @@ GRANT SELECT (a, a, e, x) ON TABLE grant_rev_db.test_tbl3
TO grant_revoke_test_A
# Verify that the privilege on 'grant_rev_db.test_tbl3.e' is indeed granted.
show grant role grant_revoke_test_ALL_SERVER on column grant_rev_db.test_tbl3.e
---- RESULTS: VERIFY_IS_EQUAL_SORTED
-'ROLE','grant_revoke_test_ALL_SERVER','*','*','*','','','all',false,regex:.+
-'ROLE','grant_revoke_test_ALL_SERVER','grant_rev_db','test_tbl3','e','','','select',false,regex:.+
+'ROLE','grant_revoke_test_ALL_SERVER','*','*','*','','','','','all',false,regex:.+
+'ROLE','grant_revoke_test_ALL_SERVER','grant_rev_db','test_tbl3','e','','','','','select',false,regex:.+
---- LABELS
-principal_type, principal_name, database, table, column, uri, udf, privilege,
grant_option, create_time
+principal_type, principal_name, database, table, column, uri, storage_type,
storage_uri, udf, privilege, grant_option, create_time
---- TYPES
-STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, BOOLEAN, STRING
+STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING,
STRING, BOOLEAN, STRING
====
---- USER
admin
@@ -809,33 +810,33 @@ REVOKE SELECT (a, b, b, y) ON TABLE
grant_rev_db.test_tbl3 FROM grant_revoke_tes
# without a defined resource in Ranger.
show grant role grant_revoke_test_ALL_SERVER on column grant_rev_db.test_tbl3.a
---- RESULTS: VERIFY_IS_EQUAL_SORTED
-'ROLE','grant_revoke_test_ALL_SERVER','*','*','*','','','all',false,regex:.+
+'ROLE','grant_revoke_test_ALL_SERVER','*','*','*','','','','','all',false,regex:.+
---- LABELS
-principal_type, principal_name, database, table, column, uri, udf, privilege,
grant_option, create_time
+principal_type, principal_name, database, table, column, uri, storage_type,
storage_uri, udf, privilege, grant_option, create_time
---- TYPES
-STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, BOOLEAN, STRING
+STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING,
STRING, BOOLEAN, STRING
====
---- QUERY
# We have to specify the resource for SHOW GRANT since SHOW GRANT is not
supported
# without a defined resource in Ranger.
show grant role grant_revoke_test_ALL_SERVER on column grant_rev_db.test_tbl3.b
---- RESULTS: VERIFY_IS_EQUAL_SORTED
-'ROLE','grant_revoke_test_ALL_SERVER','*','*','*','','','all',false,regex:.+
+'ROLE','grant_revoke_test_ALL_SERVER','*','*','*','','','','','all',false,regex:.+
---- LABELS
-principal_type, principal_name, database, table, column, uri, udf, privilege,
grant_option, create_time
+principal_type, principal_name, database, table, column, uri, storage_type,
storage_uri, udf, privilege, grant_option, create_time
---- TYPES
-STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, BOOLEAN, STRING
+STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING,
STRING, BOOLEAN, STRING
====
---- QUERY
# We have to specify the resource for SHOW GRANT since SHOW GRANT is not
supported
# without a defined resource in Ranger.
show grant role grant_revoke_test_ALL_SERVER on column grant_rev_db.test_tbl3.y
---- RESULTS: VERIFY_IS_EQUAL_SORTED
-'ROLE','grant_revoke_test_ALL_SERVER','*','*','*','','','all',false,regex:.+
+'ROLE','grant_revoke_test_ALL_SERVER','*','*','*','','','','','all',false,regex:.+
---- LABELS
-principal_type, principal_name, database, table, column, uri, udf, privilege,
grant_option, create_time
+principal_type, principal_name, database, table, column, uri, storage_type,
storage_uri, udf, privilege, grant_option, create_time
---- TYPES
-STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, BOOLEAN, STRING
+STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING,
STRING, BOOLEAN, STRING
====
---- USER
admin
@@ -851,33 +852,33 @@ REVOKE SELECT (a, b, c, x) ON TABLE
grant_rev_db.test_tbl3 FROM grant_revoke_tes
# without a defined resource in Ranger.
show grant role grant_revoke_test_ALL_SERVER on column grant_rev_db.test_tbl3.b
---- RESULTS: VERIFY_IS_EQUAL_SORTED
-'ROLE','grant_revoke_test_ALL_SERVER','*','*','*','','','all',false,regex:.+
+'ROLE','grant_revoke_test_ALL_SERVER','*','*','*','','','','','all',false,regex:.+
---- LABELS
-principal_type, principal_name, database, table, column, uri, udf, privilege,
grant_option, create_time
+principal_type, principal_name, database, table, column, uri, storage_type,
storage_uri, udf, privilege, grant_option, create_time
---- TYPES
-STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, BOOLEAN, STRING
+STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING,
STRING, BOOLEAN, STRING
====
---- QUERY
# We have to specify the resource for SHOW GRANT since SHOW GRANT is not
supported
# without a defined resource in Ranger.
show grant role grant_revoke_test_ALL_SERVER on column grant_rev_db.test_tbl3.c
---- RESULTS: VERIFY_IS_EQUAL_SORTED
-'ROLE','grant_revoke_test_ALL_SERVER','*','*','*','','','all',false,regex:.+
+'ROLE','grant_revoke_test_ALL_SERVER','*','*','*','','','','','all',false,regex:.+
---- LABELS
-principal_type, principal_name, database, table, column, uri, udf, privilege,
grant_option, create_time
+principal_type, principal_name, database, table, column, uri, storage_type,
storage_uri, udf, privilege, grant_option, create_time
---- TYPES
-STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, BOOLEAN, STRING
+STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING,
STRING, BOOLEAN, STRING
====
---- QUERY
# We have to specify the resource for SHOW GRANT since SHOW GRANT is not
supported
# without a defined resource in Ranger.
show grant role grant_revoke_test_ALL_SERVER on column grant_rev_db.test_tbl3.x
---- RESULTS: VERIFY_IS_EQUAL_SORTED
-'ROLE','grant_revoke_test_ALL_SERVER','*','*','*','','','all',false,regex:.+
+'ROLE','grant_revoke_test_ALL_SERVER','*','*','*','','','','','all',false,regex:.+
---- LABELS
-principal_type, principal_name, database, table, column, uri, udf, privilege,
grant_option, create_time
+principal_type, principal_name, database, table, column, uri, storage_type,
storage_uri, udf, privilege, grant_option, create_time
---- TYPES
-STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, BOOLEAN, STRING
+STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING,
STRING, BOOLEAN, STRING
====
---- USER
admin
@@ -893,22 +894,22 @@ REVOKE SELECT (a, b, c, d, e) ON TABLE
grant_rev_db.test_tbl3 FROM grant_revoke_
# without a defined resource in Ranger.
show grant role grant_revoke_test_ALL_SERVER on column grant_rev_db.test_tbl3.d
---- RESULTS: VERIFY_IS_EQUAL_SORTED
-'ROLE','grant_revoke_test_ALL_SERVER','*','*','*','','','all',false,regex:.+
+'ROLE','grant_revoke_test_ALL_SERVER','*','*','*','','','','','all',false,regex:.+
---- LABELS
-principal_type, principal_name, database, table, column, uri, udf, privilege,
grant_option, create_time
+principal_type, principal_name, database, table, column, uri, storage_type,
storage_uri, udf, privilege, grant_option, create_time
---- TYPES
-STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, BOOLEAN, STRING
+STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING,
STRING, BOOLEAN, STRING
====
---- QUERY
# We have to specify the resource for SHOW GRANT since SHOW GRANT is not
supported
# without a defined resource in Ranger.
show grant role grant_revoke_test_ALL_SERVER on column grant_rev_db.test_tbl3.e
---- RESULTS: VERIFY_IS_EQUAL_SORTED
-'ROLE','grant_revoke_test_ALL_SERVER','*','*','*','','','all',false,regex:.+
+'ROLE','grant_revoke_test_ALL_SERVER','*','*','*','','','','','all',false,regex:.+
---- LABELS
-principal_type, principal_name, database, table, column, uri, udf, privilege,
grant_option, create_time
+principal_type, principal_name, database, table, column, uri, storage_type,
storage_uri, udf, privilege, grant_option, create_time
---- TYPES
-STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, BOOLEAN, STRING
+STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING,
STRING, BOOLEAN, STRING
====
---- USER
admin
@@ -929,11 +930,11 @@ non_owner
# 'grant_revoke_test_NON_OWNER'.
show grant role grant_revoke_test_NON_OWNER on table grant_rev_db.test_tbl3
---- RESULTS: VERIFY_IS_EQUAL_SORTED
-'ROLE','grant_revoke_test_NON_OWNER','grant_rev_db','test_tbl3','*','','','select',false,regex:.+
+'ROLE','grant_revoke_test_NON_OWNER','grant_rev_db','test_tbl3','*','','','','','select',false,regex:.+
---- LABELS
-principal_type, principal_name, database, table, column, uri, udf, privilege,
grant_option, create_time
+principal_type, principal_name, database, table, column, uri, storage_type,
storage_uri, udf, privilege, grant_option, create_time
---- TYPES
-STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, BOOLEAN, STRING
+STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING,
STRING, BOOLEAN, STRING
====
---- USER
non_owner
@@ -975,11 +976,11 @@ non_owner
# investigate whether this is the expected behavior after IMPALA-8587.
show grant role grant_revoke_test_NON_OWNER on column grant_rev_db.test_tbl3.a
---- RESULTS: VERIFY_IS_EQUAL_SORTED
-'ROLE','grant_revoke_test_NON_OWNER','grant_rev_db','test_tbl3','a','','','select',false,regex:.+
+'ROLE','grant_revoke_test_NON_OWNER','grant_rev_db','test_tbl3','a','','','','','select',false,regex:.+
---- LABELS
-principal_type, principal_name, database, table, column, uri, udf, privilege,
grant_option, create_time
+principal_type, principal_name, database, table, column, uri, storage_type,
storage_uri, udf, privilege, grant_option, create_time
---- TYPES
-STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, BOOLEAN, STRING
+STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING,
STRING, BOOLEAN, STRING
====
---- USER
admin
@@ -995,36 +996,36 @@ GRANT SELECT (a, c, e) ON TABLE grant_rev_db.test_tbl3 TO
grant_revoke_test_ALL_
# without a defined resource in Ranger.
show grant role grant_revoke_test_ALL_SERVER on column grant_rev_db.test_tbl3.a
---- RESULTS: VERIFY_IS_EQUAL_SORTED
-'ROLE','grant_revoke_test_ALL_SERVER','*','*','*','','','all',false,regex:.+
-'ROLE','grant_revoke_test_ALL_SERVER','grant_rev_db','test_tbl3','a','','','select',true,regex:.+
+'ROLE','grant_revoke_test_ALL_SERVER','*','*','*','','','','','all',false,regex:.+
+'ROLE','grant_revoke_test_ALL_SERVER','grant_rev_db','test_tbl3','a','','','','','select',true,regex:.+
---- LABELS
-principal_type, principal_name, database, table, column, uri, udf, privilege,
grant_option, create_time
+principal_type, principal_name, database, table, column, uri, storage_type,
storage_uri, udf, privilege, grant_option, create_time
---- TYPES
-STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, BOOLEAN, STRING
+STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING,
STRING, BOOLEAN, STRING
====
---- QUERY
# We have to specify the resource for SHOW GRANT since SHOW GRANT is not
supported
# without a defined resource in Ranger.
show grant role grant_revoke_test_ALL_SERVER on column grant_rev_db.test_tbl3.c
---- RESULTS: VERIFY_IS_EQUAL_SORTED
-'ROLE','grant_revoke_test_ALL_SERVER','*','*','*','','','all',false,regex:.+
-'ROLE','grant_revoke_test_ALL_SERVER','grant_rev_db','test_tbl3','c','','','select',true,regex:.+
+'ROLE','grant_revoke_test_ALL_SERVER','*','*','*','','','','','all',false,regex:.+
+'ROLE','grant_revoke_test_ALL_SERVER','grant_rev_db','test_tbl3','c','','','','','select',true,regex:.+
---- LABELS
-principal_type, principal_name, database, table, column, uri, udf, privilege,
grant_option, create_time
+principal_type, principal_name, database, table, column, uri, storage_type,
storage_uri, udf, privilege, grant_option, create_time
---- TYPES
-STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, BOOLEAN, STRING
+STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING,
STRING, BOOLEAN, STRING
====
---- QUERY
# We have to specify the resource for SHOW GRANT since SHOW GRANT is not
supported
# without a defined resource in Ranger.
show grant role grant_revoke_test_ALL_SERVER on column grant_rev_db.test_tbl3.e
---- RESULTS: VERIFY_IS_EQUAL_SORTED
-'ROLE','grant_revoke_test_ALL_SERVER','*','*','*','','','all',false,regex:.+
-'ROLE','grant_revoke_test_ALL_SERVER','grant_rev_db','test_tbl3','e','','','select',true,regex:.+
+'ROLE','grant_revoke_test_ALL_SERVER','*','*','*','','','','','all',false,regex:.+
+'ROLE','grant_revoke_test_ALL_SERVER','grant_rev_db','test_tbl3','e','','','','','select',true,regex:.+
---- LABELS
-principal_type, principal_name, database, table, column, uri, udf, privilege,
grant_option, create_time
+principal_type, principal_name, database, table, column, uri, storage_type,
storage_uri, udf, privilege, grant_option, create_time
---- TYPES
-STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, BOOLEAN, STRING
+STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING,
STRING, BOOLEAN, STRING
====
---- USER
admin
@@ -1040,24 +1041,24 @@ REVOKE GRANT OPTION FOR SELECT (a, c) ON TABLE
grant_rev_db.test_tbl3 FROM grant
# without a defined resource in Ranger.
show grant role grant_revoke_test_ALL_SERVER on column grant_rev_db.test_tbl3.a
---- RESULTS: VERIFY_IS_EQUAL_SORTED
-'ROLE','grant_revoke_test_ALL_SERVER','*','*','*','','','all',false,regex:.+
-'ROLE','grant_revoke_test_ALL_SERVER','grant_rev_db','test_tbl3','a','','','select',false,regex:.+
+'ROLE','grant_revoke_test_ALL_SERVER','*','*','*','','','','','all',false,regex:.+
+'ROLE','grant_revoke_test_ALL_SERVER','grant_rev_db','test_tbl3','a','','','','','select',false,regex:.+
---- LABELS
-principal_type, principal_name, database, table, column, uri, udf, privilege,
grant_option, create_time
+principal_type, principal_name, database, table, column, uri, storage_type,
storage_uri, udf, privilege, grant_option, create_time
---- TYPES
-STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, BOOLEAN, STRING
+STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING,
STRING, BOOLEAN, STRING
====
---- QUERY
# We have to specify the resource for SHOW GRANT since SHOW GRANT is not
supported
# without a defined resource in Ranger.
show grant role grant_revoke_test_ALL_SERVER on column grant_rev_db.test_tbl3.c
---- RESULTS: VERIFY_IS_EQUAL_SORTED
-'ROLE','grant_revoke_test_ALL_SERVER','*','*','*','','','all',false,regex:.+
-'ROLE','grant_revoke_test_ALL_SERVER','grant_rev_db','test_tbl3','c','','','select',false,regex:.+
+'ROLE','grant_revoke_test_ALL_SERVER','*','*','*','','','','','all',false,regex:.+
+'ROLE','grant_revoke_test_ALL_SERVER','grant_rev_db','test_tbl3','c','','','','','select',false,regex:.+
---- LABELS
-principal_type, principal_name, database, table, column, uri, udf, privilege,
grant_option, create_time
+principal_type, principal_name, database, table, column, uri, storage_type,
storage_uri, udf, privilege, grant_option, create_time
---- TYPES
-STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, BOOLEAN, STRING
+STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING,
STRING, BOOLEAN, STRING
====
---- USER
admin
@@ -1128,13 +1129,14 @@ does not have privileges to execute 'CREATE' on:
grant_rev_db
# without a defined resource in Ranger.
show grant role grant_revoke_test_ALL_SERVER1 on server
---- RESULTS: VERIFY_IS_EQUAL_SORTED
-'ROLE','grant_revoke_test_ALL_SERVER1','','','','*','','all',false,regex:.+
-'ROLE','grant_revoke_test_ALL_SERVER1','*','','','','*','all',false,regex:.+
-'ROLE','grant_revoke_test_ALL_SERVER1','*','*','*','','','all',false,regex:.+
+'ROLE','grant_revoke_test_ALL_SERVER1','','','','','*','*','','rwstorage',false,regex:.+
+'ROLE','grant_revoke_test_ALL_SERVER1','','','','*','','','','all',false,regex:.+
+'ROLE','grant_revoke_test_ALL_SERVER1','*','','','','','','*','all',false,regex:.+
+'ROLE','grant_revoke_test_ALL_SERVER1','*','*','*','','','','','all',false,regex:.+
---- LABELS
-principal_type, principal_name, database, table, column, uri, udf, privilege,
grant_option, create_time
+principal_type, principal_name, database, table, column, uri, storage_type,
storage_uri, udf, privilege, grant_option, create_time
---- TYPES
-STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, BOOLEAN, STRING
+STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING,
STRING, BOOLEAN, STRING
====
---- USER
admin
@@ -1148,9 +1150,9 @@ revoke all on server server1 from
grant_revoke_test_ALL_SERVER1
show grant role grant_revoke_test_ALL_SERVER1 on server
---- RESULTS: VERIFY_IS_EQUAL_SORTED
---- LABELS
-principal_type, principal_name, database, table, column, uri, udf, privilege,
grant_option, create_time
+principal_type, principal_name, database, table, column, uri, storage_type,
storage_uri, udf, privilege, grant_option, create_time
---- TYPES
-STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, BOOLEAN, STRING
+STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING,
STRING, BOOLEAN, STRING
====
---- USER
admin
@@ -1194,9 +1196,9 @@ non_owner
show grant role grant_revoke_test_COLUMN_PRIV on table grant_rev_db.test_tbl4
---- RESULTS
---- LABELS
-principal_type, principal_name, database, table, column, uri, udf, privilege,
grant_option, create_time
+principal_type, principal_name, database, table, column, uri, storage_type,
storage_uri, udf, privilege, grant_option, create_time
---- TYPES
-STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, BOOLEAN, STRING
+STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING,
STRING, BOOLEAN, STRING
====
---- USER
non_owner
@@ -1218,11 +1220,11 @@ non_owner
---- QUERY
show grant role grant_revoke_test_COLUMN_PRIV on column
grant_rev_db.test_tbl4.col1
---- RESULTS
-'ROLE','grant_revoke_test_COLUMN_PRIV','grant_rev_db','test_tbl4','col1','','','select',false,regex:.+
+'ROLE','grant_revoke_test_COLUMN_PRIV','grant_rev_db','test_tbl4','col1','','','','','select',false,regex:.+
---- LABELS
-principal_type, principal_name, database, table, column, uri, udf, privilege,
grant_option, create_time
+principal_type, principal_name, database, table, column, uri, storage_type,
storage_uri, udf, privilege, grant_option, create_time
---- TYPES
-STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, BOOLEAN, STRING
+STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING, STRING,
STRING, BOOLEAN, STRING
====
---- USER
non_owner
@@ -1272,4 +1274,4 @@ revoke role grant_revoke_test_COLUMN_PRIV from group
`$GROUP_NAME`
# assigned any role afterwards.
show current roles
---- RESULTS
-====
+====
\ No newline at end of file
diff --git a/tests/authorization/test_ranger.py
b/tests/authorization/test_ranger.py
index 41630efaf..44f3b1b09 100644
--- a/tests/authorization/test_ranger.py
+++ b/tests/authorization/test_ranger.py
@@ -105,8 +105,8 @@ class TestRanger(CustomClusterTestSuite):
result = self.execute_query("show grant {0} {1} on database {2}"
.format(kw, ident, unique_database))
TestRanger._check_privileges(result, [
- [kw, ident, unique_database, "", "", "", "*", "select", "false"],
- [kw, ident, unique_database, "*", "*", "", "", "select",
"false"]])
+ [kw, ident, unique_database, "", "", "", "", "", "*", "select",
"false"],
+ [kw, ident, unique_database, "*", "*", "", "", "", "", "select",
"false"]])
self.execute_query_expect_success(admin_client,
"revoke select on database {0}
from {1} "
"{2}".format(unique_database, kw,
ident),
@@ -152,10 +152,10 @@ class TestRanger(CustomClusterTestSuite):
result = self.execute_query("show grant user {0} on database {1}"
.format(user1, unique_database))
TestRanger._check_privileges(result, [
- ["USER", user1, unique_database, "", "", "", "*", "insert", "true"],
- ["USER", user1, unique_database, "", "", "", "*", "select", "true"],
- ["USER", user1, unique_database, "*", "*", "", "", "insert", "true"],
- ["USER", user1, unique_database, "*", "*", "", "", "select",
"true"]])
+ ["USER", user1, unique_database, "", "", "", "", "", "*", "insert",
"true"],
+ ["USER", user1, unique_database, "", "", "", "", "", "*", "select",
"true"],
+ ["USER", user1, unique_database, "*", "*", "", "", "", "", "insert",
"true"],
+ ["USER", user1, unique_database, "*", "*", "", "", "", "", "select",
"true"]])
# Revoke select privilege and check grant option is still present
self.execute_query_expect_success(admin_client,
@@ -168,8 +168,8 @@ class TestRanger(CustomClusterTestSuite):
# current limitation of Ranger since privileges on the same resource
share the same
# delegateAdmin field in the corresponding RangerPolicyItem.
TestRanger._check_privileges(result, [
- ["USER", user1, unique_database, "", "", "", "*", "insert", "false"],
- ["USER", user1, unique_database, "*", "*", "", "", "insert",
"false"]])
+ ["USER", user1, unique_database, "", "", "", "", "", "*", "insert",
"false"],
+ ["USER", user1, unique_database, "*", "*", "", "", "", "", "insert",
"false"]])
# Revoke privilege granting from user 1
self.execute_query_expect_success(admin_client, "revoke grant option for
insert "
@@ -181,8 +181,8 @@ class TestRanger(CustomClusterTestSuite):
result = self.execute_query("show grant user {0} on database {1}"
.format(user1, unique_database))
TestRanger._check_privileges(result, [
- ["USER", user1, unique_database, "", "", "", "*", "insert", "false"],
- ["USER", user1, unique_database, "*", "*", "", "", "insert",
"false"]])
+ ["USER", user1, unique_database, "", "", "", "", "", "*", "insert",
"false"],
+ ["USER", user1, unique_database, "*", "*", "", "", "", "", "insert",
"false"]])
finally:
admin_client.execute("revoke insert on database {0} from user {1}"
.format(unique_database, user1), user=ADMIN)
@@ -242,59 +242,90 @@ class TestRanger(CustomClusterTestSuite):
result = self.client.execute("show grant user {0} on database {1}"
.format(user, unique_db))
TestRanger._check_privileges(result, [
- ["GROUP", user, unique_db, "", "", "", "*", "select", "false"],
- ["GROUP", user, unique_db, "*", "*", "", "", "select", "false"]])
+ ["GROUP", user, unique_db, "", "", "", "", "", "*", "select",
"false"],
+ ["GROUP", user, unique_db, "*", "*", "", "", "", "", "select",
"false"]])
finally:
admin_client.execute("revoke select on database {0} from group {1}"
.format(unique_db, group))
def _test_show_grant_mask(self, admin_client, user):
- privileges = ["select", "insert", "create", "alter", "drop", "refresh"]
+ privs_excl_rwstorage = ["select", "insert", "create", "alter", "drop",
"refresh"]
try:
- for privilege in privileges:
+ for privilege in privs_excl_rwstorage:
admin_client.execute("grant {0} on server to user
{1}".format(privilege, user))
result = self.client.execute("show grant user {0} on
server".format(user))
TestRanger._check_privileges(result, [
- ["USER", user, "", "", "", "*", "", "alter", "false"],
- ["USER", user, "", "", "", "*", "", "create", "false"],
- ["USER", user, "", "", "", "*", "", "drop", "false"],
- ["USER", user, "", "", "", "*", "", "insert", "false"],
- ["USER", user, "", "", "", "*", "", "refresh", "false"],
- ["USER", user, "", "", "", "*", "", "select", "false"],
- ["USER", user, "*", "", "", "", "*", "alter", "false"],
- ["USER", user, "*", "", "", "", "*", "create", "false"],
- ["USER", user, "*", "", "", "", "*", "drop", "false"],
- ["USER", user, "*", "", "", "", "*", "insert", "false"],
- ["USER", user, "*", "", "", "", "*", "refresh", "false"],
- ["USER", user, "*", "", "", "", "*", "select", "false"],
- ["USER", user, "*", "*", "*", "", "", "alter", "false"],
- ["USER", user, "*", "*", "*", "", "", "create", "false"],
- ["USER", user, "*", "*", "*", "", "", "drop", "false"],
- ["USER", user, "*", "*", "*", "", "", "insert", "false"],
- ["USER", user, "*", "*", "*", "", "", "refresh", "false"],
- ["USER", user, "*", "*", "*", "", "", "select", "false"]])
+ ["USER", user, "", "", "", "*", "", "", "", "alter", "false"],
+ ["USER", user, "", "", "", "*", "", "", "", "create", "false"],
+ ["USER", user, "", "", "", "*", "", "", "", "drop", "false"],
+ ["USER", user, "", "", "", "*", "", "", "", "insert", "false"],
+ ["USER", user, "", "", "", "*", "", "", "", "refresh", "false"],
+ ["USER", user, "", "", "", "*", "", "", "", "select", "false"],
+ ["USER", user, "*", "", "", "", "", "", "*", "alter", "false"],
+ ["USER", user, "*", "", "", "", "", "", "*", "create", "false"],
+ ["USER", user, "*", "", "", "", "", "", "*", "drop", "false"],
+ ["USER", user, "*", "", "", "", "", "", "*", "insert", "false"],
+ ["USER", user, "*", "", "", "", "", "", "*", "refresh", "false"],
+ ["USER", user, "*", "", "", "", "", "", "*", "select", "false"],
+ ["USER", user, "*", "*", "*", "", "", "", "", "alter", "false"],
+ ["USER", user, "*", "*", "*", "", "", "", "", "create", "false"],
+ ["USER", user, "*", "*", "*", "", "", "", "", "drop", "false"],
+ ["USER", user, "*", "*", "*", "", "", "", "", "insert", "false"],
+ ["USER", user, "*", "*", "*", "", "", "", "", "refresh", "false"],
+ ["USER", user, "*", "*", "*", "", "", "", "", "select", "false"]])
+
+ # GRANT RWSTORAGE ON SERVER additionally grants the RWSTORAGE privilege
on all
+ # storage types and all storage URI's.
+ admin_client.execute("grant rwstorage on server to user
{0}".format(user))
+ result = self.client.execute("show grant user {0} on
server".format(user))
+ TestRanger._check_privileges(result, [
+ ["USER", user, "", "", "", "", "*", "*", "", "rwstorage", "false"],
+ ["USER", user, "", "", "", "*", "", "", "", "alter", "false"],
+ ["USER", user, "", "", "", "*", "", "", "", "create", "false"],
+ ["USER", user, "", "", "", "*", "", "", "", "drop", "false"],
+ ["USER", user, "", "", "", "*", "", "", "", "insert", "false"],
+ ["USER", user, "", "", "", "*", "", "", "", "refresh", "false"],
+ ["USER", user, "", "", "", "*", "", "", "", "select", "false"],
+ ["USER", user, "*", "", "", "", "", "", "*", "alter", "false"],
+ ["USER", user, "*", "", "", "", "", "", "*", "create", "false"],
+ ["USER", user, "*", "", "", "", "", "", "*", "drop", "false"],
+ ["USER", user, "*", "", "", "", "", "", "*", "insert", "false"],
+ ["USER", user, "*", "", "", "", "", "", "*", "refresh", "false"],
+ ["USER", user, "*", "", "", "", "", "", "*", "select", "false"],
+ ["USER", user, "*", "*", "*", "", "", "", "", "alter", "false"],
+ ["USER", user, "*", "*", "*", "", "", "", "", "create", "false"],
+ ["USER", user, "*", "*", "*", "", "", "", "", "drop", "false"],
+ ["USER", user, "*", "*", "*", "", "", "", "", "insert", "false"],
+ ["USER", user, "*", "*", "*", "", "", "", "", "refresh", "false"],
+ ["USER", user, "*", "*", "*", "", "", "", "", "select", "false"]])
admin_client.execute("grant all on server to user {0}".format(user))
result = self.client.execute("show grant user {0} on
server".format(user))
TestRanger._check_privileges(result, [
- ["USER", user, "", "", "", "*", "", "all", "false"],
- ["USER", user, "*", "", "", "", "*", "all", "false"],
- ["USER", user, "*", "*", "*", "", "", "all", "false"]])
+ ["USER", user, "", "", "", "", "*", "*", "", "rwstorage", "false"],
+ ["USER", user, "", "", "", "*", "", "", "", "all", "false"],
+ ["USER", user, "*", "", "", "", "", "", "*", "all", "false"],
+ ["USER", user, "*", "*", "*", "", "", "", "", "all", "false"]])
finally:
admin_client.execute("revoke all on server from user {0}".format(user))
- for privilege in privileges:
+ admin_client.execute("revoke rwstorage on server from user
{0}".format(user))
+ for privilege in privs_excl_rwstorage:
admin_client.execute("revoke {0} on server from user
{1}".format(privilege, user))
def _test_show_grant_basic(self, admin_client, kw, id, unique_database,
unique_table):
uri = WAREHOUSE_PREFIX + '/tmp'
+ database = 'functional'
+ table = 'alltypes'
+ storagehandler_uri = 'kudu://localhost/impala::tpch_kudu.nation'
try:
# Grant server privileges and verify
admin_client.execute("grant all on server to {0} {1}".format(kw, id),
user=ADMIN)
result = self.client.execute("show grant {0} {1} on server".format(kw,
id))
TestRanger._check_privileges(result, [
- [kw, id, "", "", "", "*", "", "all", "false"],
- [kw, id, "*", "", "", "", "*", "all", "false"],
- [kw, id, "*", "*", "*", "", "", "all", "false"]])
+ [kw, id, "", "", "", "", "*", "*", "", "rwstorage", "false"],
+ [kw, id, "", "", "", "*", "", "", "", "all", "false"],
+ [kw, id, "*", "", "", "", "", "", "*", "all", "false"],
+ [kw, id, "*", "*", "*", "", "", "", "", "all", "false"]])
# Revoke server privileges and verify
admin_client.execute("revoke all on server from {0} {1}".format(kw, id))
@@ -307,7 +338,8 @@ class TestRanger(CustomClusterTestSuite):
result = self.client.execute("show grant {0} {1} on uri '{2}'"
.format(kw, id, uri))
TestRanger._check_privileges(result, [
- [kw, id, "", "", "", "{0}{1}".format(NAMENODE, '/tmp'), "", "all",
"false"]])
+ [kw, id, "", "", "", "{0}{1}".format(NAMENODE, '/tmp'), "", "", "",
"all",
+ "false"]])
# Revoke uri privileges and verify
admin_client.execute("revoke all on uri '{0}' from {1} {2}"
@@ -316,14 +348,46 @@ class TestRanger(CustomClusterTestSuite):
.format(kw, id, uri))
TestRanger._check_privileges(result, [])
+ # Grant storage handler URI privilege and verify
+ admin_client.execute("grant rwstorage on storagehandler_uri '{0}' to {1}
{2}"
+ .format(storagehandler_uri, kw, id))
+ result = self.client.execute("show grant {0} {1} on storagehandler_uri
'{2}'"
+ .format(kw, id, storagehandler_uri))
+ TestRanger._check_privileges(result, [
+ [kw, id, "", "", "", "", "kudu",
"localhost/impala::tpch_kudu.nation", "",
+ "rwstorage", "false"]])
+
+ # Grant the rwstorage privilege on a database does not result in the
grantee being
+ # granted the privilege on the database.
+ admin_client.execute("grant rwstorage on database {0} to {1} {2}"
+ .format(database, kw, id))
+ result = self.client.execute("show grant {0} {1} on database {2}"
+ .format(kw, id, database))
+ TestRanger._check_privileges(result, [])
+
+ # Grant the rwstorage privilege on a table does not result in the
grantee being
+ # granted the privilege on the table.
+ admin_client.execute("grant rwstorage on table {0}.{1} to {2} {3}"
+ .format(database, table, kw, id))
+ result = self.client.execute("show grant {0} {1} on table {2}.{3}"
+ .format(kw, id, database, table))
+ TestRanger._check_privileges(result, [])
+
+ # Revoke storage handler URI privilege and verify
+ admin_client.execute("revoke rwstorage on storagehandler_uri '{0}' from
{1} {2}"
+ .format(storagehandler_uri, kw, id))
+ result = self.client.execute("show grant {0} {1} on storagehandler_uri
'{2}'"
+ .format(kw, id, storagehandler_uri))
+ TestRanger._check_privileges(result, [])
+
# Grant database privileges and verify
admin_client.execute("grant select on database {0} to {1} {2}"
.format(unique_database, kw, id))
result = self.client.execute("show grant {0} {1} on database {2}"
.format(kw, id, unique_database))
TestRanger._check_privileges(result, [
- [kw, id, unique_database, "", "", "", "*", "select", "false"],
- [kw, id, unique_database, "*", "*", "", "", "select", "false"]])
+ [kw, id, unique_database, "", "", "", "", "", "*", "select",
"false"],
+ [kw, id, unique_database, "*", "*", "", "", "", "", "select",
"false"]])
# Revoke database privileges and verify
admin_client.execute("revoke select on database {0} from {1} {2}"
@@ -338,7 +402,8 @@ class TestRanger(CustomClusterTestSuite):
result = self.client.execute("show grant {0} {1} on table {2}.{3}"
.format(kw, id, unique_database,
unique_table))
TestRanger._check_privileges(result, [
- [kw, id, unique_database, unique_table, "*", "", "", "select",
"false"]])
+ [kw, id, unique_database, unique_table, "*", "", "", "", "",
"select",
+ "false"]])
# Revoke table privileges and verify
admin_client.execute("revoke select on table {0}.{1} from {2} {3}"
@@ -353,7 +418,8 @@ class TestRanger(CustomClusterTestSuite):
result = self.client.execute("show grant {0} {1} on column {2}.{3}.x"
.format(kw, id, unique_database,
unique_table))
TestRanger._check_privileges(result, [
- [kw, id, unique_database, unique_table, "x", "", "", "select",
"false"]])
+ [kw, id, unique_database, unique_table, "x", "", "", "", "",
"select",
+ "false"]])
# Revoke column privileges and verify
admin_client.execute("revoke select(x) on table {0}.{1} from {2} {3}"
@@ -365,6 +431,8 @@ class TestRanger(CustomClusterTestSuite):
admin_client.execute("revoke all on server from {0} {1}".format(kw, id))
admin_client.execute("revoke all on uri '{0}' from {1} {2}"
.format(uri, kw, id))
+ admin_client.execute("revoke rwstorage on storagehandler_uri '{0}' from
{1} {2}"
+ .format(storagehandler_uri, kw, id))
admin_client.execute("revoke select on database {0} from {1} {2}"
.format(unique_database, kw, id))
admin_client.execute("revoke select on table {0}.{1} from {2} {3}"
@@ -381,31 +449,31 @@ class TestRanger(CustomClusterTestSuite):
# Verify the privileges are correctly added
result = self.client.execute("show grant {0} {1} on server".format(kw,
id))
TestRanger._check_privileges(result, [
- [kw, id, "", "", "", "*", "", "select", "false"],
- [kw, id, "*", "", "", "", "*", "select", "false"],
- [kw, id, "*", "*", "*", "", "", "select", "false"]])
+ [kw, id, "", "", "", "*", "", "", "", "select", "false"],
+ [kw, id, "*", "", "", "", "", "", "*", "select", "false"],
+ [kw, id, "*", "*", "*", "", "", "", "", "select", "false"]])
# Verify the highest level of resource that contains the specified
resource could
# be computed when the specified resource is a database
result = self.client.execute("show grant {0} {1} on database {2}"
.format(kw, id, unique_database))
TestRanger._check_privileges(result, [
- [kw, id, "*", "", "", "", "*", "select", "false"],
- [kw, id, "*", "*", "*", "", "", "select", "false"]])
+ [kw, id, "*", "", "", "", "", "", "*", "select", "false"],
+ [kw, id, "*", "*", "*", "", "", "", "", "select", "false"]])
# Verify the highest level of resource that contains the specified
resource could
# be computed when the specified resource is a table
result = self.client.execute("show grant {0} {1} on table {2}.{3}"
.format(kw, id, unique_database,
unique_table))
TestRanger._check_privileges(result, [
- [kw, id, "*", "*", "*", "", "", "select", "false"]])
+ [kw, id, "*", "*", "*", "", "", "", "", "select", "false"]])
# Verify the highest level of resource that contains the specified
resource could
# be computed when the specified resource is a column
result = self.client.execute("show grant {0} {1} on column {2}.{3}.x"
.format(kw, id, unique_database,
unique_table))
TestRanger._check_privileges(result, [
- [kw, id, "*", "*", "*", "", "", "select", "false"]])
+ [kw, id, "*", "*", "*", "", "", "", "", "select", "false"]])
# Grant the create privilege on database and verify
admin_client.execute("grant create on database {0} to {1} {2}"
@@ -413,10 +481,10 @@ class TestRanger(CustomClusterTestSuite):
result = self.client.execute("show grant {0} {1} on database {2}"
.format(kw, id, unique_database))
TestRanger._check_privileges(result, [
- [kw, id, "*", "", "", "", "*", "select", "false"],
- [kw, id, "*", "*", "*", "", "", "select", "false"],
- [kw, id, unique_database, "", "", "", "*", "create", "false"],
- [kw, id, unique_database, "*", "*", "", "", "create", "false"]
+ [kw, id, "*", "", "", "", "", "", "*", "select", "false"],
+ [kw, id, "*", "*", "*", "", "", "", "", "select", "false"],
+ [kw, id, unique_database, "", "", "", "", "", "*", "create",
"false"],
+ [kw, id, unique_database, "*", "*", "", "", "", "", "create",
"false"]
])
# Grant the insert privilege on table and verify
@@ -425,9 +493,9 @@ class TestRanger(CustomClusterTestSuite):
result = self.client.execute("show grant {0} {1} on table {2}.{3}"
.format(kw, id, unique_database,
unique_table))
TestRanger._check_privileges(result, [
- [kw, id, "*", "*", "*", "", "", "select", "false"],
- [kw, id, unique_database, "*", "*", "", "", "create", "false"],
- [kw, id, unique_database, unique_table, "*", "", "", "insert",
"false"]
+ [kw, id, "*", "*", "*", "", "", "", "", "select", "false"],
+ [kw, id, unique_database, "*", "*", "", "", "", "", "create",
"false"],
+ [kw, id, unique_database, unique_table, "*", "", "", "", "",
"insert", "false"]
])
# Grant the select privilege on column and verify
@@ -436,9 +504,9 @@ class TestRanger(CustomClusterTestSuite):
result = self.client.execute("show grant {0} {1} on column {2}.{3}.x"
.format(kw, id, unique_database,
unique_table))
TestRanger._check_privileges(result, [
- [kw, id, unique_database, "*", "*", "", "", "create", "false"],
- [kw, id, unique_database, unique_table, "*", "", "", "insert",
"false"],
- [kw, id, unique_database, unique_table, "x", "", "", "select",
"false"]
+ [kw, id, unique_database, "*", "*", "", "", "", "", "create",
"false"],
+ [kw, id, unique_database, unique_table, "*", "", "", "", "",
"insert", "false"],
+ [kw, id, unique_database, unique_table, "x", "", "", "", "",
"select", "false"]
])
# The insert privilege on table masks the select privilege just added
@@ -447,9 +515,9 @@ class TestRanger(CustomClusterTestSuite):
result = self.client.execute("show grant {0} {1} on column {2}.{3}.x"
.format(kw, id, unique_database,
unique_table))
TestRanger._check_privileges(result, [
- [kw, id, unique_database, "*", "*", "", "", "create", "false"],
- [kw, id, unique_database, unique_table, "*", "", "", "insert",
"false"],
- [kw, id, unique_database, unique_table, "x", "", "", "select",
"false"]
+ [kw, id, unique_database, "*", "*", "", "", "", "", "create",
"false"],
+ [kw, id, unique_database, unique_table, "*", "", "", "", "",
"insert", "false"],
+ [kw, id, unique_database, unique_table, "x", "", "", "", "",
"select", "false"]
])
# The all privilege on table masks the privileges of insert and select,
but not the
@@ -459,8 +527,8 @@ class TestRanger(CustomClusterTestSuite):
result = self.client.execute("show grant {0} {1} on column {2}.{3}.x"
.format(kw, id, unique_database,
unique_table))
TestRanger._check_privileges(result, [
- [kw, id, unique_database, unique_table, "*", "", "", "all", "false"],
- [kw, id, unique_database, unique_table, "x", "", "", "select",
"false"]
+ [kw, id, unique_database, unique_table, "*", "", "", "", "", "all",
"false"],
+ [kw, id, unique_database, unique_table, "x", "", "", "", "",
"select", "false"]
])
finally:
@@ -510,8 +578,8 @@ class TestRanger(CustomClusterTestSuite):
.format(user, unique_db))
TestRanger._check_privileges(result, [
- ["USER", user, unique_db, "*", "*", "", "", "create", "false"],
- ["USER", user, unique_db, "*", "*", "", "", "select", "false"]
+ ["USER", user, unique_db, "*", "*", "", "", "", "", "create",
"false"],
+ ["USER", user, unique_db, "*", "*", "", "", "", "", "select",
"false"]
])
# Revoke privileges via Ranger REST API
@@ -521,8 +589,8 @@ class TestRanger(CustomClusterTestSuite):
result = self.client.execute("show grant user {0} on database {1}"
.format(user, unique_db))
TestRanger._check_privileges(result, [
- ["USER", user, unique_db, "*", "*", "", "", "create", "false"],
- ["USER", user, unique_db, "*", "*", "", "", "select", "false"]
+ ["USER", user, unique_db, "*", "*", "", "", "", "", "create",
"false"],
+ ["USER", user, unique_db, "*", "*", "", "", "", "", "select",
"false"]
])
# Refresh and check updated privileges
@@ -568,7 +636,7 @@ class TestRanger(CustomClusterTestSuite):
.format(user, unique_db))
TestRanger._check_privileges(result, [
- ["USER", user, unique_db, "*", "*", "", "", "select", "false"]
+ ["USER", user, unique_db, "*", "*", "", "", "", "", "select",
"false"]
])
# Assert that lock, select privilege exists in Ranger server