def read_master_key(isReset=False): passwordPattern = ".*" passwordPrompt = "Please provide master key for locking the credential store: " passwordDescr = "Invalid characters in password. Use only alphanumeric or "\ "_ or - characters" passwordDefault = "" if isReset: passwordPrompt = "Enter new Master Key: " input = True while(input): masterKey = get_validated_string_input(passwordPrompt, passwordDefault, passwordPattern, passwordDescr, True, True) if not masterKey: print "Master Key cannot be empty!" continue masterKey2 = get_validated_string_input("Re-enter master key: ", passwordDefault, passwordPattern, passwordDescr, True, True) if masterKey != masterKey2: print "Master key did not match!" continue input = False return masterKey
def update_ldap_configuration(properties, ldap_property_value_map): admin_login = get_validated_string_input("Enter Ambari Admin login: "******"Enter Ambari Admin password: "******"Configuration": { "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 setup-ldap. Http status code - ' + str(response_status_code) raise FatalException(1, err)
def setup_ambari_krb5_jaas(): jaas_conf_file = search_file(SECURITY_KERBEROS_JASS_FILENAME, get_conf_dir()) if os.path.exists(jaas_conf_file): print 'Setting up Ambari kerberos JAAS configuration to access ' + \ 'secured Hadoop daemons...' principal = get_validated_string_input( 'Enter ambari server\'s kerberos ' 'principal name ([email protected]): ', '*****@*****.**', '.*', '', False, False) keytab = get_validated_string_input( 'Enter keytab path for ambari ' 'server\'s kerberos principal: ', '/etc/security/keytabs/ambari.keytab', '.*', False, False, validatorFunction=is_valid_filepath) for line in fileinput.FileInput(jaas_conf_file, inplace=1): line = re.sub('keyTab=.*$', 'keyTab="' + keytab + '"', line) line = re.sub('principal=.*$', 'principal="' + principal + '"', line) print line, else: raise NonFatalException('No jaas config file found at location: ' + jaas_conf_file)
def _prompt_db_properties(self): if self.must_set_database_options: if self.persistence_type != STORAGE_TYPE_LOCAL: self.database_host = get_validated_string_input( "Hostname (" + self.database_host + "): ", self.database_host, "^[a-zA-Z0-9.\-]*$", "Invalid hostname.", False ) self.database_port = get_validated_string_input( "Port (" + self.database_port + "): ", self.database_port, "^([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$", "Invalid port.", False ) if not self._configure_database_name(): return False # Username is common for Oracle/MySQL/Postgres self.database_username = get_validated_string_input( 'Username (' + self.database_username + '): ', self.database_username, USERNAME_PATTERN, "Invalid characters in username. Start with _ or alpha " "followed by alphanumeric or _ or - characters", False ) self.database_password = LinuxDBMSConfig._configure_database_password(True) self._display_db_properties() return True
def _prompt_db_properties(self): if self.must_set_database_options: if self.persistence_type != STORAGE_TYPE_LOCAL: self.database_host = get_validated_string_input( "Hostname (" + self.database_host + "): ", self.database_host, "^[a-zA-Z0-9.\-]*$", "Invalid hostname.", False ) self.database_port = get_validated_string_input( "Port (" + self.database_port + "): ", self.database_port, "^([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$", "Invalid port.", False ) if not self._configure_database_name(): return False # Username is common for Oracle/MySQL/MSSQL/Postgres self.database_username = get_validated_string_input( 'Username (' + self.database_username + '): ', self.database_username, USERNAME_PATTERN, "Invalid characters in username. Start with _ or alpha " "followed by alphanumeric or _ or - characters", False ) self.database_password = LinuxDBMSConfig._configure_database_password(True, self.database_password) self._display_db_properties() return True
def setup_https(args): if not is_root(): err = 'ambari-server setup-https should be run with ' \ 'root-level privileges' raise FatalException(4, err) args.exit_message = None if not get_silent(): properties = get_ambari_properties() try: security_server_keys_dir = properties.get_property(SSL_KEY_DIR) client_api_ssl_port = DEFAULT_SSL_API_PORT if properties.get_property(SSL_API_PORT) in ("") \ else properties.get_property(SSL_API_PORT) api_ssl = properties.get_property(SSL_API) in ['true'] client_api_ssl_port_old_value = properties.get_property(SSL_API_PORT) api_ssl_old_value = properties.get_property(SSL_API) cert_was_imported = False cert_must_import = True if api_ssl: if get_YN_input("Do you want to disable HTTPS [y/n] (n)? ", False): properties.process_pair(SSL_API, "false") cert_must_import=False else: properties.process_pair(SSL_API_PORT, \ get_validated_string_input( \ "SSL port ["+str(client_api_ssl_port)+"] ? ", \ str(client_api_ssl_port), \ "^[0-9]{1,5}$", "Invalid port.", False, validatorFunction = is_valid_https_port)) cert_was_imported = import_cert_and_key_action(security_server_keys_dir, properties) else: if get_YN_input("Do you want to configure HTTPS [y/n] (y)? ", True): properties.process_pair(SSL_API_PORT, \ get_validated_string_input("SSL port ["+str(client_api_ssl_port)+"] ? ", \ str(client_api_ssl_port), "^[0-9]{1,5}$", "Invalid port.", False, validatorFunction = is_valid_https_port)) cert_was_imported = import_cert_and_key_action(security_server_keys_dir, properties) else: return False if cert_must_import and not cert_was_imported: print 'Setup of HTTPS failed. Exiting.' return False conf_file = find_properties_file() f = open(conf_file, 'w') properties.store(f, "Changed by 'ambari-server setup-https' command") if api_ssl_old_value != properties.get_property(SSL_API) \ or client_api_ssl_port_old_value != properties.get_property(SSL_API_PORT): print "Ambari server URL changed. To make use of the Tez View in Ambari " \ "please update the property tez.tez-ui.history-url.base in tez-site" ambari_user = read_ambari_user() if ambari_user: adjust_directory_permissions(ambari_user) return True except (KeyError), e: err = 'Property ' + str(e) + ' is not defined' raise FatalException(1, err)
def _create_custom_user(self): user = get_validated_string_input( "Enter user account for ambari-server service ({0}):".format(self.user), self.user, None, "Invalid username.", False ) if user in self.NR_SYSTEM_USERS: self.user = user return 0 if get_silent(): password = self.password else: password = get_validated_string_input("Enter password for user {0}:".format(user), "", None, "Password", True, False) from ambari_commons.os_windows import UserHelper uh = UserHelper(user) if uh.find_user(): print_info_msg("User {0} already exists, make sure that you typed correct password for user, " "skipping user creation".format(user)) else: status, message = uh.create_user(password) if status == UserHelper.USER_EXISTS: print_info_msg("User {0} already exists, make sure that you typed correct password for user, " "skipping user creation".format(user)) elif status == UserHelper.ACTION_FAILED: # fail print_warning_msg("Can't create user {0}. Failed with message {1}".format(user, message)) return UserHelper.ACTION_FAILED self.password = password # setting SeServiceLogonRight and SeBatchLogonRight to user #This is unconditional status, message = uh.add_user_privilege('SeServiceLogonRight') if status == UserHelper.ACTION_FAILED: print_warning_msg("Can't add SeServiceLogonRight to user {0}. Failed with message {1}".format(user, message)) return UserHelper.ACTION_FAILED status, message = uh.add_user_privilege('SeBatchLogonRight') if status == UserHelper.ACTION_FAILED: print_warning_msg("Can't add SeBatchLogonRight to user {0}. Failed with message {1}".format(user, message)) return UserHelper.ACTION_FAILED print_info_msg("User configuration is done.") print_warning_msg("When using non SYSTEM user make sure that your user has read\write access to log directories and " "all server directories. In case of integrated authentication for SQL Server make sure that your " "user is properly configured to access the ambari database.") if user.find('\\') == -1: user = '******' + user self.user = user return 0
def setup_https(args): if not is_root(): warn = 'ambari-server setup-https is run as ' \ 'non-root user, some sudo privileges might be required' print warn args.exit_message = None if not get_silent(): properties = get_ambari_properties() try: security_server_keys_dir = properties.get_property(SSL_KEY_DIR) client_api_ssl_port = DEFAULT_SSL_API_PORT if properties.get_property(SSL_API_PORT) in ("") \ else properties.get_property(SSL_API_PORT) api_ssl = properties.get_property(SSL_API) in ['true'] cert_was_imported = False cert_must_import = True if api_ssl: if get_YN_input("Do you want to disable HTTPS [y/n] (n)? ", False): properties.process_pair(SSL_API, "false") cert_must_import = False else: properties.process_pair(SSL_API_PORT, \ get_validated_string_input( \ "SSL port ["+str(client_api_ssl_port)+"] ? ", \ str(client_api_ssl_port), \ "^[0-9]{1,5}$", "Invalid port.", False, validatorFunction = is_valid_https_port)) cert_was_imported = import_cert_and_key_action( security_server_keys_dir, properties) else: if get_YN_input("Do you want to configure HTTPS [y/n] (y)? ", True): properties.process_pair(SSL_API_PORT, \ get_validated_string_input("SSL port ["+str(client_api_ssl_port)+"] ? ", \ str(client_api_ssl_port), "^[0-9]{1,5}$", "Invalid port.", False, validatorFunction = is_valid_https_port)) cert_was_imported = import_cert_and_key_action( security_server_keys_dir, properties) else: return False if cert_must_import and not cert_was_imported: print 'Setup of HTTPS failed. Exiting.' return False conf_file = find_properties_file() f = open(conf_file, 'w') properties.store(f, "Changed by 'ambari-server setup-https' command") ambari_user = read_ambari_user() if ambari_user: adjust_directory_permissions(ambari_user) return True except (KeyError), e: err = 'Property ' + str(e) + ' is not defined' raise FatalException(1, err)
def set_current(options): logger.info("Set current cluster version.") server_status, pid = is_server_runing() if not server_status: err = 'Ambari Server is not running.' raise FatalException(1, err) finalize_options = SetCurrentVersionOptions(options) if finalize_options.no_finalize_options_set(): err = 'Must specify --cluster-name and --version-display-name. Please invoke ambari-server.py --help to print the options.' raise FatalException(1, err) admin_login = get_validated_string_input(prompt="Enter Ambari Admin login: "******"Enter Ambari Admin password: "******"Failed to read properties file.") base_url = get_ambari_server_api_base(properties) url = base_url + "clusters/{0}/stack_versions".format(finalize_options.cluster_name) 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 = { "ClusterStackVersions": { "repository_version": finalize_options.desired_repo_version, "state": "CURRENT", "force": finalize_options.force_repo_version } } if get_verbose(): sys.stdout.write('\nCalling API ' + url + ' : ' + str(data) + '\n') request.add_data(json.dumps(data)) request.get_method = lambda: 'PUT' try: response = urllib2.urlopen(request) except urllib2.HTTPError, e: code = e.getcode() content = e.read() err = 'Error during setting current version. Http status code - {0}. \n {1}'.format( code, content) raise FatalException(1, err)
def set_current(options): server_status, pid = is_server_runing() if not server_status: err = 'Ambari Server is not running.' raise FatalException(1, err) finalize_options = SetCurrentVersionOptions(options) if finalize_options.no_finalize_options_set(): err = 'Must specify --cluster-name and --version-display-name. Please invoke ambari-server.py --help to print the options.' raise FatalException(1, err) admin_login = get_validated_string_input(prompt="Enter Ambari Admin login: "******"Enter Ambari Admin password: "******"Failed to read properties file.") base_url = get_ambari_server_api_base(properties) url = base_url + "clusters/{0}/stack_versions".format(finalize_options.cluster_name) 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 = { "ClusterStackVersions": { "repository_version": finalize_options.desired_repo_version, "state": "CURRENT", "force": "true" if finalize_options.force_repo_version else "false" } } if get_verbose(): sys.stdout.write('\nCalling API ' + url + ' : ' + str(data) + '\n') request.add_data(json.dumps(data)) request.get_method = lambda: 'PUT' try: response = urllib2.urlopen(request) except urllib2.HTTPError, e: code = e.getcode() content = e.read() err = 'Error during setting current version. Http status code - {0}. \n {1}'.format( code, content) raise FatalException(1, err)
def setup_https(args): if not is_root(): err = 'tbds-server setup-https should be run with ' \ 'root-level privileges' raise FatalException(4, err) args.exit_message = None if not get_silent(): properties = get_ambari_properties() try: security_server_keys_dir = properties.get_property(SSL_KEY_DIR) client_api_ssl_port = DEFAULT_SSL_API_PORT if properties.get_property(SSL_API_PORT) in ("") \ else properties.get_property(SSL_API_PORT) api_ssl = properties.get_property(SSL_API) in ['true'] cert_was_imported = False cert_must_import = True if api_ssl: if get_YN_input("Do you want to disable HTTPS [y/n] (n)? ", False): properties.process_pair(SSL_API, "false") cert_must_import=False else: properties.process_pair(SSL_API_PORT, \ get_validated_string_input( \ "SSL port ["+str(client_api_ssl_port)+"] ? ", \ str(client_api_ssl_port), \ "^[0-9]{1,5}$", "Invalid port.", False, validatorFunction = is_valid_https_port)) cert_was_imported = import_cert_and_key_action(security_server_keys_dir, properties) else: if get_YN_input("Do you want to configure HTTPS [y/n] (y)? ", True): properties.process_pair(SSL_API_PORT, \ get_validated_string_input("SSL port ["+str(client_api_ssl_port)+"] ? ", \ str(client_api_ssl_port), "^[0-9]{1,5}$", "Invalid port.", False, validatorFunction = is_valid_https_port)) cert_was_imported = import_cert_and_key_action(security_server_keys_dir, properties) else: return False if cert_must_import and not cert_was_imported: print 'Setup of HTTPS failed. Exiting.' return False conf_file = find_properties_file() f = open(conf_file, 'w') properties.store(f, "Changed by 'tbds-server setup-https' command") ambari_user = read_ambari_user() if ambari_user: adjust_directory_permissions(ambari_user) return True except (KeyError), e: err = 'Property ' + str(e) + ' is not defined' raise FatalException(1, err)
def get_ambari_admin_username_password_pair(options): """ Returns the Ambari administrator credential. If not supplied via command line options, the user is queried for the username and password. :param options: the collected command line options :return: the Ambari admin credentials """ admin_login = options.ambari_admin_username \ if hasattr(options, 'ambari_admin_username') and options.ambari_admin_username is not None \ else get_validated_string_input("Enter Ambari Admin login: "******"Enter Ambari Admin password: ", None, None, None, True, False) return admin_login, admin_password
def setup_kerberos(options): logger.info("Setting up Kerberos authentication...") if not is_root(): err = "ambari-server setup-kerberos should be run with root-level privileges" raise FatalException(4, err) properties = get_ambari_properties() kerberos_property_list_required = init_kerberos_properties_list( properties, options) kerberos_property_value_map = {} for kerberos_property in kerberos_property_list_required: input = get_validated_string_input( kerberos_property.kerberos_prop_val_prompt, kerberos_property.kerberos_prop_name, kerberos_property.prompt_regex, "Invalid characters in the input!", False, kerberos_property.allow_empty_prompt) if input is not None and input != "": kerberos_property_value_map[kerberos_property.prop_name] = input print "Properties to be updated / written into ambari properties:" pp = pprint.PrettyPrinter() pp.pprint(kerberos_property_value_map) save = get_YN_input("Save settings [y/n] (y)? ", True) if save: update_properties_2(properties, kerberos_property_value_map) print "Kerberos authentication settings successfully saved. Please restart the server in order for the new settings to take effect." else: print "Kerberos authentication settings aborted." return 0
def _configure_database_name(self): self.server_name = get_validated_string_input("Server name (" + str(self.server_name) + "): ", self.server_name, ".*", "Invalid server name", False) self.database_name = LinuxDBMSConfig._get_validated_db_name(self.database_storage_name, self.database_name) return True
def setup_pam(): if not is_root(): err = 'Ambari-server setup-pam should be run with ' \ 'root-level privileges' raise FatalException(4, err) properties = get_ambari_properties() if get_value_from_properties(properties, CLIENT_SECURITY_KEY, "") == 'ldap': err = "LDAP is configured. Can not setup PAM." raise FatalException(1, err) pam_property_value_map = {} pam_property_value_map[CLIENT_SECURITY_KEY] = 'pam' pamConfig = get_validated_string_input("Enter PAM configuration file: ", PAM_CONFIG_FILE, REGEX_ANYTHING, "Invalid characters in the input!", False, False) pam_property_value_map[PAM_CONFIG_FILE] = pamConfig if get_YN_input( "Do you want to allow automatic group creation [y/n] (y)? ", True): pam_property_value_map[AUTO_GROUP_CREATION] = 'true' else: pam_property_value_map[AUTO_GROUP_CREATION] = 'false' update_properties_2(properties, pam_property_value_map) print 'Saving...done' return 0
def _configure_database_name(self): self.server_name = get_validated_string_input("Server name (" + str(self.server_name) + "): ", self.server_name, ".*", "Invalid server name", False) self.database_name = LinuxDBMSConfig._get_validated_db_name(self.database_storage_name, self.database_name) return True
def setup_security(args): actions = create_setup_security_actions(args) #Print menu options print '=' * 75 print 'Choose one of the following options: ' iAction = 0 for actionDesc in actions: iAction += 1 print ' [{0}] {1}'.format(iAction, actionDesc[0]) print '=' * 75 choice_prompt = 'Enter choice, (1-{0}): '.format(iAction) choice_re = '[1-{0}]'.format(iAction) choice = get_validated_string_input(choice_prompt, '0', choice_re, 'Invalid choice', False, False) try: actionDesc = actions[int(choice) - 1] except IndexError: raise FatalException(1, 'Unknown option for setup-security command.') action = actionDesc[1] action.execute() return action.need_restart
def _create_custom_user(self): user = get_validated_string_input( "Enter user account for ambari-server daemon (root):", self.user, "^[a-z_][a-z0-9_-]{1,31}$", "Invalid username.", False ) print_info_msg("Trying to create user {0}".format(user)) command = self.NR_USERADD_CMD.format(user, self.NR_USER_COMMENT) retcode, out, err = run_os_command(command) if retcode == 9: # 9 = username already in use print_info_msg("User {0} already exists, " "skipping user creation".format(user)) elif retcode != 0: # fail print_warning_msg("Can't create user {0}. Command {1} " "finished with {2}: \n{3}".format(user, command, retcode, err)) return retcode print_info_msg("User configuration is done.") self.user = user return 0
def setup_security(args): actions = create_setup_security_actions(args) #Print menu options print '=' * 75 print 'Choose one of the following options: ' iAction = 0 for actionDesc in actions: iAction += 1 print ' [{0}] {1}'.format(iAction, actionDesc[0]) print '=' * 75 choice_prompt = 'Enter choice, (1-{0}): '.format(iAction) choice_re = '[1-{0}]'.format(iAction) choice = get_validated_string_input(choice_prompt, '0', choice_re, 'Invalid choice', False, False) try: actionDesc = actions[int(choice) - 1] except IndexError: raise FatalException(1, 'Unknown option for setup-security command.') action = actionDesc[1] action.execute() return action.need_restart
def _configure_database_name(self): if self.persistence_type != STORAGE_TYPE_LOCAL: # Oracle uses service name or service id idType = "1" idType = get_validated_string_input( "Select Oracle identifier type:\n1 - " + ORACLE_DB_ID_TYPES[0] + "\n2 - " + ORACLE_DB_ID_TYPES[1] + "\n(" + idType + "): ", idType, "^[12]$", "Invalid number.", False ) if idType == "1": self.sid_or_sname = "sname" elif idType == "2": self.sid_or_sname = "sid" IDTYPE_INDEX = int(idType) - 1 self.database_name = OracleConfig._get_validated_service_name(self.database_name, IDTYPE_INDEX) else: self.database_name = LinuxDBMSConfig._get_validated_db_name(self.database_storage_name, self.database_name) return True
def _configure_database_name(self): if self.persistence_type != STORAGE_TYPE_LOCAL: # Oracle uses service name or service id idType = "1" idType = get_validated_string_input( "Select Oracle identifier type:\n1 - " + ORACLE_DB_ID_TYPES[0] + "\n2 - " + ORACLE_DB_ID_TYPES[1] + "\n(" + idType + "): ", idType, "^[12]$", "Invalid number.", False ) if idType == "1": self.sid_or_sname = "sname" elif idType == "2": self.sid_or_sname = "sid" IDTYPE_INDEX = int(idType) - 1 self.database_name = OracleConfig._get_validated_service_name(self.database_name, IDTYPE_INDEX) else: self.database_name = LinuxDBMSConfig._get_validated_db_name(self.database_storage_name, self.database_name) return True
def _get_validated_service_name(service_name, index): return get_validated_string_input( ORACLE_DB_ID_TYPES[index] + " (" + service_name + "): ", service_name, ".*", "Invalid " + ORACLE_DB_ID_TYPES[index] + ".", False )
def _get_validated_db_schema(postgres_schema): return get_validated_string_input( "Postgres schema (" + postgres_schema + "): ", postgres_schema, "^[a-zA-Z0-9_\-]*$", "Invalid schema name.", False, allowEmpty=True )
def _get_validated_service_name(service_name, index): return get_validated_string_input( ORACLE_DB_ID_TYPES[index] + " (" + service_name + "): ", service_name, ".*", "Invalid " + ORACLE_DB_ID_TYPES[index] + ".", False )
def _get_validated_db_schema(postgres_schema): return get_validated_string_input( "Postgres schema (" + postgres_schema + "): ", postgres_schema, "^[a-zA-Z0-9_\-]*$", "Invalid schema name.", False, allowEmpty=True )
def _get_validated_db_name(database_storage_name, database_name): return get_validated_string_input( database_storage_name + " name (" + database_name + "): ", database_name, ".*", "Invalid " + database_storage_name.lower() + " name.", False, )
def _create_custom_user(self): user = get_validated_string_input( "Enter user account for ambari-server service ({0}):".format( self.NR_DEFAULT_USER), self.NR_DEFAULT_USER, None, "Invalid username.", False) if user == self.NR_DEFAULT_USER: return 0, user password = get_validated_string_input( "Enter password for user {0}:".format(user), "", None, "Password", True, False) from ambari_commons.os_windows import UserHelper uh = UserHelper() status, message = uh.create_user(user, password) if status == UserHelper.USER_EXISTS: print_info_msg( "User {0} already exists, make sure that you typed correct password for user, " "skipping user creation".format(user)) elif status == UserHelper.ACTION_FAILED: # fail print_warning_msg( "Can't create user {0}. Failed with message {1}".format( user, message)) return UserHelper.ACTION_FAILED, None # setting SeServiceLogonRight to user status, message = uh.add_user_privilege(user, 'SeServiceLogonRight') if status == UserHelper.ACTION_FAILED: print_warning_msg( "Can't add SeServiceLogonRight to user {0}. Failed with message {1}" .format(user, message)) return UserHelper.ACTION_FAILED, None print_info_msg("User configuration is done.") print_warning_msg( "When using non SYSTEM user make sure that your user have read\write access to log directories and " "all server directories. In case of integrated authentication for SQL Server make sure that your " "user properly configured to use ambari and metric database.") #storing username and password in os.environ temporary to pass them to service os.environ[SERVICE_USERNAME_KEY] = user os.environ[SERVICE_PASSWORD_KEY] = password return 0, user
def _prompt_db_properties(self): if self.must_set_database_options: #prompt for SQL Server host and instance name hostname_prompt = "SQL Server host and instance for the {0} database: ({1}) ".format( self.db_title, self.database_host) self.database_host = get_validated_string_input( hostname_prompt, self.database_host, None, None, False, True) #prompt for SQL Server authentication method if not self.use_windows_authentication or \ self.database_username is None or self.database_username == "": auth_option_default = '1' else: auth_option_default = '2' user_prompt = \ "[1] - Use SQL Server integrated authentication\n[2] - Use username+password authentication\n" \ "Enter choice ({0}): ".format(auth_option_default) auth_option = get_validated_string_input(user_prompt, auth_option_default, "^[12]$", "Invalid number.", False) if str(auth_option) == '1': self.use_windows_authentication = True self.database_password = None else: self.use_windows_authentication = False user_prompt = "SQL Server user name for the {0} database: ({1}) ".format( self.db_title, self.database_username) username = get_validated_string_input(user_prompt, self.database_username, None, "User name", False, False) self.database_username = username user_prompt = "SQL Server password for the {0} database: ".format( self.db_title) password = get_validated_string_input(user_prompt, "", None, "Password", True, False) self.database_password = password self.database_url = self._build_sql_server_connection_string() return True
def populate_jwt_audiences(options, properties): if options.sso_jwt_audience_list is None: audiences = get_value_from_dictionary(properties, JWT_AUDIENCES) audiences = get_validated_string_input("JWT audiences list (comma-separated), empty for any ({0}):".format(audiences), audiences, REGEX_ANYTHING, "Invalid value", False) else: audiences = options.sso_jwt_audience_list properties[JWT_AUDIENCES] = audiences
def populate_jwt_cookie_name(options, properties): if not options.sso_jwt_cookie_name and (not options.sso_provider_url or not options.sso_public_cert_file): cookie_name = get_value_from_dictionary(properties, JWT_COOKIE_NAME, JWT_COOKIE_NAME_DEFAULT) cookie_name = get_validated_string_input("JWT Cookie name ({0}):".format(cookie_name), cookie_name, REGEX_ANYTHING, "Invalid cookie name", False) else: cookie_name = options.sso_jwt_cookie_name if options.sso_jwt_cookie_name else JWT_COOKIE_NAME_DEFAULT properties[JWT_COOKIE_NAME] = cookie_name
def populate_jwt_audiences(options, properties): if options.sso_jwt_audience_list is None and (not options.sso_provider_url or not options.sso_public_cert_file): audiences = get_value_from_dictionary(properties, JWT_AUDIENCES, JWT_AUDIENCES_DEFAULT) audiences = get_validated_string_input("JWT audiences list (comma-separated), empty for any ({0}):".format(audiences), audiences, REGEX_ANYTHING, "Invalid value", False) else: audiences = options.sso_jwt_audience_list if options.sso_jwt_audience_list else JWT_AUDIENCES_DEFAULT properties[JWT_AUDIENCES] = audiences
def populate_sso_provider_url(options, properties): if not options.sso_provider_url: provider_url = get_value_from_dictionary(properties, SSO_PROVIDER_URL, SSO_PROVIDER_URL_DEFAULT) provider_url = get_validated_string_input("Provider URL ({0}):".format(provider_url), provider_url, REGEX_URL, "Invalid provider URL", False) else: provider_url = options.sso_provider_url properties[SSO_PROVIDER_URL] = provider_url
def _get_validated_db_name(database_storage_name, database_name): return get_validated_string_input( database_storage_name + " name (" + database_name + "): ", database_name, ".*", "Invalid " + database_storage_name.lower() + " name.", False )
def ensure_jdbc_driver_installed(self, properties): server_jdbc_path = properties.get_property(JDBC_DRIVER_PATH_PROPERTY) if server_jdbc_path and os.path.isfile(server_jdbc_path): return True default_driver_path = self._get_default_driver_path(properties) if default_driver_path and os.path.isfile(default_driver_path): ambari_should_use_existing_default_jdbc = get_YN_input( "Should ambari use existing default jdbc {0} [y/n] (y)? ". format(default_driver_path), True) if ambari_should_use_existing_default_jdbc: properties.process_pair(JDBC_DRIVER_PATH_PROPERTY, default_driver_path) update_properties(properties) return True path_to_custom_jdbc_driver = get_validated_string_input( "Enter full path to custom jdbc driver: ", None, None, None, False, False) if path_to_custom_jdbc_driver and os.path.isfile( path_to_custom_jdbc_driver): try: custom_jdbc_name = os.path.basename(path_to_custom_jdbc_driver) if not path_to_custom_jdbc_driver == os.path.join( configDefaults.JAVA_SHARE_PATH, custom_jdbc_name): if os.path.isfile( os.path.join(configDefaults.JAVA_SHARE_PATH, custom_jdbc_name)): replace_jdbc_in_share_dir = get_YN_input( "You already have file {0} in /usr/share/java/. Should it be replaced? [y/n] (y)? " .format(custom_jdbc_name), True) if replace_jdbc_in_share_dir: try: os.remove( os.path.join( configDefaults.JAVA_SHARE_PATH, custom_jdbc_name)) except Exception, ee: err = 'ERROR: Could not remove jdbc file. %s' % os.path.join( configDefaults.JAVA_SHARE_PATH, custom_jdbc_name) raise FatalException(1, err) shutil.copy(path_to_custom_jdbc_driver, configDefaults.JAVA_SHARE_PATH) print "Copying {0} to {1}".format( path_to_custom_jdbc_driver, configDefaults.JAVA_SHARE_PATH) except Exception, e: err = "Can not copy file {0} to {1} due to: {2} . Please check file " \ "permissions and free disk space.".format(path_to_custom_jdbc_driver, configDefaults.JAVA_SHARE_PATH, str(e)) raise FatalException(1, err) properties.process_pair(JDBC_DRIVER_PATH_PROPERTY, path_to_custom_jdbc_driver) update_properties(properties) return True
def populate_jwt_cookie_name(options, properties): if not options.sso_jwt_cookie_name: cookie_name = get_value_from_properties(properties, JWT_COOKIE_NAME, JWT_COOKIE_NAME_DEFAULT) cookie_name = get_validated_string_input( "JWT Cookie name ({0}):".format(cookie_name), cookie_name, REGEX_ANYTHING, "Invalid cookie name", False) else: cookie_name = options.sso_jwt_cookie_name properties.process_pair(JWT_COOKIE_NAME, cookie_name)
def populate_sso_provider_url(options, properties): if not options.sso_provider_url: provider_url = get_value_from_properties( properties, JWT_AUTH_PROVIDER_URL, JWT_AUTH_PROVIDER_URL_DEFAULT) provider_url = get_validated_string_input( "Provider URL [URL] ({0}):".format(provider_url), provider_url, REGEX_URL, "Invalid provider URL", False) else: provider_url = options.sso_provider_url properties.process_pair(JWT_AUTH_PROVIDER_URL, provider_url)
def populate_jwt_audiences(options, properties): if not options.sso_jwt_audience_list: audiences = properties.get_property(JWT_AUDIENCES) audiences = get_validated_string_input( "JWT audiences list (comma-separated), empty for any ({0}):". format(audiences), audiences, REGEX_ANYTHING, "Invalid value", False) else: audiences = options.sso_jwt_audience_list properties.process_pair(JWT_AUDIENCES, audiences)
def setup_truststore(options, import_cert=False): if not get_silent(): jdk_path = find_jdk() if jdk_path is None: err = "No JDK found, please run the \"ambari-server setup\" " \ "command to install a JDK automatically or install any " \ "JDK manually to " + configDefaults.JDK_INSTALL_DIR raise FatalException(1, err) properties = get_ambari_properties() truststore_confirm = True if options.trust_store_path is not None and options.trust_store_path else False truststore_reconfigure = True if options.trust_store_reconfigure is not None else False if truststore_confirm or get_YN_input("Do you want to configure a truststore [y/n] (y)? ", True): #Re-configuration enabled only for option "Setup truststore" if not import_cert and properties.get_property(SSL_TRUSTSTORE_TYPE_PROPERTY)\ and (truststore_reconfigure or get_YN_input( "The truststore is already configured. Do you want to re-configure " "the truststore [y/n] (y)? ", True)): properties.removeProp(SSL_TRUSTSTORE_TYPE_PROPERTY) properties.removeProp(SSL_TRUSTSTORE_PATH_PROPERTY) properties.removeProp(SSL_TRUSTSTORE_PASSWORD_PROPERTY) truststore_type = get_and_persist_truststore_type(properties, options) truststore_path = get_and_persist_truststore_path(properties, options) truststore_password = get_and_persist_truststore_password(properties, options) if import_cert: import_cert_confirm = True if options.import_cert_path is not None else get_YN_input("Do you want to import a certificate [y/n] (y)? ", True) if import_cert_confirm: aliasOption = options.import_cert_alias if options.import_cert_alias is not None and options.import_cert_alias else None alias = aliasOption if aliasOption is not None \ else get_validated_string_input("Please enter an alias for the certificate: ", "", None, None, False, False) run_os_command(get_delete_cert_command(jdk_path, alias, truststore_path, truststore_password)) import_cert_path = get_validated_filepath_input("Enter path to certificate: ", "Certificate not found", answer=options.import_cert_path) run_component_https_cmd(get_import_cert_command(jdk_path, alias, truststore_type, import_cert_path, truststore_path, truststore_password)) else: return conf_file = find_properties_file() f = open(conf_file, 'w') properties.store(f, "Changed by 'ambari-server setup-security' command") else: print "setup-security is not enabled in silent mode."
def setup_ambari_krb5_jaas(): jaas_conf_file = search_file(SECURITY_KERBEROS_JASS_FILENAME, get_conf_dir()) if os.path.exists(jaas_conf_file): print 'Setting up Ambari kerberos JAAS configuration to access ' + \ 'secured Hadoop daemons...' principal = get_validated_string_input('Enter ambari server\'s kerberos ' 'principal name ([email protected]): ', '*****@*****.**', '.*', '', False, False) keytab = get_validated_string_input('Enter keytab path for ambari ' 'server\'s kerberos principal: ', '/etc/security/keytabs/ambari.keytab', '.*', False, False, validatorFunction=is_valid_filepath) for line in fileinput.FileInput(jaas_conf_file, inplace=1): line = re.sub('keyTab=.*$', 'keyTab="' + keytab + '"', line) line = re.sub('principal=.*$', 'principal="' + principal + '"', line) print line, else: raise NonFatalException('No jaas config file found at location: ' + jaas_conf_file)
def get_and_persist_truststore_type(properties, options): truststore_type = properties.get_property(SSL_TRUSTSTORE_TYPE_PROPERTY) if not truststore_type: SSL_TRUSTSTORE_TYPE_DEFAULT = get_value_from_properties(properties, SSL_TRUSTSTORE_TYPE_PROPERTY, "jks") truststore_type = get_validated_string_input( "TrustStore type [jks/jceks/pkcs12] {0}:".format(get_prompt_default(SSL_TRUSTSTORE_TYPE_DEFAULT)), SSL_TRUSTSTORE_TYPE_DEFAULT, "^(jks|jceks|pkcs12)?$", "Wrong type", False, answer = options.trust_store_type) if truststore_type: properties.process_pair(SSL_TRUSTSTORE_TYPE_PROPERTY, truststore_type) return truststore_type
def _prompt_db_properties(self): if self.must_set_database_options: #prompt for SQL Server host and instance name hostname_prompt = "SQL Server host and instance for the {0} database: ({1}) ".format(self.db_title, self.database_host) self.database_host = get_validated_string_input(hostname_prompt, self.database_host, None, None, False, True) #prompt for SQL Server authentication method if not self.use_windows_authentication or \ self.database_username is None or self.database_username == "": auth_option_default = '1' else: auth_option_default = '2' user_prompt = \ "[1] - Use SQL Server integrated authentication\n[2] - Use username+password authentication\n" \ "Enter choice ({0}): ".format(auth_option_default) auth_option = get_validated_string_input(user_prompt, auth_option_default, "^[12]$", "Invalid number.", False ) if str(auth_option) == '1': self.use_windows_authentication = True self.database_password = None else: self.use_windows_authentication = False user_prompt = "SQL Server user name for the {0} database: ({1}) ".format(self.db_title, self.database_username) username = get_validated_string_input(user_prompt, self.database_username, None, "User name", False, False) self.database_username = username user_prompt = "SQL Server password for the {0} database: ".format(self.db_title) password = get_validated_string_input(user_prompt, "", None, "Password", True, False) self.database_password = password self.database_url = self._build_sql_server_connection_string() return True
def get_truststore_type(properties): truststore_type = properties.get_property(SSL_TRUSTSTORE_TYPE_PROPERTY) if not truststore_type: SSL_TRUSTSTORE_TYPE_DEFAULT = get_value_from_properties(properties, SSL_TRUSTSTORE_TYPE_PROPERTY, "jks") truststore_type = get_validated_string_input( "TrustStore type [jks/jceks/pkcs12] {0}:".format(get_prompt_default(SSL_TRUSTSTORE_TYPE_DEFAULT)), SSL_TRUSTSTORE_TYPE_DEFAULT, "^(jks|jceks|pkcs12)?$", "Wrong type", False) if truststore_type: properties.process_pair(SSL_TRUSTSTORE_TYPE_PROPERTY, truststore_type) return truststore_type
def get_truststore_path(properties): truststore_path = properties.get_property(SSL_TRUSTSTORE_PATH_PROPERTY) if not truststore_path: SSL_TRUSTSTORE_PATH_DEFAULT = get_value_from_properties(properties, SSL_TRUSTSTORE_PATH_PROPERTY) while not truststore_path: truststore_path = get_validated_string_input( "Path to TrustStore file {0}:".format(get_prompt_default(SSL_TRUSTSTORE_PATH_DEFAULT)), SSL_TRUSTSTORE_PATH_DEFAULT, ".*", False, False) if truststore_path: properties.process_pair(SSL_TRUSTSTORE_PATH_PROPERTY, truststore_path) return truststore_path
def select_dbms(self, options): try: dbms_index = options.database_index except AttributeError: db_name = get_value_from_properties(get_ambari_properties(), JDBC_DATABASE_PROPERTY, "").strip().lower() persistence_type = get_value_from_properties(get_ambari_properties(), PERSISTENCE_TYPE_PROPERTY, "").strip().lower() if persistence_type == STORAGE_TYPE_LOCAL: dbms_index = self.DBMS_KEYS_LIST.index("embedded") elif db_name: dbms_index = self.DBMS_KEYS_LIST.index(db_name) else: dbms_index = self._get_default_dbms_index(options) if options.must_set_database_options: n_dbms = 1 dbms_choice_prompt = "==============================================================================\n" \ "Choose one of the following options:\n" dbms_choices = '' for desc in self.DBMS_LIST: if len(desc.storage_name) > 0: dbms_storage = " ({0})".format(desc.storage_name) else: dbms_storage = "" dbms_choice_prompt += self.DBMS_PROMPT_PATTERN.format(n_dbms, desc.dbms_name, dbms_storage) dbms_choices += str(n_dbms) n_dbms += 1 database_num = str(dbms_index + 1) dbms_choice_prompt += self.DBMS_CHOICE_PROMPT_PATTERN.format(database_num) dbms_valid_choices = self.JDK_VALID_CHOICES_PATTERN.format(dbms_choices) database_num = get_validated_string_input( dbms_choice_prompt, database_num, dbms_valid_choices, "Invalid number.", False ) dbms_index = int(database_num) - 1 if dbms_index >= n_dbms: print_info_msg('Unknown db option, default to {0} {1}.'.format( self.DBMS_LIST[0].storage_name, self.DBMS_LIST[0].dbms_name)) dbms_index = 0 return dbms_index
def select_dbms(self, options): try: dbms_index = options.database_index except AttributeError: dbms_index = self._get_default_dbms_index(options) if options.must_set_database_options: n_dbms = 1 dbms_choice_prompt = ( "==============================================================================\n" "Choose one of the following options:\n" ) dbms_choices = "" for desc in self.DBMS_LIST: if len(desc.storage_name) > 0: dbms_storage = " ({0})".format(desc.storage_name) else: dbms_storage = "" dbms_choice_prompt += self.DBMS_PROMPT_PATTERN.format(n_dbms, desc.dbms_name, dbms_storage) dbms_choices += str(n_dbms) n_dbms += 1 database_num = str(dbms_index + 1) dbms_choice_prompt += self.DBMS_CHOICE_PROMPT_PATTERN.format(database_num) dbms_valid_choices = self.JDK_VALID_CHOICES_PATTERN.format(dbms_choices) database_num = get_validated_string_input( dbms_choice_prompt, database_num, dbms_valid_choices, "Invalid number.", False ) dbms_index = int(database_num) - 1 if dbms_index >= n_dbms: print_info_msg( "Unknown db option, default to {0} {1}.".format( self.DBMS_LIST[0].storage_name, self.DBMS_LIST[0].dbms_name ) ) dbms_index = 0 return dbms_index
def setup_truststore(import_cert=False): if not get_silent(): jdk_path = find_jdk() if jdk_path is None: err = "No JDK found, please run the \"ambari-server setup\" " \ "command to install a JDK automatically or install any " \ "JDK manually to " + configDefaults.JDK_INSTALL_DIR raise FatalException(1, err) properties = get_ambari_properties() if get_YN_input("Do you want to configure a truststore [y/n] (y)? ", True): truststore_type = get_truststore_type(properties) truststore_path = get_truststore_path(properties) truststore_password = get_truststore_password(properties) if import_cert: if get_YN_input("Do you want to import a certificate [y/n] (y)? ", True): alias = get_validated_string_input("Please enter an alias for the certificate: ", "", None, None, False, False) run_os_command(get_delete_cert_command(jdk_path, alias, truststore_path, truststore_password)) import_cert_path = get_validated_filepath_input( \ "Enter path to certificate: ", \ "Certificate not found") run_component_https_cmd(get_import_cert_command(jdk_path, alias, truststore_type, import_cert_path, truststore_path, truststore_password)) else: return conf_file = find_properties_file() f = open(conf_file, 'w') properties.store(f, "Changed by 'ambari-server setup-security' command") else: print "setup-security is not enabled in silent mode."
def get_original_master_key(properties): input = True while(input): try: masterKey = get_validated_string_input('Enter current Master Key: ', "", ".*", "", True, False) except KeyboardInterrupt: print 'Exiting...' sys.exit(1) # Find an alias that exists alias = None property = properties.get_property(JDBC_PASSWORD_PROPERTY) if property and is_alias_string(property): alias = JDBC_RCA_PASSWORD_ALIAS if not alias: property = properties.get_property(LDAP_MGR_PASSWORD_PROPERTY) if property and is_alias_string(property): alias = LDAP_MGR_PASSWORD_ALIAS if not alias: property = properties.get_property(SSL_TRUSTSTORE_PASSWORD_PROPERTY) if property and is_alias_string(property): alias = SSL_TRUSTSTORE_PASSWORD_ALIAS # Decrypt alias with master to validate it, if no master return if alias and masterKey: password = read_passwd_for_alias(alias, masterKey) if not password: print "ERROR: Master key does not match." continue input = False return masterKey
def setup_ldap(): if not is_root(): err = 'Ambari-server setup-ldap should be run with ' \ 'root-level privileges' raise FatalException(4, err) properties = get_ambari_properties() isSecure = get_is_secure(properties) ldap_property_list_reqd = init_ldap_properties_list_reqd(properties) ldap_property_list_opt = ["authentication.ldap.managerDn", 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]) 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) ldap_property_value_map = {} for ldap_prop in ldap_property_list_reqd: input = get_validated_string_input(ldap_prop.ldap_prop_val_prompt, ldap_prop.ldap_prop_name, ldap_prop.prompt_regex, "Invalid characters in the input!", False, ldap_prop.allow_empty_prompt) if input is not None and input != "": ldap_property_value_map[ldap_prop.prop_name] = input bindAnonymously = ldap_property_value_map["authentication.ldap.bindAnonymously"] anonymous = (bindAnonymously and bindAnonymously.lower() == 'true') mgr_password = None # Ask for manager credentials only if bindAnonymously is false if not anonymous: username = get_validated_string_input("Manager DN* {0}: ".format( get_prompt_default(LDAP_MGR_DN_DEFAULT)), LDAP_MGR_DN_DEFAULT, ".*", "Invalid characters in the input!", False, False) ldap_property_value_map[LDAP_MGR_USERNAME_PROPERTY] = username mgr_password = configure_ldap_password() ldap_property_value_map[LDAP_MGR_PASSWORD_PROPERTY] = mgr_password useSSL = ldap_property_value_map["authentication.ldap.useSSL"] ldaps = (useSSL and useSSL.lower() == 'true') ts_password = None if ldaps: truststore_default = "n" truststore_set = bool(SSL_TRUSTSTORE_PATH_DEFAULT) if truststore_set: truststore_default = "y" custom_trust_store = get_YN_input("Do you want to provide custom TrustStore for Ambari [y/n] ({0})?". format(truststore_default), truststore_set) if custom_trust_store: ts_type = get_validated_string_input( "TrustStore type [jks/jceks/pkcs12] {0}:".format(get_prompt_default(SSL_TRUSTSTORE_TYPE_DEFAULT)), SSL_TRUSTSTORE_TYPE_DEFAULT, "^(jks|jceks|pkcs12)?$", "Wrong type", False) ts_path = None while True: ts_path = get_validated_string_input( "Path to TrustStore file {0}:".format(get_prompt_default(SSL_TRUSTSTORE_PATH_DEFAULT)), SSL_TRUSTSTORE_PATH_DEFAULT, ".*", False, False) if os.path.exists(ts_path): break else: print 'File not found.' ts_password = read_password("", ".*", "Password for TrustStore:", "Invalid characters in password") ldap_property_value_map[SSL_TRUSTSTORE_TYPE_PROPERTY] = ts_type ldap_property_value_map[SSL_TRUSTSTORE_PATH_PROPERTY] = ts_path ldap_property_value_map[SSL_TRUSTSTORE_PASSWORD_PROPERTY] = ts_password pass else: properties.removeOldProp(SSL_TRUSTSTORE_TYPE_PROPERTY) properties.removeOldProp(SSL_TRUSTSTORE_PATH_PROPERTY) properties.removeOldProp(SSL_TRUSTSTORE_PASSWORD_PROPERTY) pass pass print '=' * 20 print 'Review Settings' print '=' * 20 for property in ldap_property_list_reqd: if property in ldap_property_value_map: print("%s: %s" % (property, ldap_property_value_map[property])) for property in ldap_property_list_opt: if ldap_property_value_map.has_key(property): if property not in ldap_property_list_passwords: print("%s: %s" % (property, ldap_property_value_map[property])) else: print("%s: %s" % (property, BLIND_PASSWORD)) save_settings = 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) if mgr_password != encrypted_passwd: ldap_property_value_map[LDAP_MGR_PASSWORD_PROPERTY] = encrypted_passwd pass if ts_password: encrypted_passwd = encrypt_password(SSL_TRUSTSTORE_PASSWORD_ALIAS, ts_password) if ts_password != encrypted_passwd: ldap_property_value_map[SSL_TRUSTSTORE_PASSWORD_PROPERTY] = encrypted_passwd pass 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) update_properties_2(properties, ldap_property_value_map) print 'Saving...done' return 0
def sync_ldap(options): if not is_root(): err = 'Ambari-server sync-ldap should be run with ' \ 'root-level privileges' raise FatalException(4, err) server_status, pid = is_server_runing() if not server_status: err = 'Ambari Server is not running.' raise FatalException(1, err) properties = get_ambari_properties() 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) if ldap_sync_options.no_ldap_sync_options_set(): err = 'Must specify a sync option (all, existing, users or groups). Please invoke ambari-server.py --help to print the options.' raise FatalException(1, err) admin_login = get_validated_string_input(prompt="Enter Ambari Admin login: "******"Enter Ambari Admin password: "******"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.') bodies = [{"Event":{"specs":[{"principal_type":"users","sync_type":"existing"},{"principal_type":"groups","sync_type":"existing"}]}}] else: sys.stdout.write('Syncing specified users and groups.') bodies = [{"Event":{"specs":[]}}] body = bodies[0] events = body['Event'] specs = events['specs'] if ldap_sync_options.ldap_sync_users is not None: new_specs = [{"principal_type":"users","sync_type":"specific","names":""}] get_ldap_event_spec_names(ldap_sync_options.ldap_sync_users, specs, new_specs) if ldap_sync_options.ldap_sync_groups is not None: new_specs = [{"principal_type":"groups","sync_type":"specific","names":""}] get_ldap_event_spec_names(ldap_sync_options.ldap_sync_groups, specs, new_specs) if get_verbose(): sys.stdout.write('\nCalling API ' + url + ' : ' + str(bodies) + '\n') request.add_data(json.dumps(bodies)) request.get_method = lambda: 'POST' try: response = urllib2.urlopen(request) except Exception as e: err = 'Sync event creation failed. Error details: %s' % e raise FatalException(1, err) response_status_code = response.getcode() if response_status_code != 201: err = 'Error during syncing. Http status code - ' + str(response_status_code) raise FatalException(1, err) response_body = json.loads(response.read()) url = response_body['resources'][0]['href'] request = urllib2.Request(url) request.add_header('Authorization', 'Basic %s' % admin_auth) request.add_header('X-Requested-By', 'ambari') body = [{"LDAP":{"synced_groups":"*","synced_users":"*"}}] request.add_data(json.dumps(body)) request.get_method = lambda: 'GET' request_in_progress = True while request_in_progress: sys.stdout.write('.') sys.stdout.flush() try: response = urllib2.urlopen(request) except Exception as e: request_in_progress = False err = 'Sync event check 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) response_body = json.loads(response.read()) sync_info = response_body['Event'] if sync_info['status'] == 'ERROR': raise FatalException(1, str(sync_info['status_detail'])) elif sync_info['status'] == 'COMPLETE': print '\n\nCompleted LDAP Sync.' print 'Summary:' for principal_type, summary in sync_info['summary'].iteritems(): print ' {0}:'.format(principal_type) for action, amount in summary.iteritems(): print ' {0} = {1!s}'.format(action, amount) request_in_progress = False else: time.sleep(1) sys.stdout.write('\n') sys.stdout.flush()
def import_cert_and_key(security_server_keys_dir): import_cert_path = get_validated_filepath_input( \ "Enter path to Certificate: ", \ "Certificate not found") import_key_path = get_validated_filepath_input( \ "Enter path to Private Key: ", "Private Key not found") pem_password = get_validated_string_input("Please enter password for Private Key: ", "", None, None, True) certInfoDict = get_cert_info(import_cert_path) if not certInfoDict: print_warning_msg('Unable to get Certificate information') else: #Validate common name of certificate if not is_valid_cert_host(certInfoDict): print_warning_msg('Unable to validate Certificate hostname') #Validate issue and expirations dates of certificate if not is_valid_cert_exp(certInfoDict): print_warning_msg('Unable to validate Certificate issue and expiration dates') #jetty requires private key files with non-empty key passwords retcode = 0 err = '' if not pem_password: print 'Generating random password for HTTPS keystore...done.' pem_password = generate_random_string() retcode, out, err = run_os_command(CHANGE_KEY_PWD_CND.format( import_key_path, pem_password)) import_key_path += '.secured' if retcode == 0: keystoreFilePath = os.path.join(security_server_keys_dir, \ SSL_KEYSTORE_FILE_NAME) keystoreFilePathTmp = os.path.join(tempfile.gettempdir(), \ SSL_KEYSTORE_FILE_NAME) passFilePath = os.path.join(security_server_keys_dir, \ SSL_KEY_PASSWORD_FILE_NAME) passFilePathTmp = os.path.join(tempfile.gettempdir(), \ SSL_KEY_PASSWORD_FILE_NAME) passinFilePath = os.path.join(tempfile.gettempdir(), \ SSL_PASSIN_FILE) passwordFilePath = os.path.join(tempfile.gettempdir(), \ SSL_PASSWORD_FILE) with open(passFilePathTmp, 'w+') as passFile: passFile.write(pem_password) passFile.close pass set_file_permissions(passFilePath, "660", read_ambari_user(), False) copy_file(passFilePathTmp, passinFilePath) copy_file(passFilePathTmp, passwordFilePath) retcode, out, err = run_os_command(EXPRT_KSTR_CMD.format(import_cert_path, \ import_key_path, passwordFilePath, passinFilePath, keystoreFilePathTmp)) if retcode == 0: print 'Importing and saving Certificate...done.' import_file_to_keystore(keystoreFilePathTmp, keystoreFilePath) import_file_to_keystore(passFilePathTmp, passFilePath) import_file_to_keystore(import_cert_path, os.path.join( \ security_server_keys_dir, SSL_CERT_FILE_NAME)) import_file_to_keystore(import_key_path, os.path.join( \ security_server_keys_dir, SSL_KEY_FILE_NAME)) #Validate keystore retcode, out, err = run_os_command(VALIDATE_KEYSTORE_CMD.format(keystoreFilePath, \ passwordFilePath, passinFilePath)) remove_file(passinFilePath) remove_file(passwordFilePath) if not retcode == 0: print 'Error during keystore validation occured!:' print err return False return True else: print_error_msg('Could not import Certificate and Private Key.') print 'SSL error on exporting keystore: ' + err.rstrip() + \ '.\nPlease ensure that provided Private Key password is correct and ' + \ 're-import Certificate.' return False
def download_and_install_jdk(self, args, properties): conf_file = properties.fileName jcePolicyWarn = "JCE Policy files are required for configuring Kerberos security. If you plan to use Kerberos," \ "please make sure JCE Unlimited Strength Jurisdiction Policy Files are valid on all hosts." if args.java_home: #java_home was specified among the command-line arguments. Use it as custom JDK location. if not validate_jdk(args.java_home): err = "Path to java home " + args.java_home + " or java binary file does not exists" raise FatalException(1, err) print_warning_msg("JAVA_HOME " + args.java_home + " must be valid on ALL hosts") print_warning_msg(jcePolicyWarn) IS_CUSTOM_JDK = True properties.process_pair(JAVA_HOME_PROPERTY, args.java_home) properties.removeOldProp(JDK_NAME_PROPERTY) properties.removeOldProp(JCE_NAME_PROPERTY) self._ensure_java_home_env_var_is_set(args.java_home) self.jdk_index = self.custom_jdk_number return java_home_var = get_JAVA_HOME() if OS_FAMILY == OSConst.WINSRV_FAMILY: progress_func = None else: progress_func = download_progress if get_silent(): if not java_home_var: #No java_home_var set, detect if java is already installed if os.environ.has_key(JAVA_HOME): args.java_home = os.environ[JAVA_HOME] properties.process_pair(JAVA_HOME_PROPERTY, args.java_home) properties.removeOldProp(JDK_NAME_PROPERTY) properties.removeOldProp(JCE_NAME_PROPERTY) self._ensure_java_home_env_var_is_set(args.java_home) self.jdk_index = self.custom_jdk_number return else: # For now, changing the existing JDK to make sure we use a supported one pass if java_home_var: change_jdk = get_YN_input("Do you want to change Oracle JDK [y/n] (n)? ", False) if not change_jdk: self._ensure_java_home_env_var_is_set(java_home_var) self.jdk_index = self.custom_jdk_number return #Continue with the normal setup, taking the first listed JDK version as the default option jdk_num = str(self.jdk_index + 1) (self.jdks, jdk_choice_prompt, jdk_valid_choices, self.custom_jdk_number) = self._populate_jdk_configs(properties, jdk_num) jdk_num = get_validated_string_input( jdk_choice_prompt, jdk_num, jdk_valid_choices, "Invalid number.", False ) self.jdk_index = int(jdk_num) - 1 if self.jdk_index == self.custom_jdk_number: print_warning_msg("JDK must be installed on all hosts and JAVA_HOME must be valid on all hosts.") print_warning_msg(jcePolicyWarn) args.java_home = get_validated_string_input("Path to JAVA_HOME: ", None, None, None, False, False) if not os.path.exists(args.java_home) or not os.path.isfile(os.path.join(args.java_home, "bin", self.JAVA_BIN)): err = "Java home path or java binary file is unavailable. Please put correct path to java home." raise FatalException(1, err) print "Validating JDK on Ambari Server...done." properties.process_pair(JAVA_HOME_PROPERTY, args.java_home) properties.removeOldProp(JDK_NAME_PROPERTY) properties.removeOldProp(JCE_NAME_PROPERTY) # Make sure any previously existing JDK and JCE name properties are removed. These will # confuse things in a Custom JDK scenario properties.removeProp(JDK_NAME_PROPERTY) properties.removeProp(JCE_NAME_PROPERTY) self._ensure_java_home_env_var_is_set(args.java_home) return jdk_cfg = self.jdks[self.jdk_index] resources_dir = get_resources_location(properties) dest_file = os.path.abspath(os.path.join(resources_dir, jdk_cfg.dest_file)) if os.path.exists(dest_file): print "JDK already exists, using " + dest_file elif properties[JDK_DOWNLOAD_SUPPORTED_PROPERTY].upper() == "FALSE": print "ERROR: Oracle JDK is not found in {1}. JDK download is not supported in this distribution. Please download Oracle JDK " \ "archive ({0}) manually from Oracle site, place it into {1} and re-run this script.".format(jdk_cfg.dest_file, dest_file) print "NOTE: If you have already downloaded the file, please verify if the name is exactly same as {0}.".format(jdk_cfg.dest_file) print 'Exiting...' sys.exit(1) else: ok = get_YN_input("To download the Oracle JDK and the Java Cryptography Extension (JCE) " "Policy Files you must accept the " "license terms found at " "http://www.oracle.com/technetwork/java/javase/" "terms/license/index.html and not accepting will " "cancel the Ambari Server setup and you must install the JDK and JCE " "files manually.\nDo you accept the " "Oracle Binary Code License Agreement [y/n] (y)? ", True) if not ok: print 'Exiting...' sys.exit(1) jdk_url = jdk_cfg.url print 'Downloading JDK from ' + jdk_url + ' to ' + dest_file self._download_jdk(jdk_url, dest_file, progress_func) try: (retcode, out, java_home_dir) = self._install_jdk(dest_file, jdk_cfg) except Exception, e: print "Installation of JDK has failed: %s\n" % str(e) file_exists = os.path.isfile(dest_file) if file_exists: ok = get_YN_input("JDK found at " + dest_file + ". " "Would you like to re-download the JDK [y/n] (y)? ", not get_silent()) if not ok: err = "Unable to install JDK. Please remove JDK file found at " + \ dest_file + " and re-run Ambari Server setup" raise FatalException(1, err) else: jdk_url = jdk_cfg.url print 'Re-downloading JDK from ' + jdk_url + ' to ' + dest_file self._download_jdk(jdk_url, dest_file, progress_func) print 'Successfully re-downloaded JDK distribution to ' + dest_file try: (retcode, out) = self._install_jdk(dest_file, jdk_cfg) except Exception, e: print "Installation of JDK was failed: %s\n" % str(e) err = "Unable to install JDK. Please remove JDK, file found at " + \ dest_file + " and re-run Ambari Server setup" raise FatalException(1, err)