def test_generate_ansible_command_extra_vars(mocker, extra_vars, expected):
    mocker.patch('os.makedirs', return_value=True)
    mocker.patch('os.path.exists', return_value=True)

    rc = RunnerConfig(private_data_dir='/', playbook='main.yaml')
    rc.inventory = '/inventory'
    rc.prepare_inventory()

    mocker.patch.object(rc.loader, 'isfile', side_effect=lambda x: True)

    rc.extra_vars = extra_vars
    cmd = rc.generate_ansible_command()
    assert cmd == expected
def test_generate_ansible_command_with_dict_extravars(mocker):
    mocker.patch('os.makedirs', return_value=True)
    rc = RunnerConfig(private_data_dir='/',
                      playbook='main.yaml',
                      extravars={"foo": "test \n hello"})
    path_exists = mocker.patch('os.path.exists')
    path_exists.return_value = True

    rc.prepare_inventory()

    cmd = rc.generate_ansible_command()
    assert cmd == [
        'ansible-playbook', '-i', '/inventory', '-e',
        '{"foo":"test \\n hello"}', 'main.yaml'
    ]
def test_prepare_with_ssh_key(mocker):
    mocker.patch('os.makedirs', return_value=True)
    open_fifo_write_mock = mocker.patch(
        'ansible_runner.config._base.open_fifo_write')
    rc = RunnerConfig('/')

    rc.prepare_inventory = mocker.Mock()
    rc.prepare_command = mocker.Mock()

    rc.wrap_args_with_ssh_agent = mocker.Mock()

    rc.ssh_key_data = None
    rc.artifact_dir = '/'
    rc.env = {}
    rc.execution_mode = ExecutionMode.ANSIBLE_PLAYBOOK
    rc.playbook = 'main.yaml'
    rc.ssh_key_data = '01234567890'
    rc.command = 'ansible-playbook'

    mocker.patch.dict('os.environ', {'AWX_LIB_DIRECTORY': '/'})

    rc.prepare()

    assert rc.ssh_key_path == '/ssh_key_data'
    assert rc.wrap_args_with_ssh_agent.called
    assert open_fifo_write_mock.called
def test_generate_ansible_command_with_cmdline_args(cmdline, tokens, mocker):
    mocker.patch('os.makedirs', return_value=True)
    rc = RunnerConfig(private_data_dir='/', playbook='main.yaml')
    path_exists = mocker.patch('os.path.exists')
    path_exists.return_value = True

    rc.prepare_inventory()
    rc.extra_vars = {}

    cmdline_side_effect = partial(load_file_side_effect, 'env/cmdline',
                                  cmdline)
    mocker.patch.object(rc.loader,
                        'load_file',
                        side_effect=cmdline_side_effect)

    cmd = rc.generate_ansible_command()
    assert cmd == ['ansible-playbook'
                   ] + tokens + ['-i', '/inventory', 'main.yaml']
def test_prepare_inventory(mocker):
    mocker.patch('os.makedirs', return_value=True)
    path_exists = mocker.patch('os.path.exists', return_value=True)

    rc = RunnerConfig(private_data_dir='/')
    rc.prepare_inventory()
    assert rc.inventory == '/inventory'
    rc.inventory = '/tmp/inventory'
    rc.prepare_inventory()
    assert rc.inventory == '/tmp/inventory'
    rc.inventory = 'localhost,anotherhost,'
    rc.prepare_inventory()
    assert rc.inventory == 'localhost,anotherhost,'
    path_exists.return_value = False
    rc.inventory = None
    rc.prepare_inventory()
    assert rc.inventory is None
def test_prepare_with_defaults(mocker):
    mocker.patch('os.makedirs', return_value=True)

    rc = RunnerConfig('/')

    rc.prepare_inventory = mocker.Mock()
    rc.prepare_env = mocker.Mock()
    rc.prepare_command = mocker.Mock()

    rc.ssh_key_data = None
    rc.artifact_dir = '/'
    rc.env = {}

    with pytest.raises(ConfigurationError) as exc:
        rc.prepare()

    assert str(exc.value) == 'No executable for runner to run'
def test_prepare(mocker):
    mocker.patch.dict(
        'os.environ', {
            'PYTHONPATH': '/python_path_via_environ',
            'AWX_LIB_DIRECTORY': '/awx_lib_directory_via_environ',
        })
    mocker.patch('os.makedirs', return_value=True)

    rc = RunnerConfig('/')
    rc.prepare_inventory = mocker.Mock()
    rc.prepare_command = mocker.Mock()
    rc.ssh_key_data = None
    rc.artifact_dir = '/'
    rc.env = {}
    rc.execution_mode = ExecutionMode.ANSIBLE_PLAYBOOK
    rc.playbook = 'main.yaml'

    rc.prepare()

    assert rc.prepare_inventory.called
    assert rc.prepare_command.called

    assert not hasattr(rc, 'ssh_key_path')
    assert not hasattr(rc, 'command')

    assert rc.env['ANSIBLE_STDOUT_CALLBACK'] == 'awx_display'
    assert rc.env['ANSIBLE_RETRY_FILES_ENABLED'] == 'False'
    assert rc.env['ANSIBLE_HOST_KEY_CHECKING'] == 'False'
    assert rc.env['AWX_ISOLATED_DATA_DIR'] == '/'
    assert rc.env['PYTHONPATH'] == '/python_path_via_environ:/awx_lib_directory_via_environ', \
        "PYTHONPATH is the union of the env PYTHONPATH and AWX_LIB_DIRECTORY"

    del rc.env['PYTHONPATH']
    os.environ['PYTHONPATH'] = "/foo/bar/python_path_via_environ"
    rc.prepare()
    assert rc.env['PYTHONPATH'] == "/foo/bar/python_path_via_environ:/awx_lib_directory_via_environ", \
        "PYTHONPATH is the union of the explicit env['PYTHONPATH'] override and AWX_LIB_DIRECTORY"
def test_generate_ansible_command(mocker):
    mocker.patch('os.makedirs', return_value=True)
    mocker.patch('os.path.exists', return_value=True)

    rc = RunnerConfig(private_data_dir='/', playbook='main.yaml')
    rc.prepare_inventory()
    rc.extra_vars = None

    cmd = rc.generate_ansible_command()
    assert cmd == ['ansible-playbook', '-i', '/inventory', 'main.yaml']

    rc.extra_vars = dict(test="key")
    cmd = rc.generate_ansible_command()
    assert cmd == [
        'ansible-playbook', '-i', '/inventory', '-e', '{"test":"key"}',
        'main.yaml'
    ]
    rc.extra_vars = None

    rc.inventory = "localhost,"
    cmd = rc.generate_ansible_command()
    assert cmd == ['ansible-playbook', '-i', 'localhost,', 'main.yaml']

    rc.inventory = ['thing1', 'thing2']
    cmd = rc.generate_ansible_command()
    assert cmd == [
        'ansible-playbook', '-i', 'thing1', '-i', 'thing2', 'main.yaml'
    ]

    rc.inventory = []
    cmd = rc.generate_ansible_command()
    assert cmd == ['ansible-playbook', 'main.yaml']

    rc.inventory = None

    mocker.patch('os.path.exists', return_value=False)
    rc.prepare_inventory()
    cmd = rc.generate_ansible_command()
    assert cmd == ['ansible-playbook', 'main.yaml']

    rc.verbosity = 3
    mocker.patch('os.path.exists', return_value=True)
    rc.prepare_inventory()
    cmd = rc.generate_ansible_command()
    assert cmd == ['ansible-playbook', '-i', '/inventory', '-vvv', 'main.yaml']
    rc.verbosity = None

    rc.limit = 'hosts'
    cmd = rc.generate_ansible_command()
    assert cmd == [
        'ansible-playbook', '-i', '/inventory', '--limit', 'hosts', 'main.yaml'
    ]
    rc.limit = None

    rc.module = 'setup'
    cmd = rc.generate_ansible_command()
    assert cmd == ['ansible', '-i', '/inventory', '-m', 'setup']
    rc.module = None

    rc.module = 'setup'
    rc.module_args = 'test=string'
    cmd = rc.generate_ansible_command()
    assert cmd == [
        'ansible', '-i', '/inventory', '-m', 'setup', '-a', 'test=string'
    ]
    rc.module_args = None
    rc.module = None

    rc.forks = 5
    cmd = rc.generate_ansible_command()
    assert cmd == [
        'ansible-playbook', '-i', '/inventory', '--forks', '5', 'main.yaml'
    ]