def test_sudosu(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('community.general.sudosu')) play_context.become_flags = sudo_flags cmd = play_context.make_become_cmd(cmd=default_cmd, executable=default_exe) assert (re.match( """%s %s su -l %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" su -l %s %s -c 'echo %s; %s'""" % (sudo_exe, sudo_flags.replace( '-n', ''), r"\[sudo via ansible, key=.+?\] password:", play_context.become_user, default_exe, success, default_cmd), cmd) is not None)
def test_action_base_sudo_only_if_user_differs(self): play_context = PlayContext() action_base = DerivedActionBase(None, None, play_context, None, None, None) action_base._connection = MagicMock(exec_command=MagicMock( return_value=(0, '', ''))) play_context.become = True play_context.become_user = play_context.remote_user = '******' play_context.make_become_cmd = MagicMock(return_value='CMD') action_base._low_level_execute_command('ECHO', sudoable=True) play_context.make_become_cmd.assert_not_called() play_context.remote_user = '******' action_base._low_level_execute_command('ECHO', sudoable=True, executable='/bin/csh') play_context.make_become_cmd.assert_called_once_with( "ECHO", executable='/bin/csh') play_context.make_become_cmd.reset_mock() become_allow_same_user = C.BECOME_ALLOW_SAME_USER C.BECOME_ALLOW_SAME_USER = True try: play_context.remote_user = '******' action_base._low_level_execute_command('ECHO SAME', sudoable=True) play_context.make_become_cmd.assert_called_once_with( "ECHO SAME", executable=None) finally: C.BECOME_ALLOW_SAME_USER = become_allow_same_user
def test_su(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" su_exe = 'su' su_flags = '' 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.become_pass = None play_context.become_method = 'su' play_context.set_become_plugin(become_loader.get('su')) play_context.become_flags = su_flags cmd = play_context.make_become_cmd(cmd=default_cmd, executable=default_exe) assert (re.match( """%s %s -c '%s -c '"'"'echo %s; %s'"'"''""" % (su_exe, play_context.become_user, default_exe, success, default_cmd), cmd) is not None)
def test_action_base__make_tmp_path(self): # create our fake task mock_task = MagicMock() def get_shell_opt(opt): ret = None if opt == 'admin_users': ret = ['root', 'toor', 'Administrator'] elif opt == 'remote_tmp': ret = '~/.ansible/tmp' return ret # create a mock connection, so we don't actually try and connect to things mock_connection = MagicMock() mock_connection.transport = 'ssh' mock_connection._shell.mkdtemp.return_value = 'mkdir command' mock_connection._shell.join_path.side_effect = os.path.join mock_connection._shell.get_option = get_shell_opt mock_connection._shell.HOMES_RE = re.compile(r'(\'|\")?(~|\$HOME)(.*)') # we're using a real play context here play_context = PlayContext() play_context.become = True play_context.become_user = '******' # 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() action_base._low_level_execute_command.return_value = dict(rc=0, stdout='/some/path') self.assertEqual(action_base._make_tmp_path('root'), '/some/path/') # empty path fails action_base._low_level_execute_command.return_value = dict(rc=0, stdout='') self.assertRaises(AnsibleError, action_base._make_tmp_path, 'root') # authentication failure action_base._low_level_execute_command.return_value = dict(rc=5, stdout='') self.assertRaises(AnsibleError, action_base._make_tmp_path, 'root') # ssh error action_base._low_level_execute_command.return_value = dict(rc=255, stdout='', stderr='') self.assertRaises(AnsibleError, action_base._make_tmp_path, 'root') play_context.verbosity = 5 self.assertRaises(AnsibleError, action_base._make_tmp_path, 'root') # general error action_base._low_level_execute_command.return_value = dict(rc=1, stdout='some stuff here', stderr='') self.assertRaises(AnsibleError, action_base._make_tmp_path, 'root') action_base._low_level_execute_command.return_value = dict(rc=1, stdout='some stuff here', stderr='No space left on device') self.assertRaises(AnsibleError, action_base._make_tmp_path, 'root')
def test_sudo_only_if_user_differs(self): play_context = PlayContext() action_base = ActionBase(None, None, play_context, None, None, None) action_base._connection = Mock(exec_command=Mock(return_value=(0, '', ''))) play_context.become = True play_context.become_user = play_context.remote_user = '******' play_context.make_become_cmd = Mock(return_value='CMD') action_base._low_level_execute_command('ECHO', sudoable=True) play_context.make_become_cmd.assert_not_called() play_context.remote_user = '******' action_base._low_level_execute_command('ECHO', sudoable=True) play_context.make_become_cmd.assert_called_once_with('ECHO', executable=None) play_context.make_become_cmd.reset_mock() become_allow_same_user = C.BECOME_ALLOW_SAME_USER C.BECOME_ALLOW_SAME_USER = True try: play_context.remote_user = '******' action_base._low_level_execute_command('ECHO SAME', sudoable=True) play_context.make_become_cmd.assert_called_once_with('ECHO SAME', executable=None) finally: C.BECOME_ALLOW_SAME_USER = become_allow_same_user
def test_dzdo(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" dzdo_exe = 'dzdo' dzdo_flags = '' 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('dzdo')) play_context.become_method = 'dzdo' play_context.become_flags = dzdo_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'""" % (dzdo_exe, dzdo_flags, play_context.become_user, default_exe, success, default_cmd), cmd) is not None play_context.become_pass = '******' play_context.set_become_plugin(become_loader.get('dzdo')) 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'""" % (dzdo_exe, dzdo_flags, r'\"\[dzdo via ansible, key=.+?\] password:\"', play_context.become_user, default_exe, success, default_cmd), cmd) is not None
def test_action_base__make_tmp_path(self): # create our fake task mock_task = MagicMock() def get_shell_opt(opt): ret = None if opt == 'admin_users': ret = ['root', 'toor', 'Administrator'] elif opt == 'remote_tmp': ret = '~/.ansible/tmp' return ret # create a mock connection, so we don't actually try and connect to things mock_connection = MagicMock() mock_connection.transport = 'ssh' mock_connection._shell.mkdtemp.return_value = 'mkdir command' mock_connection._shell.join_path.side_effect = os.path.join mock_connection._shell.get_option = get_shell_opt mock_connection._shell.HOMES_RE = re.compile(r'(\'|\")?(~|\$HOME)(.*)') # we're using a real play context here play_context = PlayContext() play_context.become = True play_context.become_user = '******' # 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() action_base._low_level_execute_command.return_value = dict(rc=0, stdout='/some/path') self.assertEqual(action_base._make_tmp_path('root'), '/some/path/') # empty path fails action_base._low_level_execute_command.return_value = dict(rc=0, stdout='') self.assertRaises(AnsibleError, action_base._make_tmp_path, 'root') # authentication failure action_base._low_level_execute_command.return_value = dict(rc=5, stdout='') self.assertRaises(AnsibleError, action_base._make_tmp_path, 'root') # ssh error action_base._low_level_execute_command.return_value = dict(rc=255, stdout='', stderr='') self.assertRaises(AnsibleError, action_base._make_tmp_path, 'root') play_context.verbosity = 5 self.assertRaises(AnsibleError, action_base._make_tmp_path, 'root') # general error action_base._low_level_execute_command.return_value = dict(rc=1, stdout='some stuff here', stderr='') self.assertRaises(AnsibleError, action_base._make_tmp_path, 'root') action_base._low_level_execute_command.return_value = dict(rc=1, stdout='some stuff here', stderr='No space left on device') self.assertRaises(AnsibleError, action_base._make_tmp_path, 'root')
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._connection = MagicMock(exec_command=MagicMock(return_value=(0, '', ''))) action_base._connection._shell = MagicMock(append_command=MagicMock(return_value=('JOINED CMD'))) play_context.become = True play_context.become_user = play_context.remote_user = '******' play_context.make_become_cmd = MagicMock(return_value='CMD') action_base._low_level_execute_command('ECHO', sudoable=True) play_context.make_become_cmd.assert_not_called() play_context.remote_user = '******' action_base._low_level_execute_command('ECHO', sudoable=True, executable='/bin/csh') play_context.make_become_cmd.assert_called_once_with("ECHO", executable='/bin/csh') play_context.make_become_cmd.reset_mock() become_allow_same_user = C.BECOME_ALLOW_SAME_USER C.BECOME_ALLOW_SAME_USER = True try: play_context.remote_user = '******' action_base._low_level_execute_command('ECHO SAME', sudoable=True) play_context.make_become_cmd.assert_called_once_with("ECHO SAME", executable=None) finally: C.BECOME_ALLOW_SAME_USER = become_allow_same_user
def test_action_base__make_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.transport = 'ssh' mock_connection._shell.mkdtemp.return_value = 'mkdir command' mock_connection._shell.join_path.side_effect = os.path.join # we're using a real play context here play_context = PlayContext() play_context.become = True play_context.become_user = '******' # 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() action_base._low_level_execute_command.return_value = dict( rc=0, stdout='/some/path') self.assertEqual(action_base._make_tmp_path('root'), '/some/path/') # empty path fails action_base._low_level_execute_command.return_value = dict(rc=0, stdout='') self.assertRaises(AnsibleError, action_base._make_tmp_path, 'root') # authentication failure action_base._low_level_execute_command.return_value = dict(rc=5, stdout='') self.assertRaises(AnsibleError, action_base._make_tmp_path, 'root') # ssh error action_base._low_level_execute_command.return_value = dict(rc=255, stdout='', stderr='') self.assertRaises(AnsibleError, action_base._make_tmp_path, 'root') play_context.verbosity = 5 self.assertRaises(AnsibleError, action_base._make_tmp_path, 'root') # general error action_base._low_level_execute_command.return_value = dict( rc=1, stdout='some stuff here', stderr='') self.assertRaises(AnsibleError, action_base._make_tmp_path, 'root') action_base._low_level_execute_command.return_value = dict( rc=1, stdout='some stuff here', stderr='No space left on device') self.assertRaises(AnsibleError, action_base._make_tmp_path, 'root')
def test_play_context_make_become_cmd(self): (options, args) = self._parser.parse_args([]) play_context = PlayContext(options=options) default_cmd = "/bin/foo" default_exe = "/bin/bash" sudo_exe = C.DEFAULT_SUDO_EXE or 'sudo' sudo_flags = C.DEFAULT_SUDO_FLAGS su_exe = C.DEFAULT_SU_EXE or 'su' su_flags = C.DEFAULT_SU_FLAGS or '' pbrun_exe = 'pbrun' pbrun_flags = '' pfexec_exe = 'pfexec' pfexec_flags = '' doas_exe = 'doas' doas_flags = ' -n -u foo ' cmd = play_context.make_become_cmd(cmd=default_cmd, executable=default_exe) self.assertEqual(cmd, default_cmd) play_context.become = True play_context.become_user = '******' play_context.become_method = 'sudo' cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") self.assertEqual(cmd, """%s -c '%s %s -n -S -u %s %s -c '"'"'echo %s; %s'"'"''""" % (default_exe, sudo_exe, sudo_flags, play_context.become_user, default_exe, play_context.success_key, default_cmd)) play_context.become_pass = '******' cmd = play_context.make_become_cmd(cmd=default_cmd, executable=default_exe) self.assertEqual(cmd, """%s -c '%s %s -p "%s" -S -u %s %s -c '"'"'echo %s; %s'"'"''""" % (default_exe, sudo_exe, sudo_flags, play_context.prompt, play_context.become_user, default_exe, play_context.success_key, default_cmd)) play_context.become_pass = None play_context.become_method = 'su' cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") self.assertEqual(cmd, """%s -c '%s %s -c "%s -c '"'"'echo %s; %s'"'"'"'""" % (default_exe, su_exe, play_context.become_user, default_exe, play_context.success_key, default_cmd)) play_context.become_method = 'pbrun' cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") self.assertEqual(cmd, """%s -c '%s -b %s -u %s '"'"'echo %s; %s'"'"''""" % (default_exe, pbrun_exe, pbrun_flags, play_context.become_user, play_context.success_key, default_cmd)) play_context.become_method = 'pfexec' cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") self.assertEqual(cmd, """%s -c '%s %s "'"'"'echo %s; %s'"'"'"'""" % (default_exe, pfexec_exe, pfexec_flags, play_context.success_key, default_cmd)) play_context.become_method = 'doas' cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") self.assertEqual(cmd, """%s -c '%s %s echo %s && %s %s env ANSIBLE=true %s'""" % (default_exe, doas_exe, doas_flags, play_context.success_key, doas_exe, doas_flags, default_cmd)) play_context.become_method = 'bad' self.assertRaises(AnsibleError, play_context.make_become_cmd, cmd=default_cmd, executable="/bin/bash")
def test_play_context_make_become_cmd(self): (options, args) = self._parser.parse_args([]) play_context = PlayContext(options=options) default_cmd = "/bin/foo" default_exe = "/bin/bash" sudo_exe = C.DEFAULT_SUDO_EXE or 'sudo' sudo_flags = C.DEFAULT_SUDO_FLAGS su_exe = C.DEFAULT_SU_EXE or 'su' su_flags = C.DEFAULT_SU_FLAGS or '' pbrun_exe = 'pbrun' pbrun_flags = '' pfexec_exe = 'pfexec' pfexec_flags = '' doas_exe = 'doas' doas_flags = ' -n -u foo ' cmd = play_context.make_become_cmd(cmd=default_cmd, executable=default_exe) self.assertEqual(cmd, default_cmd) play_context.become = True play_context.become_user = '******' play_context.become_method = 'sudo' cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") self.assertEqual(cmd, """%s %s -u %s %s -c 'echo %s; %s'""" % (sudo_exe, sudo_flags, play_context.become_user, default_exe, play_context.success_key, default_cmd)) play_context.become_pass = '******' cmd = play_context.make_become_cmd(cmd=default_cmd, executable=default_exe) self.assertEqual(cmd, """%s %s -p "%s" -u %s %s -c 'echo %s; %s'""" % (sudo_exe, sudo_flags.replace('-n',''), play_context.prompt, play_context.become_user, default_exe, play_context.success_key, default_cmd)) play_context.become_pass = None play_context.become_method = 'su' cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") self.assertEqual(cmd, """%s %s -c '%s -c '"'"'echo %s; %s'"'"''""" % (su_exe, play_context.become_user, default_exe, play_context.success_key, default_cmd)) play_context.become_method = 'pbrun' cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") self.assertEqual(cmd, """%s -b %s -u %s 'echo %s; %s'""" % (pbrun_exe, pbrun_flags, play_context.become_user, play_context.success_key, default_cmd)) play_context.become_method = 'pfexec' cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") self.assertEqual(cmd, '''%s %s "'echo %s; %s'"''' % (pfexec_exe, pfexec_flags, play_context.success_key, default_cmd)) play_context.become_method = 'doas' cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") self.assertEqual(cmd, """%s %s echo %s && %s %s env ANSIBLE=true %s""" % (doas_exe, doas_flags, play_context.success_key, doas_exe, doas_flags, default_cmd)) play_context.become_method = 'bad' self.assertRaises(AnsibleError, play_context.make_become_cmd, cmd=default_cmd, executable="/bin/bash")
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(AnsibleError): play_context.make_become_cmd(cmd=default_cmd, executable=default_exe)
def test_action_base__make_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.transport = 'ssh' mock_connection._shell.mkdtemp.return_value = 'mkdir command' mock_connection._shell.join_path.side_effect = os.path.join # we're using a real play context here play_context = PlayContext() play_context.become = True play_context.become_user = '******' # 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() action_base._low_level_execute_command.return_value = dict(rc=0, stdout='/some/path') self.assertEqual(action_base._make_tmp_path('root'), '/some/path/') # empty path fails action_base._low_level_execute_command.return_value = dict(rc=0, stdout='') self.assertRaises(AnsibleError, action_base._make_tmp_path, 'root') # authentication failure action_base._low_level_execute_command.return_value = dict(rc=5, stdout='') self.assertRaises(AnsibleError, action_base._make_tmp_path, 'root') # ssh error action_base._low_level_execute_command.return_value = dict(rc=255, stdout='', stderr='') self.assertRaises(AnsibleError, action_base._make_tmp_path, 'root') play_context.verbosity = 5 self.assertRaises(AnsibleError, action_base._make_tmp_path, 'root') # general error action_base._low_level_execute_command.return_value = dict(rc=1, stdout='some stuff here', stderr='') self.assertRaises(AnsibleError, action_base._make_tmp_path, 'root') action_base._low_level_execute_command.return_value = dict(rc=1, stdout='some stuff here', stderr='No space left on device') self.assertRaises(AnsibleError, action_base._make_tmp_path, 'root')
def get_play_context(self): play_context = PlayContext(play=None, options=None, passwords=self._passwords) play_context.remote_addr = self.addr play_context.port = self.port play_context.remote_user = self.user play_context.ssh_executable = 'ssh' play_context.timeout = 10 play_context.connection = 'ssh' play_context.become = self.sudo play_context.become_method = 'sudo' play_context.become_user = '******' return play_context
def test_pfexec(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" pfexec_exe = 'pfexec' pfexec_flags = '' 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('pfexec')) play_context.become_method = 'pfexec' play_context.become_flags = pfexec_flags cmd = play_context.make_become_cmd(cmd=default_cmd, executable=default_exe) assert re.match( '''%s %s "'echo %s; %s'"''' % (pfexec_exe, pfexec_flags, success, default_cmd), cmd) is not None
def test_plugins_connection_ssh__run(self, mock_Popen, mock_openpty, mock_osclose, mock_oswrite, mock_fcntl, mock_select): pc = PlayContext() new_stdin = StringIO() conn = ssh.Connection(pc, new_stdin) conn._send_initial_data = MagicMock() conn._examine_output = MagicMock() conn._terminate_process = MagicMock() conn.sshpass_pipe = [MagicMock(), MagicMock()] 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.return_code = 0 mock_Popen.return_value = mock_popen_res def _mock_select(rlist, wlist, elist, timeout=None): rvals = [] if mock_popen_res.stdin in rlist: rvals.append(mock_popen_res.stdin) if mock_popen_res.stderr in rlist: rvals.append(mock_popen_res.stderr) return (rvals, [], []) mock_select.side_effect = _mock_select mock_popen_res.stdout.read.side_effect = [b"some data", b""] mock_popen_res.stderr.read.side_effect = [b""] conn._run("ssh", "this is input data") # test with a password set to trigger the sshpass write pc.password = '******' mock_popen_res.stdout.read.side_effect = [b"some data", b"", b""] mock_popen_res.stderr.read.side_effect = [b""] conn._run(["ssh", "is", "a", "cmd"], "this is more data") # test with password prompting enabled pc.password = None pc.prompt = True mock_popen_res.stdout.read.side_effect = [b"some data", b"", b""] mock_popen_res.stderr.read.side_effect = [b""] conn._run("ssh", "this is input data") # test with some become settings pc.prompt = False pc.become = True pc.success_key = 'BECOME-SUCCESS-abcdefg' mock_popen_res.stdout.read.side_effect = [b"some data", b"", b""] mock_popen_res.stderr.read.side_effect = [b""] conn._run("ssh", "this is input data") # simulate no data input mock_openpty.return_value = (98, 99) mock_popen_res.stdout.read.side_effect = [b"some data", b"", b""] mock_popen_res.stderr.read.side_effect = [b""] conn._run("ssh", "") # simulate no data input but Popen using new pty's fails mock_Popen.return_value = None mock_Popen.side_effect = [OSError(), mock_popen_res] mock_popen_res.stdout.read.side_effect = [b"some data", b"", b""] mock_popen_res.stderr.read.side_effect = [b""] conn._run("ssh", "")
def test_play_context_make_become_cmd(parser): (options, args) = parser.parse_args([]) play_context = PlayContext(options=options) default_cmd = "/bin/foo" default_exe = "/bin/bash" sudo_exe = C.DEFAULT_SUDO_EXE or 'sudo' sudo_flags = C.DEFAULT_SUDO_FLAGS su_exe = C.DEFAULT_SU_EXE or 'su' su_flags = C.DEFAULT_SU_FLAGS or '' pbrun_exe = 'pbrun' pbrun_flags = '' pfexec_exe = 'pfexec' pfexec_flags = '' doas_exe = 'doas' doas_flags = ' -n -u foo ' ksu_exe = 'ksu' ksu_flags = '' dzdo_exe = 'dzdo' cmd = play_context.make_become_cmd(cmd=default_cmd, executable=default_exe) assert cmd == default_cmd play_context.become = True play_context.become_user = '******' play_context.become_method = 'sudo' cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") assert (cmd == """%s %s -u %s %s -c 'echo %s; %s'""" % (sudo_exe, sudo_flags, play_context.become_user, default_exe, play_context.success_key, default_cmd)) play_context.become_pass = '******' cmd = play_context.make_become_cmd(cmd=default_cmd, executable=default_exe) assert (cmd == """%s %s -p "%s" -u %s %s -c 'echo %s; %s'""" % (sudo_exe, sudo_flags.replace('-n', ''), play_context.prompt, play_context.become_user, default_exe, play_context.success_key, default_cmd)) play_context.become_pass = None play_context.become_method = 'su' cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") assert (cmd == """%s %s -c '%s -c '"'"'echo %s; %s'"'"''""" % (su_exe, play_context.become_user, default_exe, play_context.success_key, default_cmd)) play_context.become_method = 'pbrun' cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") assert cmd == """%s %s -u %s 'echo %s; %s'""" % (pbrun_exe, pbrun_flags, play_context.become_user, play_context.success_key, default_cmd) play_context.become_method = 'pfexec' cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") assert cmd == '''%s %s "'echo %s; %s'"''' % (pfexec_exe, pfexec_flags, play_context.success_key, default_cmd) play_context.become_method = 'doas' cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") assert (cmd == """%s %s echo %s && %s %s env ANSIBLE=true %s""" % (doas_exe, doas_flags, play_context. success_key, doas_exe, doas_flags, default_cmd)) play_context.become_method = 'ksu' cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") assert (cmd == """%s %s %s -e %s -c 'echo %s; %s'""" % (ksu_exe, play_context.become_user, ksu_flags, default_exe, play_context.success_key, default_cmd)) play_context.become_method = 'bad' with pytest.raises(AnsibleError): play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") play_context.become_method = 'dzdo' cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") assert cmd == """%s -u %s %s -c 'echo %s; %s'""" % (dzdo_exe, play_context.become_user, default_exe, play_context.success_key, default_cmd) play_context.become_pass = '******' play_context.become_method = 'dzdo' cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") assert (cmd == """%s -p %s -u %s %s -c 'echo %s; %s'""" % (dzdo_exe, shlex_quote(play_context.prompt), play_context.become_user, default_exe, play_context.success_key, default_cmd))
def test_action_base__execute_module(self): # create our fake task mock_task = MagicMock() mock_task.action = 'copy' mock_task.args = dict(a=1, b=2, c=3) # create a mock connection, so we don't actually try and connect to things def build_module_command(env_string, shebang, cmd, arg_path=None, rm_tmp=None): to_run = [env_string, cmd] if arg_path: to_run.append(arg_path) if rm_tmp: to_run.append(rm_tmp) return " ".join(to_run) mock_connection = MagicMock() mock_connection.build_module_command.side_effect = build_module_command mock_connection._shell.join_path.side_effect = os.path.join # 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, ) # fake a lot of methods as we test those elsewhere action_base._configure_module = MagicMock() action_base._supports_check_mode = MagicMock() action_base._late_needs_tmp_path = MagicMock() action_base._make_tmp_path = MagicMock() action_base._transfer_data = MagicMock() action_base._compute_environment_string = MagicMock() action_base._low_level_execute_command = MagicMock() action_base._fixup_perms = MagicMock() action_base._configure_module.return_value = ( 'new', '#!/usr/bin/python', 'this is the module data', 'path') action_base._late_needs_tmp_path.return_value = False action_base._compute_environment_string.return_value = '' action_base._connection.has_pipelining = True action_base._low_level_execute_command.return_value = dict( stdout='{"rc": 0, "stdout": "ok"}') self.assertEqual( action_base._execute_module(module_name=None, module_args=None), dict(_ansible_parsed=True, rc=0, stdout="ok", stdout_lines=['ok'])) self.assertEqual( action_base._execute_module(module_name='foo', module_args=dict(z=9, y=8, x=7), task_vars=dict(a=1)), dict(_ansible_parsed=True, rc=0, stdout="ok", stdout_lines=['ok'])) # test with needing/removing a remote tmp path action_base._configure_module.return_value = ( 'old', '#!/usr/bin/python', 'this is the module data', 'path') action_base._late_needs_tmp_path.return_value = True action_base._make_tmp_path.return_value = '/the/tmp/path' self.assertEqual( action_base._execute_module(), dict(_ansible_parsed=True, rc=0, stdout="ok", stdout_lines=['ok'])) action_base._configure_module.return_value = ( 'non_native_want_json', '#!/usr/bin/python', 'this is the module data', 'path') self.assertEqual( action_base._execute_module(), dict(_ansible_parsed=True, rc=0, stdout="ok", stdout_lines=['ok'])) play_context.become = True play_context.become_user = '******' self.assertEqual( action_base._execute_module(), dict(_ansible_parsed=True, rc=0, stdout="ok", stdout_lines=['ok'])) # test an invalid shebang return action_base._configure_module.return_value = ( 'new', '', 'this is the module data', 'path') action_base._late_needs_tmp_path.return_value = False self.assertRaises(AnsibleError, action_base._execute_module) # test with check mode enabled, once with support for check # mode and once with support disabled to raise an error play_context.check_mode = True action_base._configure_module.return_value = ( 'new', '#!/usr/bin/python', 'this is the module data', 'path') self.assertEqual( action_base._execute_module(), dict(_ansible_parsed=True, rc=0, stdout="ok", stdout_lines=['ok'])) action_base._supports_check_mode = False self.assertRaises(AnsibleError, action_base._execute_module)
def test_plugins_connection_ssh__run(self, mock_Popen, mock_openpty, mock_osclose, mock_oswrite, mock_fcntl, mock_select): pc = PlayContext() new_stdin = StringIO() conn = ssh.Connection(pc, new_stdin) conn._send_initial_data = MagicMock() conn._examine_output = MagicMock() conn._terminate_process = MagicMock() conn.sshpass_pipe = [MagicMock(), MagicMock()] 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.return_code = 0 mock_Popen.return_value = mock_popen_res def _mock_select(rlist, wlist, elist, timeout=None): rvals = [] if mock_popen_res.stdin in rlist: rvals.append(mock_popen_res.stdin) if mock_popen_res.stderr in rlist: rvals.append(mock_popen_res.stderr) return (rvals, [], []) mock_select.side_effect = _mock_select mock_popen_res.stdout.read.side_effect = [b"some data", b""] mock_popen_res.stderr.read.side_effect = [b""] conn._run("ssh", "this is input data") # test with a password set to trigger the sshpass write pc.password = '******' mock_popen_res.stdout.read.side_effect = [b"some data", b"", b""] mock_popen_res.stderr.read.side_effect = [b""] conn._run(["ssh", "is", "a", "cmd"], "this is more data") # test with password prompting enabled pc.password = None pc.prompt = True mock_popen_res.stdout.read.side_effect = [b"some data", b"", b""] mock_popen_res.stderr.read.side_effect = [b""] conn._run("ssh", "this is input data") # test with some become settings pc.prompt = False pc.become = True pc.success_key = 'BECOME-SUCCESS-abcdefg' mock_popen_res.stdout.read.side_effect = [b"some data", b"", b""] mock_popen_res.stderr.read.side_effect = [b""] conn._run("ssh", "this is input data") # simulate no data input mock_openpty.return_value = (98, 99) mock_popen_res.stdout.read.side_effect = [b"some data", b"", b""] mock_popen_res.stderr.read.side_effect = [b""] conn._run("ssh", "") # simulate no data input but Popen using new pty's fails mock_Popen.return_value = None mock_Popen.side_effect = [OSError(), mock_popen_res] mock_popen_res.stdout.read.side_effect = [b"some data", b"", b""] mock_popen_res.stderr.read.side_effect = [b""] conn._run("ssh", "")
def test_play_context_make_become_cmd(mocker, parser, reset_cli_args): (options, args) = parser.parse_args([]) options.args = 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' su_exe = 'su' su_flags = '' pbrun_exe = 'pbrun' pbrun_flags = '' pfexec_exe = 'pfexec' pfexec_flags = '' doas_exe = 'doas' doas_flags = '-n' ksu_exe = 'ksu' ksu_flags = '' dzdo_exe = 'dzdo' dzdo_flags = '' 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="/bin/bash") 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 ansible, key=.+?\] password:"******"/bin/bash") assert (re.match("""%s %s -c '%s -c '"'"'echo %s; %s'"'"''""" % (su_exe, play_context.become_user, default_exe, success, default_cmd), cmd) is not None) play_context.set_become_plugin(become_loader.get('pbrun')) play_context.become_flags = pbrun_flags cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") assert re.match("""%s %s -u %s 'echo %s; %s'""" % (pbrun_exe, pbrun_flags, play_context.become_user, success, default_cmd), cmd) is not None play_context.set_become_plugin(become_loader.get('pfexec')) play_context.become_flags = pfexec_flags cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") assert re.match('''%s %s "'echo %s; %s'"''' % (pfexec_exe, pfexec_flags, success, default_cmd), cmd) is not None play_context.set_become_plugin(become_loader.get('doas')) play_context.become_flags = doas_flags cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") assert (re.match("""%s %s -u %s %s -c 'echo %s; %s'""" % (doas_exe, doas_flags, play_context.become_user, default_exe, success, default_cmd), cmd) is not None) play_context.set_become_plugin(become_loader.get('ksu')) play_context.become_flags = ksu_flags cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") assert (re.match("""%s %s %s -e %s -c 'echo %s; %s'""" % (ksu_exe, play_context.become_user, ksu_flags, default_exe, success, default_cmd), cmd) is not None) play_context.set_become_plugin(become_loader.get('bad')) with pytest.raises(AnsibleError): play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") play_context.set_become_plugin(become_loader.get('dzdo')) play_context.become_flags = dzdo_flags cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") assert re.match("""%s %s -u %s %s -c 'echo %s; %s'""" % (dzdo_exe, dzdo_flags, play_context.become_user, default_exe, success, default_cmd), cmd) is not None play_context.become_pass = '******' play_context.set_become_plugin(become_loader.get('dzdo')) cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") assert re.match("""%s %s -p %s -u %s %s -c 'echo %s; %s'""" % (dzdo_exe, dzdo_flags, r'\"\[dzdo via ansible, key=.+?\] password:\"', play_context.become_user, default_exe, success, default_cmd), cmd) is not None
def test_play_context_make_become_cmd(parser): (options, args) = parser.parse_args([]) play_context = PlayContext(options=options) default_cmd = "/bin/foo" default_exe = "/bin/bash" sudo_exe = C.DEFAULT_SUDO_EXE or 'sudo' sudo_flags = C.DEFAULT_SUDO_FLAGS su_exe = C.DEFAULT_SU_EXE or 'su' su_flags = C.DEFAULT_SU_FLAGS or '' pbrun_exe = 'pbrun' pbrun_flags = '' pfexec_exe = 'pfexec' pfexec_flags = '' doas_exe = 'doas' doas_flags = ' -n -u foo ' ksu_exe = 'ksu' ksu_flags = '' dzdo_exe = 'dzdo' dzdo_flags = '' cmd = play_context.make_become_cmd(cmd=default_cmd, executable=default_exe) assert cmd == default_cmd play_context.become = True play_context.become_user = '******' play_context.become_method = 'sudo' cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") assert (cmd == """%s %s -u %s %s -c 'echo %s; %s'""" % (sudo_exe, sudo_flags, play_context.become_user, default_exe, play_context.success_key, default_cmd)) play_context.become_pass = '******' cmd = play_context.make_become_cmd(cmd=default_cmd, executable=default_exe) assert (cmd == """%s %s -p "%s" -u %s %s -c 'echo %s; %s'""" % (sudo_exe, sudo_flags.replace( '-n', ''), play_context.prompt, play_context.become_user, default_exe, play_context.success_key, default_cmd)) play_context.become_pass = None play_context.become_method = 'su' cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") assert (cmd == """%s %s -c '%s -c '"'"'echo %s; %s'"'"''""" % (su_exe, play_context.become_user, default_exe, play_context.success_key, default_cmd)) play_context.become_method = 'pbrun' cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") assert cmd == """%s %s -u %s 'echo %s; %s'""" % ( pbrun_exe, pbrun_flags, play_context.become_user, play_context.success_key, default_cmd) play_context.become_method = 'pfexec' cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") assert cmd == '''%s %s "'echo %s; %s'"''' % ( pfexec_exe, pfexec_flags, play_context.success_key, default_cmd) play_context.become_method = 'doas' cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") assert (cmd == """%s %s echo %s && %s %s env ANSIBLE=true %s""" % (doas_exe, doas_flags, play_context.success_key, doas_exe, doas_flags, default_cmd)) play_context.become_method = 'ksu' cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") assert (cmd == """%s %s %s -e %s -c 'echo %s; %s'""" % (ksu_exe, play_context.become_user, ksu_flags, default_exe, play_context.success_key, default_cmd)) play_context.become_method = 'bad' with pytest.raises(AnsibleError): play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") play_context.become_method = 'dzdo' cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") assert cmd == """%s %s -u %s %s -c 'echo %s; %s'""" % ( dzdo_exe, dzdo_flags, play_context.become_user, default_exe, play_context.success_key, default_cmd) play_context.become_pass = '******' play_context.become_method = 'dzdo' cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") assert (cmd == """%s %s -p %s -u %s %s -c 'echo %s; %s'""" % (dzdo_exe, dzdo_flags, shlex_quote( play_context.prompt), play_context.become_user, default_exe, play_context.success_key, default_cmd))
def test_action_base__execute_module(self): # create our fake task mock_task = MagicMock() mock_task.action = 'copy' mock_task.args = dict(a=1, b=2, c=3) # create a mock connection, so we don't actually try and connect to things def build_module_command(env_string, shebang, cmd, arg_path=None, rm_tmp=None): to_run = [env_string, cmd] if arg_path: to_run.append(arg_path) if rm_tmp: to_run.append(rm_tmp) return " ".join(to_run) mock_connection = MagicMock() mock_connection.build_module_command.side_effect = build_module_command mock_connection._shell.get_remote_filename.return_value = 'copy.py' mock_connection._shell.join_path.side_effect = os.path.join # 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, ) # fake a lot of methods as we test those elsewhere action_base._configure_module = MagicMock() action_base._supports_check_mode = MagicMock() action_base._is_pipelining_enabled = MagicMock() action_base._make_tmp_path = MagicMock() action_base._transfer_data = MagicMock() action_base._compute_environment_string = MagicMock() action_base._low_level_execute_command = MagicMock() action_base._fixup_perms2 = MagicMock() action_base._configure_module.return_value = ('new', '#!/usr/bin/python', 'this is the module data', 'path') action_base._is_pipelining_enabled.return_value = False action_base._compute_environment_string.return_value = '' action_base._connection.has_pipelining = False action_base._make_tmp_path.return_value = '/the/tmp/path' action_base._low_level_execute_command.return_value = dict(stdout='{"rc": 0, "stdout": "ok"}') self.assertEqual(action_base._execute_module(module_name=None, module_args=None), dict(_ansible_parsed=True, rc=0, stdout="ok", stdout_lines=['ok'])) self.assertEqual( action_base._execute_module( module_name='foo', module_args=dict(z=9, y=8, x=7), task_vars=dict(a=1) ), dict( _ansible_parsed=True, rc=0, stdout="ok", stdout_lines=['ok'], ) ) # test with needing/removing a remote tmp path action_base._configure_module.return_value = ('old', '#!/usr/bin/python', 'this is the module data', 'path') action_base._is_pipelining_enabled.return_value = False action_base._make_tmp_path.return_value = '/the/tmp/path' self.assertEqual(action_base._execute_module(), dict(_ansible_parsed=True, rc=0, stdout="ok", stdout_lines=['ok'])) action_base._configure_module.return_value = ('non_native_want_json', '#!/usr/bin/python', 'this is the module data', 'path') self.assertEqual(action_base._execute_module(), dict(_ansible_parsed=True, rc=0, stdout="ok", stdout_lines=['ok'])) play_context.become = True play_context.become_user = '******' self.assertEqual(action_base._execute_module(), dict(_ansible_parsed=True, rc=0, stdout="ok", stdout_lines=['ok'])) # test an invalid shebang return action_base._configure_module.return_value = ('new', '', 'this is the module data', 'path') action_base._is_pipelining_enabled.return_value = False action_base._make_tmp_path.return_value = '/the/tmp/path' self.assertRaises(AnsibleError, action_base._execute_module) # test with check mode enabled, once with support for check # mode and once with support disabled to raise an error play_context.check_mode = True action_base._configure_module.return_value = ('new', '#!/usr/bin/python', 'this is the module data', 'path') self.assertEqual(action_base._execute_module(), dict(_ansible_parsed=True, rc=0, stdout="ok", stdout_lines=['ok'])) action_base._supports_check_mode = False self.assertRaises(AnsibleError, action_base._execute_module)