mirror of
https://github.com/apache/impala.git
synced 2026-01-27 06:10:53 -05:00
This patch adds an environment variable DISABLE_SENTRY to allow Impala to run tests without Sentry. Specifically, we start up Sentry only when $DISABLE_SENTRY does not evaluate to true. The corresponding Sentry FE and E2E tests will also be skipped if $DISABLE_SENTRY is true. Moreover, in this patch we will set DISABLE_SENTRY to true if $USE_CDP_HIVE evaluates to true, allowing one to only test Impala's authorization with Ranger when support for Sentry is dropped after we switch to the CDP Hive. Note that in this patch we also change the way we generate hive-site.xml when $DISABLE_SENTRY is true. To be more precise, when generating hive-site.xml, we do not add the Sentry server as a metastore event listener if $DISABLE_SENTRY is true. Recall that both CDH Hive and CDP Hive would make an RPC to the registered listeners every time after the method of create_database_core() in HiveMetaStore.java is called, which happens when Hive instead of Impala is used to create a database, e.g., when some databases in the TPC-DS data set are created during the execution of create-load-data.sh. Thus the removal of Sentry as an event listener is necessary when $DISABLE_SENTRY is true in that it prevents the HiveMetaStore from keeping connecting to the Sentry server that is not online, which could make create-load-data.sh time out. Testing: Except for two currently known issues of IMPALA-9513 AND IMPALA-9451, verified this patch passes the exhaustive tests in the DEBUG build - when $USE_CDP_HIVE is false, and - when $USE_CDP_HIVE is true. Change-Id: Ifa3f1840a77a7b32310a5c8b78a2c26300ccb41e Reviewed-on: http://gerrit.cloudera.org:8080/15505 Reviewed-by: Impala Public Jenkins <impala-public-jenkins@cloudera.com> Tested-by: Impala Public Jenkins <impala-public-jenkins@cloudera.com>
149 lines
7.0 KiB
Python
149 lines
7.0 KiB
Python
# 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.
|
|
|
|
import grp
|
|
import pytest
|
|
import os
|
|
from getpass import getuser
|
|
|
|
from tests.common.custom_cluster_test_suite import CustomClusterTestSuite
|
|
from tests.common.sentry_cache_test_suite import SentryCacheTestSuite
|
|
from tests.common.skip import SkipIf
|
|
|
|
SENTRY_CONFIG_DIR = os.getenv('IMPALA_HOME') + '/fe/src/test/resources/'
|
|
SENTRY_CONFIG_FILE = SENTRY_CONFIG_DIR + 'sentry-site.xml'
|
|
|
|
|
|
@SkipIf.sentry_disabled
|
|
class TestSentry(CustomClusterTestSuite):
|
|
"""This class contains Sentry specific authorization tests."""
|
|
@pytest.mark.execute_serially
|
|
@CustomClusterTestSuite.with_args(
|
|
impalad_args="--server_name=server1 --sentry_config={0} "
|
|
"--authorization_policy_provider_class="
|
|
"org.apache.impala.testutil.TestSentryResourceAuthorizationProvider"
|
|
.format(SENTRY_CONFIG_FILE),
|
|
catalogd_args="--sentry_config={0} "
|
|
"--authorization_policy_provider_class="
|
|
"org.apache.impala.testutil.TestSentryResourceAuthorizationProvider"
|
|
.format(SENTRY_CONFIG_FILE).format(SENTRY_CONFIG_FILE))
|
|
|
|
def test_sentry_admin(self, unique_role, unique_name):
|
|
"""
|
|
Tests that only admin user can execute certain authorization statements.
|
|
"""
|
|
admin = getuser()
|
|
# doesnot_exist user does not exist.
|
|
doesnot_exist = unique_name
|
|
# root user exists but is not a Sentry admin.
|
|
non_admin = "root"
|
|
admin_client = self.create_impala_client()
|
|
doesntexist_client = self.create_impala_client()
|
|
root_client = self.create_impala_client()
|
|
try:
|
|
self.execute_query_expect_success(admin_client,
|
|
"create role {0}".format(unique_role),
|
|
user=admin)
|
|
|
|
# show current roles is always allowed.
|
|
self.execute_query_expect_success(admin_client, "show current roles", user=admin)
|
|
self.execute_query_expect_success(doesntexist_client, "show current roles",
|
|
user=doesnot_exist)
|
|
self.execute_query_expect_success(root_client, "show current roles",
|
|
user=non_admin)
|
|
|
|
for statement in ["show roles",
|
|
"show grant role {0}".format(unique_role)]:
|
|
self.execute_query_expect_success(admin_client, statement, user=admin)
|
|
# doesnotexist user does not exist.
|
|
result = self.execute_query_expect_failure(doesntexist_client, statement,
|
|
user=doesnot_exist)
|
|
|
|
assert "AuthorizationException: User '{0}' does not have privileges to access " \
|
|
"the requested policy metadata.".format(doesnot_exist) in str(result)
|
|
|
|
# root user exists, but is not a Sentry admin.
|
|
result = self.execute_query_expect_failure(root_client, statement,
|
|
user=non_admin)
|
|
assert "AuthorizationException: User '{0}' does not have privileges to access " \
|
|
"the requested policy metadata.".format(non_admin) in str(result)
|
|
|
|
finally:
|
|
admin_client.execute("drop role {0}".format(unique_role))
|
|
|
|
@pytest.mark.execute_serially
|
|
@SentryCacheTestSuite.with_args(
|
|
impalad_args="--server_name=server1",
|
|
catalogd_args="--sentry_config=" + SENTRY_CONFIG_FILE,
|
|
sentry_config=SENTRY_CONFIG_FILE)
|
|
def test_grant_revoke_invalid_role(self, unique_name):
|
|
role_name = "foobar"
|
|
group = grp.getgrnam(getuser()).gr_name
|
|
try:
|
|
# This will create "foobar" role catalog object.
|
|
self.client.execute("create role {0}".format(role_name))
|
|
self.client.execute("grant all on server to {0}".format(role_name))
|
|
self.client.execute("grant role {0} to group `{1}`".format(role_name, group))
|
|
self.client.execute("create database {0}".format(unique_name))
|
|
|
|
ex = self.execute_query_expect_failure(
|
|
self.client, "grant all on database {0} to role non_role".format(unique_name))
|
|
assert "Role 'non_role' does not exist." in str(ex)
|
|
|
|
ex = self.execute_query_expect_failure(
|
|
self.client, "revoke all on database {0} from role non_role".format(unique_name))
|
|
assert "Role 'non_role' does not exist." in str(ex)
|
|
|
|
ex = self.execute_query_expect_failure(self.client, "show grant role non_role")
|
|
assert "Role 'non_role' does not exist." in str(ex)
|
|
|
|
ex = self.execute_query_expect_failure(
|
|
self.client, "grant role non_role to group `{0}`".format(group))
|
|
assert "Role 'non_role' does not exist." in str(ex)
|
|
|
|
ex = self.execute_query_expect_failure(self.client, "drop role non_role")
|
|
assert "Role 'non_role' does not exist." in str(ex)
|
|
|
|
ex = self.execute_query_expect_failure(self.client,
|
|
"create role {0}".format(role_name))
|
|
assert "Role '{0}' already exists.".format(role_name) in str(ex)
|
|
finally:
|
|
self.client.execute("drop database {0}".format(unique_name))
|
|
self.client.execute("drop role {0}".format(role_name))
|
|
|
|
@pytest.mark.execute_serially
|
|
@CustomClusterTestSuite.with_args(
|
|
impalad_args="--server_name=server1 --sentry_config={0}".format(SENTRY_CONFIG_FILE),
|
|
catalogd_args="--sentry_config={0}".format(SENTRY_CONFIG_FILE))
|
|
def test_unsupported_sql(self):
|
|
"""Tests unsupported SQL statements when running with Sentry."""
|
|
user = getuser()
|
|
impala_client = self.create_impala_client()
|
|
error_msg = "UnsupportedFeatureException: {0} is not supported by Sentry."
|
|
statements = [("grant select on database functional to user foo",
|
|
error_msg.format("GRANT <privilege> TO USER")),
|
|
("grant select on database functional to group foo",
|
|
error_msg.format("GRANT <privilege> TO GROUP")),
|
|
("revoke select on database functional from user foo",
|
|
error_msg.format("REVOKE <privilege> FROM USER")),
|
|
("revoke select on database functional from group foo",
|
|
error_msg.format("REVOKE <privilege> FROM GROUP")),
|
|
("show grant group foo", error_msg.format("SHOW GRANT GROUP"))]
|
|
for statement in statements:
|
|
result = self.execute_query_expect_failure(impala_client, statement[0], user=user)
|
|
assert statement[1] in str(result)
|