From 978a979566ebd324542f1e835d1bd86fc71d3dd1 Mon Sep 17 00:00:00 2001 From: Jordan Borean Date: Mon, 6 Nov 2017 09:44:04 +1000 Subject: 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 version --- test/integration/targets/win_dsc/defaults/main.yml | 5 +- .../targets/win_dsc/files/custom-result-normal.txt | 44 +++ .../win_dsc/files/custom-result-versioned.txt | 44 +++ .../win_dsc/filter_plugins/strip_newline.py | 16 + .../win_dsc/library/test_win_dsc_iis_info.ps1 | 41 +++ .../targets/win_dsc/tasks/destructive.yml | 135 +++++++++ test/integration/targets/win_dsc/tasks/main.yml | 153 +++------- test/integration/targets/win_dsc/tasks/smoke.yml | 8 + test/integration/targets/win_dsc/tasks/tests.yml | 330 +++++++++++++++++++++ .../win_dsc/templates/ANSIBLE_xTestResource.psm1 | 173 +++++++++++ .../templates/ANSIBLE_xTestResource.schema.mof | 25 ++ .../targets/win_dsc/templates/xTestDsc.psd1 | 12 + 12 files changed, 865 insertions(+), 121 deletions(-) create mode 100644 test/integration/targets/win_dsc/files/custom-result-normal.txt create mode 100644 test/integration/targets/win_dsc/files/custom-result-versioned.txt create mode 100644 test/integration/targets/win_dsc/filter_plugins/strip_newline.py create mode 100644 test/integration/targets/win_dsc/library/test_win_dsc_iis_info.ps1 create mode 100644 test/integration/targets/win_dsc/tasks/destructive.yml create mode 100644 test/integration/targets/win_dsc/tasks/smoke.yml create mode 100644 test/integration/targets/win_dsc/tasks/tests.yml create mode 100644 test/integration/targets/win_dsc/templates/ANSIBLE_xTestResource.psm1 create mode 100644 test/integration/targets/win_dsc/templates/ANSIBLE_xTestResource.schema.mof create mode 100644 test/integration/targets/win_dsc/templates/xTestDsc.psd1 (limited to 'test/integration/targets/win_dsc') diff --git a/test/integration/targets/win_dsc/defaults/main.yml b/test/integration/targets/win_dsc/defaults/main.yml index e1833cd8a8..90aaec6656 100644 --- a/test/integration/targets/win_dsc/defaults/main.yml +++ b/test/integration/targets/win_dsc/defaults/main.yml @@ -1,4 +1,5 @@ --- - # 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 diff --git a/test/integration/targets/win_dsc/files/custom-result-normal.txt b/test/integration/targets/win_dsc/files/custom-result-normal.txt new file mode 100644 index 0000000000..8220d589f8 --- /dev/null +++ b/test/integration/targets/win_dsc/files/custom-result-normal.txt @@ -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[] diff --git a/test/integration/targets/win_dsc/files/custom-result-versioned.txt b/test/integration/targets/win_dsc/files/custom-result-versioned.txt new file mode 100644 index 0000000000..fe5a6e2dff --- /dev/null +++ b/test/integration/targets/win_dsc/files/custom-result-versioned.txt @@ -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[] diff --git a/test/integration/targets/win_dsc/filter_plugins/strip_newline.py b/test/integration/targets/win_dsc/filter_plugins/strip_newline.py new file mode 100644 index 0000000000..bfa642de49 --- /dev/null +++ b/test/integration/targets/win_dsc/filter_plugins/strip_newline.py @@ -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) diff --git a/test/integration/targets/win_dsc/library/test_win_dsc_iis_info.ps1 b/test/integration/targets/win_dsc/library/test_win_dsc_iis_info.ps1 new file mode 100644 index 0000000000..3c353d01cc --- /dev/null +++ b/test/integration/targets/win_dsc/library/test_win_dsc_iis_info.ps1 @@ -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 diff --git a/test/integration/targets/win_dsc/tasks/destructive.yml b/test/integration/targets/win_dsc/tasks/destructive.yml new file mode 100644 index 0000000000..f455f9dbd6 --- /dev/null +++ b/test/integration/targets/win_dsc/tasks/destructive.yml @@ -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 diff --git a/test/integration/targets/win_dsc/tasks/main.yml b/test/integration/targets/win_dsc/tasks/main.yml index 3e8d6ed662..1c241e7217 100644 --- a/test/integration/targets/win_dsc/tasks/main.yml +++ b/test/integration/targets/win_dsc/tasks/main.yml @@ -1,119 +1,34 @@ -# test code for the win_feature module -# (c) 2014, Chris Church - -# This file is part of Ansible -# -# Ansible is free software: you can redistribute it and/or modify -# 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 . - - -- name: check whether servermanager module is available (windows 2008 r2 or later) - raw: PowerShell -Command Import-Module ServerManager - register: win_feature_has_servermanager - ignore_errors: true - - -- name: start with feature absent - win_feature: - name: "{{ test_win_feature_name }}" - 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 - assert: - that: - - "win_dsc_2_result|changed" - - "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 - win_dsc: - resource_name: windowsfeature - name: "{{ test_win_feature_name }}" - 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 - 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) +--- +- name: get powershell version + win_shell: $PSVersionTable.PSVersion.Major + register: powershell_version + +- name: run smoke tests when we can't run the full suite + include_tasks: smoke.yml + when: powershell_version.stdout_lines[0]|int < 5 + +- block: + - name: run non-destructive tests + include_tasks: tests.yml + + - name: run destructive tests if flag is set + include_tasks: destructive.yml + when: test_win_dsc_run_desctructive == True + + always: + - name: remove test feature + win_feature: + name: '{{test_win_dsc_feature_name}}' + state: absent + + - name: remove test folder + win_file: + path: '{{test_win_dsc_folder}}' + state: absent + + - name: remove custom DSC resource folder + win_file: + path: C:\Program Files\WindowsPowerShell\Modules\xTestDsc + state: absent + + when: powershell_version.stdout_lines[0]|int >= 5 diff --git a/test/integration/targets/win_dsc/tasks/smoke.yml b/test/integration/targets/win_dsc/tasks/smoke.yml new file mode 100644 index 0000000000..5489cf4dfa --- /dev/null +++ b/test/integration/targets/win_dsc/tasks/smoke.yml @@ -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' diff --git a/test/integration/targets/win_dsc/tasks/tests.yml b/test/integration/targets/win_dsc/tasks/tests.yml new file mode 100644 index 0000000000..9866001796 --- /dev/null +++ b/test/integration/targets/win_dsc/tasks/tests.yml @@ -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 diff --git a/test/integration/targets/win_dsc/templates/ANSIBLE_xTestResource.psm1 b/test/integration/targets/win_dsc/templates/ANSIBLE_xTestResource.psm1 new file mode 100644 index 0000000000..59569f8ff7 --- /dev/null +++ b/test/integration/targets/win_dsc/templates/ANSIBLE_xTestResource.psm1 @@ -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 diff --git a/test/integration/targets/win_dsc/templates/ANSIBLE_xTestResource.schema.mof b/test/integration/targets/win_dsc/templates/ANSIBLE_xTestResource.schema.mof new file mode 100644 index 0000000000..00632f3f55 --- /dev/null +++ b/test/integration/targets/win_dsc/templates/ANSIBLE_xTestResource.schema.mof @@ -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[]; +}; diff --git a/test/integration/targets/win_dsc/templates/xTestDsc.psd1 b/test/integration/targets/win_dsc/templates/xTestDsc.psd1 new file mode 100644 index 0000000000..b3cdc08d57 --- /dev/null +++ b/test/integration/targets/win_dsc/templates/xTestDsc.psd1 @@ -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 = '*' +} -- cgit v1.2.1