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 <34065904+smolna...@users.noreply.github.com>
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
rle...@apache.org.

Reply via email to