summaryrefslogtreecommitdiffstats
path: root/test/integration/targets/win_exec_wrapper/tasks/main.yml
blob: 8fc54f7ca8fbe5547687dadf0dcd85897194bb6e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
---
- name: fetch current target date/time for log filtering
  raw: '[datetime]::now | Out-String'
  register: test_starttime

- name: test normal module execution
  test_fail:
  register: normal

- name: assert test normal module execution
  assert:
    that:
    - not normal is failed

- name: test fail module execution
  test_fail:
    data: fail
  register: fail_module
  ignore_errors: yes

- name: assert test fail module execution
  assert:
    that:
    - fail_module is failed
    - fail_module.msg == "fail message"
    - not fail_module.exception is defined

- name: test module with exception thrown
  test_fail:
    data: throw
  register: throw_module
  ignore_errors: yes

- name: assert test module with exception thrown
  assert:
    that:
    - throw_module is failed
    - 'throw_module.msg == "Unhandled exception while executing module: module is thrown"'
    - '"throw [ArgumentException]\"module is thrown\"" in throw_module.exception'

- name: test module with error msg
  test_fail:
    data: error
  register: error_module
  ignore_errors: yes
  vars:
    # Running with coverage means the module is run from a script and not as a psuedo script in a pipeline. This
    # results in a different error message being returned so we disable coverage collection for this task.
    _ansible_coverage_remote_output: ''

- name: assert test module with error msg
  assert:
    that:
    - error_module is failed
    - 'error_module.msg == "Unhandled exception while executing module: error"'
    - '"Write-Error -Message $data" in error_module.exception'

- name: test module with cmdlet error
  test_fail:
    data: cmdlet_error
  register: cmdlet_error
  ignore_errors: yes

- name: assert test module with cmdlet error
  assert:
    that:
    - cmdlet_error is failed
    - 'cmdlet_error.msg == "Unhandled exception while executing module: Cannot find drive. A drive with the name ''fake'' does not exist."'
    - '"Get-Item -Path \"fake:\\path\"" in cmdlet_error.exception'

- name: test module with .NET exception
  test_fail:
    data: dotnet_exception
  register: dotnet_exception
  ignore_errors: yes

- name: assert test module with .NET exception
  assert:
    that:
    - dotnet_exception is failed
    - 'dotnet_exception.msg == "Unhandled exception while executing module: Exception calling \"GetFullPath\" with \"1\" argument(s): \"The path is not of a legal form.\""'
    - '"[System.IO.Path]::GetFullPath($null)" in dotnet_exception.exception'

- name: test module with function exception
  test_fail:
    data: function_throw
  register: function_exception
  ignore_errors: yes
  vars:
    _ansible_coverage_remote_output: ''

- name: assert test module with function exception
  assert:
    that:
    - function_exception is failed
    - 'function_exception.msg == "Unhandled exception while executing module: exception in function"'
    - '"throw \"exception in function\"" in function_exception.exception'
    - '"at Test-ThrowException, <No file>: line" in function_exception.exception'

- name: test module with fail process but Exit-Json
  test_fail:
    data: proc_exit_fine
  register: proc_exit_fine

- name: assert test module with fail process but Exit-Json
  assert:
    that:
    - not proc_exit_fine is failed

- name: test module with fail process but Fail-Json
  test_fail:
    data: proc_exit_fail
  register: proc_exit_fail
  ignore_errors: yes

- name: assert test module with fail process but Fail-Json
  assert:
    that:
    - proc_exit_fail is failed
    - proc_exit_fail.msg == "proc_exit_fail"
    - not proc_exit_fail.exception is defined

- name: test out invalid options
  test_invalid_requires:
  register: invalid_options

- name: assert test out invalid options
  assert:
    that:
    - invalid_options is successful
    - invalid_options.output == "output"

- name: test out invalid os version
  test_min_os_version:
  register: invalid_os_version
  ignore_errors: yes

- name: assert test out invalid os version
  assert:
    that:
    - invalid_os_version is failed
    - '"This module cannot run on this OS as it requires a minimum version of 20.0, actual was " in invalid_os_version.msg'

- name: test out invalid powershell version
  test_min_ps_version:
  register: invalid_ps_version
  ignore_errors: yes

- name: assert test out invalid powershell version
  assert:
    that:
    - invalid_ps_version is failed
    - '"This module cannot run as it requires a minimum PowerShell version of 20.0.0.0, actual was " in invalid_ps_version.msg'

- name: test out environment block for task
  win_shell: set
  args:
    executable: cmd.exe
  environment:
    String: string value
    Int: 1234
    Bool: True
    double_quote: 'double " quote'
    single_quote: "single ' quote"
    hyphen-var: abc@123
    '_-(){}[]<>*+-/\?"''!@#$%^&|;:i,.`~0': '_-(){}[]<>*+-/\?"''!@#$%^&|;:i,.`~0'
    '‘key': 'value‚'
  register: environment_block

- name: assert environment block for task
  assert:
    that:
    - '"String=string value" in environment_block.stdout_lines'
    - '"Int=1234" in environment_block.stdout_lines'
    - '"Bool=True" in environment_block.stdout_lines'
    - '"double_quote=double \" quote" in environment_block.stdout_lines'
    - '"single_quote=single '' quote" in environment_block.stdout_lines'
    - '"hyphen-var=abc@123" in environment_block.stdout_lines'
    # yaml escaping rules - (\\ == \), (\" == "), ('' == ')
    - '"_-(){}[]<>*+-/\\?\"''!@#$%^&|;:i,.`~0=_-(){}[]<>*+-/\\?\"''!@#$%^&|;:i,.`~0" in environment_block.stdout_lines'
    - '"‘key=value‚" in environment_block.stdout_lines'

- name: test out become requires without become_user set
  test_all_options:
  register: become_system

- name: assert become requires without become_user set
  assert:
    that:
    - become_system is successful
    - become_system.output == "S-1-5-18"

- set_fact:
    become_test_username: ansible_become_test
    gen_pw: "{{ 'password123!' + lookup('password', '/dev/null chars=ascii_letters,digits length=8') }}"

- name: create unprivileged user
  win_user:
    name: "{{ become_test_username }}"
    password: "{{ gen_pw }}"
    update_password: always
    groups: Users
  register: become_test_user_result

- name: execute tests and ensure that test user is deleted regardless of success/failure
  block:
  - name: ensure current user is not the become user
    win_shell: whoami
    register: whoami_out

  - name: verify output
    assert:
      that:
      - not whoami_out.stdout_lines[0].endswith(become_test_username)

  - name: get become user profile dir so we can clean it up later
    vars: &become_vars
      ansible_become_user: "{{ become_test_username }}"
      ansible_become_password: "{{ gen_pw }}"
      ansible_become_method: runas
      ansible_become: yes
    win_shell: $env:USERPROFILE
    register: profile_dir_out

  - name: ensure profile dir contains test username (eg, if become fails silently, prevent deletion of real user profile)
    assert:
      that:
      - become_test_username in profile_dir_out.stdout_lines[0]

  - name: test out become requires when become_user set
    test_all_options:
    vars: *become_vars
    register: become_system

  - name: assert become requires when become_user set
    assert:
      that:
      - become_system is successful
      - become_system.output == become_test_user_result.sid

  always:
  - name: ensure test user is deleted
    win_user:
      name: "{{ become_test_username }}"
      state: absent

  - name: ensure test user profile is deleted
    # NB: have to work around powershell limitation of long filenames until win_file fixes it
    win_shell: rmdir /S /Q {{ profile_dir_out.stdout_lines[0] }}
    args:
      executable: cmd.exe
    when: become_test_username in profile_dir_out.stdout_lines[0]

- name: test common functions in exec
  test_common_functions:
  register: common_functions_res

- name: assert test common functions in exec
  assert:
    that:
    - not common_functions_res is failed
    - common_functions_res.msg == "good"

- name: get PS events containing module args or envvars created since test start
  raw: |
    $dt=[datetime]"{{ test_starttime.stdout|trim }}"
    (Get-WinEvent -LogName Microsoft-Windows-Powershell/Operational |
    ? { $_.TimeCreated -ge $dt -and $_.Message -match "fail_module|hyphen-var" }).Count
  register: ps_log_count

- name: assert no PS events contain module args or envvars
  assert:
    that:
    - ps_log_count.stdout | int == 0