Skip to content

install

Installation Manager for Elasticsearch and its dependencies.

To import...

from dynamite_nsm.services.elasticsearch import install as elasticsearch_install

InstallManager

__init__(self, configuration_directory, install_directory, log_directory, download_elasticsearch_archive=True, stdout=False, verbose=False) special

Install Elasticsearch

Parameters:

Name Type Description Default
configuration_directory str

Path to the configuration directory (E.G /etc/dynamite/elasticsearch/)

required
install_directory str

Path to the install directory (E.G /opt/dynamite/elasticsearch/)

required
log_directory str

Path to the log directory (E.G /var/log/dynamite/elasticsearch/)

required
download_elasticsearch_archive Optional[bool]

If True, download the ElasticSearch archive from a mirror

True
stdout Optional[bool]

Print output to console

False
verbose Optional[bool]

Include detailed debug messages

False
Source code in dynamite_nsm/services/elasticsearch/install.py
def __init__(self, configuration_directory: str, install_directory: str, log_directory: str,
             download_elasticsearch_archive: Optional[bool] = True,
             stdout: Optional[bool] = False, verbose: Optional[bool] = False):
    """Install Elasticsearch
    Args:
        configuration_directory: Path to the configuration directory (E.G /etc/dynamite/elasticsearch/)
        install_directory: Path to the install directory (E.G /opt/dynamite/elasticsearch/)
        log_directory: Path to the log directory (E.G /var/log/dynamite/elasticsearch/)
        download_elasticsearch_archive: If True, download the ElasticSearch archive from a mirror
        stdout: Print output to console
        verbose: Include detailed debug messages
    """
    self.configuration_directory = configuration_directory
    self.install_directory = install_directory
    self.log_directory = log_directory
    self.stdout = stdout
    self.verbose = verbose
    install.BaseInstallManager.__init__(self, 'elasticsearch.install', verbose=self.verbose, stdout=stdout)
    java_home = self.dynamite_environ.get('JAVA_HOME')
    if not java_home:
        self.logger.info('Installing compatible version of Java.')
        from dynamite_nsm.services.java import install as java_install
        java_install.InstallManager(const.JVM_ROOT, stdout=stdout, verbose=verbose).setup()
    if download_elasticsearch_archive:
        self.logger.info("Attempting to download Elasticsearch (OpenDistro) archive.")
        _, archive_name, self.local_mirror_root = self.download_from_mirror(const.ELASTICSEARCH_MIRRORS)
        self.logger.info(f'Attempting to extract Elasticsearch archive ({archive_name}).')
        self.extract_archive(os.path.join(const.INSTALL_CACHE, archive_name))
        self.logger.info("Extraction completed.")
    else:
        _, _, self.local_mirror_root = self.get_mirror_info(const.ELASTICSEARCH_MIRRORS)

copy_elasticsearch_files_and_directories(self)

Copy the required Elasticsearch files from the install cache to their respective directories

Source code in dynamite_nsm/services/elasticsearch/install.py
def copy_elasticsearch_files_and_directories(self) -> None:
    """
    Copy the required Elasticsearch files from the install cache to their respective directories
    """
    elasticsearch_tarball_extracted = f'{const.INSTALL_CACHE}/{self.local_mirror_root}'
    config_paths = [
        'config/elasticsearch.yml',
        'config/jvm.options',
        'config/log4j2.properties',
        'config/opendistro-reports-scheduler'
    ]
    install_paths = [
        'bin/',
        'data/',
        'lib/',
        'logs/',
        'modules/',
        'plugins/'
    ]
    for conf in config_paths:
        self.copy_file_or_directory_to_destination(f'{elasticsearch_tarball_extracted}/{conf}',
                                                   self.configuration_directory)
    for inst in install_paths:
        self.copy_file_or_directory_to_destination(f'{elasticsearch_tarball_extracted}/{inst}',
                                                   self.install_directory)

create_update_elasticsearch_environment_variables(self)

Creates all the required ElasticSearch environmental variables

Source code in dynamite_nsm/services/elasticsearch/install.py
def create_update_elasticsearch_environment_variables(self) -> None:
    """
    Creates all the required ElasticSearch environmental variables
    """
    self.create_update_env_variable('ES_PATH_CONF', self.configuration_directory)
    self.create_update_env_variable('ES_HOME', self.install_directory)
    self.create_update_env_variable('ES_LOGS', self.log_directory)

setup(self, node_name=None, network_host=None, port=None, initial_master_nodes=None, discover_seed_hosts=None, tls_cert_subject=None, heap_size_gigs=None)

Setup Elasticsearch

Parameters:

Name Type Description Default
node_name Optional[str]

The name of this elasticsearch node

None
network_host Optional[str]

The IP address to listen on (E.G "0.0.0.0")

None
port Optional[int]

The port that the ES API is bound to (E.G 9200)

None
initial_master_nodes Optional[List[str]]

A list of nodes representing master (and master-eligible) nodes in this cluster

None
discover_seed_hosts Optional[List[str]]

A list of IPs on other hosts you wish to form a cluster with

None
tls_cert_subject Optional[str]

Denotes the thing being secured; E.G (/C=US/ST=GA/L=Atlanta/O=Dynamite Analytics/OU=R&D/CN=dynamite.ai)

None
heap_size_gigs Optional[int]

The initial/max java heap space to allocate

None

Returns:

Type Description
None

None

Source code in dynamite_nsm/services/elasticsearch/install.py
def setup(self, node_name: Optional[str] = None, network_host: Optional[str] = None, port: Optional[int] = None,
          initial_master_nodes: Optional[List[str]] = None, discover_seed_hosts: Optional[List[str]] = None,
          tls_cert_subject: Optional[str] = None, heap_size_gigs: Optional[int] = None) -> None:
    """Setup Elasticsearch
    Args:
        node_name: The name of this elasticsearch node
        network_host: The IP address to listen on (E.G "0.0.0.0")
        port: The port that the ES API is bound to (E.G 9200)
        initial_master_nodes: A list of nodes representing master (and master-eligible) nodes in this cluster
        discover_seed_hosts: A list of IPs on other hosts you wish to form a cluster with
        tls_cert_subject: Denotes the thing being secured; E.G (/C=US/ST=GA/L=Atlanta/O=Dynamite Analytics/OU=R&D/CN=dynamite.ai)
        heap_size_gigs: The initial/max java heap space to allocate
    Returns:
        None
    """
    sysctl = systemctl.SystemCtl()

    # System patching and directory setup
    self.logger.debug('Patching sysctl.')
    utilities.update_sysctl()
    self.logger.debug('Patching file-handle limits.')
    utilities.update_user_file_handle_limits()

    self.logger.debug(f'Creating directory: {self.configuration_directory}')
    utilities.makedirs(self.configuration_directory)
    self.logger.debug(f'Creating directory: {self.install_directory}')
    utilities.makedirs(self.install_directory)
    self.logger.debug(f'Creating directory: {self.log_directory}')
    utilities.makedirs(self.log_directory)

    self.copy_elasticsearch_files_and_directories()
    self.create_update_elasticsearch_environment_variables()

    # Overwrite with dynamite default configurations
    self.copy_file_or_directory_to_destination(f'{const.DEFAULT_CONFIGS}/elasticsearch/elasticsearch.yml',
                                               self.configuration_directory)
    self.copy_file_or_directory_to_destination(f'{const.DEFAULT_CONFIGS}/elasticsearch/jvm.options',
                                               self.configuration_directory)
    self.copy_file_or_directory_to_destination(f'{const.DEFAULT_CONFIGS}/elasticsearch/security',
                                               self.configuration_directory)

    # Optimize Configurations
    es_main_config = config.ConfigManager(self.configuration_directory, verbose=self.verbose, stdout=self.stdout)
    es_java_config = config.JavaHeapOptionsConfigManager(self.configuration_directory, verbose=self.verbose,
                                                         stdout=self.stdout)
    es_main_config.path_logs = self.log_directory
    if not node_name:
        node_name = utilities.get_default_es_node_name()
    if not network_host:
        network_host = utilities.get_primary_ip_address()
    if not port:
        port = 9200
    if not initial_master_nodes:
        initial_master_nodes = [node_name]
    if not discover_seed_hosts:
        discover_seed_hosts = [network_host]
    if not tls_cert_subject:
        tls_cert_subject = '/C=US/ST=GA/L=Atlanta/O=Dynamite/OU=R&D/CN=dynamite.ai'
    else:
        tls_cert_subject = tls_cert_subject
    if not heap_size_gigs:
        reserved_memory = utilities.get_memory_available_bytes() * .75
        heap_size_gigs = int((reserved_memory / 10 ** 9) / 2)
    formatted_subj = tls_cert_subject.lstrip("/").replace("/", ",")
    formatted_subj_2 = ','.join(reversed(formatted_subj.split(',')))
    es_main_config.node_name = node_name
    es_main_config.network_host = network_host
    es_main_config.http_port = port
    es_main_config.initial_master_nodes = initial_master_nodes
    es_main_config.seed_hosts = discover_seed_hosts
    es_main_config.authcz_admin_distinguished_names = [formatted_subj, formatted_subj_2]
    es_java_config.initial_memory = f'{heap_size_gigs}g'
    es_java_config.maximum_memory = f'{heap_size_gigs}g'
    self.logger.debug(f'Java Heap Initial & Max Memory = {heap_size_gigs} GB')
    es_main_config.commit()
    es_java_config.commit()
    self.logger.info('Applying configuration.')

    # Fix Permissions
    self.logger.info('Setting up file permissions.')
    utilities.set_ownership_of_file(self.configuration_directory, user='dynamite', group='dynamite')
    utilities.set_ownership_of_file(self.install_directory, user='dynamite', group='dynamite')
    utilities.set_ownership_of_file(self.log_directory, user='dynamite', group='dynamite')

    # Install and enable service
    self.logger.info(f'Installing service -> {const.DEFAULT_CONFIGS}/systemd/elasticsearch.service')
    sysctl.install_and_enable(f'{const.DEFAULT_CONFIGS}/systemd/elasticsearch.service')

    self.logger.info('Generating SSL Certificates and Keys.')
    ssl_gen_task_results = setup_security.GenerateElasticsearchSSLCertificates(subj=tls_cert_subject).invoke()

    for res in ssl_gen_task_results:
        cmd, out, err = res
        self.logger.debug(f'{" ".join(cmd)} -> out: {out} err: {err}')

    self.logger.info('Installing SSL Certificates and Keys')
    install_ssl_task_results = setup_security.InstallElasticsearchCertificates(
        network_host=network_host).invoke()

    for res in install_ssl_task_results:
        cmd, out, err = res
        self.logger.debug(f'{" ".join(cmd)} -> out: {out} err: {err}')

    self.logger.info('Setting up persistent cluster settings.')
    configure_cluster_task_results = configure_cluster.UpdateClusterSettings(network_host=network_host,
                                                                             http_port=port).invoke()
    rcode, msg = configure_cluster_task_results
    self.logger.debug(f'rcode: {rcode}-> msg: {msg}')

    """
    # We'll revisit this in another release

    self.logger.info('Install events_to_hosts job.')
    event_to_host_task = install_events_to_hosts.EventsToHostsTask('admin', 'admin',
                                                                 target=f'https://{network_host}:{port}')
    event_to_host_task.download_and_install()
    event_to_host_task.create_cronjob(interval_minutes=5)
    """

UninstallManager

__init__(self, purge_config=True, stdout=False, verbose=False) special

Uninstall Elasticsearch

Parameters:

Name Type Description Default
purge_config Optional[bool]

If enabled, remove all the configuration files associated with this installation

True
stdout Optional[bool]

Print output to console

False
verbose Optional[bool]

Include detailed debug messages

False

Returns:

Type Description

None

Source code in dynamite_nsm/services/elasticsearch/install.py
def __init__(self, purge_config: Optional[bool] = True, stdout: Optional[bool] = False,
             verbose: Optional[bool] = False):
    """Uninstall Elasticsearch
    Args:
        purge_config: If enabled, remove all the configuration files associated with this installation
        stdout: Print output to console
        verbose: Include detailed debug messages
    Returns:
        None
    """
    from dynamite_nsm.services.elasticsearch.process import ProcessManager

    env_vars = utilities.get_environment_file_dict()
    es_directories = [env_vars.get('ES_HOME'), env_vars.get('ES_LOGS')]
    if purge_config:
        es_directories.append(env_vars.get('ES_PATH_CONF'))
    super().__init__('elasticsearch.uninstall', directories=es_directories,
                     environ_vars=['ES_PATH_CONF', 'ES_HOME', 'ES_LOGS'],
                     process=ProcessManager(stdout=stdout, verbose=verbose),
                     sysctl_service_name='elasticsearch.service', stdout=stdout, verbose=verbose)