Remove incidental_win_psexec (#71953)
* Explicit coverage to remove incidental_win_psexec * rc=1 failed * ci_complete ci_coverage * Test rc!=0 without failed and until * ci_complete ci_coverage * Remove incidental_win_psexec * Reduce delay * ci_complete ci_coverage
This commit is contained in:
parent
7c1dd1c7fb
commit
5d811fc551
7 changed files with 41 additions and 408 deletions
|
@ -1,2 +0,0 @@
|
|||
shippable/windows/incidental
|
||||
windows
|
|
@ -1,2 +0,0 @@
|
|||
dependencies:
|
||||
- setup_remote_tmp_dir
|
|
@ -1,80 +0,0 @@
|
|||
# Would use [] but this has troubles with PATH and trying to find the executable so just resort to keeping a space
|
||||
- name: record special path for tests
|
||||
set_fact:
|
||||
testing_dir: '{{ remote_tmp_dir }}\ansible win_psexec'
|
||||
|
||||
- name: create special path testing dir
|
||||
win_file:
|
||||
path: '{{ testing_dir }}'
|
||||
state: directory
|
||||
|
||||
- name: Download PsExec
|
||||
win_get_url:
|
||||
url: https://ansible-ci-files.s3.amazonaws.com/test/integration/targets/win_psexec/PsExec.exe
|
||||
dest: '{{ testing_dir }}\PsExec.exe'
|
||||
|
||||
- name: Get the existing PATH env var
|
||||
win_shell: '$env:PATH'
|
||||
register: system_path
|
||||
changed_when: False
|
||||
|
||||
- name: Run whoami
|
||||
win_psexec:
|
||||
command: whoami.exe
|
||||
nobanner: true
|
||||
register: whoami
|
||||
environment:
|
||||
PATH: '{{ testing_dir }};{{ system_path.stdout | trim }}'
|
||||
|
||||
- name: Test whoami
|
||||
assert:
|
||||
that:
|
||||
- whoami.rc == 0
|
||||
- whoami.stdout == ''
|
||||
# FIXME: Standard output does not work or is truncated
|
||||
#- whoami.stdout == '{{ ansible_hostname|lower }}'
|
||||
|
||||
- name: Run whoami as SYSTEM
|
||||
win_psexec:
|
||||
command: whoami.exe
|
||||
system: yes
|
||||
nobanner: true
|
||||
executable: '{{ testing_dir }}\PsExec.exe'
|
||||
register: whoami_as_system
|
||||
# Seems to be a bug with PsExec where the stdout can be empty, just retry the task to make this test a bit more stable
|
||||
until: whoami_as_system.rc == 0 and whoami_as_system.stdout == 'nt authority\system'
|
||||
retries: 3
|
||||
delay: 2
|
||||
|
||||
# FIXME: Behaviour is not consistent on all Windows systems
|
||||
#- name: Run whoami as ELEVATED
|
||||
# win_psexec:
|
||||
# command: whoami.exe
|
||||
# elevated: yes
|
||||
# register: whoami_as_elevated
|
||||
#
|
||||
## Ensure we have basic facts
|
||||
#- setup:
|
||||
#
|
||||
#- debug:
|
||||
# msg: '{{ whoami_as_elevated.stdout|lower }} == {{ ansible_hostname|lower }}\{{ ansible_user_id|lower }}'
|
||||
#
|
||||
#- name: Test whoami
|
||||
# assert:
|
||||
# that:
|
||||
# - whoami_as_elevated.rc == 0
|
||||
# - whoami_as_elevated.stdout|lower == '{{ ansible_hostname|lower }}\{{ ansible_user_id|lower }}'
|
||||
|
||||
- name: Run command with multiple arguments
|
||||
win_psexec:
|
||||
command: powershell.exe -NonInteractive "exit 1"
|
||||
ignore_errors: yes
|
||||
register: whoami_multiple_args
|
||||
environment:
|
||||
PATH: '{{ testing_dir }};{{ system_path.stdout | trim }}'
|
||||
|
||||
- name: Test command with multiple argumetns
|
||||
assert:
|
||||
that:
|
||||
- whoami_multiple_args.rc == 1
|
||||
- whoami_multiple_args.psexec_command == "psexec.exe -accepteula powershell.exe -NonInteractive \"exit 1\""
|
|
@ -0,0 +1,28 @@
|
|||
# Copyright: (c) 2017, Ansible Project
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
from __future__ import (absolute_import, division, print_function)
|
||||
__metaclass__ = type
|
||||
|
||||
from ansible.plugins.action import ActionBase
|
||||
|
||||
|
||||
class ActionModule(ActionBase):
|
||||
|
||||
def run(self, tmp=None, task_vars=None):
|
||||
del tmp # tmp no longer has any effect
|
||||
|
||||
try:
|
||||
self._task.args['_raw_params'] = self._task.args.pop('cmd')
|
||||
except KeyError:
|
||||
pass
|
||||
shell_action = self._shared_loader_obj.action_loader.get('ansible.legacy.shell',
|
||||
task=self._task,
|
||||
connection=self._connection,
|
||||
play_context=self._play_context,
|
||||
loader=self._loader,
|
||||
templar=self._templar,
|
||||
shared_loader_obj=self._shared_loader_obj)
|
||||
result = shell_action.run(task_vars=task_vars)
|
||||
result.pop('failed', None)
|
||||
return result
|
|
@ -69,3 +69,16 @@
|
|||
retries: 5
|
||||
delay: 0.5
|
||||
failed_when: changed_when_attempts.attempts > 6
|
||||
|
||||
# Test until on module that doesn't return failed, but does return rc
|
||||
- name: create counter file
|
||||
copy:
|
||||
dest: "{{ output_dir }}/until_counter"
|
||||
content: 3
|
||||
|
||||
- shell_no_failed:
|
||||
cmd: |
|
||||
COUNTER=$(cat "{{ output_dir }}/until_counter"); NEW=$(expr $COUNTER - 1); echo $NEW > "{{ output_dir }}/until_counter"; exit $COUNTER
|
||||
register: counter
|
||||
delay: 0.5
|
||||
until: counter.rc == 0
|
||||
|
|
|
@ -1,152 +0,0 @@
|
|||
#!powershell
|
||||
|
||||
# Copyright: (c) 2017, Dag Wieers (@dagwieers) <dag@wieers.com>
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
#AnsibleRequires -CSharpUtil Ansible.Basic
|
||||
#Requires -Module Ansible.ModuleUtils.ArgvParser
|
||||
#Requires -Module Ansible.ModuleUtils.CommandUtil
|
||||
|
||||
# See also: https://technet.microsoft.com/en-us/sysinternals/pxexec.aspx
|
||||
|
||||
$spec = @{
|
||||
options = @{
|
||||
command = @{ type='str'; required=$true }
|
||||
executable = @{ type='path'; default='psexec.exe' }
|
||||
hostnames = @{ type='list' }
|
||||
username = @{ type='str' }
|
||||
password = @{ type='str'; no_log=$true }
|
||||
chdir = @{ type='path' }
|
||||
wait = @{ type='bool'; default=$true }
|
||||
nobanner = @{ type='bool'; default=$false }
|
||||
noprofile = @{ type='bool'; default=$false }
|
||||
elevated = @{ type='bool'; default=$false }
|
||||
limited = @{ type='bool'; default=$false }
|
||||
system = @{ type='bool'; default=$false }
|
||||
interactive = @{ type='bool'; default=$false }
|
||||
session = @{ type='int' }
|
||||
priority = @{ type='str'; choices=@( 'background', 'low', 'belownormal', 'abovenormal', 'high', 'realtime' ) }
|
||||
timeout = @{ type='int' }
|
||||
}
|
||||
}
|
||||
|
||||
$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec)
|
||||
|
||||
$command = $module.Params.command
|
||||
$executable = $module.Params.executable
|
||||
$hostnames = $module.Params.hostnames
|
||||
$username = $module.Params.username
|
||||
$password = $module.Params.password
|
||||
$chdir = $module.Params.chdir
|
||||
$wait = $module.Params.wait
|
||||
$nobanner = $module.Params.nobanner
|
||||
$noprofile = $module.Params.noprofile
|
||||
$elevated = $module.Params.elevated
|
||||
$limited = $module.Params.limited
|
||||
$system = $module.Params.system
|
||||
$interactive = $module.Params.interactive
|
||||
$session = $module.Params.session
|
||||
$priority = $module.Params.Priority
|
||||
$timeout = $module.Params.timeout
|
||||
|
||||
$module.Result.changed = $true
|
||||
|
||||
If (-Not (Get-Command $executable -ErrorAction SilentlyContinue)) {
|
||||
$module.FailJson("Executable '$executable' was not found.")
|
||||
}
|
||||
|
||||
$arguments = [System.Collections.Generic.List`1[String]]@($executable)
|
||||
|
||||
If ($nobanner -eq $true) {
|
||||
$arguments.Add("-nobanner")
|
||||
}
|
||||
|
||||
# Support running on local system if no hostname is specified
|
||||
If ($hostnames) {
|
||||
$hostname_argument = ($hostnames | sort -Unique) -join ','
|
||||
$arguments.Add("\\$hostname_argument")
|
||||
}
|
||||
|
||||
# Username is optional
|
||||
If ($null -ne $username) {
|
||||
$arguments.Add("-u")
|
||||
$arguments.Add($username)
|
||||
}
|
||||
|
||||
# Password is optional
|
||||
If ($null -ne $password) {
|
||||
$arguments.Add("-p")
|
||||
$arguments.Add($password)
|
||||
}
|
||||
|
||||
If ($null -ne $chdir) {
|
||||
$arguments.Add("-w")
|
||||
$arguments.Add($chdir)
|
||||
}
|
||||
|
||||
If ($wait -eq $false) {
|
||||
$arguments.Add("-d")
|
||||
}
|
||||
|
||||
If ($noprofile -eq $true) {
|
||||
$arguments.Add("-e")
|
||||
}
|
||||
|
||||
If ($elevated -eq $true) {
|
||||
$arguments.Add("-h")
|
||||
}
|
||||
|
||||
If ($system -eq $true) {
|
||||
$arguments.Add("-s")
|
||||
}
|
||||
|
||||
If ($interactive -eq $true) {
|
||||
$arguments.Add("-i")
|
||||
If ($null -ne $session) {
|
||||
$arguments.Add($session)
|
||||
}
|
||||
}
|
||||
|
||||
If ($limited -eq $true) {
|
||||
$arguments.Add("-l")
|
||||
}
|
||||
|
||||
If ($null -ne $priority) {
|
||||
$arguments.Add("-$priority")
|
||||
}
|
||||
|
||||
If ($null -ne $timeout) {
|
||||
$arguments.Add("-n")
|
||||
$arguments.Add($timeout)
|
||||
}
|
||||
|
||||
$arguments.Add("-accepteula")
|
||||
|
||||
$argument_string = Argv-ToString -arguments $arguments
|
||||
|
||||
# Add the command at the end of the argument string, we don't want to escape
|
||||
# that as psexec doesn't expect it to be one arg
|
||||
$argument_string += " $command"
|
||||
|
||||
$start_datetime = [DateTime]::UtcNow
|
||||
$module.Result.psexec_command = $argument_string
|
||||
|
||||
$command_result = Run-Command -command $argument_string
|
||||
|
||||
$end_datetime = [DateTime]::UtcNow
|
||||
|
||||
$module.Result.stdout = $command_result.stdout
|
||||
$module.Result.stderr = $command_result.stderr
|
||||
|
||||
If ($wait -eq $true) {
|
||||
$module.Result.rc = $command_result.rc
|
||||
} else {
|
||||
$module.Result.rc = 0
|
||||
$module.Result.pid = $command_result.rc
|
||||
}
|
||||
|
||||
$module.Result.start = $start_datetime.ToString("yyyy-MM-dd hh:mm:ss.ffffff")
|
||||
$module.Result.end = $end_datetime.ToString("yyyy-MM-dd hh:mm:ss.ffffff")
|
||||
$module.Result.delta = $($end_datetime - $start_datetime).ToString("h\:mm\:ss\.ffffff")
|
||||
|
||||
$module.ExitJson()
|
|
@ -1,172 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright: 2017, Dag Wieers (@dagwieers) <dag@wieers.com>
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
ANSIBLE_METADATA = {'metadata_version': '1.1',
|
||||
'status': ['preview'],
|
||||
'supported_by': 'community'}
|
||||
|
||||
DOCUMENTATION = r'''
|
||||
---
|
||||
module: win_psexec
|
||||
version_added: '2.3'
|
||||
short_description: Runs commands (remotely) as another (privileged) user
|
||||
description:
|
||||
- Run commands (remotely) through the PsExec service.
|
||||
- Run commands as another (domain) user (with elevated privileges).
|
||||
requirements:
|
||||
- Microsoft PsExec
|
||||
options:
|
||||
command:
|
||||
description:
|
||||
- The command line to run through PsExec (limited to 260 characters).
|
||||
type: str
|
||||
required: yes
|
||||
executable:
|
||||
description:
|
||||
- The location of the PsExec utility (in case it is not located in your PATH).
|
||||
type: path
|
||||
default: psexec.exe
|
||||
hostnames:
|
||||
description:
|
||||
- The hostnames to run the command.
|
||||
- If not provided, the command is run locally.
|
||||
type: list
|
||||
username:
|
||||
description:
|
||||
- The (remote) user to run the command as.
|
||||
- If not provided, the current user is used.
|
||||
type: str
|
||||
password:
|
||||
description:
|
||||
- The password for the (remote) user to run the command as.
|
||||
- This is mandatory in order authenticate yourself.
|
||||
type: str
|
||||
chdir:
|
||||
description:
|
||||
- Run the command from this (remote) directory.
|
||||
type: path
|
||||
nobanner:
|
||||
description:
|
||||
- Do not display the startup banner and copyright message.
|
||||
- This only works for specific versions of the PsExec binary.
|
||||
type: bool
|
||||
default: no
|
||||
version_added: '2.4'
|
||||
noprofile:
|
||||
description:
|
||||
- Run the command without loading the account's profile.
|
||||
type: bool
|
||||
default: no
|
||||
elevated:
|
||||
description:
|
||||
- Run the command with elevated privileges.
|
||||
type: bool
|
||||
default: no
|
||||
interactive:
|
||||
description:
|
||||
- Run the program so that it interacts with the desktop on the remote system.
|
||||
type: bool
|
||||
default: no
|
||||
session:
|
||||
description:
|
||||
- Specifies the session ID to use.
|
||||
- This parameter works in conjunction with I(interactive).
|
||||
- It has no effect when I(interactive) is set to C(no).
|
||||
type: int
|
||||
version_added: '2.7'
|
||||
limited:
|
||||
description:
|
||||
- Run the command as limited user (strips the Administrators group and allows only privileges assigned to the Users group).
|
||||
type: bool
|
||||
default: no
|
||||
system:
|
||||
description:
|
||||
- Run the remote command in the System account.
|
||||
type: bool
|
||||
default: no
|
||||
priority:
|
||||
description:
|
||||
- Used to run the command at a different priority.
|
||||
choices: [ abovenormal, background, belownormal, high, low, realtime ]
|
||||
timeout:
|
||||
description:
|
||||
- The connection timeout in seconds
|
||||
type: int
|
||||
wait:
|
||||
description:
|
||||
- Wait for the application to terminate.
|
||||
- Only use for non-interactive applications.
|
||||
type: bool
|
||||
default: yes
|
||||
notes:
|
||||
- More information related to Microsoft PsExec is available from
|
||||
U(https://technet.microsoft.com/en-us/sysinternals/bb897553.aspx)
|
||||
seealso:
|
||||
- module: psexec
|
||||
- module: raw
|
||||
- module: win_command
|
||||
- module: win_shell
|
||||
author:
|
||||
- Dag Wieers (@dagwieers)
|
||||
'''
|
||||
|
||||
EXAMPLES = r'''
|
||||
- name: Test the PsExec connection to the local system (target node) with your user
|
||||
win_psexec:
|
||||
command: whoami.exe
|
||||
|
||||
- name: Run regedit.exe locally (on target node) as SYSTEM and interactively
|
||||
win_psexec:
|
||||
command: regedit.exe
|
||||
interactive: yes
|
||||
system: yes
|
||||
|
||||
- name: Run the setup.exe installer on multiple servers using the Domain Administrator
|
||||
win_psexec:
|
||||
command: E:\setup.exe /i /IACCEPTEULA
|
||||
hostnames:
|
||||
- remote_server1
|
||||
- remote_server2
|
||||
username: DOMAIN\Administrator
|
||||
password: some_password
|
||||
priority: high
|
||||
|
||||
- name: Run PsExec from custom location C:\Program Files\sysinternals\
|
||||
win_psexec:
|
||||
command: netsh advfirewall set allprofiles state off
|
||||
executable: C:\Program Files\sysinternals\psexec.exe
|
||||
hostnames: [ remote_server ]
|
||||
password: some_password
|
||||
priority: low
|
||||
'''
|
||||
|
||||
RETURN = r'''
|
||||
cmd:
|
||||
description: The complete command line used by the module, including PsExec call and additional options.
|
||||
returned: always
|
||||
type: str
|
||||
sample: psexec.exe -nobanner \\remote_server -u "DOMAIN\Administrator" -p "some_password" -accepteula E:\setup.exe
|
||||
pid:
|
||||
description: The PID of the async process created by PsExec.
|
||||
returned: when C(wait=False)
|
||||
type: int
|
||||
sample: 1532
|
||||
rc:
|
||||
description: The return code for the command.
|
||||
returned: always
|
||||
type: int
|
||||
sample: 0
|
||||
stdout:
|
||||
description: The standard output from the command.
|
||||
returned: always
|
||||
type: str
|
||||
sample: Success.
|
||||
stderr:
|
||||
description: The error output from the command.
|
||||
returned: always
|
||||
type: str
|
||||
sample: Error 15 running E:\setup.exe
|
||||
'''
|
Loading…
Reference in a new issue