def update_play_context(self, pc_data): """Updates the play context information for the connection""" pc_data = to_bytes(pc_data) if PY3: pc_data = cPickle.loads(pc_data, encoding="bytes") else: pc_data = cPickle.loads(pc_data) play_context = PlayContext() play_context.deserialize(pc_data) self.queue_message("vvvv", "updating play_context for connection") if self._play_context.become ^ play_context.become: if play_context.become is True: auth_pass = play_context.become_pass self._terminal.on_become(passwd=auth_pass) self.queue_message("vvvv", "authorizing connection") else: self._terminal.on_unbecome() self.queue_message("vvvv", "deauthorizing connection") self._play_context = play_context if hasattr(self, "reset_history"): self.reset_history() if hasattr(self, "disable_response_logging"): self.disable_response_logging()
def test_plugins_connection_ssh_module(self): play_context = PlayContext() play_context.prompt = ( '[sudo via assible, key=ouzmdnewuhucvuaabtjmweasarviygqq] password: ' ) in_stream = StringIO() self.assertIsInstance(ssh.Connection(play_context, in_stream), ssh.Connection)
def test_action_base__remove_tmp_path(self): # create our fake task mock_task = MagicMock() # create a mock connection, so we don't actually try and connect to things mock_connection = MagicMock() mock_connection._shell.remove.return_value = 'rm some stuff' # we're using a real play context here play_context = PlayContext() # our test class action_base = DerivedActionBase( task=mock_task, connection=mock_connection, play_context=play_context, loader=None, templar=None, shared_loader_obj=None, ) action_base._low_level_execute_command = MagicMock() # these don't really return anything or raise errors, so # we're pretty much calling these for coverage right now action_base._remove_tmp_path('/bad/path/dont/remove') action_base._remove_tmp_path('/good/path/to/assible-tmp-thing')
def test_action_base_sudo_only_if_user_differs(self): fake_loader = MagicMock() fake_loader.get_basedir.return_value = os.getcwd() play_context = PlayContext() action_base = DerivedActionBase(None, None, play_context, fake_loader, None, None) action_base.get_become_option = MagicMock(return_value='root') action_base._get_remote_user = MagicMock(return_value='root') action_base._connection = MagicMock(exec_command=MagicMock( return_value=(0, '', ''))) action_base._connection._shell = shell = MagicMock( append_command=MagicMock(return_value=('JOINED CMD'))) action_base._connection.become = become = MagicMock() become.build_become_command.return_value = 'foo' action_base._low_level_execute_command('ECHO', sudoable=True) become.build_become_command.assert_not_called() action_base._get_remote_user.return_value = 'apo' action_base._low_level_execute_command('ECHO', sudoable=True, executable='/bin/csh') become.build_become_command.assert_called_once_with("ECHO", shell) become.build_become_command.reset_mock() with patch.object(C, 'BECOME_ALLOW_SAME_USER', new=True): action_base._get_remote_user.return_value = 'root' action_base._low_level_execute_command('ECHO SAME', sudoable=True) become.build_become_command.assert_called_once_with( "ECHO SAME", shell)
def test_kinit_error_subprocess(self, monkeypatch): expected_err = "kinit: krb5_parse_name: " \ "Configuration file does not specify default realm" def mock_communicate(input=None, timeout=None): return b"", to_bytes(expected_err) mock_popen = MagicMock() mock_popen.return_value.communicate = mock_communicate mock_popen.return_value.returncode = 1 monkeypatch.setattr("subprocess.Popen", mock_popen) winrm.HAS_PEXPECT = False pc = PlayContext() new_stdin = StringIO() conn = connection_loader.get('winrm', pc, new_stdin) conn.set_options(var_options={"_extras": {}}) conn._build_winrm_kwargs() with pytest.raises(AssibleConnectionFailure) as err: conn._kerb_auth("invaliduser", "pass") assert str(err.value) == \ "Kerberos auth failure for principal invaliduser with " \ "subprocess: %s" % (expected_err)
def test_plugins_connection_ssh_basic(self): pc = PlayContext() new_stdin = StringIO() conn = ssh.Connection(pc, new_stdin) # connect just returns self, so assert that res = conn._connect() self.assertEqual(conn, res) ssh.SSHPASS_AVAILABLE = False self.assertFalse(conn._sshpass_available()) ssh.SSHPASS_AVAILABLE = True self.assertTrue(conn._sshpass_available()) with patch('subprocess.Popen') as p: ssh.SSHPASS_AVAILABLE = None p.return_value = MagicMock() self.assertTrue(conn._sshpass_available()) ssh.SSHPASS_AVAILABLE = None p.return_value = None p.side_effect = OSError() self.assertFalse(conn._sshpass_available()) conn.close() self.assertFalse(conn._connected)
def test_kinit_success_pexpect(self, monkeypatch, options, expected): pytest.importorskip("pexpect") mock_pexpect = MagicMock() mock_pexpect.return_value.exitstatus = 0 monkeypatch.setattr("pexpect.spawn", mock_pexpect) winrm.HAS_PEXPECT = True pc = PlayContext() new_stdin = StringIO() conn = connection_loader.get('winrm', pc, new_stdin) conn.set_options(var_options=options) conn._build_winrm_kwargs() conn._kerb_auth("user@domain", "pass") mock_calls = mock_pexpect.mock_calls assert mock_calls[0][1] == expected actual_env = mock_calls[0][2]['env'] assert list(actual_env.keys()) == ['KRB5CCNAME'] assert actual_env['KRB5CCNAME'].startswith("FILE:/") assert mock_calls[0][2]['echo'] is False assert mock_calls[1][0] == "().expect" assert mock_calls[1][1] == (".*:",) assert mock_calls[2][0] == "().sendline" assert mock_calls[2][1] == ("pass",) assert mock_calls[3][0] == "().read" assert mock_calls[4][0] == "().wait"
def test_play_context_make_become_bad(mocker, parser, reset_cli_args): options = parser.parse_args([]) context._init_global_context(options) play_context = PlayContext() default_cmd = "/bin/foo" default_exe = "/bin/bash" play_context.become = True play_context.become_user = '******' play_context.set_become_plugin(become_loader.get('bad')) play_context.become_method = 'bad' with pytest.raises(AssibleError): play_context.make_become_cmd(cmd=default_cmd, executable=default_exe)
def update_play_context(self, pc_data): """Updates the play context information for the connection""" pc_data = to_bytes(pc_data) if PY3: pc_data = cPickle.loads(pc_data, encoding="bytes") else: pc_data = cPickle.loads(pc_data) play_context = PlayContext() play_context.deserialize(pc_data) self.queue_message("vvvv", "updating play_context for connection") if self._play_context.become ^ play_context.become: self.set_become(play_context) if play_context.become is True: self.queue_message("vvvv", "authorizing connection") else: self.queue_message("vvvv", "deauthorizing connection") self._play_context = play_context
def test_action_base__execute_remote_stat(self): # create our fake task mock_task = MagicMock() # create a mock connection, so we don't actually try and connect to things mock_connection = MagicMock() # we're using a real play context here play_context = PlayContext() # our test class action_base = DerivedActionBase( task=mock_task, connection=mock_connection, play_context=play_context, loader=None, templar=None, shared_loader_obj=None, ) action_base._execute_module = MagicMock() # test normal case action_base._execute_module.return_value = dict(stat=dict( checksum='1111111111111111111111111111111111', exists=True)) res = action_base._execute_remote_stat(path='/path/to/file', all_vars=dict(), follow=False) self.assertEqual(res['checksum'], '1111111111111111111111111111111111') # test does not exist action_base._execute_module.return_value = dict(stat=dict( exists=False)) res = action_base._execute_remote_stat(path='/path/to/file', all_vars=dict(), follow=False) self.assertFalse(res['exists']) self.assertEqual(res['checksum'], '1') # test no checksum in result from _execute_module action_base._execute_module.return_value = dict(stat=dict(exists=True)) res = action_base._execute_remote_stat(path='/path/to/file', all_vars=dict(), follow=False) self.assertTrue(res['exists']) self.assertEqual(res['checksum'], '') # test stat call failed action_base._execute_module.return_value = dict( failed=True, msg="because I said so") self.assertRaises(AssibleError, action_base._execute_remote_stat, path='/path/to/file', all_vars=dict(), follow=False)
def test_plugins_connection_ssh_put_file(self, mock_ospe, mock_sleep): pc = PlayContext() new_stdin = StringIO() conn = connection_loader.get('ssh', pc, new_stdin) conn._build_command = MagicMock() conn._bare_run = MagicMock() mock_ospe.return_value = True conn._build_command.return_value = 'some command to run' conn._bare_run.return_value = (0, '', '') conn.host = "some_host" C.ASSIBLE_SSH_RETRIES = 9 # Test with C.DEFAULT_SCP_IF_SSH set to smart # Test when SFTP works C.DEFAULT_SCP_IF_SSH = 'smart' expected_in_data = b' '.join((b'put', to_bytes(shlex_quote('/path/to/in/file')), to_bytes(shlex_quote('/path/to/dest/file')))) + b'\n' conn.put_file('/path/to/in/file', '/path/to/dest/file') conn._bare_run.assert_called_with('some command to run', expected_in_data, checkrc=False) # Test when SFTP doesn't work but SCP does conn._bare_run.side_effect = [(1, 'stdout', 'some errors'), (0, '', '')] conn.put_file('/path/to/in/file', '/path/to/dest/file') conn._bare_run.assert_called_with('some command to run', None, checkrc=False) conn._bare_run.side_effect = None # test with C.DEFAULT_SCP_IF_SSH enabled C.DEFAULT_SCP_IF_SSH = True conn.put_file('/path/to/in/file', '/path/to/dest/file') conn._bare_run.assert_called_with('some command to run', None, checkrc=False) conn.put_file(u'/path/to/in/file/with/unicode-fö〩', u'/path/to/dest/file/with/unicode-fö〩') conn._bare_run.assert_called_with('some command to run', None, checkrc=False) # test with C.DEFAULT_SCP_IF_SSH disabled C.DEFAULT_SCP_IF_SSH = False expected_in_data = b' '.join((b'put', to_bytes(shlex_quote('/path/to/in/file')), to_bytes(shlex_quote('/path/to/dest/file')))) + b'\n' conn.put_file('/path/to/in/file', '/path/to/dest/file') conn._bare_run.assert_called_with('some command to run', expected_in_data, checkrc=False) expected_in_data = b' '.join((b'put', to_bytes(shlex_quote('/path/to/in/file/with/unicode-fö〩')), to_bytes(shlex_quote('/path/to/dest/file/with/unicode-fö〩')))) + b'\n' conn.put_file(u'/path/to/in/file/with/unicode-fö〩', u'/path/to/dest/file/with/unicode-fö〩') conn._bare_run.assert_called_with('some command to run', expected_in_data, checkrc=False) # test that a non-zero rc raises an error conn._bare_run.return_value = (1, 'stdout', 'some errors') self.assertRaises(AssibleError, conn.put_file, '/path/to/bad/file', '/remote/path/to/file') # test that a not-found path raises an error mock_ospe.return_value = False conn._bare_run.return_value = (0, 'stdout', '') self.assertRaises(AssibleFileNotFound, conn.put_file, '/path/to/bad/file', '/remote/path/to/file')
def test_action_base__compute_environment_string(self): fake_loader = DictDataLoader({}) # create our fake task mock_task = MagicMock() mock_task.action = "copy" mock_task.args = dict(a=1) # create a mock connection, so we don't actually try and connect to things def env_prefix(**args): return ' '.join([ '%s=%s' % (k, shlex_quote(text_type(v))) for k, v in args.items() ]) mock_connection = MagicMock() mock_connection._shell.env_prefix.side_effect = env_prefix # we're using a real play context here play_context = PlayContext() # and we're using a real templar here too templar = Templar(loader=fake_loader) # our test class action_base = DerivedActionBase( task=mock_task, connection=mock_connection, play_context=play_context, loader=fake_loader, templar=templar, shared_loader_obj=None, ) # test standard environment setup mock_task.environment = [dict(FOO='foo'), None] env_string = action_base._compute_environment_string() self.assertEqual(env_string, "FOO=foo") # test where environment is not a list mock_task.environment = dict(FOO='foo') env_string = action_base._compute_environment_string() self.assertEqual(env_string, "FOO=foo") # test environment with a variable in it templar.available_variables = dict(the_var='bar') mock_task.environment = [dict(FOO='{{the_var}}')] env_string = action_base._compute_environment_string() self.assertEqual(env_string, "FOO=bar") # test with a bad environment set mock_task.environment = dict(FOO='foo') mock_task.environment = ['hi there'] self.assertRaises(AssibleError, action_base._compute_environment_string)
def test_play_context(mocker, parser, reset_cli_args): options = parser.parse_args(['-vv', '--check']) context._init_global_context(options) play = Play.load({}) play_context = PlayContext(play=play) assert play_context.remote_addr is None assert play_context.remote_user is None assert play_context.password == '' assert play_context.private_key_file == C.DEFAULT_PRIVATE_KEY_FILE assert play_context.timeout == C.DEFAULT_TIMEOUT assert play_context.verbosity == 2 assert play_context.check_mode is True mock_play = mocker.MagicMock() mock_play.force_handlers = True play_context = PlayContext(play=mock_play) assert play_context.force_handlers is True mock_task = mocker.MagicMock() mock_task.connection = 'mocktask' mock_task.remote_user = '******' mock_task.port = 1234 mock_task.no_log = True mock_task.become = True mock_task.become_method = 'mocktask' mock_task.become_user = '******' mock_task.become_pass = '******' mock_task._local_action = False mock_task.delegate_to = None all_vars = dict( assible_connection='mock_inventory', assible_ssh_port=4321, ) mock_templar = mocker.MagicMock() play_context = PlayContext() play_context = play_context.set_task_and_variable_override( task=mock_task, variables=all_vars, templar=mock_templar) assert play_context.connection == 'mock_inventory' assert play_context.remote_user == 'mocktask' assert play_context.no_log is True mock_task.no_log = False play_context = play_context.set_task_and_variable_override( task=mock_task, variables=all_vars, templar=mock_templar) assert play_context.no_log is False
def test_action_base__transfer_data(self, mock_mkstemp, mock_fdopen, mock_unlink): # create our fake task mock_task = MagicMock() # create a mock connection, so we don't actually try and connect to things mock_connection = MagicMock() mock_connection.put_file.return_value = None # we're using a real play context here play_context = PlayContext() # our test class action_base = DerivedActionBase( task=mock_task, connection=mock_connection, play_context=play_context, loader=None, templar=None, shared_loader_obj=None, ) mock_afd = MagicMock() mock_afile = MagicMock() mock_mkstemp.return_value = (mock_afd, mock_afile) mock_unlink.return_value = None mock_afo = MagicMock() mock_afo.write.return_value = None mock_afo.flush.return_value = None mock_afo.close.return_value = None mock_fdopen.return_value = mock_afo self.assertEqual( action_base._transfer_data('/path/to/remote/file', 'some data'), '/path/to/remote/file') self.assertEqual( action_base._transfer_data('/path/to/remote/file', 'some mixed data: fö〩'), '/path/to/remote/file') self.assertEqual( action_base._transfer_data('/path/to/remote/file', dict(some_key='some value')), '/path/to/remote/file') self.assertEqual( action_base._transfer_data('/path/to/remote/file', dict(some_key='fö〩')), '/path/to/remote/file') mock_afo.write.side_effect = Exception() self.assertRaises(AssibleError, action_base._transfer_data, '/path/to/remote/file', '')
def test_set_options(self, options, expected): pc = PlayContext() new_stdin = StringIO() conn = connection_loader.get('psrp', pc, new_stdin) conn.set_options(var_options=options) conn._build_kwargs() for attr, expected in expected.items(): actual = getattr(conn, attr) assert actual == expected, \ "psrp attr '%s', actual '%s' != expected '%s'"\ % (attr, actual, expected)
def test_plugins_connection_ssh_exec_command(self): pc = PlayContext() new_stdin = StringIO() conn = connection_loader.get('ssh', pc, new_stdin) conn._build_command = MagicMock() conn._build_command.return_value = 'ssh something something' conn._run = MagicMock() conn._run.return_value = (0, 'stdout', 'stderr') conn.get_option = MagicMock() conn.get_option.return_value = True res, stdout, stderr = conn.exec_command('ssh') res, stdout, stderr = conn.exec_command('ssh', 'this is some data')
def test_set_options(self, options, direct, expected, kerb): winrm.HAVE_KERBEROS = kerb pc = PlayContext() new_stdin = StringIO() conn = connection_loader.get('winrm', pc, new_stdin) conn.set_options(var_options=options, direct=direct) conn._build_winrm_kwargs() for attr, expected in expected.items(): actual = getattr(conn, attr) assert actual == expected, \ "winrm attr '%s', actual '%s' != expected '%s'"\ % (attr, actual, expected)
def test_kinit_error_pass_in_output_pexpect(self, monkeypatch): pytest.importorskip("pexpect") mock_pexpect = MagicMock() mock_pexpect.return_value.expect = MagicMock() mock_pexpect.return_value.read.return_value = \ b"Error with kinit\npassword\n" mock_pexpect.return_value.exitstatus = 1 monkeypatch.setattr("pexpect.spawn", mock_pexpect) winrm.HAS_PEXPECT = True pc = PlayContext() pc = PlayContext() new_stdin = StringIO() conn = connection_loader.get('winrm', pc, new_stdin) conn.set_options(var_options={"_extras": {}}) conn._build_winrm_kwargs() with pytest.raises(AssibleConnectionFailure) as err: conn._kerb_auth("username", "password") assert str(err.value) == \ "Kerberos auth failure for principal username with pexpect: " \ "Error with kinit\n<redacted>"
def test_set_invalid_extras_options(self, monkeypatch): pc = PlayContext() new_stdin = StringIO() conn = connection_loader.get('psrp', pc, new_stdin) conn.set_options( var_options={'_extras': { 'assible_psrp_mock_test3': True }}) mock_display = MagicMock() monkeypatch.setattr(Display, "warning", mock_display) conn._build_kwargs() assert mock_display.call_args[0][0] == \ 'assible_psrp_mock_test3 is unsupported by the current psrp version installed'
def test_kinit_with_missing_executable_subprocess(self, monkeypatch): expected_err = "[Errno 2] No such file or directory: " \ "'/fake/kinit': '/fake/kinit'" mock_popen = MagicMock(side_effect=OSError(expected_err)) monkeypatch.setattr("subprocess.Popen", mock_popen) winrm.HAS_PEXPECT = False pc = PlayContext() new_stdin = StringIO() conn = connection_loader.get('winrm', pc, new_stdin) options = {"_extras": {}, "assible_winrm_kinit_cmd": "/fake/kinit"} conn.set_options(var_options=options) conn._build_winrm_kwargs() with pytest.raises(AssibleConnectionFailure) as err: conn._kerb_auth("user@domain", "pass") assert str(err.value) == "Kerberos auth failure when calling " \ "kinit cmd '/fake/kinit': %s" % expected_err
def test_action_base_run(self): mock_task = MagicMock() mock_task.action = "foo" mock_task.args = dict(a=1, b=2, c=3) mock_connection = MagicMock() play_context = PlayContext() mock_task.async_val = None action_base = DerivedActionBase(mock_task, mock_connection, play_context, None, None, None) results = action_base.run() self.assertEqual(results, dict()) mock_task.async_val = 0 action_base = DerivedActionBase(mock_task, mock_connection, play_context, None, None, None) results = action_base.run() self.assertEqual(results, {})
def test_kinit_error_pass_in_output_subprocess(self, monkeypatch): def mock_communicate(input=None, timeout=None): return b"", b"Error with kinit\n" + input mock_popen = MagicMock() mock_popen.return_value.communicate = mock_communicate mock_popen.return_value.returncode = 1 monkeypatch.setattr("subprocess.Popen", mock_popen) winrm.HAS_PEXPECT = False pc = PlayContext() new_stdin = StringIO() conn = connection_loader.get('winrm', pc, new_stdin) conn.set_options(var_options={"_extras": {}}) conn._build_winrm_kwargs() with pytest.raises(AssibleConnectionFailure) as err: conn._kerb_auth("username", "password") assert str(err.value) == \ "Kerberos auth failure for principal username with subprocess: " \ "Error with kinit\n<redacted>"
def test_kinit_with_missing_executable_pexpect(self, monkeypatch): pexpect = pytest.importorskip("pexpect") expected_err = "The command was not found or was not " \ "executable: /fake/kinit" mock_pexpect = \ MagicMock(side_effect=pexpect.ExceptionPexpect(expected_err)) monkeypatch.setattr("pexpect.spawn", mock_pexpect) winrm.HAS_PEXPECT = True pc = PlayContext() new_stdin = StringIO() conn = connection_loader.get('winrm', pc, new_stdin) options = {"_extras": {}, "assible_winrm_kinit_cmd": "/fake/kinit"} conn.set_options(var_options=options) conn._build_winrm_kwargs() with pytest.raises(AssibleConnectionFailure) as err: conn._kerb_auth("user@domain", "pass") assert str(err.value) == "Kerberos auth failure when calling " \ "kinit cmd '/fake/kinit': %s" % expected_err
def mock_run_env(request, mocker): pc = PlayContext() new_stdin = StringIO() conn = connection_loader.get('ssh', pc, new_stdin) conn.set_become_plugin(become_loader.get('sudo')) conn._send_initial_data = MagicMock() conn._examine_output = MagicMock() conn._terminate_process = MagicMock() conn._load_name = 'ssh' conn.sshpass_pipe = [MagicMock(), MagicMock()] request.cls.pc = pc request.cls.conn = conn mock_popen_res = MagicMock() mock_popen_res.poll = MagicMock() mock_popen_res.wait = MagicMock() mock_popen_res.stdin = MagicMock() mock_popen_res.stdin.fileno.return_value = 1000 mock_popen_res.stdout = MagicMock() mock_popen_res.stdout.fileno.return_value = 1001 mock_popen_res.stderr = MagicMock() mock_popen_res.stderr.fileno.return_value = 1002 mock_popen_res.returncode = 0 request.cls.mock_popen_res = mock_popen_res mock_popen = mocker.patch('subprocess.Popen', return_value=mock_popen_res) request.cls.mock_popen = mock_popen request.cls.mock_selector = MockSelector() mocker.patch('assible.module_utils.compat.selectors.DefaultSelector', lambda: request.cls.mock_selector) request.cls.mock_openpty = mocker.patch('pty.openpty') mocker.patch('fcntl.fcntl') mocker.patch('os.write') mocker.patch('os.close')
def test_kinit_success_subprocess(self, monkeypatch, options, expected): def mock_communicate(input=None, timeout=None): return b"", b"" mock_popen = MagicMock() mock_popen.return_value.communicate = mock_communicate mock_popen.return_value.returncode = 0 monkeypatch.setattr("subprocess.Popen", mock_popen) winrm.HAS_PEXPECT = False pc = PlayContext() new_stdin = StringIO() conn = connection_loader.get('winrm', pc, new_stdin) conn.set_options(var_options=options) conn._build_winrm_kwargs() conn._kerb_auth("user@domain", "pass") mock_calls = mock_popen.mock_calls assert len(mock_calls) == 1 assert mock_calls[0][1] == expected actual_env = mock_calls[0][2]['env'] assert list(actual_env.keys()) == ['KRB5CCNAME'] assert actual_env['KRB5CCNAME'].startswith("FILE:/")
def test_action_base__early_needs_tmp_path(self): # create our fake task mock_task = MagicMock() # create a mock connection, so we don't actually try and connect to things mock_connection = MagicMock() # we're using a real play context here play_context = PlayContext() # our test class action_base = DerivedActionBase( task=mock_task, connection=mock_connection, play_context=play_context, loader=None, templar=None, shared_loader_obj=None, ) self.assertFalse(action_base._early_needs_tmp_path()) action_base.TRANSFERS_FILES = True self.assertTrue(action_base._early_needs_tmp_path())
def test_kinit_error_pexpect(self, monkeypatch): pytest.importorskip("pexpect") expected_err = "Configuration file does not specify default realm" mock_pexpect = MagicMock() mock_pexpect.return_value.expect = MagicMock(side_effect=OSError) mock_pexpect.return_value.read.return_value = to_bytes(expected_err) mock_pexpect.return_value.exitstatus = 1 monkeypatch.setattr("pexpect.spawn", mock_pexpect) winrm.HAS_PEXPECT = True pc = PlayContext() new_stdin = StringIO() conn = connection_loader.get('winrm', pc, new_stdin) conn.set_options(var_options={"_extras": {}}) conn._build_winrm_kwargs() with pytest.raises(AssibleConnectionFailure) as err: conn._kerb_auth("invaliduser", "pass") assert str(err.value) == \ "Kerberos auth failure for principal invaliduser with " \ "pexpect: %s" % (expected_err)
def test_sudo(mocker, parser, reset_cli_args): options = parser.parse_args([]) context._init_global_context(options) play_context = PlayContext() default_cmd = "/bin/foo" default_exe = "/bin/bash" sudo_exe = 'sudo' sudo_flags = '-H -s -n' cmd = play_context.make_become_cmd(cmd=default_cmd, executable=default_exe) assert cmd == default_cmd success = 'BECOME-SUCCESS-.+?' play_context.become = True play_context.become_user = '******' play_context.set_become_plugin(become_loader.get('sudo')) play_context.become_flags = sudo_flags cmd = play_context.make_become_cmd(cmd=default_cmd, executable=default_exe) assert (re.match( """%s %s -u %s %s -c 'echo %s; %s'""" % (sudo_exe, sudo_flags, play_context.become_user, default_exe, success, default_cmd), cmd) is not None) play_context.become_pass = '******' cmd = play_context.make_become_cmd(cmd=default_cmd, executable=default_exe) assert (re.match( """%s %s -p "%s" -u %s %s -c 'echo %s; %s'""" % (sudo_exe, sudo_flags.replace( '-n', ''), r"\[sudo via assible, key=.+?\] password:", play_context.become_user, default_exe, success, default_cmd), cmd) is not None)
def test_plugins_connection_ssh__examine_output(self): pc = PlayContext() new_stdin = StringIO() conn = connection_loader.get('ssh', pc, new_stdin) conn.set_become_plugin(become_loader.get('sudo')) conn.check_password_prompt = MagicMock() conn.check_become_success = MagicMock() conn.check_incorrect_password = MagicMock() conn.check_missing_password = MagicMock() def _check_password_prompt(line): if b'foo' in line: return True return False def _check_become_success(line): if b'BECOME-SUCCESS-abcdefghijklmnopqrstuvxyz' in line: return True return False def _check_incorrect_password(line): if b'incorrect password' in line: return True return False def _check_missing_password(line): if b'bad password' in line: return True return False conn.become.check_password_prompt = MagicMock(side_effect=_check_password_prompt) conn.become.check_become_success = MagicMock(side_effect=_check_become_success) conn.become.check_incorrect_password = MagicMock(side_effect=_check_incorrect_password) conn.become.check_missing_password = MagicMock(side_effect=_check_missing_password) # test examining output for prompt conn._flags = dict( become_prompt=False, become_success=False, become_error=False, become_nopasswd_error=False, ) pc.prompt = True conn.become.prompt = True def get_option(option): if option == 'become_pass': return 'password' return None conn.become.get_option = get_option output, unprocessed = conn._examine_output(u'source', u'state', b'line 1\nline 2\nfoo\nline 3\nthis should be the remainder', False) self.assertEqual(output, b'line 1\nline 2\nline 3\n') self.assertEqual(unprocessed, b'this should be the remainder') self.assertTrue(conn._flags['become_prompt']) self.assertFalse(conn._flags['become_success']) self.assertFalse(conn._flags['become_error']) self.assertFalse(conn._flags['become_nopasswd_error']) # test examining output for become prompt conn._flags = dict( become_prompt=False, become_success=False, become_error=False, become_nopasswd_error=False, ) pc.prompt = False conn.become.prompt = False pc.success_key = u'BECOME-SUCCESS-abcdefghijklmnopqrstuvxyz' conn.become.success = u'BECOME-SUCCESS-abcdefghijklmnopqrstuvxyz' output, unprocessed = conn._examine_output(u'source', u'state', b'line 1\nline 2\nBECOME-SUCCESS-abcdefghijklmnopqrstuvxyz\nline 3\n', False) self.assertEqual(output, b'line 1\nline 2\nline 3\n') self.assertEqual(unprocessed, b'') self.assertFalse(conn._flags['become_prompt']) self.assertTrue(conn._flags['become_success']) self.assertFalse(conn._flags['become_error']) self.assertFalse(conn._flags['become_nopasswd_error']) # test examining output for become failure conn._flags = dict( become_prompt=False, become_success=False, become_error=False, become_nopasswd_error=False, ) pc.prompt = False conn.become.prompt = False pc.success_key = None output, unprocessed = conn._examine_output(u'source', u'state', b'line 1\nline 2\nincorrect password\n', True) self.assertEqual(output, b'line 1\nline 2\nincorrect password\n') self.assertEqual(unprocessed, b'') self.assertFalse(conn._flags['become_prompt']) self.assertFalse(conn._flags['become_success']) self.assertTrue(conn._flags['become_error']) self.assertFalse(conn._flags['become_nopasswd_error']) # test examining output for missing password conn._flags = dict( become_prompt=False, become_success=False, become_error=False, become_nopasswd_error=False, ) pc.prompt = False conn.become.prompt = False pc.success_key = None output, unprocessed = conn._examine_output(u'source', u'state', b'line 1\nbad password\n', True) self.assertEqual(output, b'line 1\nbad password\n') self.assertEqual(unprocessed, b'') self.assertFalse(conn._flags['become_prompt']) self.assertFalse(conn._flags['become_success']) self.assertFalse(conn._flags['become_error']) self.assertTrue(conn._flags['become_nopasswd_error'])
def test_plugins_connection_ssh__build_command(self): pc = PlayContext() new_stdin = StringIO() conn = connection_loader.get('ssh', pc, new_stdin) conn._build_command('ssh')