Skip to content
Snippets Groups Projects
ansible.py 3.85 KiB
Newer Older
"""
Module responsible for running the Ansible part of the OpenAppStack setup.
"""
import logging
import subprocess
import yaml

log = logging.getLogger(__name__)  # pylint: disable=invalid-name

ANSIBLE_INVENTORY = './clusters/{cluster_name}/inventory.yml'
ANSIBLE_PATH = os.path.join(os.path.dirname(__file__),
                            '..', 'ansible')
def run_ansible(clus, playbook, ansible_params=None):
    """
    Call `ansible-playbook` in a subprocess to run the specified playbook. Runs
    in the package's ansible directory.

    :param str playbook: path to the playbook to run.
    :param list ansible_params: Optionally provide a list of lists with ansible
        params.  Each inner list may only contain one element. Can be directly
        forwarded from argparse. Example:
        `ansible_params = [[become-user=root], [verbose]]`
    # playbook path here is relative to private_data_dir/project, see
    # https://ansible-runner.readthedocs.io/en/latest/intro.html#inputdir
    ansible_playbook_command = ['ansible-playbook']
    if ansible_params:
        for param in ansible_params:
            if len(param) > 1:
                log.warning('More than 1 parameter. Ignoring the rest! Use '
                            '--ansible-param several times to supply '
                            'more than 1 parameter')
            param = param[0]
            ansible_playbook_command.append(param)
    ansible_playbook_command += \
        ['-e', 'cluster_dir=' + clus.cluster_dir]
    ansible_playbook_command += \
        ['-i', clus.inventory_file, playbook]
    log.info('Running "%s" in ansible directory "%s"',
             ansible_playbook_command,
        ansible_playbook_command,
    if returncode > 0:
        raise RuntimeError('Playbook failed with rc %s.'
                           % returncode)

def create_inventory(cluster):
    """
    Creates inventory for the ansible playbook. Needs the droplet's hostname
    for identification and the IP for connecting with Ansible

    :param cluster.Cluster cluster: Cluster object to for which inventory file
        will be written. Used for getting hostname and IP address.
    with open(os.path.join(ANSIBLE_PATH, 'inventory.yml.example'),
    # Rename the hostname in the inventory to one provided by the user.
    if cluster.hostname != 'oas-dev':
        inventory['all']['hosts'][cluster.hostname] = \
            inventory['all']['hosts']['oas-dev']
        del inventory['all']['hosts']['oas-dev']
    inventory['all']['hosts'][cluster.hostname]['ansible_host'] = \
        cluster.ip_address
    inventory['all']['hosts'][cluster.hostname]['domain'] = \
        cluster.domain

    if cluster.docker_mirror_endpoint \
            and cluster.docker_mirror_server \
            and cluster.docker_mirror_username \
            and cluster.docker_mirror_password:
        docker_mirror = {}
        docker_mirror['enabled'] = True
        docker_mirror['endpoint'] = cluster.docker_mirror_endpoint
        docker_mirror['username'] = cluster.docker_mirror_username
        docker_mirror['password'] = cluster.docker_mirror_password
        docker_mirror['server'] = cluster.docker_mirror_server
        inventory['all']['hosts'][cluster.hostname]['docker_mirror'] = \
            docker_mirror
    inventory['all']['children']['master']['hosts'] = cluster.hostname
    inventory['all']['children']['worker']['hosts'] = cluster.hostname
    file_contents = yaml.safe_dump(inventory, default_flow_style=False)
    log.debug(file_contents)
    with open(cluster.inventory_file, 'w') as stream:
        stream.write(file_contents)
        log.info("Created %s", cluster.inventory_file)