mirror of https://github.com/ansible/ansible.git
win_dsc: improved parameter handling (#31556)
* win_dsc: improved parameter handling * removed uneeded try/catch leftover from testing * removed undeed return values * added custom DSC to fully test out casting * fix up codestyle issues * using new Requires ps version check * fixed up error message check on earlier ps versionpull/32582/head
parent
55bc8291d6
commit
978a979566
@ -1,4 +1,5 @@
|
|||||||
---
|
---
|
||||||
|
|
||||||
# Feature not normally installed by default.
|
# Feature not normally installed by default.
|
||||||
test_win_feature_name: Telnet-Client
|
test_win_dsc_feature_name: Telnet-Client
|
||||||
|
test_win_dsc_folder: C:\ansible test
|
||||||
|
test_win_dsc_run_desctructive: no
|
||||||
|
@ -0,0 +1,44 @@
|
|||||||
|
xTestResource Version: 2.0.0
|
||||||
|
|
||||||
|
Ensure:
|
||||||
|
Type: System.String
|
||||||
|
Value: Present
|
||||||
|
|
||||||
|
StringParam:
|
||||||
|
Type: System.String
|
||||||
|
Value: string param
|
||||||
|
|
||||||
|
UInt32Param:
|
||||||
|
Type: System.UInt32
|
||||||
|
Value: 1000
|
||||||
|
|
||||||
|
UInt64Param:
|
||||||
|
Type: System.UInt64
|
||||||
|
Value: 1000000
|
||||||
|
|
||||||
|
StringArrayParam:
|
||||||
|
Type: System.String[]
|
||||||
|
Value: [ "string 1", "string 2" ]
|
||||||
|
|
||||||
|
UInt32ArrayParam:
|
||||||
|
Type: System.UInt32[]
|
||||||
|
Value: [ 1000, 2000 ]
|
||||||
|
|
||||||
|
UInt64ArrayParam:
|
||||||
|
Type: System.UInt64[]
|
||||||
|
Value: [ 1000000, 2000000 ]
|
||||||
|
|
||||||
|
BooleanParam:
|
||||||
|
Type: System.Boolean
|
||||||
|
Value: True
|
||||||
|
|
||||||
|
PSCredentialParam:
|
||||||
|
Type: System.Management.Automation.PSCredential
|
||||||
|
Username: username
|
||||||
|
Password: password
|
||||||
|
|
||||||
|
CimInstanceParam:
|
||||||
|
Type: Microsoft.Management.Infrastructure.CimInstance
|
||||||
|
|
||||||
|
CimInstanceArrayParam:
|
||||||
|
Type: Microsoft.Management.Infrastructure.CimInstance[]
|
@ -0,0 +1,44 @@
|
|||||||
|
xTestResource Version: 1.0.0
|
||||||
|
|
||||||
|
Ensure:
|
||||||
|
Type: System.String
|
||||||
|
Value: Present
|
||||||
|
|
||||||
|
StringParam:
|
||||||
|
Type: System.String
|
||||||
|
Value: string param
|
||||||
|
|
||||||
|
UInt32Param:
|
||||||
|
Type: System.UInt32
|
||||||
|
Value: 1000
|
||||||
|
|
||||||
|
UInt64Param:
|
||||||
|
Type: System.UInt64
|
||||||
|
Value: 1000000
|
||||||
|
|
||||||
|
StringArrayParam:
|
||||||
|
Type: System.String[]
|
||||||
|
Value: [ "string 1", "string 2" ]
|
||||||
|
|
||||||
|
UInt32ArrayParam:
|
||||||
|
Type: System.UInt32[]
|
||||||
|
Value: [ 1000, 2000 ]
|
||||||
|
|
||||||
|
UInt64ArrayParam:
|
||||||
|
Type: System.UInt64[]
|
||||||
|
Value: [ 1000000, 2000000 ]
|
||||||
|
|
||||||
|
BooleanParam:
|
||||||
|
Type: System.Boolean
|
||||||
|
Value: True
|
||||||
|
|
||||||
|
PSCredentialParam:
|
||||||
|
Type: System.Management.Automation.PSCredential
|
||||||
|
Username: username
|
||||||
|
Password: password
|
||||||
|
|
||||||
|
CimInstanceParam:
|
||||||
|
Type: Microsoft.Management.Infrastructure.CimInstance
|
||||||
|
|
||||||
|
CimInstanceArrayParam:
|
||||||
|
Type: Microsoft.Management.Infrastructure.CimInstance[]
|
@ -0,0 +1,16 @@
|
|||||||
|
# (c) 2017 Red Hat, Inc.
|
||||||
|
#
|
||||||
|
# This file is part of Ansible
|
||||||
|
|
||||||
|
|
||||||
|
class FilterModule(object):
|
||||||
|
def filters(self):
|
||||||
|
return {
|
||||||
|
'strip_newline': self.strip_newline
|
||||||
|
}
|
||||||
|
|
||||||
|
def strip_newline(self, value):
|
||||||
|
# will convert \r\n and \n to just \n
|
||||||
|
split_lines = value.splitlines()
|
||||||
|
|
||||||
|
return "\n".join(split_lines)
|
@ -0,0 +1,41 @@
|
|||||||
|
#!powershell
|
||||||
|
# This file is part of Ansible
|
||||||
|
|
||||||
|
# Copyright (c) 2017 Ansible Project
|
||||||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
|
#Requires -Module Ansible.ModuleUtils.Legacy
|
||||||
|
|
||||||
|
Import-Module -Name WebAdministration
|
||||||
|
$params = Parse-Args $args -supports_check_mode $true
|
||||||
|
$name = Get-AnsibleParam -obj $params -name "name" -type "str" -failifempty $true
|
||||||
|
|
||||||
|
$site = Get-Website -Name $name
|
||||||
|
|
||||||
|
$result = @{}
|
||||||
|
if ($site -eq $null) {
|
||||||
|
$result.exists = $false
|
||||||
|
} else {
|
||||||
|
$result.exists = $true
|
||||||
|
$site_config = Get-WebConfiguration -Filter "System.WebServer/Security/Authentication/*" -PSPath "IIS:\Sites\$name"
|
||||||
|
$http_bindings = $site.bindings.Collection | Where-Object { $_.protocol -eq "http" }
|
||||||
|
$https_bindings = $site.bindings.Collection | Where-Object { $_.protocol -eq "https" }
|
||||||
|
|
||||||
|
$result.http = @{
|
||||||
|
binding = $http_bindings.bindingInformation
|
||||||
|
}
|
||||||
|
$result.https = @{
|
||||||
|
binding = $https_bindings.bindingInformation
|
||||||
|
sslFlags = $https_bindings.sslFlags
|
||||||
|
store = ($https_bindings.Attributes | Where-Object { $_.Name -eq "certificateStoreName" }).Value
|
||||||
|
hash = ($https_bindings.Attributes | Where-Object { $_.Name -eq "certificateHash" }).Value
|
||||||
|
}
|
||||||
|
$result.auth = @{
|
||||||
|
anonymous = ($site_config | Where-Object { $_.ElementTagName -like "*anonymous*" }).enabled
|
||||||
|
basic = ($site_config | Where-Object { $_.ElementTagName -like "*basic*" }).enabled
|
||||||
|
digest = ($site_config | Where-Object { $_.ElementTagName -like "*digest*" }).enabled
|
||||||
|
windows = ($site_config | Where-Object { $_.ElementTagName -like "*windows*" }).enabled
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Exit-Json -obj $result
|
@ -0,0 +1,135 @@
|
|||||||
|
# these tests are destructive and can be run manually on a throwaway host
|
||||||
|
# set test_win_dsc_run_desctructive: yes in default/main.yml
|
||||||
|
---
|
||||||
|
- name: ensure IIS features are installed
|
||||||
|
win_feature:
|
||||||
|
name: Web-Server
|
||||||
|
include_sub_features: yes
|
||||||
|
include_management_tools: no
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: install xWebAdministration module
|
||||||
|
win_psmodule:
|
||||||
|
name: xWebAdministration
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: ensure IIS website does not exists
|
||||||
|
win_iis_website:
|
||||||
|
name: Ansible DSC Test
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: get certificate hash for IIS test
|
||||||
|
win_shell: (Get-ChildItem -Path Cert:\LocalMachine\My)[0].Thumbprint
|
||||||
|
register: win_dsc_cert_thumbprint
|
||||||
|
|
||||||
|
- name: create an IIS website with auth and binding info (check mode)
|
||||||
|
win_dsc:
|
||||||
|
resource_name: xWebSite
|
||||||
|
Ensure: Present
|
||||||
|
Name: Ansible DSC Test
|
||||||
|
State: Started
|
||||||
|
PhysicalPath: C:\inetpub\wwwroot
|
||||||
|
BindingInfo:
|
||||||
|
- Protocol: https
|
||||||
|
Port: 8443
|
||||||
|
CertificateStoreName: MY
|
||||||
|
CertificateThumbprint: '{{win_dsc_cert_thumbprint.stdout_lines[0]}}'
|
||||||
|
HostName: DSCTest
|
||||||
|
IPAddress: '*'
|
||||||
|
SSLFlags: '1'
|
||||||
|
- Protocol: http
|
||||||
|
Port: 8888
|
||||||
|
IPAddress: '*'
|
||||||
|
AuthenticationInfo:
|
||||||
|
Anonymous: yes
|
||||||
|
Basic: no
|
||||||
|
Digest: no
|
||||||
|
Windows: yes
|
||||||
|
register: win_dsc_iis_check
|
||||||
|
check_mode: yes
|
||||||
|
|
||||||
|
- name: get result of create an IIS website (check mode)
|
||||||
|
test_win_dsc_iis_info:
|
||||||
|
name: Ansible DSC Test
|
||||||
|
register: win_dsc_iis_check_result
|
||||||
|
|
||||||
|
- name: assert results of create an IIS website (check mode)
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- win_dsc_iis_check|changed
|
||||||
|
- win_dsc_iis_check_result.exists == False
|
||||||
|
|
||||||
|
- name: create an IIS website with auth and binding info
|
||||||
|
win_dsc:
|
||||||
|
resource_name: xWebSite
|
||||||
|
Ensure: Present
|
||||||
|
Name: Ansible DSC Test
|
||||||
|
State: Started
|
||||||
|
PhysicalPath: C:\inetpub\wwwroot
|
||||||
|
BindingInfo:
|
||||||
|
- Protocol: https
|
||||||
|
Port: 8443
|
||||||
|
CertificateStoreName: MY
|
||||||
|
CertificateThumbprint: '{{win_dsc_cert_thumbprint.stdout_lines[0]}}'
|
||||||
|
HostName: Test
|
||||||
|
IPAddress: '*'
|
||||||
|
SSLFlags: '1'
|
||||||
|
- Protocol: http
|
||||||
|
Port: 8888
|
||||||
|
IPAddress: '*'
|
||||||
|
AuthenticationInfo:
|
||||||
|
Anonymous: yes
|
||||||
|
Basic: no
|
||||||
|
Digest: no
|
||||||
|
Windows: yes
|
||||||
|
register: win_dsc_iis
|
||||||
|
|
||||||
|
- name: get result of create an IIS website
|
||||||
|
test_win_dsc_iis_info:
|
||||||
|
name: Ansible DSC Test
|
||||||
|
register: win_dsc_iis_result
|
||||||
|
|
||||||
|
- name: assert results of create an IIS website
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- win_dsc_iis|changed
|
||||||
|
- win_dsc_iis_result.exists == True
|
||||||
|
- win_dsc_iis_result.auth.anonymous == True
|
||||||
|
- win_dsc_iis_result.auth.basic == False
|
||||||
|
- win_dsc_iis_result.auth.digest == False
|
||||||
|
- win_dsc_iis_result.auth.windows == True
|
||||||
|
- win_dsc_iis_result.http.binding == "*:8888:"
|
||||||
|
- win_dsc_iis_result.https.binding == "*:8443:Test"
|
||||||
|
- win_dsc_iis_result.https.hash == '{{win_dsc_cert_thumbprint.stdout_lines[0]}}'
|
||||||
|
- win_dsc_iis_result.https.sslFlags == 1
|
||||||
|
- win_dsc_iis_result.https.store == "MY"
|
||||||
|
|
||||||
|
- name: create an IIS website with auth and binding info (idempotent)
|
||||||
|
win_dsc:
|
||||||
|
resource_name: xWebSite
|
||||||
|
Ensure: Present
|
||||||
|
Name: Ansible DSC Test
|
||||||
|
State: Started
|
||||||
|
PhysicalPath: C:\inetpub\wwwroot
|
||||||
|
BindingInfo:
|
||||||
|
- Protocol: https
|
||||||
|
Port: 8443
|
||||||
|
CertificateStoreName: MY
|
||||||
|
CertificateThumbprint: '{{win_dsc_cert_thumbprint.stdout_lines[0]}}'
|
||||||
|
HostName: Test
|
||||||
|
IPAddress: '*'
|
||||||
|
SSLFlags: '1'
|
||||||
|
- Protocol: http
|
||||||
|
Port: 8888
|
||||||
|
IPAddress: '*'
|
||||||
|
AuthenticationInfo:
|
||||||
|
Anonymous: yes
|
||||||
|
Basic: no
|
||||||
|
Digest: no
|
||||||
|
Windows: yes
|
||||||
|
register: win_dsc_iis_again
|
||||||
|
|
||||||
|
- name: assert results of create an IIS website (idempotent)
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- not win_dsc_iis_again|changed
|
@ -1,119 +1,34 @@
|
|||||||
# test code for the win_feature module
|
---
|
||||||
# (c) 2014, Chris Church <chris@ninemoreminutes.com>
|
- name: get powershell version
|
||||||
|
win_shell: $PSVersionTable.PSVersion.Major
|
||||||
|
register: powershell_version
|
||||||
|
|
||||||
# This file is part of Ansible
|
- name: run smoke tests when we can't run the full suite
|
||||||
#
|
include_tasks: smoke.yml
|
||||||
# Ansible is free software: you can redistribute it and/or modify
|
when: powershell_version.stdout_lines[0]|int < 5
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# Ansible is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
|
- block:
|
||||||
|
- name: run non-destructive tests
|
||||||
|
include_tasks: tests.yml
|
||||||
|
|
||||||
- name: check whether servermanager module is available (windows 2008 r2 or later)
|
- name: run destructive tests if flag is set
|
||||||
raw: PowerShell -Command Import-Module ServerManager
|
include_tasks: destructive.yml
|
||||||
register: win_feature_has_servermanager
|
when: test_win_dsc_run_desctructive == True
|
||||||
ignore_errors: true
|
|
||||||
|
|
||||||
|
always:
|
||||||
- name: start with feature absent
|
- name: remove test feature
|
||||||
win_feature:
|
win_feature:
|
||||||
name: "{{ test_win_feature_name }}"
|
name: '{{test_win_dsc_feature_name}}'
|
||||||
state: absent
|
state: absent
|
||||||
when: (win_feature_has_servermanager|success) and (ansible_powershell_version is defined) and (ansible_powershell_version >= 5)
|
|
||||||
|
|
||||||
- name: Invoke DSC with check mode
|
|
||||||
win_dsc:
|
|
||||||
resource_name: windowsfeature
|
|
||||||
name: "{{ test_win_feature_name }}"
|
|
||||||
check_mode: yes
|
|
||||||
register: win_dsc_checkmode_result
|
|
||||||
when: (win_feature_has_servermanager|success) and (ansible_powershell_version is defined) and (ansible_powershell_version >= 5)
|
|
||||||
|
|
||||||
- name: check result of Invoke DSC with check mode
|
|
||||||
assert:
|
|
||||||
that:
|
|
||||||
- "win_dsc_checkmode_result|changed"
|
|
||||||
- "win_dsc_checkmode_result|success"
|
|
||||||
when: (win_feature_has_servermanager|success) and (ansible_powershell_version is defined) and (ansible_powershell_version >= 5)
|
|
||||||
|
|
||||||
- name: Make sure the feature is still absent
|
|
||||||
win_dsc:
|
|
||||||
resource_name: windowsfeature
|
|
||||||
name: "{{ test_win_feature_name }}"
|
|
||||||
ensure: absent
|
|
||||||
register: win_dsc_1_result
|
|
||||||
when: (win_feature_has_servermanager|success) and (ansible_powershell_version is defined) and (ansible_powershell_version >= 5)
|
|
||||||
|
|
||||||
- name: check result of Make sure the feature is still absent
|
|
||||||
assert:
|
|
||||||
that:
|
|
||||||
- "not win_dsc_1_result|changed"
|
|
||||||
- "win_dsc_1_result|success"
|
|
||||||
when: (win_feature_has_servermanager|success) and (ansible_powershell_version is defined) and (ansible_powershell_version >= 5)
|
|
||||||
|
|
||||||
- name: Install feature for realz
|
|
||||||
win_dsc:
|
|
||||||
resource_name: windowsfeature
|
|
||||||
name: "{{ test_win_feature_name }}"
|
|
||||||
register: win_dsc_2_result
|
|
||||||
when: (win_feature_has_servermanager|success) and (ansible_powershell_version is defined) and (ansible_powershell_version >= 5)
|
|
||||||
|
|
||||||
- name: check result of Install feature for realz
|
- name: remove test folder
|
||||||
assert:
|
win_file:
|
||||||
that:
|
path: '{{test_win_dsc_folder}}'
|
||||||
- "win_dsc_2_result|changed"
|
state: absent
|
||||||
- "win_dsc_2_result|success"
|
|
||||||
when: (win_feature_has_servermanager|success) and (ansible_powershell_version is defined) and (ansible_powershell_version >= 5)
|
|
||||||
|
|
||||||
- name: Ensure clean failure
|
|
||||||
win_dsc:
|
|
||||||
resource_name: some_unknown_resource_that_wont_ever_exist
|
|
||||||
name: "{{ test_win_feature_name }}"
|
|
||||||
register: win_dsc_3_result
|
|
||||||
ignore_errors: true
|
|
||||||
when: (win_feature_has_servermanager|success) and (ansible_powershell_version is defined) and (ansible_powershell_version >= 5)
|
|
||||||
|
|
||||||
- name: check result of Ensure clean failure
|
|
||||||
assert:
|
|
||||||
that:
|
|
||||||
- "not win_dsc_3_result|changed"
|
|
||||||
- "not win_dsc_3_result|success"
|
|
||||||
when: (win_feature_has_servermanager|success) and (ansible_powershell_version is defined) and (ansible_powershell_version >= 5)
|
|
||||||
|
|
||||||
- name: Make sure the feature is absent
|
|
||||||
win_dsc:
|
|
||||||
resource_name: windowsfeature
|
|
||||||
name: "{{ test_win_feature_name }}"
|
|
||||||
ensure: absent
|
|
||||||
register: win_dsc_4_result
|
|
||||||
when: (win_feature_has_servermanager|success) and (ansible_powershell_version is defined) and (ansible_powershell_version >= 5)
|
|
||||||
|
|
||||||
- name: check result of Make sure the feature is absent
|
|
||||||
assert:
|
|
||||||
that:
|
|
||||||
- "win_dsc_4_result|changed"
|
|
||||||
- "win_dsc_4_result|success"
|
|
||||||
when: (win_feature_has_servermanager|success) and (ansible_powershell_version is defined) and (ansible_powershell_version >= 5)
|
|
||||||
|
|
||||||
- name: Make sure the feature is still absent with no changes
|
- name: remove custom DSC resource folder
|
||||||
win_dsc:
|
win_file:
|
||||||
resource_name: windowsfeature
|
path: C:\Program Files\WindowsPowerShell\Modules\xTestDsc
|
||||||
name: "{{ test_win_feature_name }}"
|
state: absent
|
||||||
ensure: absent
|
|
||||||
register: win_dsc_5_result
|
|
||||||
when: (win_feature_has_servermanager|success) and (ansible_powershell_version is defined) and (ansible_powershell_version >= 5)
|
|
||||||
|
|
||||||
- name: check result of Make sure the feature is absent
|
when: powershell_version.stdout_lines[0]|int >= 5
|
||||||
assert:
|
|
||||||
that:
|
|
||||||
- "not win_dsc_5_result|changed"
|
|
||||||
- "win_dsc_5_result|success"
|
|
||||||
when: (win_feature_has_servermanager|success) and (ansible_powershell_version is defined) and (ansible_powershell_version >= 5)
|
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
# basic smoke tests run on hosts that cannot run DSC, verifies the code is at
|
||||||
|
# least runnable
|
||||||
|
---
|
||||||
|
- name: expect failure when running on old PS hosts
|
||||||
|
win_dsc:
|
||||||
|
resource_name: File
|
||||||
|
register: fail_dsc_old
|
||||||
|
failed_when: '"This module cannot run as it requires a minimum PowerShell version of 5.0, actual was " not in fail_dsc_old.msg'
|
@ -0,0 +1,330 @@
|
|||||||
|
# slightly non-destructive tests that will run if WMF 5.0 is installed
|
||||||
|
---
|
||||||
|
- name: start with feature absent
|
||||||
|
win_feature:
|
||||||
|
name: '{{test_win_dsc_feature_name}}'
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: fail with incorrect DSC resource name
|
||||||
|
win_dsc:
|
||||||
|
resource_name: FakeResource
|
||||||
|
Name: fake
|
||||||
|
register: fail_invalid_resource
|
||||||
|
failed_when: fail_invalid_resource.msg != "Resource FakeResource not found"
|
||||||
|
|
||||||
|
- name: fail by not setting mandatory option
|
||||||
|
win_dsc:
|
||||||
|
resource_name: WindowsFeature
|
||||||
|
Ensure: Present
|
||||||
|
register: fail_missing_mandatory
|
||||||
|
failed_when: fail_missing_mandatory.msg != "Could not find mandatory property Name. Add this property and try again."
|
||||||
|
|
||||||
|
- name: fail to add a non-existant feature
|
||||||
|
win_dsc:
|
||||||
|
resource_name: WindowsFeature
|
||||||
|
Name: InvalidFeature
|
||||||
|
Ensure: Present
|
||||||
|
register: fail_invalid_feature
|
||||||
|
failed_when: '"The requested feature InvalidFeature is not found on the target machine" not in fail_invalid_feature.msg'
|
||||||
|
|
||||||
|
- name: add Windows feature (check mode)
|
||||||
|
win_dsc:
|
||||||
|
resource_name: WindowsFeature
|
||||||
|
Name: '{{test_win_dsc_feature_name}}'
|
||||||
|
Ensure: Present
|
||||||
|
register: win_dsc_add_feature_check
|
||||||
|
check_mode: yes
|
||||||
|
|
||||||
|
- name: get result of add Windows feature (check mode)
|
||||||
|
win_shell: (Get-WindowsFeature -Name {{test_win_dsc_feature_name}}).Installed
|
||||||
|
register: win_dsc_add_feature_result_check
|
||||||
|
|
||||||
|
- name: assert result of add Windows feature (check mode)
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- win_dsc_add_feature_check|changed
|
||||||
|
- win_dsc_add_feature_result_check.stdout == "False\r\n"
|
||||||
|
|
||||||
|
- name: add Windows feature
|
||||||
|
win_dsc:
|
||||||
|
resource_name: WindowsFeature
|
||||||
|
Name: '{{test_win_dsc_feature_name}}'
|
||||||
|
Ensure: Present
|
||||||
|
register: win_dsc_add_feature
|
||||||
|
|
||||||
|
- name: get result of add Windows feature
|
||||||
|
win_shell: (Get-WindowsFeature -Name {{test_win_dsc_feature_name}}).Installed
|
||||||
|
register: win_dsc_add_feature_result
|
||||||
|
|
||||||
|
- name: assert result of add Windows feature
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- win_dsc_add_feature|changed
|
||||||
|
- win_dsc_add_feature_result.stdout == "True\r\n"
|
||||||
|
|
||||||
|
- name: add Windows feature (idempotent)
|
||||||
|
win_dsc:
|
||||||
|
resource_name: WindowsFeature
|
||||||
|
Name: '{{test_win_dsc_feature_name}}'
|
||||||
|
Ensure: Present
|
||||||
|
register: win_dsc_add_feature_again
|
||||||
|
|
||||||
|
- name: assert result of add Windows feature (idempotent)
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- not win_dsc_add_feature_again|changed
|
||||||
|
|
||||||
|
- name: remove Windows feature (check mode)
|
||||||
|
win_dsc:
|
||||||
|
resource_name: WindowsFeature
|
||||||
|
Name: '{{test_win_dsc_feature_name}}'
|
||||||
|
Ensure: Absent
|
||||||
|
register: win_dsc_remove_feature_check
|
||||||
|
check_mode: yes
|
||||||
|
|
||||||
|
- name: get result of remove Windows feature (check mode)
|
||||||
|
win_shell: (Get-WindowsFeature -Name {{test_win_dsc_feature_name}}).Installed
|
||||||
|
register: win_dsc_remove_feature_result_check
|
||||||
|
|
||||||
|
- name: assert result of remove Windows feature (check mode)
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- win_dsc_remove_feature_check|changed
|
||||||
|
- win_dsc_remove_feature_result_check.stdout == "True\r\n"
|
||||||
|
|
||||||
|
- name: remove Windows feature
|
||||||
|
win_dsc:
|
||||||
|
resource_name: WindowsFeature
|
||||||
|
Name: '{{test_win_dsc_feature_name}}'
|
||||||
|
Ensure: Absent
|
||||||
|
register: win_dsc_remove_feature
|
||||||
|
|
||||||
|
- name: get result of remove Windows feature
|
||||||
|
win_shell: (Get-WindowsFeature -Name {{test_win_dsc_feature_name}}).Installed
|
||||||
|
register: win_dsc_remove_feature_result
|
||||||
|
|
||||||
|
- name: assert result of remove Windows feature
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- win_dsc_remove_feature|changed
|
||||||
|
- win_dsc_remove_feature_result.stdout == "False\r\n"
|
||||||
|
|
||||||
|
- name: remove Windows feature (idempotent)
|
||||||
|
win_dsc:
|
||||||
|
resource_name: WindowsFeature
|
||||||
|
Name: '{{test_win_dsc_feature_name}}'
|
||||||
|
Ensure: Absent
|
||||||
|
register: win_dsc_remove_feature_again
|
||||||
|
|
||||||
|
- name: assert result of remove Windows feature (idempotent)
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- not win_dsc_remove_feature_again|changed
|
||||||
|
|
||||||
|
- name: ensure test folder doesn't exist before test
|
||||||
|
win_file:
|
||||||
|
path: '{{test_win_dsc_folder}}'
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: create test file (check mode)
|
||||||
|
win_dsc:
|
||||||
|
resource_name: File
|
||||||
|
DestinationPath: '{{test_win_dsc_folder}}\dsc-file'
|
||||||
|
Contents: file contents
|
||||||
|
Attributes:
|
||||||
|
- Hidden
|
||||||
|
- ReadOnly
|
||||||
|
Ensure: Present
|
||||||
|
Type: File
|
||||||
|
register: win_dsc_create_file_check
|
||||||
|
check_mode: yes
|
||||||
|
|
||||||
|
- name: get result of create test file (check mode)
|
||||||
|
win_stat:
|
||||||
|
path: '{{test_win_dsc_folder}}\dsc-file'
|
||||||
|
register: win_dsc_create_file_result_check
|
||||||
|
|
||||||
|
- name: assert results of create test file (check mode)
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- win_dsc_create_file_check|changed
|
||||||
|
- win_dsc_create_file_result_check.stat.exists == False
|
||||||
|
|
||||||
|
- name: create test file
|
||||||
|
win_dsc:
|
||||||
|
resource_name: File
|
||||||
|
DestinationPath: '{{test_win_dsc_folder}}\dsc-file'
|
||||||
|
Contents: file contents
|
||||||
|
Attributes:
|
||||||
|
- Hidden
|
||||||
|
- ReadOnly
|
||||||
|
Ensure: Present
|
||||||
|
Type: File
|
||||||
|
register: win_dsc_create_file
|
||||||
|
|
||||||
|
- name: get result of create test file
|
||||||
|
win_stat:
|
||||||
|
path: '{{test_win_dsc_folder}}\dsc-file'
|
||||||
|
register: win_dsc_create_file_result
|
||||||
|
|
||||||
|
- name: assert results of create test file
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- win_dsc_create_file|changed
|
||||||
|
- win_dsc_create_file_result.stat.exists == True
|
||||||
|
- win_dsc_create_file_result.stat.isdir == False
|
||||||
|
- win_dsc_create_file_result.stat.ishidden == True
|
||||||
|
- win_dsc_create_file_result.stat.isreadonly == True
|
||||||
|
|
||||||
|
- name: create test file (idempotent)
|
||||||
|
win_dsc:
|
||||||
|
resource_name: File
|
||||||
|
DestinationPath: '{{test_win_dsc_folder}}\dsc-file'
|
||||||
|
Contents: file contents
|
||||||
|
Attributes: Hidden, ReadOnly
|
||||||
|
Ensure: Present
|
||||||
|
Type: File
|
||||||
|
register: win_dsc_create_file_again
|
||||||
|
|
||||||
|
- name: assert results of create test file (idempotent)
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- not win_dsc_create_file_again|changed
|
||||||
|
|
||||||
|
- name: get SID of current ansible user
|
||||||
|
win_shell: (New-Object System.Security.Principal.NTAccount("{{ansible_user}}")).Translate([System.Security.Principal.SecurityIdentifier]).ToString()
|
||||||
|
register: win_dsc_actual_sid
|
||||||
|
|
||||||
|
- name: run DSC process as another user
|
||||||
|
win_dsc:
|
||||||
|
resource_name: Script
|
||||||
|
GetScript: '@{ Result = "" }'
|
||||||
|
SetScript: |
|
||||||
|
$output = &whoami.exe
|
||||||
|
$sid = (New-Object System.Security.Principal.NTAccount($output)).Translate([System.Security.Principal.SecurityIdentifier]).ToString()
|
||||||
|
Set-Content -Path "{{test_win_dsc_folder}}\file" -Value $sid
|
||||||
|
TestScript: Test-Path -Path "{{test_win_dsc_folder}}\file"
|
||||||
|
PsDscRunAsCredential_username: '{{ansible_user}}'
|
||||||
|
PsDscRunAsCredential_password: '{{ansible_password}}'
|
||||||
|
register: win_dsc_runas
|
||||||
|
|
||||||
|
- name: get content of script output file
|
||||||
|
slurp:
|
||||||
|
path: '{{test_win_dsc_folder}}\file'
|
||||||
|
register: win_dsc_runas_result
|
||||||
|
|
||||||
|
- name: assert results of run DSC process as another user
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- win_dsc_runas|changed
|
||||||
|
- win_dsc_runas_result.content|b64decode == win_dsc_actual_sid.stdout
|
||||||
|
|
||||||
|
- name: create custom DSC resource folder
|
||||||
|
win_file:
|
||||||
|
path: C:\Program Files\WindowsPowerShell\Modules\xTestDsc\{{item}}\DSCResources\ANSIBLE_xTestResource
|
||||||
|
state: directory
|
||||||
|
with_items:
|
||||||
|
- "1.0.0"
|
||||||
|
- "2.0.0"
|
||||||
|
|
||||||
|
- name: template custom DSC resource files
|
||||||
|
win_template:
|
||||||
|
src: '{{item.src}}'
|
||||||
|
dest: C:\Program Files\WindowsPowerShell\Modules\xTestDsc\{{item.version}}\{{item.dest}}
|
||||||
|
with_items:
|
||||||
|
- src: ANSIBLE_xTestResource.schema.mof
|
||||||
|
dest: DSCResources\ANSIBLE_xTestResource\ANSIBLE_xTestResource.schema.mof
|
||||||
|
version: "1.0.0"
|
||||||
|
- src: ANSIBLE_xTestResource.psm1
|
||||||
|
dest: DSCResources\ANSIBLE_xTestResource\ANSIBLE_xTestResource.psm1
|
||||||
|
version: "1.0.0"
|
||||||
|
- src: xTestDsc.psd1
|
||||||
|
dest: xTestDsc.psd1
|
||||||
|
version: "1.0.0"
|
||||||
|
- src: ANSIBLE_xTestResource.schema.mof
|
||||||
|
dest: DSCResources\ANSIBLE_xTestResource\ANSIBLE_xTestResource.schema.mof
|
||||||
|
version: "2.0.0"
|
||||||
|
- src: ANSIBLE_xTestResource.psm1
|
||||||
|
dest: DSCResources\ANSIBLE_xTestResource\ANSIBLE_xTestResource.psm1
|
||||||
|
version: "2.0.0"
|
||||||
|
- src: xTestDsc.psd1
|
||||||
|
dest: xTestDsc.psd1
|
||||||
|
version: "2.0.0"
|
||||||
|
|
||||||
|
- name: run custom DSC resource
|
||||||
|
win_dsc: &dsc_params
|
||||||
|
resource_name: xTestResource
|
||||||
|
Path: '{{test_win_dsc_folder}}\custom-output.txt'
|
||||||
|
Ensure: Present
|
||||||
|
StringParam: string param
|
||||||
|
UInt32Param: 1000
|
||||||
|
UInt64Param: 1000000
|
||||||
|
StringArrayParam:
|
||||||
|
- string 1
|
||||||
|
- string 2
|
||||||
|
UInt32ArrayParam:
|
||||||
|
- 1000
|
||||||
|
- 2000
|
||||||
|
UInt64ArrayParam:
|
||||||
|
- 1000000
|
||||||
|
- 2000000
|
||||||
|
BooleanParam: yes
|
||||||
|
PSCredentialParam_username: username
|
||||||
|
PSCredentialParam_password: password
|
||||||
|
CimInstanceParam:
|
||||||
|
StringKey: a
|
||||||
|
BooleanKey: yes
|
||||||
|
UInt32Key: 1
|
||||||
|
StringArrayKey:
|
||||||
|
- string 1
|
||||||
|
- string 2
|
||||||
|
CimInstanceArrayParam:
|
||||||
|
- StringKey: b
|
||||||
|
BooleanKey: no
|
||||||
|
UInt32Key: 2
|
||||||
|
StringArrayKey:
|
||||||
|
- string 3
|
||||||
|
- string 4
|
||||||
|
- StringKey: c
|
||||||
|
BooleanKey: no
|
||||||
|
UInt32Key: 3
|
||||||
|
StringArrayKey:
|
||||||
|
- string 5
|
||||||
|
- string 6
|
||||||
|
register: test_dsc_custom
|
||||||
|
|
||||||
|
- name: get output of custom DSC resource
|
||||||
|
slurp:
|
||||||
|
path: '{{test_win_dsc_folder}}\custom-output.txt'
|
||||||
|
register: test_dsc_custom_output
|
||||||
|
|
||||||
|
- name: get expected output of custom DSC resource
|
||||||
|
set_fact:
|
||||||
|
test_dsc_custom_expected: '{{lookup("file", "custom-result-normal.txt")}}'
|
||||||
|
|
||||||
|
- name: assert result of custom DSC resource
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- test_dsc_custom|changed
|
||||||
|
- test_dsc_custom_output.content|b64decode|strip_newline == test_dsc_custom_expected|strip_newline
|
||||||
|
|
||||||
|
- name: run custom DSC resource with version
|
||||||
|
win_dsc:
|
||||||
|
<<: *dsc_params
|
||||||
|
module_version: '1.0.0'
|
||||||
|
register: test_dsc_custom_version
|
||||||
|
|
||||||
|
- name: get output of custom DSC resource with version
|
||||||
|
slurp:
|
||||||
|
path: '{{test_win_dsc_folder}}\custom-output.txt'
|
||||||
|
register: test_dsc_custom_output_version
|
||||||
|
|
||||||
|
- name: get expected output of custom DSC resource with version
|
||||||
|
set_fact:
|
||||||
|
test_dsc_custom_expected_version: '{{lookup("file", "custom-result-versioned.txt")}}'
|
||||||
|
|
||||||
|
- name: assert result of custom DSC resource with version
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- test_dsc_custom|changed
|
||||||
|
- test_dsc_custom_output_version.content|b64decode|strip_newline == test_dsc_custom_expected_version|strip_newline
|
@ -0,0 +1,173 @@
|
|||||||
|
#Requires -Version 5.0 -Modules CimCmdlets
|
||||||
|
|
||||||
|
Function Get-TargetResource
|
||||||
|
{
|
||||||
|
[CmdletBinding()]
|
||||||
|
[OutputType([Hashtable])]
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[ValidateSet("Present", "Absent")]
|
||||||
|
[String]
|
||||||
|
$Ensure = "Present",
|
||||||
|
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[ValidateNotNullOrEmpty()]
|
||||||
|
[String]
|
||||||
|
$Path
|
||||||
|
)
|
||||||
|
return @{
|
||||||
|
Ensure = $Ensure
|
||||||
|
Path = $Path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Function Set-TargetResource
|
||||||
|
{
|
||||||
|
[CmdletBinding()]
|
||||||
|
param
|
||||||
|
(
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[ValidateSet("Present", "Absent")]
|
||||||
|
[String]
|
||||||
|
$Ensure = "Present",
|
||||||
|
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[ValidateNotNullOrEmpty()]
|
||||||
|
[String]
|
||||||
|
$Path,
|
||||||
|
|
||||||
|
[String]
|
||||||
|
$StringParam,
|
||||||
|
|
||||||
|
[UInt32]
|
||||||
|
$UInt32Param,
|
||||||
|
|
||||||
|
[UInt64]
|
||||||
|
$UInt64Param,
|
||||||
|
|
||||||
|
[String[]]
|
||||||
|
$StringArrayParam,
|
||||||
|
|
||||||
|
[UInt32[]]
|
||||||
|
$UInt32ArrayParam,
|
||||||
|
|
||||||
|
[UInt64[]]
|
||||||
|
$UInt64ArrayParam,
|
||||||
|
|
||||||
|
[Boolean]
|
||||||
|
$BooleanParam,
|
||||||
|
|
||||||
|
[PSCredential]
|
||||||
|
$PSCredentialParam,
|
||||||
|
|
||||||
|
[Microsoft.Management.Infrastructure.CimInstance]
|
||||||
|
$CimInstanceParam,
|
||||||
|
|
||||||
|
[Microsoft.Management.Infrastructure.CimInstance[]]
|
||||||
|
$CimInstanceArrayParam
|
||||||
|
)
|
||||||
|
|
||||||
|
$file_contents = @"
|
||||||
|
xTestResource Version: {{item.version}}
|
||||||
|
|
||||||
|
Ensure:
|
||||||
|
Type: $($Ensure.GetType().FullName)
|
||||||
|
Value: $($Ensure.ToString())
|
||||||
|
|
||||||
|
StringParam:
|
||||||
|
Type: $($StringParam.GetType().FullName)
|
||||||
|
Value: $($StringParam)
|
||||||
|
|
||||||
|
UInt32Param:
|
||||||
|
Type: $($UInt32Param.GetType().FullName)
|
||||||
|
Value: $($UInt32Param.ToString())
|
||||||
|
|
||||||
|
UInt64Param:
|
||||||
|
Type: $($UInt64Param.GetType().FullName)
|
||||||
|
Value: $($UInt64Param.ToString())
|
||||||
|
|
||||||
|
StringArrayParam:
|
||||||
|
Type: $($StringArrayParam.GetType().FullName)
|
||||||
|
Value: [ "$($StringArrayParam -join '", "')" ]
|
||||||
|
|
||||||
|
UInt32ArrayParam:
|
||||||
|
Type: $($UInt32ArrayParam.GetType().FullName)
|
||||||
|
Value: [ $($UInt32ArrayParam -join ', ') ]
|
||||||
|
|
||||||
|
UInt64ArrayParam:
|
||||||
|
Type: $($UInt64ArrayParam.GetType().FullName)
|
||||||
|
Value: [ $($UInt64ArrayParam -join ', ') ]
|
||||||
|
|
||||||
|
BooleanParam:
|
||||||
|
Type: $($BooleanParam.GetType().FullName)
|
||||||
|
Value: $($BooleanParam.ToString())
|
||||||
|
|
||||||
|
PSCredentialParam:
|
||||||
|
Type: $($PSCredentialParam.GetType().FullName)
|
||||||
|
Username: $($PSCredentialParam.GetNetworkCredential().Username)
|
||||||
|
Password: $($PSCredentialParam.GetNetworkCredential().Password)
|
||||||
|
|
||||||
|
CimInstanceParam:
|
||||||
|
Type: $($CimInstanceParam.GetType().FullName)
|
||||||
|
|
||||||
|
CimInstanceArrayParam:
|
||||||
|
Type: $($CimInstanceArrayParam.GetType().FullName)
|
||||||
|
"@
|
||||||
|
if (Test-Path -Path $Path)
|
||||||
|
{
|
||||||
|
Remove-Item -Path $Path -Force > $null
|
||||||
|
}
|
||||||
|
New-Item -Path $Path -ItemType File > $null
|
||||||
|
Set-Content -Path $Path -Value $file_contents > $null
|
||||||
|
}
|
||||||
|
|
||||||
|
Function Test-TargetResource
|
||||||
|
{
|
||||||
|
[CmdletBinding()]
|
||||||
|
[OutputType([Boolean])]
|
||||||
|
param
|
||||||
|
(
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[ValidateSet("Present", "Absent")]
|
||||||
|
[String]
|
||||||
|
$Ensure = "Present",
|
||||||
|
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[ValidateNotNullOrEmpty()]
|
||||||
|
[String]
|
||||||
|
$Path,
|
||||||
|
|
||||||
|
[String]
|
||||||
|
$StringParam,
|
||||||
|
|
||||||
|
[UInt32]
|
||||||
|
$UInt32Param,
|
||||||
|
|
||||||
|
[UInt64]
|
||||||
|
$UInt64Param,
|
||||||
|
|
||||||
|
[String[]]
|
||||||
|
$StringArrayParam,
|
||||||
|
|
||||||
|
[UInt32[]]
|
||||||
|
$UInt32ArrayParam,
|
||||||
|
|
||||||
|
[UInt64[]]
|
||||||
|
$UInt64ArrayParam,
|
||||||
|
|
||||||
|
[Boolean]
|
||||||
|
$BooleanParam,
|
||||||
|
|
||||||
|
[PSCredential]
|
||||||
|
$PSCredentialParam,
|
||||||
|
|
||||||
|
[Microsoft.Management.Infrastructure.CimInstance]
|
||||||
|
$CimInstanceParam,
|
||||||
|
|
||||||
|
[Microsoft.Management.Infrastructure.CimInstance[]]
|
||||||
|
$CimInstanceArrayParam
|
||||||
|
)
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
|
||||||
|
Export-ModuleMember -Function *-TargetResource
|
@ -0,0 +1,25 @@
|
|||||||
|
[ClassVersion("{{item.version}}")]
|
||||||
|
class ANSIBLE_xTestClass
|
||||||
|
{
|
||||||
|
[Write] String StringKey;
|
||||||
|
[Write] Boolean BooleanKey;
|
||||||
|
[Write] UInt32 UInt32Key;
|
||||||
|
[Write] String StringArrayKey[];
|
||||||
|
};
|
||||||
|
|
||||||
|
[ClassVersion("{{item.version}}"), FriendlyName("xTestResource")]
|
||||||
|
class ANSIBLE_xTestResource : OMI_BaseResource
|
||||||
|
{
|
||||||
|
[Key] String Path;
|
||||||
|
[Required, ValueMap{"Present", "Absent"}, Values{"Present", "Absent"}] String Ensure;
|
||||||
|
[Write] String StringParam;
|
||||||
|
[Write] UInt32 UInt32Param;
|
||||||
|
[Write] UInt64 UInt64Param;
|
||||||
|
[Write] String StringArrayParam[];
|
||||||
|
[Write] UInt32 UInt32ArrayParam[];
|
||||||
|
[Write] UInt64 UInt64ArrayParam[];
|
||||||
|
[Write] Boolean BooleanParam;
|
||||||
|
[Write, EmbeddedInstance("MSFT_Credential")] String PSCredentialParam;
|
||||||
|
[Write, EmbeddedInstance("ANSIBLE_xTestClass")] String CimInstanceParam;
|
||||||
|
[Write, EmbeddedInstance("ANSIBLE_xTestClass")] String CimInstanceArrayParam[];
|
||||||
|
};
|
@ -0,0 +1,12 @@
|
|||||||
|
@{
|
||||||
|
ModuleVersion = '{{item.version}}'
|
||||||
|
GUID = '{{item.version|to_uuid}}'
|
||||||
|
Author = 'Ansible'
|
||||||
|
CompanyName = 'Ansible'
|
||||||
|
Copyright = '(c) 2017'
|
||||||
|
Description = 'Test DSC Resource for Ansible integration tests'
|
||||||
|
PowerShellVersion = '5.0'
|
||||||
|
CLRVersion = '4.0'
|
||||||
|
FunctionsToExport = '*'
|
||||||
|
CmdletsToExport = '*'
|
||||||
|
}
|
Loading…
Reference in New Issue