This is an automated email from the ASF dual-hosted git repository.
rlevas pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ambari.git
The following commit(s) were added to refs/heads/trunk by this push:
new c88e0a1 [AMBARI-22885] LDAP sync fails with 'LDAP is not configured'
error after configuring LDAP
c88e0a1 is described below
commit c88e0a1c833bdb4015f721df8985a84077af06b5
Author: smolnar82 <[email protected]>
AuthorDate: Fri Feb 2 11:40:08 2018 +0100
[AMBARI-22885] LDAP sync fails with 'LDAP is not configured' error after
configuring LDAP
* AMBARI-22885. We fetch 'ldap enabled' flag from both ambari.properties
(to support backward compatibility) and from AMBARI DB via our REST API
* AMBARI-22885. Make sure we close response (even if an error occurred)
* AMBARI-22885. Retrieving the 'is LDAP enabled' flag from AMBARI DB is
enough (do not need to search it in ambari.properties)
---
.../src/main/python/ambari_server/setupSecurity.py | 61 ++++++++++--
ambari-server/src/test/python/TestAmbariServer.py | 110 ++++++---------------
2 files changed, 84 insertions(+), 87 deletions(-)
diff --git a/ambari-server/src/main/python/ambari_server/setupSecurity.py
b/ambari-server/src/main/python/ambari_server/setupSecurity.py
index db5ef3d..25673b8 100644
--- a/ambari-server/src/main/python/ambari_server/setupSecurity.py
+++ b/ambari-server/src/main/python/ambari_server/setupSecurity.py
@@ -56,6 +56,7 @@ from ambari_server.userInput import
get_validated_string_input, get_prompt_defau
from ambari_server.serverClassPath import ServerClassPath
from ambari_server.dbConfiguration import DBMSConfigFactory,
check_jdbc_drivers, \
get_jdbc_driver_path, ensure_jdbc_driver_is_installed, LINUX_DBMS_KEYS_LIST
+from contextlib import closing
logger = logging.getLogger(__name__)
@@ -274,6 +275,51 @@ class LdapSyncOptions:
def no_ldap_sync_options_set(self):
return not self.ldap_sync_all and not self.ldap_sync_existing and
self.ldap_sync_users is None and self.ldap_sync_groups is None
+def getLdapPropertyFromDB(properties, admin_login, admin_password,
property_name):
+ ldapProperty = None
+ url = get_ambari_server_api_base(properties) + SETUP_LDAP_CONFIG_URL
+ admin_auth = base64.encodestring('%s:%s' % (admin_login,
admin_password)).replace('\n', '')
+ request = urllib2.Request(url)
+ request.add_header('Authorization', 'Basic %s' % admin_auth)
+ request.add_header('X-Requested-By', 'ambari')
+ request.get_method = lambda: 'GET'
+ request_in_progress = True
+
+ sys.stdout.write('\nFetching LDAP configuration from DB')
+ numOfTries = 0
+ while request_in_progress:
+ numOfTries += 1
+ if (numOfTries == 60):
+ raise FatalException(1, "Could not fetch LDAP configuration within a
minute; giving up!")
+ sys.stdout.write('.')
+ sys.stdout.flush()
+
+ try:
+ with closing(urllib2.urlopen(request)) as response:
+ response_status_code = response.getcode()
+ if response_status_code != 200:
+ request_in_progress = False
+ err = 'Error while fetching LDAP configuration. Http status code - '
+ str(response_status_code)
+ raise FatalException(1, err)
+ else:
+ response_body = json.loads(response.read())
+ ldapProperties = response_body['Configuration']['properties']
+ ldapProperty = ldapProperties[property_name]
+ if not ldapProperty:
+ time.sleep(1)
+ else:
+ request_in_progress = False
+ except Exception as e:
+ request_in_progress = False
+ err = 'Error while fetching LDAP configuration. Error details: %s' % e
+ raise FatalException(1, err)
+
+ return ldapProperty
+
+def is_ldap_enabled(properties, admin_login, admin_password):
+ ldapEnabled = getLdapPropertyFromDB(properties, admin_login, admin_password,
IS_LDAP_CONFIGURED)
+ return ldapEnabled if ldapEnabled != None else 'false'
+
#
# Sync users and groups with configured LDAP
@@ -295,11 +341,6 @@ def sync_ldap(options):
if properties == -1:
raise FatalException(1, "Failed to read properties file.")
- ldap_configured = properties.get_property(IS_LDAP_CONFIGURED)
- if ldap_configured != 'true':
- err = "LDAP is not configured. Run 'ambari-server setup-ldap' first."
- raise FatalException(1, err)
-
# set ldap sync options
ldap_sync_options = LdapSyncOptions(options)
@@ -318,6 +359,10 @@ def sync_ldap(options):
pattern=None, description=None,
is_pass=True, allowEmpty=False)
+ if is_ldap_enabled(properties, admin_login, admin_password) != 'true':
+ err = "LDAP is not configured. Run 'ambari-server setup-ldap' first."
+ raise FatalException(1, err)
+
url = get_ambari_server_api_base(properties) + SERVER_API_LDAP_URL
admin_auth = base64.encodestring('%s:%s' % (admin_login,
admin_password)).replace('\n', '')
request = urllib2.Request(url)
@@ -325,13 +370,13 @@ def sync_ldap(options):
request.add_header('X-Requested-By', 'ambari')
if ldap_sync_options.ldap_sync_all:
- sys.stdout.write('Syncing all.')
+ sys.stdout.write('\nSyncing all.')
bodies =
[{"Event":{"specs":[{"principal_type":"users","sync_type":"all"},{"principal_type":"groups","sync_type":"all"}]}}]
elif ldap_sync_options.ldap_sync_existing:
- sys.stdout.write('Syncing existing.')
+ sys.stdout.write('\nSyncing existing.')
bodies =
[{"Event":{"specs":[{"principal_type":"users","sync_type":"existing"},{"principal_type":"groups","sync_type":"existing"}]}}]
else:
- sys.stdout.write('Syncing specified users and groups.')
+ sys.stdout.write('\nSyncing specified users and groups.')
bodies = [{"Event":{"specs":[]}}]
body = bodies[0]
events = body['Event']
diff --git a/ambari-server/src/test/python/TestAmbariServer.py
b/ambari-server/src/test/python/TestAmbariServer.py
index d2d48c1..97a0bd5 100644
--- a/ambari-server/src/test/python/TestAmbariServer.py
+++ b/ambari-server/src/test/python/TestAmbariServer.py
@@ -7472,16 +7472,17 @@ class TestAmbariServer(TestCase):
@patch("urllib2.urlopen")
@patch("ambari_server.setupSecurity.get_validated_string_input")
@patch("ambari_server.setupSecurity.get_ambari_properties")
+ @patch("ambari_server.setupSecurity.is_ldap_enabled")
@patch("ambari_server.setupSecurity.is_server_runing")
@patch("ambari_server.setupSecurity.is_root")
@patch("ambari_server.setupSecurity.logger")
- def test_ldap_sync_all(self, logger_mock, is_root_method,
is_server_runing_mock, get_ambari_properties_mock,
+ def test_ldap_sync_all(self, logger_mock, is_root_method,
is_server_runing_mock, is_ldap_enabled_mock, get_ambari_properties_mock,
get_validated_string_input_mock, urlopen_mock):
is_root_method.return_value = True
is_server_runing_mock.return_value = (True, 0)
+ is_ldap_enabled_mock.return_value = 'true'
properties = Properties()
- properties.process_pair(IS_LDAP_CONFIGURED, 'true')
properties.process_pair(CLIENT_API_PORT_PROPERTY, '8080')
get_ambari_properties_mock.return_value = properties
get_validated_string_input_mock.side_effect = ['admin', 'admin']
@@ -7515,10 +7516,11 @@ class TestAmbariServer(TestCase):
@patch("urllib2.urlopen")
@patch("ambari_server.setupSecurity.get_validated_string_input")
@patch("ambari_server.setupSecurity.get_ambari_properties")
+ @patch("ambari_server.setupSecurity.is_ldap_enabled")
@patch("ambari_server.setupSecurity.is_server_runing")
@patch("ambari_server.setupSecurity.is_root")
@patch("ambari_server.setupSecurity.logger")
- def test_ldap_sync_users(self, logger_mock, is_root_method,
is_server_runing_mock, get_ambari_properties_mock,
+ def test_ldap_sync_users(self, logger_mock, is_root_method,
is_server_runing_mock, is_ldap_enabled_mock, get_ambari_properties_mock,
get_validated_string_input_mock, urlopen_mock,
os_path_exists_mock, open_mock):
os_path_exists_mock.return_value = 1
@@ -7528,9 +7530,7 @@ class TestAmbariServer(TestCase):
open_mock.return_value = f
is_root_method.return_value = True
is_server_runing_mock.return_value = (True, 0)
- properties = Properties()
- properties.process_pair(IS_LDAP_CONFIGURED, 'true')
- get_ambari_properties_mock.return_value = properties
+ is_ldap_enabled_mock.return_value = 'true'
get_validated_string_input_mock.side_effect = ['admin', 'admin']
response = MagicMock()
@@ -7562,10 +7562,11 @@ class TestAmbariServer(TestCase):
@patch("urllib2.urlopen")
@patch("ambari_server.setupSecurity.get_validated_string_input")
@patch("ambari_server.setupSecurity.get_ambari_properties")
+ @patch("ambari_server.setupSecurity.is_ldap_enabled")
@patch("ambari_server.setupSecurity.is_server_runing")
@patch("ambari_server.setupSecurity.is_root")
@patch("ambari_server.setupSecurity.logger")
- def test_ldap_sync_groups(self, logger_mock, is_root_method,
is_server_runing_mock, get_ambari_properties_mock,
+ def test_ldap_sync_groups(self, logger_mock, is_root_method,
is_server_runing_mock, is_ldap_enabled_mock, get_ambari_properties_mock,
get_validated_string_input_mock, urlopen_mock,
os_path_exists_mock, open_mock):
os_path_exists_mock.return_value = 1
@@ -7575,9 +7576,7 @@ class TestAmbariServer(TestCase):
open_mock.return_value = f
is_root_method.return_value = True
is_server_runing_mock.return_value = (True, 0)
- properties = Properties()
- properties.process_pair(IS_LDAP_CONFIGURED, 'true')
- get_ambari_properties_mock.return_value = properties
+ is_ldap_enabled_mock.return_value = 'true'
get_validated_string_input_mock.side_effect = ['admin', 'admin']
response = MagicMock()
@@ -7607,16 +7606,17 @@ class TestAmbariServer(TestCase):
@patch("urllib2.urlopen")
@patch("ambari_server.setupSecurity.get_validated_string_input")
@patch("ambari_server.setupSecurity.get_ambari_properties")
+ @patch("ambari_server.setupSecurity.is_ldap_enabled")
@patch("ambari_server.setupSecurity.is_server_runing")
@patch("ambari_server.setupSecurity.is_root")
@patch("ambari_server.setupSecurity.logger")
- def test_ldap_sync_ssl(self, logger_mock, is_root_method,
is_server_runing_mock, get_ambari_properties_mock,
+ def test_ldap_sync_ssl(self, logger_mock, is_root_method,
is_server_runing_mock, is_ldap_enabled_mock, get_ambari_properties_mock,
get_validated_string_input_mock, urlopen_mock):
is_root_method.return_value = True
is_server_runing_mock.return_value = (True, 0)
+ is_ldap_enabled_mock.return_value = 'true'
properties = Properties()
- properties.process_pair(IS_LDAP_CONFIGURED, 'true')
properties.process_pair(SSL_API, 'true')
properties.process_pair(SSL_API_PORT, '8443')
get_ambari_properties_mock.return_value = properties
@@ -7650,18 +7650,16 @@ class TestAmbariServer(TestCase):
@patch("urllib2.urlopen")
@patch("ambari_server.setupSecurity.get_validated_string_input")
- @patch("ambari_server.setupSecurity.get_ambari_properties")
+ @patch("ambari_server.setupSecurity.is_ldap_enabled")
@patch("ambari_server.setupSecurity.is_server_runing")
@patch("ambari_server.setupSecurity.is_root")
@patch("ambari_server.setupSecurity.logger")
- def test_ldap_sync_existing(self, logger_mock, is_root_method,
is_server_runing_mock, get_ambari_properties_mock,
+ def test_ldap_sync_existing(self, logger_mock, is_root_method,
is_server_runing_mock, is_ldap_enabled_mock,
get_validated_string_input_mock, urlopen_mock):
is_root_method.return_value = True
is_server_runing_mock.return_value = (True, 0)
- properties = Properties()
- properties.process_pair(IS_LDAP_CONFIGURED, 'true')
- get_ambari_properties_mock.return_value = properties
+ is_ldap_enabled_mock.return_value = 'true'
get_validated_string_input_mock.side_effect = ['admin', 'admin']
response = MagicMock()
@@ -7686,18 +7684,16 @@ class TestAmbariServer(TestCase):
@patch("urllib2.urlopen")
@patch("ambari_server.setupSecurity.get_validated_string_input")
- @patch("ambari_server.setupSecurity.get_ambari_properties")
+ @patch("ambari_server.setupSecurity.is_ldap_enabled")
@patch("ambari_server.setupSecurity.is_server_runing")
@patch("ambari_server.setupSecurity.is_root")
@patch("ambari_server.setupSecurity.logger")
- def test_ldap_sync_no_sync_mode(self, logger_mock, is_root_method,
is_server_runing_mock, get_ambari_properties_mock,
+ def test_ldap_sync_no_sync_mode(self, logger_mock, is_root_method,
is_server_runing_mock, is_ldap_enabled_mock,
get_validated_string_input_mock, urlopen_mock):
is_root_method.return_value = True
is_server_runing_mock.return_value = (True, 0)
- properties = Properties()
- properties.process_pair(IS_LDAP_CONFIGURED, 'true')
- get_ambari_properties_mock.return_value = properties
+ is_ldap_enabled_mock.return_value = 'true'
get_validated_string_input_mock.side_effect = ['admin', 'admin']
response = MagicMock()
@@ -7723,18 +7719,16 @@ class TestAmbariServer(TestCase):
@patch("urllib2.urlopen")
@patch("ambari_server.setupSecurity.get_validated_string_input")
- @patch("ambari_server.setupSecurity.get_ambari_properties")
+ @patch("ambari_server.setupSecurity.is_ldap_enabled")
@patch("ambari_server.setupSecurity.is_server_runing")
@patch("ambari_server.setupSecurity.is_root")
@patch("ambari_server.setupSecurity.logger")
- def test_ldap_sync_error_status(self, logger_mock, is_root_method,
is_server_runing_mock, get_ambari_properties_mock,
+ def test_ldap_sync_error_status(self, logger_mock, is_root_method,
is_server_runing_mock, is_ldap_enabled_mock,
get_validated_string_input_mock, urlopen_mock):
is_root_method.return_value = True
is_server_runing_mock.return_value = (True, 0)
- properties = Properties()
- properties.process_pair(IS_LDAP_CONFIGURED, 'true')
- get_ambari_properties_mock.return_value = properties
+ is_ldap_enabled_mock.return_value = 'true'
get_validated_string_input_mock.side_effect = ['admin', 'admin']
response = MagicMock()
@@ -7761,10 +7755,10 @@ class TestAmbariServer(TestCase):
@patch("urllib2.Request")
@patch("base64.encodestring")
@patch("ambari_server.setupSecurity.is_server_runing")
- @patch("ambari_server.setupSecurity.get_ambari_properties")
+ @patch("ambari_server.setupSecurity.is_ldap_enabled")
@patch("ambari_server.setupSecurity.get_validated_string_input")
@patch("ambari_server.setupSecurity.logger")
- def test_sync_ldap_forbidden(self, logger_mock,
get_validated_string_input_method, get_ambari_properties_method,
+ def test_sync_ldap_forbidden(self, logger_mock,
get_validated_string_input_method, is_ldap_enabled_mock,
is_server_runing_method,
encodestring_method, request_constructor,
urlopen_method):
@@ -7774,28 +7768,8 @@ class TestAmbariServer(TestCase):
options.ldap_sync_users = None
options.ldap_sync_groups = None
- is_server_runing_method.return_value = (None, None)
- try:
- sync_ldap(options)
- self.fail("Should throw exception if ambari is stopped")
- except FatalException as fe:
- # Expected
- self.assertTrue("not running" in fe.reason)
- pass
- is_server_runing_method.return_value = (True, None)
-
- configs = MagicMock()
- configs.get_property.return_value = None
- get_ambari_properties_method.return_value = configs
- try:
- sync_ldap(options)
- self.fail("Should throw exception if ldap is not configured")
- except FatalException as fe:
- # Expected
- self.assertTrue("not configured" in fe.reason)
- pass
- configs.get_property.return_value = 'true'
-
+ is_server_runing_method.return_value = (True, 0)
+ is_ldap_enabled_mock.return_value = 'true'
get_validated_string_input_method.return_value = 'admin'
encodestring_method.return_value = 'qwe123'
@@ -7815,25 +7789,6 @@ class TestAmbariServer(TestCase):
pass
@patch("ambari_server.setupSecurity.is_root")
- def test_sync_ldap_ambari_stopped(self, is_root_method):
- is_root_method.return_value = False
-
- options = self._create_empty_options_mock()
- options.ldap_sync_all = True
- options.ldap_sync_existing = False
- options.ldap_sync_users = None
- options.ldap_sync_groups = None
-
- try:
- sync_ldap(options)
- self.fail("Should throw exception if not root")
- except FatalException as fe:
- # Expected
- self.assertTrue("root-level" in fe.reason)
- pass
- pass
-
- @patch("ambari_server.setupSecurity.is_root")
@patch("ambari_server.setupSecurity.is_server_runing")
@patch("ambari_server.setupSecurity.logger")
def test_sync_ldap_ambari_stopped(self, logger_mock,
is_server_runing_method, is_root_method):
@@ -7855,18 +7810,15 @@ class TestAmbariServer(TestCase):
pass
pass
- @patch("ambari_server.setupSecurity.is_root")
+ @patch("ambari_server.setupSecurity.get_validated_string_input")
@patch("ambari_server.setupSecurity.is_server_runing")
- @patch("ambari_server.setupSecurity.get_ambari_properties")
+ @patch("ambari_server.setupSecurity.is_ldap_enabled")
@patch("ambari_server.setupSecurity.logger")
- def test_sync_ldap_not_configured(self, logger_mock,
get_ambari_properties_method,
- is_server_runing_method, is_root_method):
- is_root_method.return_value = True
+ def test_sync_ldap_not_configured(self, logger_mock, is_ldap_enabled_mock,
+ is_server_runing_method, get_validated_string_input):
+ get_validated_string_input.return_value = 'admin'
is_server_runing_method.return_value = (True, None)
-
- configs = MagicMock()
- configs.get_property.return_value = None
- get_ambari_properties_method.return_value = configs
+ is_ldap_enabled_mock.return_value = 'false'
options = self._create_empty_options_mock()
options.ldap_sync_all = True
--
To stop receiving notification emails like this one, please contact
[email protected].