You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by nc...@apache.org on 2018/01/26 15:22:08 UTC
[ambari] 03/21: AMBARI-22797. The stup-ldap tool should persists
its output into Ambari database rather than ambari.properties
This is an automated email from the ASF dual-hosted git repository.
ncole pushed a commit to branch branch-feature-AMBARI-21674
in repository https://gitbox.apache.org/repos/asf/ambari.git
commit 49d8082d3cfb3af448933b331ae0ac225771d903
Author: Sandor Molnar <sm...@hortonworks.com>
AuthorDate: Fri Jan 19 16:12:19 2018 +0100
AMBARI-22797. The stup-ldap tool should persists its output into Ambari database rather than ambari.properties
---
.../internal/AmbariServerConfigurationHandler.java | 9 +-
ambari-server/src/main/python/ambari-server.py | 12 +-
.../python/ambari_server/serverConfiguration.py | 7 +-
.../src/main/python/ambari_server/serverUpgrade.py | 8 +-
.../src/main/python/ambari_server/setupSecurity.py | 136 +++++---
...ComponentConfigurationResourceProviderTest.java | 2 +-
ambari-server/src/test/python/TestAmbariServer.py | 381 +++++++++++++--------
7 files changed, 356 insertions(+), 199 deletions(-)
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariServerConfigurationHandler.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariServerConfigurationHandler.java
index f3ff2dd..f96ad08 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariServerConfigurationHandler.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariServerConfigurationHandler.java
@@ -115,10 +115,13 @@ class AmbariServerConfigurationHandler extends RootServiceComponentConfiguration
while (propertiesIterator.hasNext()) {
Map.Entry<String, String> property = propertiesIterator.next();
if (AmbariServerConfigurationUtils.isPassword(categoryName, property.getKey())) {
- if (updatePasswordIfNeeded(categoryName, property.getKey(), property.getValue())) {
- toBePublished = true;
+ final String passwordFileOrCredentailStoreAlias = fetchPasswordFileNameOrCredentialStoreAlias(categoryName, property.getKey());
+ if (StringUtils.isNotBlank(passwordFileOrCredentailStoreAlias)) { //if blank -> this is the first time setup; we simply need to store the alias/file name
+ if (updatePasswordIfNeeded(categoryName, property.getKey(), property.getValue())) {
+ toBePublished = true;
+ }
+ propertiesIterator.remove(); //we do not need to change the any PASSWORD type configuration going forward
}
- propertiesIterator.remove(); //we do not need to change the any PASSWORD type configuration going forward
}
}
diff --git a/ambari-server/src/main/python/ambari-server.py b/ambari-server/src/main/python/ambari-server.py
index 4fd82e8..72dd292 100755
--- a/ambari-server/src/main/python/ambari-server.py
+++ b/ambari-server/src/main/python/ambari-server.py
@@ -532,8 +532,10 @@ def init_ldap_sync_parser_options(parser):
@OsFamilyFuncImpl(OsFamilyImpl.DEFAULT)
def init_ldap_setup_parser_options(parser):
- parser.add_option('--ldap-url', default=None, help="Primary url for LDAP", dest="ldap_url")
- parser.add_option('--ldap-secondary-url', default=None, help="Secondary url for LDAP", dest="ldap_secondary_url")
+ parser.add_option('--ldap-url-host', default=None, help="Primary Host for LDAP", dest="ldap_url_host")
+ parser.add_option('--ldap-url-port', default=None, help="Primary Port for LDAP", dest="ldap_url_port")
+ parser.add_option('--ldap-secondary-url-host', default=None, help="Secondary Host for LDAP", dest="ldap_secondary_url_host")
+ parser.add_option('--ldap-secondary-url-port', default=None, help="Secondary Port for LDAP", dest="ldap_secondary_url_port")
parser.add_option('--ldap-ssl', default=None, help="Use SSL [true/false] for LDAP", dest="ldap_ssl")
parser.add_option('--ldap-user-class', default=None, help="User Attribute Object Class for LDAP", dest="ldap_user_class")
parser.add_option('--ldap-user-attr', default=None, help="User Attribute Name for LDAP", dest="ldap_user_attr")
@@ -548,6 +550,8 @@ def init_ldap_setup_parser_options(parser):
parser.add_option('--ldap-referral', default=None, help="Referral method [follow/ignore] for LDAP", dest="ldap_referral")
parser.add_option('--ldap-bind-anonym', default=None, help="Bind anonymously [true/false] for LDAP", dest="ldap_bind_anonym")
parser.add_option('--ldap-sync-username-collisions-behavior', default=None, help="Handling behavior for username collisions [convert/skip] for LDAP sync", dest="ldap_sync_username_collisions_behavior")
+ parser.add_option('--ldap-force-lowercase-usernames', default=None, help="Declares whether to force the ldap user name to be lowercase or leave as-is", dest="ldap_force_lowercase_usernames")
+ parser.add_option('--ldap-pagination-enabled', default=None, help="Determines whether results from LDAP are paginated when requested", dest="ldap_pagination_enabled")
@OsFamilyFuncImpl(OsFamilyImpl.DEFAULT)
def init_pam_setup_parser_options(parser):
@@ -972,10 +976,6 @@ def mainBody():
parser = optparse.OptionParser(usage="usage: %prog action [options]",)
action = sys.argv[1]
- if action == "setup-ldap":
- print "setup-ldap action is deprecated. Please configure LDAP integration from the Ambari UI"
- sys.exit(0)
-
init_action_parser(action, parser)
(options, args) = parser.parse_args()
diff --git a/ambari-server/src/main/python/ambari_server/serverConfiguration.py b/ambari-server/src/main/python/ambari_server/serverConfiguration.py
index fd8bf73..fc9a28f 100644
--- a/ambari-server/src/main/python/ambari_server/serverConfiguration.py
+++ b/ambari-server/src/main/python/ambari_server/serverConfiguration.py
@@ -112,6 +112,7 @@ JDBC_RCA_PASSWORD_FILENAME = "rca_password.dat"
CLIENT_API_PORT_PROPERTY = "client.api.port"
CLIENT_API_PORT = "8080"
+CLIENT_SECURITY = "client.security"
SERVER_VERSION_FILE_PATH = "server.version.file"
@@ -158,12 +159,8 @@ RESOURCES_DIR_PROPERTY = "resources.dir"
STACK_LOCATION_KEY = 'metadata.path'
# LDAP security
-IS_LDAP_CONFIGURED = "ambari.ldap.isConfigured"
LDAP_MGR_PASSWORD_ALIAS = "ambari.ldap.manager.password"
-LDAP_MGR_PASSWORD_PROPERTY = "authentication.ldap.managerPassword"
-LDAP_MGR_PASSWORD_FILENAME = "ldap-password.dat"
-LDAP_MGR_USERNAME_PROPERTY = "authentication.ldap.managerDn"
-LDAP_PRIMARY_URL_PROPERTY = "authentication.ldap.primaryUrl"
+LDAP_MGR_PASSWORD_PROPERTY = "ambari.ldap.connectivity.bind_password"
# SSL truststore
SSL_TRUSTSTORE_PASSWORD_ALIAS = "ambari.ssl.trustStore.password"
diff --git a/ambari-server/src/main/python/ambari_server/serverUpgrade.py b/ambari-server/src/main/python/ambari_server/serverUpgrade.py
index dd847e3..accbd26 100644
--- a/ambari-server/src/main/python/ambari_server/serverUpgrade.py
+++ b/ambari-server/src/main/python/ambari_server/serverUpgrade.py
@@ -40,7 +40,7 @@ from ambari_server.serverConfiguration import configDefaults, get_resources_loca
check_database_name_property, get_ambari_properties, get_ambari_version, \
get_java_exe_path, get_stack_location, parse_properties_file, read_ambari_user, update_ambari_properties, \
update_database_name_property, get_admin_views_dir, get_views_dir, get_views_jars, \
- AMBARI_PROPERTIES_FILE, IS_LDAP_CONFIGURED, LDAP_PRIMARY_URL_PROPERTY, RESOURCES_DIR_PROPERTY, \
+ AMBARI_PROPERTIES_FILE, CLIENT_SECURITY, RESOURCES_DIR_PROPERTY, \
SETUP_OR_UPGRADE_MSG, update_krb_jaas_login_properties, AMBARI_KRB_JAAS_LOGIN_FILE, get_db_type, update_ambari_env, \
AMBARI_ENV_FILE, JDBC_DATABASE_PROPERTY, get_default_views_dir, write_gpl_license_accepted
from ambari_server.setupSecurity import adjust_directory_permissions, \
@@ -304,9 +304,9 @@ def upgrade(args):
for views_jar in views_jars:
os.utime(views_jar, None)
- # check if ambari has obsolete LDAP configuration
- if properties.get_property(LDAP_PRIMARY_URL_PROPERTY) and not properties.get_property(IS_LDAP_CONFIGURED):
- args.warnings.append("Existing LDAP configuration is detected. You must run the \"ambari-server setup-ldap\" command to adjust existing LDAP configuration.")
+ # check if ambari is configured to use LDAP authentication
+ if properties.get_property(CLIENT_SECURITY) == "ldap":
+ args.warnings.append("LDAP authentication is detected. You must run the \"ambari-server setup-ldap\" command to adjust existing LDAP configuration.")
# adding custom jdbc name and previous custom jdbc properties
# we need that to support new dynamic jdbc names for upgraded ambari
diff --git a/ambari-server/src/main/python/ambari_server/setupSecurity.py b/ambari-server/src/main/python/ambari_server/setupSecurity.py
index f175d7c..47bc3e4 100644
--- a/ambari-server/src/main/python/ambari_server/setupSecurity.py
+++ b/ambari-server/src/main/python/ambari_server/setupSecurity.py
@@ -42,10 +42,10 @@ from ambari_server.serverConfiguration import configDefaults, parse_properties_f
get_credential_store_location, get_is_persisted, get_is_secure, get_master_key_location, get_db_type, write_property, \
get_original_master_key, get_value_from_properties, get_java_exe_path, is_alias_string, read_ambari_user, \
read_passwd_for_alias, remove_password_file, save_passwd_for_alias, store_password_file, update_properties_2, \
- BLIND_PASSWORD, BOOTSTRAP_DIR_PROPERTY, IS_LDAP_CONFIGURED, JDBC_PASSWORD_FILENAME, JDBC_PASSWORD_PROPERTY, \
+ BLIND_PASSWORD, BOOTSTRAP_DIR_PROPERTY, JDBC_PASSWORD_FILENAME, JDBC_PASSWORD_PROPERTY, \
JDBC_RCA_PASSWORD_ALIAS, JDBC_RCA_PASSWORD_FILE_PROPERTY, JDBC_USE_INTEGRATED_AUTH_PROPERTY, \
- LDAP_MGR_PASSWORD_ALIAS, LDAP_MGR_PASSWORD_FILENAME, LDAP_MGR_PASSWORD_PROPERTY, LDAP_MGR_USERNAME_PROPERTY, \
- LDAP_PRIMARY_URL_PROPERTY, SECURITY_IS_ENCRYPTION_ENABLED, SECURITY_KEY_ENV_VAR_NAME, SECURITY_KERBEROS_JASS_FILENAME, \
+ LDAP_MGR_PASSWORD_ALIAS, LDAP_MGR_PASSWORD_PROPERTY, CLIENT_SECURITY, \
+ SECURITY_IS_ENCRYPTION_ENABLED, SECURITY_KEY_ENV_VAR_NAME, SECURITY_KERBEROS_JASS_FILENAME, \
SECURITY_PROVIDER_KEY_CMD, SECURITY_MASTER_KEY_FILENAME, SSL_TRUSTSTORE_PASSWORD_ALIAS, \
SSL_TRUSTSTORE_PASSWORD_PROPERTY, SSL_TRUSTSTORE_PATH_PROPERTY, SSL_TRUSTSTORE_TYPE_PROPERTY, \
SSL_API, SSL_API_PORT, DEFAULT_SSL_API_PORT, CLIENT_API_PORT, JDK_NAME_PROPERTY, JCE_NAME_PROPERTY, JAVA_HOME_PROPERTY, \
@@ -61,6 +61,7 @@ logger = logging.getLogger(__name__)
REGEX_IP_ADDRESS = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"
REGEX_HOSTNAME = "^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$"
+REGEX_PORT = "^([0-9]{1,5}$)"
REGEX_HOSTNAME_PORT = "^(.*:[0-9]{1,5}$)"
REGEX_TRUE_FALSE = "^(true|false)?$"
REGEX_SKIP_CONVERT = "^(skip|convert)?$"
@@ -70,14 +71,16 @@ LDAP_TO_PAM_MIGRATION_HELPER_CMD = "{0} -cp {1} " + \
"org.apache.ambari.server.security.authentication.LdapToPamMigrationHelper" + \
" >> " + configDefaults.SERVER_OUT_FILE + " 2>&1"
-CLIENT_SECURITY_KEY = "client.security"
-
AUTO_GROUP_CREATION = "auto.group.creation"
SERVER_API_LDAP_URL = 'ldap_sync_events'
+SETUP_LDAP_CONFIG_URL = 'services/AMBARI/components/AMBARI_SERVER/configurations/ldap-configuration'
PAM_CONFIG_FILE = 'pam.configuration'
+IS_LDAP_CONFIGURED = "ambari.ldap.authentication.enabled"
+LDAP_MGR_USERNAME_PROPERTY = "ambari.ldap.connectivity.bind_dn"
+LDAP_MGR_PASSWORD_FILENAME = "ldap-password.dat"
def read_master_key(isReset=False, options = None):
passwordPattern = ".*"
@@ -278,7 +281,7 @@ def sync_ldap(options):
properties = get_ambari_properties()
- if get_value_from_properties(properties,CLIENT_SECURITY_KEY,"") == 'pam':
+ if get_value_from_properties(properties,CLIENT_SECURITY,"") == 'pam':
err = "PAM is configured. Can not sync LDAP."
raise FatalException(1, err)
@@ -587,37 +590,76 @@ class LdapPropTemplate:
def init_ldap_properties_list_reqd(properties, options):
# python2.x dict is not ordered
ldap_properties = [
- LdapPropTemplate(properties, options.ldap_url, "authentication.ldap.primaryUrl", "Primary URL* {{host:port}} {0}: ", REGEX_HOSTNAME_PORT, False),
- LdapPropTemplate(properties, options.ldap_secondary_url, "authentication.ldap.secondaryUrl", "Secondary URL {{host:port}} {0}: ", REGEX_HOSTNAME_PORT, True),
- LdapPropTemplate(properties, options.ldap_ssl, "authentication.ldap.useSSL", "Use SSL* [true/false] {0}: ", REGEX_TRUE_FALSE, False, "false"),
- LdapPropTemplate(properties, options.ldap_user_attr, "authentication.ldap.usernameAttribute", "User name attribute* {0}: ", REGEX_ANYTHING, False, "uid"),
- LdapPropTemplate(properties, options.ldap_base_dn, "authentication.ldap.baseDn", "Base DN* {0}: ", REGEX_ANYTHING, False),
- LdapPropTemplate(properties, options.ldap_referral, "authentication.ldap.referral", "Referral method [follow/ignore] {0}: ", REGEX_REFERRAL, True),
- LdapPropTemplate(properties, options.ldap_bind_anonym, "authentication.ldap.bindAnonymously" "Bind anonymously* [true/false] {0}: ", REGEX_TRUE_FALSE, False, "false")
+ LdapPropTemplate(properties, options.ldap_url_host, "ambari.ldap.connectivity.server.host", "Primary URL Host* {0}: ", REGEX_HOSTNAME, False),
+ LdapPropTemplate(properties, options.ldap_url_port, "ambari.ldap.connectivity.server.port", "Primary URL Port* {0}: ", REGEX_PORT, False),
+ LdapPropTemplate(properties, options.ldap_secondary_url_host, "ambari.ldap.connectivity.secondary.server.host", "Secondary URL Host {0}: ", REGEX_HOSTNAME, True),
+ LdapPropTemplate(properties, options.ldap_secondary_url_port, "ambari.ldap.connectivity.secondary.server.port", "Secondary URL Port {0}: ", REGEX_PORT, True),
+ LdapPropTemplate(properties, options.ldap_ssl, "ambari.ldap.connectivity.use_ssl", "Use SSL* [true/false] {0}: ", REGEX_TRUE_FALSE, False, "false"),
+ LdapPropTemplate(properties, options.ldap_user_attr, "ambari.ldap.attributes.user.name_attr", "User name attribute* {0}: ", REGEX_ANYTHING, False, "uid"),
+ LdapPropTemplate(properties, options.ldap_base_dn, "ambari.ldap.attributes.user.search_base", "Base DN* {0}: ", REGEX_ANYTHING, False, "dc=ambari,dc=apache,dc=org"),
+ LdapPropTemplate(properties, options.ldap_referral, "ambari.ldap.advanced.referrals", "Referral method [follow/ignore] {0}: ", REGEX_REFERRAL, True),
+ LdapPropTemplate(properties, options.ldap_bind_anonym, "ambari.ldap.connectivity.anonymous_bind" "Bind anonymously* [true/false] {0}: ", REGEX_TRUE_FALSE, False, "false")
]
return ldap_properties
@OsFamilyFuncImpl(OsFamilyImpl.DEFAULT)
def init_ldap_properties_list_reqd(properties, options):
ldap_properties = [
- LdapPropTemplate(properties, options.ldap_url, LDAP_PRIMARY_URL_PROPERTY, "Primary URL* {{host:port}} {0}: ", REGEX_HOSTNAME_PORT, False),
- LdapPropTemplate(properties, options.ldap_secondary_url, "authentication.ldap.secondaryUrl", "Secondary URL {{host:port}} {0}: ", REGEX_HOSTNAME_PORT, True),
- LdapPropTemplate(properties, options.ldap_ssl, "authentication.ldap.useSSL", "Use SSL* [true/false] {0}: ", REGEX_TRUE_FALSE, False, "false"),
- LdapPropTemplate(properties, options.ldap_user_class, "authentication.ldap.userObjectClass", "User object class* {0}: ", REGEX_ANYTHING, False, "posixAccount"),
- LdapPropTemplate(properties, options.ldap_user_attr, "authentication.ldap.usernameAttribute", "User name attribute* {0}: ", REGEX_ANYTHING, False, "uid"),
- LdapPropTemplate(properties, options.ldap_group_class, "authentication.ldap.groupObjectClass", "Group object class* {0}: ", REGEX_ANYTHING, False, "posixGroup"),
- LdapPropTemplate(properties, options.ldap_group_attr, "authentication.ldap.groupNamingAttr", "Group name attribute* {0}: ", REGEX_ANYTHING, False, "cn"),
- LdapPropTemplate(properties, options.ldap_member_attr, "authentication.ldap.groupMembershipAttr", "Group member attribute* {0}: ", REGEX_ANYTHING, False, "memberUid"),
- LdapPropTemplate(properties, options.ldap_dn, "authentication.ldap.dnAttribute", "Distinguished name attribute* {0}: ", REGEX_ANYTHING, False, "dn"),
- LdapPropTemplate(properties, options.ldap_base_dn, "authentication.ldap.baseDn", "Base DN* {0}: ", REGEX_ANYTHING, False),
- LdapPropTemplate(properties, options.ldap_referral, "authentication.ldap.referral", "Referral method [follow/ignore] {0}: ", REGEX_REFERRAL, True),
- LdapPropTemplate(properties, options.ldap_bind_anonym, "authentication.ldap.bindAnonymously", "Bind anonymously* [true/false] {0}: ", REGEX_TRUE_FALSE, False, "false"),
- LdapPropTemplate(properties, options.ldap_sync_username_collisions_behavior, "ldap.sync.username.collision.behavior", "Handling behavior for username collisions [convert/skip] for LDAP sync* {0}: ", REGEX_SKIP_CONVERT, False, "convert"),
+ LdapPropTemplate(properties, options.ldap_url_host, "ambari.ldap.connectivity.server.host", "Primary URL Host* {0}: ", REGEX_HOSTNAME, False),
+ LdapPropTemplate(properties, options.ldap_url_port, "ambari.ldap.connectivity.server.port", "Primary URL Port* {0}: ", REGEX_PORT, False),
+ LdapPropTemplate(properties, options.ldap_secondary_url_host, "ambari.ldap.connectivity.secondary.server.host", "Secondary URL Host {0}: ", REGEX_HOSTNAME, True),
+ LdapPropTemplate(properties, options.ldap_secondary_url_port, "ambari.ldap.connectivity.secondary.server.port", "Secondary URL Port {0}: ", REGEX_PORT, True),
+ LdapPropTemplate(properties, options.ldap_ssl, "ambari.ldap.connectivity.use_ssl", "Use SSL* [true/false] {0}: ", REGEX_TRUE_FALSE, False, "false"),
+ LdapPropTemplate(properties, options.ldap_user_class, "ambari.ldap.attributes.user.object_class", "User object class* {0}: ", REGEX_ANYTHING, False, "person"),
+ LdapPropTemplate(properties, options.ldap_user_attr, "ambari.ldap.attributes.user.name_attr", "User name attribute* {0}: ", REGEX_ANYTHING, False, "uid"),
+ LdapPropTemplate(properties, options.ldap_group_class, "ambari.ldap.attributes.group.object_class", "Group object class* {0}: ", REGEX_ANYTHING, False, "ou=groups,dc=ambari,dc=apache,dc=org"),
+ LdapPropTemplate(properties, options.ldap_group_attr, "ambari.ldap.attributes.group.name_attr", "Group name attribute* {0}: ", REGEX_ANYTHING, False, "cn"),
+ LdapPropTemplate(properties, options.ldap_member_attr, "ambari.ldap.attributes.group.member_attr", "Group member attribute* {0}: ", REGEX_ANYTHING, False, "memberUid"),
+ LdapPropTemplate(properties, options.ldap_dn, "ambari.ldap.attributes.dn_attr", "Distinguished name attribute* {0}: ", REGEX_ANYTHING, False, "dn"),
+ LdapPropTemplate(properties, options.ldap_base_dn, "ambari.ldap.attributes.user.search_base", "Base DN* {0}: ", REGEX_ANYTHING, False, "dc=ambari,dc=apache,dc=org"),
+ LdapPropTemplate(properties, options.ldap_referral, "ambari.ldap.advanced.referrals", "Referral method [follow/ignore] {0}: ", REGEX_REFERRAL, True),
+ LdapPropTemplate(properties, options.ldap_bind_anonym, "ambari.ldap.connectivity.anonymous_bind", "Bind anonymously* [true/false] {0}: ", REGEX_TRUE_FALSE, False, "false"),
+ LdapPropTemplate(properties, options.ldap_sync_username_collisions_behavior, "ambari.ldap.advance.collision_behavior", "Handling behavior for username collisions [convert/skip] for LDAP sync* {0}: ", REGEX_SKIP_CONVERT, False, "convert"),
+ LdapPropTemplate(properties, options.ldap_force_lowercase_usernames, "ambari.ldap.advanced.force_lowercase_usernames", "Force lower-case user names [true/false] {0}:", REGEX_TRUE_FALSE, True),
+ LdapPropTemplate(properties, options.ldap_pagination_enabled, "ambari.ldap.advanced.pagination_enabled", "Results from LDAP are paginated when requested [true/false] {0}:", REGEX_TRUE_FALSE, True)
]
return ldap_properties
+def update_ldap_configuration(properties, ldap_property_value_map):
+ admin_login = get_validated_string_input("Enter Ambari Admin login: ", None, None, None, False, False)
+ admin_password = get_validated_string_input("Enter Ambari Admin password: ", None, None, None, True, False)
+ 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')
+ data = {
+ "Configuration": {
+ "service_name": "AMBARI",
+ "component_name": "AMBARI_SERVER",
+ "category": "ldap-configuration",
+ "properties": {
+ }
+ }
+ }
+ data['Configuration']['properties'] = ldap_property_value_map
+ request.add_data(json.dumps(data))
+ request.get_method = lambda: 'PUT'
+
+ try:
+ response = urllib2.urlopen(request)
+ except Exception as e:
+ err = 'Updating LDAP configuration failed. Error details: %s' % e
+ raise FatalException(1, err)
+
+ response_status_code = response.getcode()
+ if response_status_code != 200:
+ err = 'Error during syncing. Http status code - ' + str(response_status_code)
+ raise FatalException(1, err)
+
def setup_ldap(options):
logger.info("Setup LDAP.")
+
if not is_root():
err = 'Ambari-server setup-ldap should be run with ' \
'root-level privileges'
@@ -625,7 +667,12 @@ def setup_ldap(options):
properties = get_ambari_properties()
- if get_value_from_properties(properties,CLIENT_SECURITY_KEY,"") == 'pam':
+ server_status, pid = is_server_runing()
+ if not server_status:
+ err = 'Ambari Server is not running.'
+ raise FatalException(1, err)
+
+ if get_value_from_properties(properties,CLIENT_SECURITY,"") == 'pam':
query = "PAM is currently configured, do you wish to use LDAP instead [y/n] (n)? "
if get_YN_input(query, False):
pass
@@ -637,20 +684,16 @@ def setup_ldap(options):
ldap_property_list_reqd = init_ldap_properties_list_reqd(properties, options)
- ldap_property_list_opt = ["authentication.ldap.managerDn",
+ ldap_property_list_opt = ["ambari.ldap.connectivity.bind_dn",
LDAP_MGR_PASSWORD_PROPERTY,
SSL_TRUSTSTORE_TYPE_PROPERTY,
SSL_TRUSTSTORE_PATH_PROPERTY,
SSL_TRUSTSTORE_PASSWORD_PROPERTY]
- ldap_property_list_truststore=[SSL_TRUSTSTORE_TYPE_PROPERTY,
- SSL_TRUSTSTORE_PATH_PROPERTY,
- SSL_TRUSTSTORE_PASSWORD_PROPERTY]
-
ldap_property_list_passwords=[LDAP_MGR_PASSWORD_PROPERTY,
SSL_TRUSTSTORE_PASSWORD_PROPERTY]
- LDAP_MGR_DN_DEFAULT = get_value_from_properties(properties, ldap_property_list_opt[0])
+ LDAP_MGR_DN_DEFAULT = None
SSL_TRUSTSTORE_TYPE_DEFAULT = get_value_from_properties(properties, SSL_TRUSTSTORE_TYPE_PROPERTY, "jks")
SSL_TRUSTSTORE_PATH_DEFAULT = get_value_from_properties(properties, SSL_TRUSTSTORE_PATH_PROPERTY)
@@ -663,7 +706,7 @@ def setup_ldap(options):
if input is not None and input != "":
ldap_property_value_map[ldap_prop.prop_name] = input
- bindAnonymously = ldap_property_value_map["authentication.ldap.bindAnonymously"]
+ bindAnonymously = ldap_property_value_map["ambari.ldap.connectivity.anonymous_bind"]
anonymous = (bindAnonymously and bindAnonymously.lower() == 'true')
mgr_password = None
# Ask for manager credentials only if bindAnonymously is false
@@ -675,7 +718,7 @@ def setup_ldap(options):
mgr_password = configure_ldap_password(options)
ldap_property_value_map[LDAP_MGR_PASSWORD_PROPERTY] = mgr_password
- useSSL = ldap_property_value_map["authentication.ldap.useSSL"]
+ useSSL = ldap_property_value_map["ambari.ldap.connectivity.use_ssl"]
ldaps = (useSSL and useSSL.lower() == 'true')
ts_password = None
@@ -725,7 +768,7 @@ def setup_ldap(options):
print 'Review Settings'
print '=' * 20
for property in ldap_property_list_reqd:
- if property in ldap_property_value_map:
+ if ldap_property_value_map.has_key(property):
print("%s: %s" % (property, ldap_property_value_map[property]))
for property in ldap_property_list_opt:
@@ -738,7 +781,6 @@ def setup_ldap(options):
save_settings = True if options.ldap_save_settings is not None else get_YN_input("Save settings [y/n] (y)? ", True)
if save_settings:
- ldap_property_value_map[CLIENT_SECURITY_KEY] = 'ldap'
if isSecure:
if mgr_password:
encrypted_passwd = encrypt_password(LDAP_MGR_PASSWORD_ALIAS, mgr_password, options)
@@ -753,11 +795,21 @@ def setup_ldap(options):
pass
# Persisting values
- ldap_property_value_map[IS_LDAP_CONFIGURED] = "true"
if mgr_password:
ldap_property_value_map[LDAP_MGR_PASSWORD_PROPERTY] = store_password_file(mgr_password, LDAP_MGR_PASSWORD_FILENAME)
+
+ print 'Saving LDAP properties...'
+
+ ldap_property_value_map[IS_LDAP_CONFIGURED] = "true"
+ #Saving LDAP configuration in Ambari DB using the REST API
+ update_ldap_configuration(properties, ldap_property_value_map)
+
+ #The only property we want to write out in Ambari.properties is the client.security type being LDAP
+ ldap_property_value_map.clear()
+ ldap_property_value_map[CLIENT_SECURITY] = 'ldap'
update_properties_2(properties, ldap_property_value_map)
- print 'Saving...done'
+
+ print 'Saving LDAP properties finished'
return 0
@@ -855,7 +907,7 @@ def setup_pam(options):
properties = get_ambari_properties()
- if get_value_from_properties(properties,CLIENT_SECURITY_KEY,"") == 'ldap':
+ if get_value_from_properties(properties,CLIENT_SECURITY,"") == 'ldap':
query = "LDAP is currently configured, do you wish to use PAM instead [y/n] (n)? "
if get_YN_input(query, False):
pass
@@ -866,7 +918,7 @@ def setup_pam(options):
pam_property_list_reqd = init_pam_properties_list_reqd(properties, options)
pam_property_value_map = {}
- pam_property_value_map[CLIENT_SECURITY_KEY] = 'pam'
+ pam_property_value_map[CLIENT_SECURITY] = 'pam'
for pam_prop in pam_property_list_reqd:
input = get_validated_string_input(pam_prop.pam_prop_val_prompt, pam_prop.pam_prop_name, pam_prop.prompt_regex,
@@ -891,7 +943,7 @@ def setup_pam(options):
def migrate_ldap_pam(args):
properties = get_ambari_properties()
- if get_value_from_properties(properties,CLIENT_SECURITY_KEY,"") != 'pam':
+ if get_value_from_properties(properties,CLIENT_SECURITY,"") != 'pam':
err = "PAM is not configured. Please configure PAM authentication first."
raise FatalException(1, err)
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RootServiceComponentConfigurationResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RootServiceComponentConfigurationResourceProviderTest.java
index bd0ff1d..6dbdd65 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RootServiceComponentConfigurationResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RootServiceComponentConfigurationResourceProviderTest.java
@@ -530,7 +530,7 @@ public class RootServiceComponentConfigurationResourceProviderTest extends EasyM
private void setupBasicExpectations(Map<String, String> expectedProperties) {
expect(request.getProperties()).andReturn(propertySets).once();
expect(request.getRequestInfoProperties()).andReturn(new HashMap<>());
- expect(dao.findByCategory(LDAP_CONFIG_CATEGORY)).andReturn(createEntities(AmbariServerConfigurationCategory.LDAP_CONFIGURATION.getCategoryName(), expectedProperties)).once();
+ expect(dao.findByCategory(LDAP_CONFIG_CATEGORY)).andReturn(createEntities(AmbariServerConfigurationCategory.LDAP_CONFIGURATION.getCategoryName(), expectedProperties)).times(2);
expect(factory.getInstance(RootService.AMBARI.name(), RootComponent.AMBARI_SERVER.name(), LDAP_CONFIG_CATEGORY)).andReturn(new AmbariServerLDAPConfigurationHandler()).once();
}
diff --git a/ambari-server/src/test/python/TestAmbariServer.py b/ambari-server/src/test/python/TestAmbariServer.py
index 9152d0f..e1d0b3c 100644
--- a/ambari-server/src/test/python/TestAmbariServer.py
+++ b/ambari-server/src/test/python/TestAmbariServer.py
@@ -97,14 +97,14 @@ with patch.object(platform, "linux_distribution", return_value = MagicMock(retur
AMBARI_CONF_VAR, AMBARI_SERVER_LIB, JDBC_DATABASE_PROPERTY, JDBC_RCA_PASSWORD_FILE_PROPERTY, \
PERSISTENCE_TYPE_PROPERTY, JDBC_URL_PROPERTY, get_conf_dir, JDBC_USER_NAME_PROPERTY, JDBC_PASSWORD_PROPERTY, \
JDBC_DATABASE_NAME_PROPERTY, OS_TYPE_PROPERTY, validate_jdk, JDBC_POSTGRES_SCHEMA_PROPERTY, \
- RESOURCES_DIR_PROPERTY, JDBC_RCA_PASSWORD_ALIAS, JDBC_RCA_SCHEMA_PROPERTY, IS_LDAP_CONFIGURED, \
+ RESOURCES_DIR_PROPERTY, JDBC_RCA_PASSWORD_ALIAS, JDBC_RCA_SCHEMA_PROPERTY, \
SSL_API, SSL_API_PORT, CLIENT_API_PORT_PROPERTY,\
JDBC_CONNECTION_POOL_TYPE, JDBC_CONNECTION_POOL_ACQUISITION_SIZE, \
JDBC_CONNECTION_POOL_IDLE_TEST_INTERVAL, JDBC_CONNECTION_POOL_MAX_AGE, JDBC_CONNECTION_POOL_MAX_IDLE_TIME, \
JDBC_CONNECTION_POOL_MAX_IDLE_TIME_EXCESS,\
LDAP_MGR_PASSWORD_PROPERTY, LDAP_MGR_PASSWORD_ALIAS, JDBC_PASSWORD_FILENAME, NR_USER_PROPERTY, SECURITY_KEY_IS_PERSISTED, \
SSL_TRUSTSTORE_PASSWORD_PROPERTY, SECURITY_IS_ENCRYPTION_ENABLED, PID_DIR_PROPERTY, SSL_TRUSTSTORE_PASSWORD_ALIAS, \
- SECURITY_MASTER_KEY_LOCATION, SECURITY_KEYS_DIR, LDAP_PRIMARY_URL_PROPERTY, store_password_file, \
+ SECURITY_MASTER_KEY_LOCATION, SECURITY_KEYS_DIR, store_password_file, \
get_pass_file_path, GET_FQDN_SERVICE_URL, JDBC_USE_INTEGRATED_AUTH_PROPERTY, SECURITY_KEY_ENV_VAR_NAME, \
JAVA_HOME_PROPERTY, JDK_NAME_PROPERTY, JCE_NAME_PROPERTY, STACK_LOCATION_KEY, SERVER_VERSION_FILE_PATH, \
COMMON_SERVICES_PATH_PROPERTY, WEBAPP_DIR_PROPERTY, SHARED_RESOURCES_DIR, BOOTSTRAP_SCRIPT, \
@@ -121,7 +121,7 @@ with patch.object(platform, "linux_distribution", return_value = MagicMock(retur
SRVR_ONE_WAY_SSL_PORT_PROPERTY, SRVR_TWO_WAY_SSL_PORT_PROPERTY, GANGLIA_HTTPS
from ambari_server.setupSecurity import adjust_directory_permissions, get_alias_string, get_ldap_event_spec_names, sync_ldap, LdapSyncOptions, \
configure_ldap_password, setup_ldap, REGEX_HOSTNAME_PORT, REGEX_TRUE_FALSE, REGEX_ANYTHING, setup_master_key, \
- setup_ambari_krb5_jaas, ensure_can_start_under_current_user, generate_env
+ setup_ambari_krb5_jaas, ensure_can_start_under_current_user, generate_env, IS_LDAP_CONFIGURED
from ambari_server.userInput import get_YN_input, get_choice_string_input, get_validated_string_input, \
read_password
from ambari_server_main import get_ulimit_open_files, ULIMIT_OPEN_FILES_KEY, ULIMIT_OPEN_FILES_DEFAULT
@@ -7147,15 +7147,16 @@ class TestAmbariServer(TestCase):
def _init_test_ldap_properties_map_invalid_input_1():
ldap_properties_map = \
{
- LDAP_PRIMARY_URL_PROPERTY: "a:3",
- "authentication.ldap.secondaryUrl": "b:2",
- "authentication.ldap.useSSL": "false",
- "authentication.ldap.usernameAttribute": "user",
- "authentication.ldap.baseDn": "uid",
- "authentication.ldap.bindAnonymously": "true",
- "authentication.ldap.referral": "follow",
- "client.security": "ldap",
- "ambari.ldap.isConfigured": "true"
+ "ambari.ldap.connectivity.server.host": "a",
+ "ambari.ldap.connectivity.server.port" : "3",
+ "ambari.ldap.connectivity.secondary.server.host": "b",
+ "ambari.ldap.connectivity.secondary.server.port" : "2",
+ "ambari.ldap.connectivity.use_ssl": "false",
+ "ambari.ldap.attributes.user.name_attr": "user",
+ "ambari.ldap.attributes.user.search_base": "uid",
+ "ambari.ldap.connectivity.anonymous_bind": "true",
+ "ambari.ldap.advanced.referrals": "follow",
+ "ambari.ldap.authentication.enabled": "true"
}
return ldap_properties_map
@@ -7164,21 +7165,24 @@ class TestAmbariServer(TestCase):
def _init_test_ldap_properties_map_invalid_input_1():
ldap_properties_map = \
{
- LDAP_PRIMARY_URL_PROPERTY: "a:3",
- "authentication.ldap.secondaryUrl": "b:2",
- "authentication.ldap.useSSL": "false",
- "authentication.ldap.userObjectClass": "user",
- "authentication.ldap.usernameAttribute": "uid",
- "authentication.ldap.groupObjectClass": "group",
- "authentication.ldap.groupNamingAttr": "cn",
- "authentication.ldap.groupMembershipAttr": "member",
- "authentication.ldap.dnAttribute": "dn",
- "authentication.ldap.baseDn": "base",
- "authentication.ldap.referral": "follow",
- "authentication.ldap.bindAnonymously": "true",
- "ldap.sync.username.collision.behavior": "skip",
- "client.security": "ldap",
- "ambari.ldap.isConfigured": "true"
+ "ambari.ldap.connectivity.server.host": "a",
+ "ambari.ldap.connectivity.server.port" : "3",
+ "ambari.ldap.connectivity.secondary.server.host": "b",
+ "ambari.ldap.connectivity.secondary.server.port" : "2",
+ "ambari.ldap.connectivity.use_ssl": "false",
+ "ambari.ldap.attributes.user.object_class": "user",
+ "ambari.ldap.attributes.user.name_attr": "uid",
+ "ambari.ldap.attributes.group.object_class": "group",
+ "ambari.ldap.attributes.group.name_attr": "cn",
+ "ambari.ldap.attributes.group.member_attr": "member",
+ "ambari.ldap.attributes.dn_attr": "dn",
+ "ambari.ldap.attributes.user.search_base": "base",
+ "ambari.ldap.advanced.referrals": "follow",
+ "ambari.ldap.connectivity.anonymous_bind": "true",
+ "ambari.ldap.advance.collision_behavior": "skip",
+ "ambari.ldap.advanced.force_lowercase_usernames": "false",
+ "ambari.ldap.advanced.pagination_enabled": "false",
+ "ambari.ldap.authentication.enabled": "true"
}
return ldap_properties_map
@@ -7187,15 +7191,17 @@ class TestAmbariServer(TestCase):
def _init_test_ldap_properties_map_invalid_input_2():
ldap_properties_map = \
{
- LDAP_PRIMARY_URL_PROPERTY: "a:3",
- "authentication.ldap.useSSL": "false",
- "authentication.ldap.usernameAttribute": "user",
- "authentication.ldap.baseDn": "uid",
- "authentication.ldap.bindAnonymously": "true",
- "ldap.sync.username.collision.behavior": "skip",
- "authentication.ldap.referral": "follow",
- "client.security": "ldap",
- "ambari.ldap.isConfigured": "true"
+ "ambari.ldap.connectivity.server.host": "a",
+ "ambari.ldap.connectivity.server.port" : "3",
+ "ambari.ldap.connectivity.use_ssl": "false",
+ "ambari.ldap.attributes.user.name_attr": "user",
+ "ambari.ldap.attributes.user.search_base": "uid",
+ "ambari.ldap.connectivity.anonymous_bind": "true",
+ "ambari.ldap.advance.collision_behavior": "skip",
+ "ambari.ldap.advanced.force_lowercase_usernames": "false",
+ "ambari.ldap.advanced.pagination_enabled": "false",
+ "ambari.ldap.advanced.referrals": "follow",
+ "ambari.ldap.authentication.enabled": "true"
}
return ldap_properties_map
@@ -7204,25 +7210,29 @@ class TestAmbariServer(TestCase):
def _init_test_ldap_properties_map_invalid_input_2():
ldap_properties_map = \
{
- LDAP_PRIMARY_URL_PROPERTY: "a:3",
- "authentication.ldap.useSSL": "false",
- "authentication.ldap.userObjectClass": "user",
- "authentication.ldap.usernameAttribute": "uid",
- "authentication.ldap.groupObjectClass": "group",
- "authentication.ldap.groupNamingAttr": "cn",
- "authentication.ldap.groupMembershipAttr": "member",
- "authentication.ldap.dnAttribute": "dn",
- "authentication.ldap.baseDn": "base",
- "authentication.ldap.referral": "follow",
- "authentication.ldap.bindAnonymously": "true",
- "ldap.sync.username.collision.behavior": "skip",
- "client.security": "ldap",
- "ambari.ldap.isConfigured": "true"
+ "ambari.ldap.connectivity.server.host": "a",
+ "ambari.ldap.connectivity.server.port" : "3",
+ "ambari.ldap.connectivity.use_ssl": "false",
+ "ambari.ldap.attributes.user.object_class": "user",
+ "ambari.ldap.attributes.user.name_attr": "uid",
+ "ambari.ldap.attributes.group.object_class": "group",
+ "ambari.ldap.attributes.group.name_attr": "cn",
+ "ambari.ldap.attributes.group.member_attr": "member",
+ "ambari.ldap.attributes.dn_attr": "dn",
+ "ambari.ldap.attributes.user.search_base": "base",
+ "ambari.ldap.advanced.referrals": "follow",
+ "ambari.ldap.connectivity.anonymous_bind": "true",
+ "ambari.ldap.advance.collision_behavior": "skip",
+ "ambari.ldap.advanced.force_lowercase_usernames": "false",
+ "ambari.ldap.advanced.pagination_enabled": "false",
+ "ambari.ldap.authentication.enabled": "true"
}
return ldap_properties_map
@patch.object(OSCheck, "os_distribution", new = MagicMock(return_value = os_distro_value))
+ @patch("urllib2.urlopen")
@patch("__builtin__.raw_input")
+ @patch("ambari_server.userInput.get_password")
@patch("ambari_server.setupSecurity.get_is_secure")
@patch("ambari_server.setupSecurity.get_YN_input")
@patch("ambari_server.setupSecurity.update_properties_2")
@@ -7230,73 +7240,144 @@ class TestAmbariServer(TestCase):
@patch("ambari_server.setupSecurity.get_ambari_properties")
@patch("ambari_server.setupSecurity.is_root")
@patch("ambari_server.setupSecurity.logger")
- def test_setup_ldap_invalid_input(self, logger_mock, is_root_method, get_ambari_properties_method,
+ @patch("ambari_server.setupSecurity.is_server_runing")
+ def test_setup_ldap_invalid_input(self, is_server_runing_method, logger_mock, is_root_method, get_ambari_properties_method,
search_file_message,
update_properties_method,
get_YN_input_method,
get_is_secure_method,
- raw_input_mock):
+ get_password_mock, raw_input_mock, urlopen_mock):
out = StringIO.StringIO()
sys.stdout = out
is_root_method.return_value = True
+ is_server_runing_method.return_value = (True, 0)
search_file_message.return_value = "filepath"
- configs = {SECURITY_MASTER_KEY_LOCATION: "filepath",
- SECURITY_KEYS_DIR: tempfile.gettempdir(),
- SECURITY_IS_ENCRYPTION_ENABLED: "true"
- }
+ properties = Properties();
+ properties.process_pair(SECURITY_MASTER_KEY_LOCATION, "filepath")
+ properties.process_pair(SECURITY_KEYS_DIR, tempfile.gettempdir())
+ properties.process_pair(SECURITY_IS_ENCRYPTION_ENABLED, "true")
+ properties.process_pair(CLIENT_API_PORT_PROPERTY, '8080')
- get_ambari_properties_method.return_value = configs
- raw_input_mock.side_effect = ['a:3', 'b:b', 'hody', 'b:2', 'false', 'user', 'uid', 'group', 'cn', 'member', 'dn', 'base', 'follow', 'true', 'skip']
+ get_ambari_properties_method.return_value = properties
+ raw_input_mock.side_effect = ['a', '3', 'b', 'b', 'hody', 'b', '2', 'false', 'user', 'uid', 'group', 'cn', 'member', 'dn', 'base', 'follow', 'true', 'skip', 'false', 'false', 'admin']
+ get_password_mock.side_effect = ['admin']
set_silent(False)
get_YN_input_method.return_value = True
+
+ response = MagicMock()
+ response.getcode.return_value = 200
+ urlopen_mock.return_value = response
options = self._create_empty_options_mock()
setup_ldap(options)
-
- ldap_properties_map = TestAmbariServer._init_test_ldap_properties_map_invalid_input_1()
-
- sorted_x = sorted(ldap_properties_map.iteritems(), key=operator.itemgetter(0))
- sorted_y = sorted(update_properties_method.call_args[0][1].iteritems(),
- key=operator.itemgetter(0))
- self.assertEquals(sorted_x, sorted_y)
+
+ requestCall = urlopen_mock.call_args_list[0]
+ args, kwargs = requestCall
+ request = args[0]
+ requestData = json.loads(request.data)
+ self.assertTrue(isinstance(requestData, dict))
+ ldapProperties = requestData['Configuration']['properties'];
+ properties_updated_in_ambari_db = sorted(ldapProperties.iteritems(), key=operator.itemgetter(0))
+ properties_should_be_updated_in_ambari_db = sorted(TestAmbariServer._init_test_ldap_properties_map_invalid_input_1().iteritems(), key=operator.itemgetter(0))
+ self.assertEqual(properties_should_be_updated_in_ambari_db, properties_updated_in_ambari_db)
+
+ properties_updated_in_ambari_dot_properties = sorted(update_properties_method.call_args[0][1].iteritems(), key=operator.itemgetter(0))
+ properties_should_be_updated_in_ambari_dot_properties = sorted({"client.security": "ldap"}.iteritems(), key=operator.itemgetter(0))
+ self.assertEquals(properties_should_be_updated_in_ambari_dot_properties, properties_updated_in_ambari_dot_properties)
+
+ self.assertTrue(urlopen_mock.called)
+ self.assertTrue(update_properties_method.called)
self.assertTrue(get_YN_input_method.called)
- self.assertEquals(15, raw_input_mock.call_count)
-
+ self.assertEquals(21, raw_input_mock.call_count)
+ self.assertEqual(1, get_password_mock.call_count)
+
raw_input_mock.reset_mock()
- raw_input_mock.side_effect = ['a:3', '', 'b:2', 'false', 'user', 'uid', 'group', 'cn', 'member', 'dn', 'base', 'follow', 'true', 'skip']
+ raw_input_mock.side_effect = ['a', '3', '', '', 'b', '2', 'false', 'user', 'uid', 'group', 'cn', 'member', 'dn', 'base', 'follow', 'true', 'skip', 'false', 'false', 'admin']
+ get_password_mock.reset_mock()
+ get_password_mock.side_effect = ['admin']
+
+ urlopen_mock.reset_mock()
+ urlopen_mock.return_value = response
setup_ldap(options)
- ldap_properties_map = TestAmbariServer._init_test_ldap_properties_map_invalid_input_2()
+ requestCall = urlopen_mock.call_args_list[0]
+ args, kwargs = requestCall
+ request = args[0]
+ requestData = json.loads(request.data)
+ self.assertTrue(isinstance(requestData, dict))
+ ldapProperties = requestData['Configuration']['properties'];
+ properties_updated_in_ambari_db = sorted(ldapProperties.iteritems(), key=operator.itemgetter(0))
+ properties_should_be_updated_in_ambari_db = sorted(TestAmbariServer._init_test_ldap_properties_map_invalid_input_2().iteritems(), key=operator.itemgetter(0))
+ self.assertEqual(properties_should_be_updated_in_ambari_db, properties_updated_in_ambari_db)
+
+ properties_updated_in_ambari_dot_properties = sorted(update_properties_method.call_args[0][1].iteritems(), key=operator.itemgetter(0))
+ properties_should_be_updated_in_ambari_dot_properties = sorted({"client.security": "ldap"}.iteritems(), key=operator.itemgetter(0))
+ self.assertEquals(properties_should_be_updated_in_ambari_dot_properties, properties_updated_in_ambari_dot_properties)
- sorted_x = sorted(ldap_properties_map.iteritems(), key=operator.itemgetter(0))
- sorted_y = sorted(update_properties_method.call_args[0][1].iteritems(),
- key=operator.itemgetter(0))
- self.assertEquals(sorted_x, sorted_y)
- self.assertEquals(14, raw_input_mock.call_count)
+ self.assertTrue(urlopen_mock.called)
+ self.assertTrue(update_properties_method.called)
+ self.assertTrue(get_YN_input_method.called)
+ self.assertEquals(20, raw_input_mock.call_count)
+ self.assertEqual(1, get_password_mock.call_count)
sys.stdout = sys.__stdout__
pass
+ @patch("ambari_server.setupSecurity.is_root")
+ def test_setup_ldap_should_fail_if_executed_by_not_root_user(self, is_root_mock):
+ out = StringIO.StringIO()
+ sys.stdout = out
+ is_root_mock.return_value = False
+ try:
+ setup_ldap(self._create_empty_options_mock())
+ self.fail("Should throw exception")
+ except FatalException as fe:
+ self.assertTrue("root-level" in fe.reason)
+ pass
+
+ sys.stdout = sys.__stdout__
+ pass
+
+ @patch("ambari_server.setupSecurity.is_server_runing")
+ @patch("ambari_server.setupSecurity.is_root")
+ def test_setup_ldap_should_fail_if_ambari_server_is_not_running(self, is_root_mock, is_server_runing_mock):
+ out = StringIO.StringIO()
+ sys.stdout = out
+ is_root_mock.return_value = True
+ is_server_runing_mock.return_value = (False, 0)
+ try:
+ setup_ldap(self._create_empty_options_mock())
+ self.fail("Should throw exception")
+ except FatalException as fe:
+ self.assertTrue("Ambari Server is not running." == fe.reason)
+ pass
+
+ sys.stdout = sys.__stdout__
+ pass
@staticmethod
@OsFamilyFuncImpl(OSConst.WINSRV_FAMILY)
def _init_test_ldap_properties_map():
ldap_properties_map = \
{
- "authentication.ldap.primaryUrl": "test",
- "authentication.ldap.secondaryUrl": "test",
- "authentication.ldap.useSSL": "false",
- "authentication.ldap.usernameAttribute": "test",
- "authentication.ldap.baseDn": "test",
- "authentication.ldap.bindAnonymously": "false",
- "ldap.sync.username.collision.behavior": "skip",
- "authentication.ldap.managerDn": "test",
- "authentication.ldap.referral": "test",
+ "ambari.ldap.connectivity.server.host": "test",
+ "ambari.ldap.connectivity.server.port" : "1",
+ "ambari.ldap.connectivity.secondary.server.host": "test",
+ "ambari.ldap.connectivity.secondary.server.port" : "2",
+ "ambari.ldap.connectivity.use_ssl": "false",
+ "ambari.ldap.attributes.user.name_attr": "test",
+ "ambari.ldap.attributes.user.search_base": "test",
+ "ambari.ldap.connectivity.anonymous_bind": "false",
+ "ambari.ldap.advance.collision_behavior": "skip",
+ "ambari.ldap.advanced.force_lowercase_usernames": "false",
+ "ambari.ldap.advanced.pagination_enabled": "false",
+ "ambari.ldap.connectivity.bind_dn": "test",
+ "ambari.ldap.advanced.referrals": "test",
"client.security": "ldap",
LDAP_MGR_PASSWORD_PROPERTY: "ldap-password.dat",
- "ambari.ldap.isConfigured": "true"
+ "ambari.ldap.authentication.enabled": "true"
}
return ldap_properties_map
@@ -7305,27 +7386,31 @@ class TestAmbariServer(TestCase):
def _init_test_ldap_properties_map():
ldap_properties_map = \
{
- "authentication.ldap.primaryUrl": "test",
- "authentication.ldap.secondaryUrl": "test",
- "authentication.ldap.useSSL": "false",
- "authentication.ldap.userObjectClass": "test",
- "authentication.ldap.usernameAttribute": "test",
- "authentication.ldap.baseDn": "test",
- "authentication.ldap.bindAnonymously": "false",
- "ldap.sync.username.collision.behavior": "skip",
- "authentication.ldap.managerDn": "test",
- "authentication.ldap.groupObjectClass": "test",
- "authentication.ldap.groupMembershipAttr": "test",
- "authentication.ldap.groupNamingAttr": "test",
- "authentication.ldap.dnAttribute": "test",
- "authentication.ldap.referral": "test",
- "client.security": "ldap",
+ "ambari.ldap.connectivity.server.host": "test",
+ "ambari.ldap.connectivity.server.port" : "1",
+ "ambari.ldap.connectivity.secondary.server.host": "test",
+ "ambari.ldap.connectivity.secondary.server.port" : "1",
+ "ambari.ldap.connectivity.use_ssl": "false",
+ "ambari.ldap.attributes.user.object_class": "test",
+ "ambari.ldap.attributes.user.name_attr": "test",
+ "ambari.ldap.attributes.user.search_base": "test",
+ "ambari.ldap.connectivity.anonymous_bind": "false",
+ "ambari.ldap.advance.collision_behavior": "skip",
+ "ambari.ldap.advanced.force_lowercase_usernames": "false",
+ "ambari.ldap.advanced.pagination_enabled": "false",
+ "ambari.ldap.connectivity.bind_dn": "test",
+ "ambari.ldap.attributes.group.object_class": "test",
+ "ambari.ldap.attributes.group.member_attr": "test",
+ "ambari.ldap.attributes.group.name_attr": "test",
+ "ambari.ldap.attributes.dn_attr": "test",
+ "ambari.ldap.advanced.referrals": "test",
LDAP_MGR_PASSWORD_PROPERTY: "ldap-password.dat",
- "ambari.ldap.isConfigured": "true"
+ "ambari.ldap.authentication.enabled": "true"
}
return ldap_properties_map
@patch.object(OSCheck, "os_distribution", new = MagicMock(return_value = os_distro_value))
+ @patch("urllib2.urlopen")
@patch("ambari_server.setupSecurity.get_is_secure")
@patch("ambari_server.setupSecurity.encrypt_password")
@patch("ambari_server.setupSecurity.save_passwd_for_alias")
@@ -7339,37 +7424,29 @@ class TestAmbariServer(TestCase):
@patch("ambari_server.setupSecurity.read_password")
@patch("os.path.exists")
@patch("ambari_server.setupSecurity.logger")
- def test_setup_ldap(self, logger_mock, exists_method, read_password_method, is_root_method, get_ambari_properties_method,
+ @patch("ambari_server.setupSecurity.is_server_runing")
+ def test_setup_ldap(self, is_server_runing_method, logger_mock, exists_method, read_password_method, is_root_method, get_ambari_properties_method,
search_file_message,
get_validated_string_input_method,
configure_ldap_password_method, update_properties_method,
get_YN_input_method, save_passwd_for_alias_method,
- encrypt_password_method, get_is_secure_method):
+ encrypt_password_method, get_is_secure_method, urlopen_mock):
out = StringIO.StringIO()
sys.stdout = out
options = self._create_empty_options_mock()
- # Testing call under non-root
- is_root_method.return_value = False
- try:
- setup_ldap(options)
- self.fail("Should throw exception")
- except FatalException as fe:
- # Expected
- self.assertTrue("root-level" in fe.reason)
- pass
-
- # Testing call under root
is_root_method.return_value = True
+ is_server_runing_method.return_value = (True, 0)
search_file_message.return_value = "filepath"
- configs = {SECURITY_MASTER_KEY_LOCATION: "filepath",
- SECURITY_KEYS_DIR: tempfile.gettempdir(),
- SECURITY_IS_ENCRYPTION_ENABLED: "true"
- }
+ properties = Properties();
+ properties.process_pair(SECURITY_MASTER_KEY_LOCATION, "filepath")
+ properties.process_pair(SECURITY_KEYS_DIR, tempfile.gettempdir())
+ properties.process_pair(SECURITY_IS_ENCRYPTION_ENABLED, "true")
+ properties.process_pair(CLIENT_API_PORT_PROPERTY, '8080')
- get_ambari_properties_method.return_value = configs
+ get_ambari_properties_method.return_value = properties
configure_ldap_password_method.return_value = "password"
save_passwd_for_alias_method.return_value = 0
encrypt_password_method.return_value = get_alias_string(LDAP_MGR_PASSWORD_ALIAS)
@@ -7380,13 +7457,17 @@ class TestAmbariServer(TestCase):
else:
return True
- get_YN_input_method.side_effect = [True, ]
+ get_YN_input_method.side_effect = yn_input_side_effect
def valid_input_side_effect(*args, **kwargs):
- if 'Bind anonymously' in args[0]:
+ if 'Bind anonymously' in args[0] or 'lower-case' in args[0] or 'paginated' in args[0]:
return 'false'
if 'username collisions' in args[0]:
return 'skip'
+ if 'URL Port' in args[0]:
+ return '1'
+ if 'Ambari Admin' in args[0]:
+ return 'admin'
if args[1] == "true" or args[1] == "false":
return args[1]
else:
@@ -7394,14 +7475,27 @@ class TestAmbariServer(TestCase):
get_validated_string_input_method.side_effect = valid_input_side_effect
- setup_ldap(options)
+ response = MagicMock()
+ response.getcode.return_value = 200
+ urlopen_mock.return_value = response
- ldap_properties_map = TestAmbariServer._init_test_ldap_properties_map()
+ setup_ldap(options)
- sorted_x = sorted(ldap_properties_map.iteritems(), key=operator.itemgetter(0))
- sorted_y = sorted(update_properties_method.call_args[0][1].iteritems(),
- key=operator.itemgetter(0))
- self.assertEquals(sorted_x, sorted_y)
+ requestCall = urlopen_mock.call_args_list[0]
+ args, kwargs = requestCall
+ request = args[0]
+ requestData = json.loads(request.data)
+ self.assertTrue(isinstance(requestData, dict))
+ ldapProperties = requestData['Configuration']['properties'];
+ properties_updated_in_ambari_db = sorted(ldapProperties.iteritems(), key=operator.itemgetter(0))
+ properties_should_be_updated_in_ambari_db = sorted(TestAmbariServer._init_test_ldap_properties_map().iteritems(), key=operator.itemgetter(0))
+ self.assertEqual(properties_should_be_updated_in_ambari_db, properties_updated_in_ambari_db)
+
+ properties_updated_in_ambari_dot_properties = sorted(update_properties_method.call_args[0][1].iteritems(), key=operator.itemgetter(0))
+ properties_should_be_updated_in_ambari_dot_properties = sorted({"client.security": "ldap"}.iteritems(), key=operator.itemgetter(0))
+ self.assertEquals(properties_should_be_updated_in_ambari_dot_properties, properties_updated_in_ambari_dot_properties)
+
+ self.assertTrue(urlopen_mock.called)
self.assertTrue(update_properties_method.called)
self.assertTrue(configure_ldap_password_method.called)
self.assertTrue(get_validated_string_input_method.called)
@@ -7427,6 +7521,10 @@ class TestAmbariServer(TestCase):
return "bogus"
else:
return "valid"
+ if 'URL Port' in args[0]:
+ return '1'
+ if 'Ambari Admin' in args[0]:
+ return 'admin'
if args[1] == "true" or args[1] == "false":
return args[1]
else:
@@ -7442,7 +7540,8 @@ class TestAmbariServer(TestCase):
get_YN_input_method.side_effect = [True, True]
update_properties_method.reset_mock()
- options.ldap_url = None
+ options.ldap_url_host = None
+ options.ldap_url_port = None
options.ldap_member_attr = None
setup_ldap(options)
@@ -7450,15 +7549,17 @@ class TestAmbariServer(TestCase):
ldap_properties_map = \
{
- "authentication.ldap.primaryUrl": "test",
- "authentication.ldap.secondaryUrl": "test",
- "authentication.ldap.useSSL": "true",
- "authentication.ldap.usernameAttribute": "test",
- "authentication.ldap.baseDn": "test",
- "authentication.ldap.dnAttribute": "test",
- "authentication.ldap.bindAnonymously": "false",
- "ldap.sync.username.collision.behavior": "skip",
- "authentication.ldap.managerDn": "test",
+ "ambari.ldap.connectivity.server.host": "a",
+ "ambari.ldap.connectivity.server.port" : "3",
+ "ambari.ldap.connectivity.secondary.server.host": "b",
+ "ambari.ldap.connectivity.secondary.server.port" : "2",
+ "ambari.ldap.connectivity.use_ssl": "true",
+ "ambari.ldap.attributes.user.name_attr": "test",
+ "ambari.ldap.attributes.user.search_base": "test",
+ "ambari.ldap.attributes.dn_attr": "test",
+ "ambari.ldap.connectivity.anonymous_bind": "false",
+ "ambari.ldap.advance.collision_behavior": "skip",
+ "ambari.ldap.connectivity.bind_dn": "test",
"client.security": "ldap",
"ssl.trustStore.type": "test",
"ssl.trustStore.path": "valid",
@@ -8584,8 +8685,10 @@ class TestAmbariServer(TestCase):
def _create_empty_options_mock(self):
options = MagicMock()
- options.ldap_url = None
- options.ldap_secondary_url = None
+ options.ldap_url_host = None
+ options.ldap_url_port = None
+ options.ldap_secondary_url_host = None
+ options.ldap_secondary_url_port = None
options.ldap_ssl = None
options.ldap_user_class = None
options.ldap_user_attr = None
@@ -8601,6 +8704,8 @@ class TestAmbariServer(TestCase):
options.ldap_bind_anonym = None
options.ldap_sync_admin_name = None
options.ldap_sync_username_collisions_behavior = None
+ options.ldap_force_lowercase_usernames = None
+ options.ldap_pagination_enabled = None
options.ldap_sync_admin_password = None
options.custom_trust_store = None
options.trust_store_type = None
--
To stop receiving notification emails like this one, please contact
ncole@apache.org.