def test_dump_artifacts_ssh_key(): with patch('ansible_runner.utils.dump_artifact') as mock_dump_artifact: ssh_key = '1234567890' kwargs = {'private_data_dir': '/tmp', 'ssh_key': ssh_key} dump_artifacts(kwargs) assert mock_dump_artifact.call_count == 1 data, fp, fn = mock_dump_artifact.call_args[0] assert data == ssh_key assert fp == '/tmp/env' assert fn == 'ssh_key' assert 'ssh_key' not in kwargs
def test_dump_artifacts_extravars(): with patch('ansible_runner.utils.dump_artifact') as mock_dump_artifact: extravars = {'foo': 'bar'} kwargs = {'private_data_dir': '/tmp', 'extravars': extravars} dump_artifacts(kwargs) assert mock_dump_artifact.call_count == 1 data, fp, fn = mock_dump_artifact.call_args[0] assert data == json.dumps(extravars) assert fp == '/tmp/env' assert fn == 'extravars' assert 'extravars' not in kwargs
def test_dump_artifacts_private_data_dir_create_tempfile(mocker): mocker.patch('ansible_runner.utils.os.path.exists', side_effect=AttributeError('Raised intentionally')) mocker.patch('ansible_runner.utils.tempfile.mkdtemp', return_value='/tmp/dir') kwargs = {} with pytest.raises(AttributeError, match='Raised intentionally'): dump_artifacts(kwargs) assert kwargs['private_data_dir'] == '/tmp/dir'
def test_dump_artifacts_cmdline(): with patch('ansible_runner.utils.dump_artifact') as mock_dump_artifact: cmdline = '--tags foo --skip-tags' kwargs = {'private_data_dir': '/tmp', 'cmdline': cmdline} dump_artifacts(kwargs) assert mock_dump_artifact.call_count == 1 data, fp, fn = mock_dump_artifact.call_args[0] assert data == cmdline assert fp == '/tmp/env' assert fn == 'cmdline' assert 'cmdline' not in kwargs
def test_dump_artifacts_playbook_object(mocker, playbook): mock_dump_artifact = mocker.patch( 'ansible_runner.utils.dump_artifact', side_effect=AttributeError('Raised intentionally')) mocker.patch('ansible_runner.utils.isplaybook', return_value=True) playbook_string = '[{"playbook": [{"hosts": "all"}]}]' kwargs = {'private_data_dir': '/tmp', 'playbook': playbook} with pytest.raises(AttributeError, match='Raised intentionally'): dump_artifacts(kwargs) mock_dump_artifact.assert_called_once_with(playbook_string, '/tmp/project', 'main.json')
def test_dump_artifacts_role(mocker): mock_dump_artifact = mocker.patch('ansible_runner.utils.dump_artifact') kwargs = { 'private_data_dir': '/tmp', 'role': 'test', 'playbook': [{ 'playbook': [{ 'hosts': 'all' }] }], } dump_artifacts(kwargs) assert mock_dump_artifact.call_count == 2 mock_dump_artifact.assert_called_with( '{"ANSIBLE_ROLES_PATH": "/tmp/roles"}', '/tmp/env', 'envvars')
def init_runner(**kwargs): ''' Initialize the Runner() instance This function will properly initialize both run() and run_async() functions in the same way and return a value instance of Runner. ''' dump_artifacts(kwargs) debug = kwargs.pop('debug', None) logfile = None if debug: logfile = os.path.join(kwargs['private_data_dir'], 'debug.log') configure_logging(filename=logfile, debug=debug) rc = RunnerConfig(**kwargs) rc.prepare() return Runner(rc)
def test_dump_artifacts_playbook(): with patch('ansible_runner.utils.dump_artifact') as mock_dump_artifact: # playbook as a native object pb = [{'playbook': [{'hosts': 'all'}]}] kwargs = {'private_data_dir': '/tmp', 'playbook': pb} dump_artifacts(kwargs) assert mock_dump_artifact.call_count == 1 data, fp, fn = mock_dump_artifact.call_args[0] assert data == json.dumps(pb) assert fp == '/tmp/project' assert fn == 'main.json' mock_dump_artifact.reset_mock() # playbook as a path pb = 'test.yml' kwargs = {'private_data_dir': '/tmp', 'playbook': pb} dump_artifacts(kwargs) assert mock_dump_artifact.call_count == 0 assert mock_dump_artifact.called is False mock_dump_artifact.reset_mock() # invalid playbook structures for obj in ({'foo': 'bar'}, None, True, False, 'foo', []): mock_dump_artifact.reset_mock() kwargs = {'private_data_dir': '/tmp', 'playbook': obj} dump_artifacts(kwargs) assert mock_dump_artifact.call_count == 0 assert mock_dump_artifact.called is False
def test_dump_artifacts_inventory(): with patch('ansible_runner.utils.dump_artifact') as mock_dump_artifact: # inventory as a string (INI) inv = '[all]\nlocalhost' kwargs = {'private_data_dir': '/tmp', 'inventory': inv} dump_artifacts(kwargs) assert mock_dump_artifact.call_count == 1 data, fp, fn = mock_dump_artifact.call_args[0] assert data == inv assert fp == '/tmp/inventory' assert fn == 'hosts' mock_dump_artifact.reset_mock() # inventory as a path inv = '/tmp' kwargs = {'private_data_dir': '/tmp', 'inventory': inv} dump_artifacts(kwargs) assert mock_dump_artifact.call_count == 0 assert mock_dump_artifact.called is False assert kwargs['inventory'] == inv mock_dump_artifact.reset_mock() # inventory as a native object inv = {'foo': 'bar'} kwargs = {'private_data_dir': '/tmp', 'inventory': inv} dump_artifacts(kwargs) assert mock_dump_artifact.call_count == 1 data, fp, fn = mock_dump_artifact.call_args[0] assert data == json.dumps(inv) assert fp == '/tmp/inventory' assert fn == 'hosts.json'
def init_runner(**kwargs): ''' Initialize the Runner() instance This function will properly initialize both run() and run_async() functions in the same way and return a value instance of Runner. See parameters given to :py:func:`ansible_runner.interface.run` ''' dump_artifacts(kwargs) debug = kwargs.pop('debug', None) logfile = kwargs.pop('logfile', None) if not kwargs.pop("ignore_logging", True): output.configure() if debug in (True, False): output.set_debug('enable' if debug is True else 'disable') if logfile: output.set_logfile(logfile) if kwargs.get("process_isolation", False): check_isolation_executable_installed( kwargs.get("process_isolation_executable", "bwrap")) event_callback_handler = kwargs.pop('event_handler', None) status_callback_handler = kwargs.pop('status_handler', None) cancel_callback = kwargs.pop('cancel_callback', None) finished_callback = kwargs.pop('finished_callback', None) rc = RunnerConfig(**kwargs) rc.prepare() return Runner(rc, event_handler=event_callback_handler, status_handler=status_callback_handler, cancel_callback=cancel_callback, finished_callback=finished_callback)
def test_dump_artifacts_roles(): with patch('ansible_runner.utils.dump_artifact') as mock_dump_artifact: kwargs = dict(private_data_dir="/tmp", role="test", playbook=[{'playbook': [{'hosts': 'all'}]}]) dump_artifacts(kwargs) assert mock_dump_artifact.call_count == 2 data, envpath, fp = mock_dump_artifact.call_args[0] assert fp == "envvars" data = json.loads(data) assert "ANSIBLE_ROLES_PATH" in data assert data['ANSIBLE_ROLES_PATH'] == "/tmp/roles" mock_dump_artifact.reset_mock() kwargs = dict(private_data_dir="/tmp", role="test", roles_path="/tmp/altrole", playbook=[{'playbook': [{'hosts': 'all'}]}]) dump_artifacts(kwargs) assert mock_dump_artifact.call_count == 2 data, envpath, fp = mock_dump_artifact.call_args[0] assert fp == "envvars" data = json.loads(data) assert "ANSIBLE_ROLES_PATH" in data assert data['ANSIBLE_ROLES_PATH'] == "/tmp/altrole:/tmp/roles"
def test_dump_artifacts_role_vars(mocker): mock_dump_artifact = mocker.patch( 'ansible_runner.utils.dump_artifact', side_effect=AttributeError('Raised intentionally')) kwargs = { 'private_data_dir': '/tmp', 'role': 'test', 'role_vars': { 'name': 'nginx' }, 'playbook': [{ 'playbook': [{ 'hosts': 'all' }] }], } with pytest.raises(AttributeError, match='Raised intentionally'): dump_artifacts(kwargs) mock_dump_artifact.assert_called_once_with( '[{"hosts": "all", "roles": [{"name": "test", "vars": {"name": "nginx"}}]}]', '/tmp/project', 'main.json')
def test_dump_artifacts_private_data_dir(): data_dir = tempfile.gettempdir() kwargs = {'private_data_dir': data_dir} dump_artifacts(kwargs) assert kwargs['private_data_dir'] == data_dir kwargs = {'private_data_dir': None} dump_artifacts(kwargs) assert kwargs['private_data_dir'].startswith(tempfile.gettempdir()) shutil.rmtree(kwargs['private_data_dir']) with pytest.raises(ValueError): data_dir = '/foo' kwargs = {'private_data_dir': data_dir} dump_artifacts(kwargs)
def test_dump_artifacts_private_data_dir(): data_dir = '/tmp' kwargs = {'private_data_dir': data_dir} dump_artifacts(kwargs) assert kwargs['private_data_dir'] == data_dir kwargs = {'private_data_dir': None} dump_artifacts(kwargs) assert kwargs['private_data_dir'].startswith('/tmp/tmp') shutil.rmtree(kwargs['private_data_dir']) with raises(ValueError): data_dir = '/foo' kwargs = {'private_data_dir': data_dir} dump_artifacts(kwargs)
def init_runner(**kwargs): ''' Initialize the Runner() instance This function will properly initialize both run() and run_async() functions in the same way and return a value instance of Runner. See parameters given to :py:func:`ansible_runner.interface.run` ''' # If running via the transmit-worker-process method, we must only extract things as read-only # inside of one of these commands. That could be either transmit or worker. if not kwargs.get('cli_execenv_cmd') and (kwargs.get('streamer') not in ('worker', 'process')): dump_artifacts(kwargs) if kwargs.get('streamer'): # undo any full paths that were dumped by dump_artifacts above in the streamer case private_data_dir = kwargs['private_data_dir'] project_dir = os.path.join(private_data_dir, 'project') playbook_path = kwargs.get('playbook') or '' if os.path.isabs(playbook_path) and playbook_path.startswith( project_dir): kwargs['playbook'] = os.path.relpath(playbook_path, project_dir) inventory_path = kwargs.get('inventory') or '' if os.path.isabs(inventory_path) and inventory_path.startswith( private_data_dir): kwargs['inventory'] = os.path.relpath(inventory_path, private_data_dir) roles_path = kwargs.get('envvars', {}).get('ANSIBLE_ROLES_PATH') or '' if os.path.isabs(roles_path) and roles_path.startswith( private_data_dir): kwargs['envvars']['ANSIBLE_ROLES_PATH'] = os.path.relpath( roles_path, private_data_dir) debug = kwargs.pop('debug', None) logfile = kwargs.pop('logfile', None) if not kwargs.pop("ignore_logging", True): output.configure() if debug in (True, False): output.set_debug('enable' if debug is True else 'disable') if logfile: output.set_logfile(logfile) if kwargs.get("process_isolation", False): pi_executable = kwargs.get("process_isolation_executable", "podman") if not check_isolation_executable_installed(pi_executable): print( f'Unable to find process isolation executable: {pi_executable}' ) sys.exit(1) event_callback_handler = kwargs.pop('event_handler', None) status_callback_handler = kwargs.pop('status_handler', None) artifacts_handler = kwargs.pop('artifacts_handler', None) cancel_callback = kwargs.pop('cancel_callback', None) finished_callback = kwargs.pop('finished_callback', None) streamer = kwargs.pop('streamer', None) if streamer: if streamer == 'transmit': stream_transmitter = Transmitter(**kwargs) return stream_transmitter if streamer == 'worker': stream_worker = Worker(**kwargs) return stream_worker if streamer == 'process': stream_processor = Processor( event_handler=event_callback_handler, status_handler=status_callback_handler, artifacts_handler=artifacts_handler, cancel_callback=cancel_callback, finished_callback=finished_callback, **kwargs) return stream_processor kwargs.pop('_input', None) kwargs.pop('_output', None) rc = RunnerConfig(**kwargs) rc.prepare() return Runner(rc, event_handler=event_callback_handler, status_handler=status_callback_handler, artifacts_handler=artifacts_handler, cancel_callback=cancel_callback, finished_callback=finished_callback)