示例#1
0
def change_elasticsearch_password(old_password, password='******', remote_host=None, remote_port=None,
                                  prompt_user=True, stdout=True, verbose=False):
    """
    Change the Elasticsearch password for all builtin users

    :param old_password: The old Elasticsearch password
    :param password: The new Elasticsearch password
    :param prompt_user: If True, warning prompt is displayed before proceeding
    :param stdout: Print status to stdout
    :param verbose: Include detailed debug messages
    """

    from dynamite_nsm.services.elasticsearch import process as elastic_process
    from dynamite_nsm.services.elasticsearch import profile as elastic_profile

    log_level = logging.INFO
    if verbose:
        log_level = logging.DEBUG
    logger = get_logger('ELASTICSEARCH', level=log_level, stdout=stdout)

    if prompt_user:
        resp = utilities.prompt_input(
            '\n\033[93m[-] WARNING! Changing the ElasticSearch password may result in connected components losing '
            'communication. Be sure to update Kibana/LogStash passwords.\n'
            '[?] Are you sure you wish to continue? [no]|yes):\033[0m ')
        while resp not in ['', 'no', 'yes']:
            resp = utilities.prompt_input('\033[93m[?] Are you sure you wish to continue? ([no]|yes):\033[0m ')
        if resp != 'yes':
            if stdout:
                sys.stdout.write('[+] Exiting\n')
            exit(0)
    if remote_host:
        logger.info("Resetting ElasticSearch password on remote host: {}:{}".format(remote_host, remote_port))
    else:
        logger.info("Resetting ElasticSearch password on localhost.")
        if elastic_profile.ProcessProfiler().is_installed():
            # If ElasticSearch is installed Locally.
            # Start the process, in order to perform a reset.
            if not elastic_process.ProcessManager().start():
                logger.error('Could not start ElasticSearch Process. Password reset failed.')
                raise general_exceptions.ResetPasswordError(
                    "ElasticSearch process was not able to start, check your ElasticSearch logs.")
            while not elastic_profile.ProcessProfiler().is_listening():
                logger.info('Waiting for ElasticSearch API to become accessible.')
                time.sleep(5)

            logger.info('ElasticSearch API is up.')
            logger.debug('Sleeping for 5 seconds, while ElasticSearch API finishes booting.')
            time.sleep(5)
        else:
            logger.error("ElasticSearch is not installed, and no remote ElasticSearch host was specified.")
            raise general_exceptions.ResetPasswordError(
                "ElasticSearch is not installed, and no remote ElasticSearch host was specified.")

    es_pw_config = PasswordConfigManager('elastic', current_password=old_password, remote_host=remote_host,
                                         remote_http_port=remote_port)
    logger.info("Attempting password reset.")
    es_pw_config.set_all_passwords(password)
 def invoke(self) -> Tuple[int, Dict]:
     es_url = f'https://{self.network_host}:{self.http_port}'
     es_cluster_data = {
         'persistent': {
             'script.max_compilations_rate': '1000/5m'
         },
         'transient': {
             'script.max_compilations_rate': '1000/5m'
         }
     }
     attempts = 0
     es_process_profile = profile.ProcessProfiler()
     if not es_process_profile.is_listening():
         process.ProcessManager().start()
     while not es_process_profile.is_listening(
     ) and attempts < self.max_attempts:
         attempts += 1
         sleep(10)
     r = requests.put(url=f'{es_url}/_cluster/settings',
                      data=json.dumps(es_cluster_data),
                      auth=('admin', 'admin'),
                      headers={'content-type': 'application/json'},
                      verify=False)
     if self.terminate_elasticsearch:
         process.ProcessManager().stop()
     if r.status_code != 200:
         return r.status_code, {'error': r.text}
     else:
         return r.status_code, r.json()
示例#3
0
    def __init__(self,
                 stdout: Optional[bool] = True,
                 verbose: Optional[bool] = False,
                 pretty_print_status: Optional[bool] = False):
        """Manage Elasticsearch Process
        Args:
            stdout: Print output to console
            verbose: Include detailed debug messages
            pretty_print_status: If enabled, status will be printed in a tabulated style
        Returns:
            None
        """

        environ = utilities.get_environment_file_dict()
        process.BaseProcessManager.__init__(
            self,
            'elasticsearch.service',
            'elasticsearch.process',
            log_path=environ.get('ES_LOGS'),
            create_pid_file=True,
            stdout=stdout,
            verbose=verbose,
            pretty_print_status=pretty_print_status)

        if not elasticsearch_profile.ProcessProfiler().is_installed():
            self.logger.error(
                "Elasticsearch is not installed. Install it with 'dynamite elasticsearch install -h'"
            )
            raise CallElasticProcessError("Elasticsearch is not installed.")
示例#4
0
 def _install_kibana_objects(self):
     self.logger.info('Installing Kibana Dashboards')
     self.logger.info('Waiting for ElasticSearch to become accessible.')
     # Start ElasticSearch if it is installed locally and is not running
     if self.elasticsearch_host in ['localhost', '127.0.0.1', '0.0.0.0', '::1', '::/128']:
         self.logger.info('Starting ElasticSearch.')
         elastic_process.ProcessManager().start()
         while not elastic_profile.ProcessProfiler().is_listening():
             self.logger.info('Waiting for ElasticSearch API to become accessible.')
             time.sleep(5)
         self.logger.info('ElasticSearch API is up.')
         self.logger.info('Sleeping for 5 seconds, while ElasticSearch API finishes booting.')
         time.sleep(5)
     try:
         kibana_proc = kibana_process.ProcessManager()
         kibana_proc.optimize()
         utilities.set_ownership_of_file(self.install_directory, user='******', group='dynamite')
         utilities.set_ownership_of_file(self.configuration_directory, user='******', group='dynamite')
         time.sleep(5)
         self.logger.info('Starting Kibana.')
         kibana_proc.start()
     except Exception as e:
         raise kibana_exceptions.InstallKibanaError("General error while starting Kibana process; {}".format(e))
     kibana_api_start_attempts = 0
     while not kibana_profile.ProcessProfiler().is_listening() and kibana_api_start_attempts != 5:
         self.logger.info('Waiting for Kibana API to become accessible.')
         kibana_api_start_attempts += 1
         time.sleep(5)
     if kibana_api_start_attempts == 5:
         self.logger.error('Kibana API could not be started after {} attempts.'.format(kibana_api_start_attempts))
         raise kibana_exceptions.InstallKibanaError(
             "Kibana API could not be started after {} attempts.".format(kibana_api_start_attempts))
     self.logger.info('Kibana API is up.')
     self.logger.info('Sleeping for 10 seconds, while Kibana API finishes booting.')
     time.sleep(10)
     api_config = kibana_configs.ApiConfigManager(self.configuration_directory)
     kibana_object_create_attempts = 1
     while kibana_object_create_attempts != 5:
         try:
             self.logger.info('[Attempt {}] Attempting to install dashboards/visualizations.'.format(
                 kibana_object_create_attempts))
             api_config.create_dynamite_kibana_objects()
             break
         except kibana_exceptions.CreateKibanaObjectsError:
             kibana_object_create_attempts += 1
             time.sleep(10)
     if kibana_object_create_attempts == 5:
         self.logger.error(
             "Kibana objects could not be created after {} attempts".format(kibana_object_create_attempts))
         raise kibana_exceptions.InstallKibanaError(
             "Kibana objects could not be created after {} attempts".format(kibana_object_create_attempts))
     self.logger.info('Successfully created dashboards/visualizations.')
     kibana_proc.stop()
    def __init__(self, prompt_user, stdout, verbose):
        execution_strategy.BaseExecStrategy.__init__(
            self,
            strategy_name="monitor_uninstall",
            strategy_description="Uninstall Monitor.",
            functions=(
                utilities.create_dynamite_environment_file,
                prompt_monitor_uninstall,
            ),
            arguments=(
                # utilities.create_dynamite_environment_file
                {},

                # prompt_user
                {
                    "prompt_user": bool(prompt_user),
                    "stdout": bool(stdout)
                },
            ),
            return_formats=(None, None))
        if kb_profile.ProcessProfiler().is_installed():
            self.add_function(func=kb_install.uninstall_kibana,
                              argument_dict={
                                  'prompt_user': False,
                                  'stdout': bool(stdout),
                                  'verbose': bool(verbose)
                              })
        if ls_profile.ProcessProfiler().is_installed():
            self.add_function(func=ls_install.uninstall_logstash,
                              argument_dict={
                                  'prompt_user': False,
                                  'stdout': bool(stdout),
                                  'verbose': bool(verbose)
                              })
        if es_profile.ProcessProfiler().is_installed():
            self.add_function(func=es_install.uninstall_elasticsearch,
                              argument_dict={
                                  'prompt_user': False,
                                  'stdout': bool(stdout),
                                  'verbose': bool(verbose)
                              })

        self.add_function(func=log_message,
                          argument_dict={
                              "msg":
                              '*** Monitor uninstalled successfully. ***',
                              'stdout': bool(stdout),
                              'verbose': bool(verbose)
                          })
示例#6
0
 def stop(self) -> bool:
     """Stop the monitor services
     Returns:
         True, if successfully stopped
     """
     kibana_res, logstash_res, elasticsearch_res = True, True, True
     if not elasticsearch_profile.ProcessProfiler().is_installed():
         self.logger.error('You must install kibana to run this command.')
         return False
     elasticsearch_res = elasticsearch_process.ProcessManager().stop()
     if logstash_profile.ProcessProfiler().is_installed():
         logstash_res = logstash_process.ProcessManager().stop()
     if kibana_profile.ProcessProfiler().is_installed():
         kibana_res = kibana_process.ProcessManager().stop()
     return kibana_res and elasticsearch_res and logstash_res
示例#7
0
 def invoke(self, shell: Optional[bool] = False, cwd: Optional[str] = None) -> List[
     Tuple[List, bytes, bytes]]:
     utilities.set_permissions_of_file(file_path=self.opendistro_security_admin, unix_permissions_integer='+x')
     if not cwd:
         cwd = self.security_conf_directory
     attempts = 0
     es_process_profile = profile.ProcessProfiler()
     if not es_process_profile.is_listening():
         process.ProcessManager().start()
     while not es_process_profile.is_listening() and attempts < self.max_attempts:
         attempts += 1
         sleep(10)
     results = super().invoke(shell, cwd)
     if self.terminate_elasticsearch:
         process.ProcessManager().stop()
     return results
示例#8
0
    def __init__(self, install_directory, configuration_directory, log_directory, host='0.0.0.0', port=5601,
                 elasticsearch_host=None, elasticsearch_port=None, elasticsearch_password='******',
                 download_kibana_archive=True, stdout=True, verbose=False):
        """
        :param install_directory: Path to the install directory (E.G /opt/dynamite/kibana/)
        :param configuration_directory: Path to the configuration directory (E.G /etc/dynamite/kibana/)
        :param log_directory: Path to the log directory (E.G /var/log/dynamite/kibana/)
        :param host: The IP address to listen on (E.G "0.0.0.0")
        :param port: The port that the Kibana UI/API is bound to (E.G 5601)
        :param elasticsearch_host: A hostname/IP of the target elasticsearch instance
        :param elasticsearch_port: A port number for the target elasticsearch instance
        :param elasticsearch_password: The password used for authentication across all builtin ES users
        :param download_kibana_archive: If True, download the Kibana archive from a mirror
        :param stdout: Print the output to console
        :param verbose: Include detailed debug messages
        """

        self.host = host
        self.port = port
        self.elasticsearch_host = elasticsearch_host
        self.elasticsearch_port = elasticsearch_port
        self.elasticsearch_password = elasticsearch_password
        if not elasticsearch_host:
            if elastic_profile.ProcessProfiler().is_installed():
                self.elasticsearch_host = 'localhost'
            else:
                raise kibana_exceptions.InstallKibanaError(
                    "ElasticSearch must either be installed locally, or a remote host must be specified.")
        self.install_directory = install_directory
        self.configuration_directory = configuration_directory
        self.log_directory = log_directory
        self.stdout = stdout
        self.verbose = verbose
        utilities.create_dynamite_environment_file()
        if download_kibana_archive:
            try:
                self.download_from_mirror(const.KIBANA_MIRRORS, const.KIBANA_ARCHIVE_NAME, stdout=stdout,
                                          verbose=verbose)
            except (general_exceptions.ArchiveExtractionError, general_exceptions.DownloadError):
                self.logger.error("Failed to download Kibana archive.")
                raise kibana_exceptions.InstallKibanaError("Failed to download Kibana archive.")
        try:
            self.extract_archive(os.path.join(const.INSTALL_CACHE, const.KIBANA_ARCHIVE_NAME))
        except general_exceptions.ArchiveExtractionError:
            self.logger.error("Failed to extract Kibana archive.")
            raise kibana_exceptions.InstallKibanaError("Failed to extract Kibana archive.")
        install.BaseInstallManager.__init__(self, 'kibana', verbose=self.verbose, stdout=self.stdout)
示例#9
0
    def uninstall(self):
        from dynamite_nsm.services.elasticsearch import profile as elasticsearch_profile
        from dynamite_nsm.services.logstash import profile as logstash_profile
        from dynamite_nsm.services.kibana import profile as kibana_profile

        if elasticsearch_profile.ProcessProfiler().is_installed():
            elasticsearch_install.UninstallManager(
                purge_config=True, stdout=self.stdout,
                verbose=self.verbose).uninstall()
        if logstash_profile.ProcessProfiler().is_installed():
            logstash_install.UninstallManager(
                purge_config=True, stdout=self.stdout,
                verbose=self.verbose).uninstall()
        if kibana_profile.ProcessProfiler().is_installed():
            kibana_install.UninstallManager(purge_config=True,
                                            stdout=self.stdout,
                                            verbose=self.verbose).uninstall()
    def __init__(self, old_password, new_password, stdout, verbose):
        execution_strategy.BaseExecStrategy.__init__(
            self,
            strategy_name="monitor_change_password",
            strategy_description=
            "Change the password for all monitor components.",
        )
        if es_profile.ProcessProfiler().is_installed():
            self.add_function(func=es_config.change_elasticsearch_password,
                              argument_dict={
                                  'old_password': str(old_password),
                                  'password': str(new_password),
                                  'prompt_user': False,
                                  'stdout': bool(stdout),
                                  'verbose': bool(verbose)
                              })
        if ls_profile.ProcessProfiler().is_installed():
            self.add_function(
                func=ls_config.change_logstash_elasticsearch_password,
                argument_dict={
                    'password': str(new_password),
                    'prompt_user': False,
                    'stdout': bool(stdout),
                    'verbose': bool(verbose)
                })
        if kb_profile.ProcessProfiler().is_installed():
            self.add_function(
                func=kb_config.change_kibana_elasticsearch_password,
                argument_dict={
                    'password': str(new_password),
                    'prompt_user': False,
                    'stdout': bool(stdout),
                    'verbose': bool(verbose)
                })

        self.add_function(func=log_message,
                          argument_dict={
                              'msg': 'Monitor passwords changed successfully!',
                              'stdout': bool(stdout),
                              'verbose': bool(verbose)
                          })
示例#11
0
 def __init__(self, stdout=True, verbose=False, pretty_print_status=False):
     environ = utilities.get_environment_file_dict()
     try:
         process.BaseProcessManager.__init__(
             self,
             'elasticsearch.service',
             'elasticsearch',
             log_path=environ.get('ES_LOGS'),
             pid_file=os.path.join(PID_DIRECTORY, 'elasticsearch.pid'),
             stdout=stdout,
             verbose=verbose,
             pretty_print_status=pretty_print_status)
     except general_exceptions.CallProcessError:
         self.logger.error("Could not find systemctl on this system.")
         raise elasticsearch_exceptions.CallElasticProcessError(
             "Could not find systemctl.")
     if not elasticsearch_profile.ProcessProfiler().is_installed():
         self.logger.error(
             "ElasticSearch is not installed. Install it with 'dynamite elasticsearch install -h'"
         )
         raise elasticsearch_exceptions.CallElasticProcessError(
             "ElasticSearch is not installed.")
示例#12
0
    def __init__(self,
                 configuration_directory,
                 install_directory,
                 log_directory,
                 host='0.0.0.0',
                 elasticsearch_host='localhost',
                 elasticsearch_port=9200,
                 elasticsearch_password='******',
                 heap_size_gigs=4,
                 download_logstash_archive=True,
                 stdout=True,
                 verbose=False):
        """
        :param configuration_directory: Path to the configuration directory (E.G /etc/dynamite/logstash/)
        :param install_directory: Path to the install directory (E.G /opt/dynamite/logstash/)
        :param log_directory: Path to the log directory (E.G /var/log/dynamite/logstash/)
        :param host: The IP address to listen on (E.G "0.0.0.0")
        :param elasticsearch_host: A hostname/IP of the target elasticsearch instance
        :param elasticsearch_port: A port number for the target elasticsearch instance
        :param elasticsearch_password: The password used for authentication across all builtin ES users
        :param heap_size_gigs: The initial/max java heap space to allocate
        :param download_logstash_archive: If True, download the LogStash archive from a mirror
        :param stdout: Print output to console
        :param verbose: Include output from system utilities
        """

        self.host = host
        if not elasticsearch_host:
            if elastic_profile.ProcessProfiler().is_installed():
                self.elasticsearch_host = 'localhost'
                self.logger.info(
                    "Assuming LogStash will connect to local ElasticSearch instance, "
                    "as ElasticSearch is installed on this host.")
            else:
                self.logger.error(
                    "ElasticSearch must either be installed locally, or a remote host must be specified."
                )
                raise logstash_exceptions.InstallLogstashError(
                    "ElasticSearch must either be installed locally, or a remote host must be specified."
                )
        else:
            self.elasticsearch_host = elasticsearch_host
        self.elasticsearch_port = elasticsearch_port
        self.configuration_directory = configuration_directory
        self.install_directory = install_directory
        self.elasticsearch_password = elasticsearch_password
        self.heap_size_gigs = heap_size_gigs
        self.log_directory = log_directory
        self.stdout = stdout
        self.verbose = verbose
        utilities.create_dynamite_environment_file()
        if download_logstash_archive:
            try:
                self.download_from_mirror(const.LOGSTASH_MIRRORS,
                                          const.LOGSTASH_ARCHIVE_NAME,
                                          stdout=stdout,
                                          verbose=verbose)
            except (general_exceptions.ArchiveExtractionError,
                    general_exceptions.DownloadError):
                self.logger.error("Failed to download LogStash archive.")
                raise logstash_exceptions.InstallLogstashError(
                    "Failed to download LogStash archive.")
        try:
            self.extract_archive(
                os.path.join(const.INSTALL_CACHE, const.LOGSTASH_ARCHIVE_NAME))
        except general_exceptions.ArchiveExtractionError:
            self.logger.error("Failed to extract LogStash archive.")
            raise logstash_exceptions.InstallLogstashError(
                "Failed to extract LogStash archive.")
        install.BaseInstallManager.__init__(self,
                                            'logstash',
                                            verbose=self.verbose,
                                            stdout=stdout)
示例#13
0
def uninstall_elasticsearch(prompt_user=True, stdout=True, verbose=False):
    """
    Uninstall ElasticSearch

    :param prompt_user: Print a warning before continuing
    :param stdout: Print the output to console
    :param verbose: Include detailed debug messages
    """

    log_level = logging.INFO
    if verbose:
        log_level = logging.DEBUG
    logger = get_logger('ELASTICSEARCH', level=log_level, stdout=stdout)

    env_file = os.path.join(const.CONFIG_PATH, 'environment')
    environment_variables = utilities.get_environment_file_dict()
    es_profiler = elastic_profile.ProcessProfiler()
    if not es_profiler.is_installed():
        logger.error('ElasticSearch is not installed.')
        raise elastic_exceptions.UninstallElasticsearchError(
            "ElasticSearch is not installed.")
    configuration_directory = environment_variables.get('ES_PATH_CONF')
    es_config = elastic_configs.ConfigManager(
        configuration_directory=configuration_directory)
    if prompt_user:
        sys.stderr.write(
            '\n\033[93m[-] WARNING! Removing ElasticSearch Will Delete All Data.'
            '\033[0m\n')
        resp = utilities.prompt_input(
            '\033[93m[?] Are you sure you wish to continue? ([no]|yes):\033[0m '
        )
        while resp not in ['', 'no', 'yes']:
            resp = utilities.prompt_input(
                '\n\033[93m[?] Are you sure you wish to continue? ([no]|yes):\033[0m '
            )
        if resp != 'yes':
            if stdout:
                sys.stdout.write('\n[+] Exiting\n')
            exit(0)
    if es_profiler.is_running():
        elastic_process.ProcessManager().stop()
    try:
        shutil.rmtree(es_config.configuration_directory)
        shutil.rmtree(es_config.es_home)
        shutil.rmtree(es_config.path_logs)
        shutil.rmtree(const.INSTALL_CACHE, ignore_errors=True)
        env_lines = ''
        with open(env_file) as env_fr:
            for line in env_fr.readlines():
                if 'ES_PATH_CONF' in line:
                    continue
                elif 'ES_HOME' in line:
                    continue
                elif 'ES_LOGS' in line:
                    continue
                elif line.strip() == '':
                    continue
                env_lines += line.strip() + '\n'
        with open(env_file, 'w') as env_fw:
            env_fw.write(env_lines)
    except Exception as e:
        logger.error(
            "General error occurred while attempting to uninstall ElasticSearch."
            .format(e))
        logger.debug(
            "General error occurred while attempting to uninstall ElasticSearch; {}"
            .format(e))
        raise elastic_exceptions.UninstallElasticsearchError(
            "General error occurred while attempting to uninstall ElasticSearch; {}"
            .format(e))
    try:
        sysctl = systemctl.SystemCtl()
    except general_exceptions.CallProcessError:
        raise elastic_exceptions.UninstallElasticsearchError(
            "Could not find systemctl.")
    sysctl.uninstall_and_disable('elasticsearch')
示例#14
0
def install_elasticsearch(configuration_directory,
                          install_directory,
                          log_directory,
                          password='******',
                          heap_size_gigs=4,
                          install_jdk=True,
                          create_dynamite_user=True,
                          stdout=True,
                          verbose=False):
    """
    Install ElasticSearch

    :param configuration_directory: Path to the configuration directory (E.G /etc/dynamite/elasticsearch/)
    :param install_directory: Path to the install directory (E.G /opt/dynamite/elasticsearch/)
    :param log_directory: Path to the log directory (E.G /var/log/dynamite/elasticsearch/)
    :param password: The password used for authentication across all builtin users
    :param heap_size_gigs: The initial/max java heap space to allocate
    :param install_jdk: Install the latest OpenJDK that will be used by Logstash/ElasticSearch
    :param create_dynamite_user: Automatically create the 'dynamite' user, who has privs to run Logstash/ElasticSearch
    :param stdout: Print the output to console
    :param verbose: Include detailed debug messages
    """

    log_level = logging.INFO
    if verbose:
        log_level = logging.DEBUG
    logger = get_logger('ELASTICSEARCH', level=log_level, stdout=stdout)

    es_profiler = elastic_profile.ProcessProfiler()
    if es_profiler.is_installed():
        logger.error('ElasticSearch is already installed.')
        raise elastic_exceptions.AlreadyInstalledElasticsearchError()
    if utilities.get_memory_available_bytes() < 6 * (1000**3):
        sys.stderr.write(
            '\n\033[93m[-] WARNING! ElasticSearch should have at-least 6GB to run '
            'currently available [{} GB]\033[0m\n'.format(
                utilities.get_memory_available_bytes() / (1000**3)))
        if str(utilities.prompt_input(
                '\033[93m[?] Continue? [y|N]:\033[0m ')).lower() != 'y':
            sys.stdout.write('\n[+] Exiting\n')
            exit(0)
    es_installer = InstallManager(
        configuration_directory=configuration_directory,
        install_directory=install_directory,
        log_directory=log_directory,
        password=password,
        heap_size_gigs=heap_size_gigs,
        download_elasticsearch_archive=not es_profiler.is_downloaded(),
        stdout=stdout,
        verbose=verbose)
    if install_jdk:
        try:
            utilities.download_java(stdout=stdout)
            utilities.extract_java()
            utilities.setup_java()
        except Exception as e:
            logger.error(
                'General error occurred while attempting to setup Java.')
            logger.debug(
                "General error occurred while attempting to setup Java; {}".
                format(e))
            raise elastic_exceptions.InstallElasticsearchError(
                "General error occurred while attempting to setup Java; {}".
                format(e))
    if create_dynamite_user:
        utilities.create_dynamite_user(utilities.generate_random_password(50))
    es_installer.setup_elasticsearch()
示例#15
0
    def setup_passwords(self):
        env_dict = utilities.get_environment_file_dict()

        def setup_from_bootstrap(s):
            bootstrap_users_and_passwords = {}
            for line in s.split('\n'):
                if 'PASSWORD' in line:
                    _, user, _, password = line.split(' ')
                    if not isinstance(password, str):
                        password = password.decode()
                    bootstrap_users_and_passwords[user] = password
            es_pass_config = elastic_configs.PasswordConfigManager(
                auth_user='******',
                current_password=bootstrap_users_and_passwords['elastic'],
                stdout=self.stdout,
                verbose=self.verbose)
            es_pass_config.set_all_passwords(new_password=self.password)

        if not elastic_profile.ProcessProfiler().is_installed():
            self.logger.error(
                'ElasticSearch must be installed and running to bootstrap passwords.'
            )
            raise elastic_exceptions.InstallElasticsearchError(
                "ElasticSearch must be installed and running to bootstrap passwords."
            )
        self.logger.info('Creating certificate keystore.')
        es_config_path = os.path.join(self.configuration_directory, 'config')
        try:
            utilities.makedirs(es_config_path, exist_ok=True)
        except Exception as e:
            self.logger.error(
                "General error occurred while attempting to create {} directory."
                .format(es_config_path))
            self.logger.debug(
                "General error occurred while attempting to create {} directory; {}"
                .format(es_config_path, e))
            raise elastic_exceptions.InstallElasticsearchError(
                "General error occurred while attempting to create {} directory; {}"
                .format(es_config_path, e))
        es_cert_util = os.path.join(self.install_directory, 'bin',
                                    'elasticsearch-certutil')
        es_cert_keystore = os.path.join(self.configuration_directory, 'config',
                                        'elastic-certificates.p12')
        cert_p = subprocess.Popen(
            [es_cert_util, 'cert', '-out', es_cert_keystore, '-pass', ''],
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
            stdin=subprocess.PIPE,
            env=env_dict)
        try:
            cert_p_res = cert_p.communicate()
        except Exception as e:
            self.logger.error(
                "General error occurred while attempting to install SSL keystores."
            )
            self.logger.debug(
                "General error occurred while attempting to install SSL keystores; {}"
                .format(e))
            raise elastic_exceptions.InstallElasticsearchError(
                "General error occurred while attempting to install SSL keystores; {}"
                .format(e))
        if not os.path.exists(es_cert_keystore):
            self.logger.error(
                'Failed to setup SSL certificate keystore: \noutput: {}\n\t'.
                format(cert_p_res))
            raise elastic_exceptions.InstallElasticsearchError(
                "Failed to setup SSL keystore; {}".format(cert_p_res))
        keystore_config_path = os.path.join(self.configuration_directory,
                                            'config')
        try:
            utilities.set_ownership_of_file(keystore_config_path,
                                            user='******',
                                            group='dynamite')
        except Exception as e:
            self.logger.error(
                'General error occurred while attempting to set permissions for {}.'
                .format(keystore_config_path))
            self.logger.debug(
                "General error occurred while attempting to set permissions for {}; {}"
                .format(keystore_config_path, e))
            raise elastic_exceptions.InstallElasticsearchError(
                "General error occurred while attempting to set permissions for {}; {}"
                .format(keystore_config_path, e))
        if not elastic_profile.ProcessProfiler().is_running():
            elastic_process.ProcessManager().start()
            attempts = 0
            while not elastic_profile.ProcessProfiler().is_listening():
                self.logger.info(
                    'Waiting for ElasticSearch API to become accessible.')
                time.sleep(10)
                attempts += 1
                if attempts == 10:
                    self.logger.error(
                        "Failed to start ElasticSearch API after 10 attempts.")
                    raise elastic_exceptions.InstallElasticsearchError(
                        "Failed to start Elasticsearch API after 10 attempts.")
            self.logger.info('ElasticSearch API is up.')
            self.logger.debug(
                'Sleeping for 5 seconds, while ElasticSearch API finishes booting.'
            )
            time.sleep(5)
        self.logger.info('Bootstrapping passwords.')
        es_password_util = os.path.join(self.install_directory, 'bin',
                                        'elasticsearch-setup-passwords')
        bootstrap_p = subprocess.Popen([es_password_util, 'auto'],
                                       cwd=self.configuration_directory,
                                       stdout=subprocess.PIPE,
                                       stderr=subprocess.STDOUT,
                                       stdin=subprocess.PIPE,
                                       env=env_dict)
        try:
            bootstrap_p_res = bootstrap_p.communicate(input=b'y\n')
            if not bootstrap_p_res:
                self.logger.error('Failed to setup new passwords.')
                raise elastic_exceptions.InstallElasticsearchError(
                    "Failed to bootstrap password.")
            try:
                if not isinstance(bootstrap_p_res[0], str):
                    setup_from_bootstrap(bootstrap_p_res[0].decode())
                else:
                    setup_from_bootstrap(bootstrap_p_res[0])
            except general_exceptions.ResetPasswordError:
                self.logger.error("Failed to bootstrap password.")
                raise elastic_exceptions.InstallElasticsearchError(
                    "Failed to bootstrap password.")
        except Exception as e:
            self.logger.error(
                "General error occurred while attempting to bootstrap ElasticSearch passwords."
            )
            self.logger.debug(
                "General error occurred while attempting to bootstrap ElasticSearch passwords {}"
                .format(e))
            raise elastic_exceptions.InstallElasticsearchError(
                "General error occurred while attempting to bootstrap ElasticSearch passwords {}"
                .format(e))
示例#16
0
    def __init__(self,
                 configuration_directory,
                 notebook_home,
                 elasticsearch_host=None,
                 elasticsearch_port=None,
                 elasticsearch_password='******',
                 jupyterhub_host=None,
                 jupyterhub_password='******',
                 download_dynamite_sdk_archive=True,
                 extract_dynamite_sdk_archive=True,
                 stdout=True,
                 verbose=False):
        """
        :param configuration_directory: Path to the configuration directory (E.G /etc/dynamite/dynamite_sdk/)
        :param notebook_home: The path where Jupyter notebooks are stored
        :param elasticsearch_host: A hostname/IP of the target elasticsearch instance
        :param elasticsearch_port: A port number for the target elasticsearch instance
        :param elasticsearch_password: The password used for authentication across all builtin ES users
        :param jupyterhub_host: The host by which users can access this instance;
                                (Used for creating kibana -> Jupyter hyperlinks)
        :param jupyterhub_password: The password used for authenticating to jupyterhub (via jupyter user)
        :param download_dynamite_sdk_archive: If True, download the DynamiteSDK archive from a mirror
        :param extract_dynamite_sdk_archive: If True, extracts the DynamiteSDK archive
        :param stdout: Print output to console
        :param verbose: Include detailed debug messages
        """

        log_level = logging.INFO
        if verbose:
            log_level = logging.DEBUG
        self.logger = get_logger('LAB', level=log_level, stdout=stdout)

        self.elasticsearch_host = elasticsearch_host
        self.elasticsearch_port = elasticsearch_port
        self.elasticsearch_password = elasticsearch_password
        self.jupyterhub_host = jupyterhub_host
        self.jupyterhub_password = jupyterhub_password
        self.configuration_directory = configuration_directory
        self.notebook_home = notebook_home
        if download_dynamite_sdk_archive:
            try:
                self.download_dynamite_sdk(stdout=stdout)
            except general_exceptions.DownloadError:
                self.logger.error('Failed to download DynamiteSDK archive.')
                raise lab_exceptions.InstallLabError(
                    "Failed to download DynamiteSDK archive.")
        if extract_dynamite_sdk_archive:
            try:
                self.extract_dynamite_sdk()
            except general_exceptions.ArchiveExtractionError:
                self.logger.error('Failed to extract DynamiteSDK archive.')
                raise lab_exceptions.InstallLabError(
                    "Failed to extract DynamiteSDK archive.")
        try:
            self.install_dependencies(stdout=stdout, verbose=verbose)
            self.install_jupyterhub(stdout=stdout)
        except (general_exceptions.InvalidOsPackageManagerDetectedError,
                general_exceptions.OsPackageManagerInstallError,
                general_exceptions.OsPackageManagerRefreshError):
            self.logger.error('One or more OS dependencies failed to install.')
            raise lab_exceptions.InstallLabError(
                "One or more OS dependencies failed to install.")
        self.logger.info('Creating jupyter user in dynamite group.')
        utilities.create_jupyter_user(password=self.jupyterhub_password)
        self.stdout = stdout
        self.verbose = verbose

        if not elasticsearch_host:
            if elastic_profile.ProcessProfiler().is_installed():
                self.elasticsearch_host = 'localhost'
            else:
                raise lab_exceptions.InstallLabError(
                    "Elasticsearch must either be installed locally, or a remote host must be specified."
                )
    def __init__(self, logstash_listen_address, kibana_listen_address,
                 kibana_listen_port, elasticsearch_host, elasticsearch_port,
                 elasticsearch_password, elasticsearch_heap_size_gigs,
                 logstash_heap_size_gigs, install_jdk, stdout, verbose):
        execution_strategy.BaseExecStrategy.__init__(
            self,
            strategy_name="monitor_install",
            strategy_description=
            "Install ElasticSearch, LogStash, and Kibana on the same instance.",
            functions=(utilities.create_dynamite_environment_file, ),
            arguments=({}, ),
            return_formats=(None, ))

        self.add_function(func=remove_elasticsearch_tar_archive,
                          argument_dict={},
                          return_format=None)

        self.add_function(func=remove_logstash_tar_archive,
                          argument_dict={},
                          return_format=None)

        self.add_function(func=remove_kibana_tar_archive,
                          argument_dict={},
                          return_format=None)

        if not es_profile.ProcessProfiler().is_installed():
            self.add_function(func=es_install.install_elasticsearch,
                              argument_dict={
                                  "configuration_directory":
                                  "/etc/dynamite/elasticsearch/",
                                  "install_directory":
                                  "/opt/dynamite/elasticsearch/",
                                  "log_directory":
                                  "/var/log/dynamite/elasticsearch/",
                                  "password":
                                  str(elasticsearch_password),
                                  "heap_size_gigs":
                                  int(elasticsearch_heap_size_gigs),
                                  "install_jdk":
                                  bool(install_jdk),
                                  "create_dynamite_user":
                                  True,
                                  "stdout":
                                  bool(stdout),
                                  "verbose":
                                  bool(verbose)
                              },
                              return_format=None)
        else:
            self.add_function(
                func=log_message,
                argument_dict={
                    "msg":
                    'Skipping ElasticSearch installation; already installed.',
                    'stdout': bool(stdout),
                    'verbose': bool(verbose)
                },
                return_format=None)

        self.add_function(func=es_process.start,
                          argument_dict={"stdout": False},
                          return_format=None)

        if not ls_profile.ProcessProfiler().is_installed():
            self.add_function(func=ls_install.install_logstash,
                              argument_dict={
                                  "configuration_directory":
                                  "/etc/dynamite/logstash/",
                                  "install_directory":
                                  "/opt/dynamite/logstash/",
                                  "log_directory":
                                  "/var/log/dynamite/logstash/",
                                  "host":
                                  str(logstash_listen_address),
                                  "elasticsearch_host":
                                  str(elasticsearch_host),
                                  "elasticsearch_port":
                                  int(elasticsearch_port),
                                  "elasticsearch_password":
                                  str(elasticsearch_password),
                                  "heap_size_gigs":
                                  int(logstash_heap_size_gigs),
                                  "install_jdk":
                                  False,
                                  "create_dynamite_user":
                                  False,
                                  "stdout":
                                  bool(stdout),
                                  "verbose":
                                  bool(verbose)
                              },
                              return_format=None)
        else:
            self.add_function(
                func=log_message,
                argument_dict={
                    "msg":
                    'Skipping LogStash installation; already installed.',
                    'stdout': bool(stdout),
                    'verbose': bool(verbose)
                },
                return_format=None)

        if not kb_profile.ProcessProfiler().is_installed():
            self.add_function(func=kb_install.install_kibana,
                              argument_dict={
                                  "configuration_directory":
                                  "/etc/dynamite/kibana/",
                                  "install_directory":
                                  "/opt/dynamite/kibana/",
                                  "log_directory":
                                  "/var/log/dynamite/kibana/",
                                  "host":
                                  str(kibana_listen_address),
                                  "port":
                                  int(kibana_listen_port),
                                  "elasticsearch_host":
                                  str(elasticsearch_host),
                                  "elasticsearch_port":
                                  int(elasticsearch_port),
                                  "elasticsearch_password":
                                  str(elasticsearch_password),
                                  "create_dynamite_user":
                                  True,
                                  "stdout":
                                  bool(stdout),
                                  "verbose":
                                  bool(verbose)
                              },
                              return_format=None)
        else:
            self.add_function(
                func=log_message,
                argument_dict={
                    "msg": 'Skipping Kibana installation; already installed.',
                    'stdout': bool(stdout),
                    'verbose': bool(verbose)
                },
                return_format=None)

        self.add_function(func=kb_process.stop,
                          argument_dict={"stdout": False},
                          return_format=None)

        self.add_function(func=es_process.stop,
                          argument_dict={"stdout": False},
                          return_format=None)

        self.add_function(func=log_message,
                          argument_dict={
                              "msg": '*** Monitor installed successfully. ***',
                              'stdout': bool(stdout),
                              'verbose': bool(verbose)
                          },
                          return_format=None)

        self.add_function(
            func=log_message,
            argument_dict={
                "msg":
                'Next, Start your monitor: '
                '\'dynamite monitor start\'. It will be available at: \033[4m{}:{}\033[0m once started.'
                ''.format(kibana_listen_address, kibana_listen_port),
                'stdout':
                bool(stdout),
                'verbose':
                bool(verbose)
            },
            return_format=None)
示例#18
0
    def status(self) -> Optional[Union[Dict, str]]:
        """Get the statuses of monitor services
        Returns:
            The statuses of monitor services
        """
        agent_status = {}
        kibana_status, elasticsearch_status, logstash_status = {}, {}, {}
        if not elasticsearch_profile.ProcessProfiler().is_installed():
            self.logger.error(
                'You must install elasticsearch to run this command.')
            return None

        elasticsearch_status = elasticsearch_process.ProcessManager().status()
        agent_status.update({
            'elasticsearch': {
                'running':
                elasticsearch_status.get('running'),
                'enabled_on_startup':
                elasticsearch_status.get('enabled_on_startup')
            }
        })
        if logstash_profile.ProcessProfiler().is_installed():
            logstash_status = logstash_process.ProcessManager().status()
            agent_status.update({
                'logstash': {
                    'running': logstash_status.get('running'),
                    'enabled_on_startup':
                    logstash_status.get('enabled_on_startup')
                }
            })
        if kibana_profile.ProcessProfiler().is_installed():
            kibana_status = kibana_process.ProcessManager().status()
            agent_status.update({
                'kibana': {
                    'running': kibana_status.get('running'),
                    'enabled_on_startup':
                    kibana_status.get('enabled_on_startup')
                }
            })

        if self.pretty_print_status:
            colorize = utilities.PrintDecorations.colorize
            child_services = [
                ['Service', 'Running', 'Enabled on Startup'],
                [
                    'kibana',
                    colorize('yes', 'green')
                    if kibana_status.get('running') else colorize('no', 'red'),
                    colorize('yes', 'green')
                    if kibana_status.get('enabled_on_startup') else colorize(
                        'no', 'red')
                ]
            ]
            if elasticsearch_status:
                child_services.append([
                    'elasticsearch',
                    colorize('yes', 'green')
                    if elasticsearch_status.get('running') else colorize(
                        'no', 'red'),
                    colorize('yes', 'green')
                    if elasticsearch_status.get('enabled_on_startup') else
                    colorize('no', 'red')
                ])
            if logstash_status:
                child_services.append([
                    'logstash',
                    colorize('yes', 'green')
                    if elasticsearch_status.get('running') else colorize(
                        'no', 'red'),
                    colorize('yes', 'green')
                    if elasticsearch_status.get('enabled_on_startup') else
                    colorize('no', 'red')
                ])

            return tabulate.tabulate(child_services, tablefmt='fancy_grid')
        return agent_status