Ansible-win_dsc icon indicating copy to clipboard operation
Ansible-win_dsc copied to clipboard

win_dsc5.ps1 does not respect check mode in Ansible 2.3 stable

Open Sholdaway opened this issue 7 years ago • 3 comments

Mentioned on Google Groups the other day: https://groups.google.com/forum/#!topic/ansible-devel/_qiLy2drebI

When calling win_dsc5 from a playbook or using ansible on the command line the --check parameter does not take effect. Basically, the tasks apply config rather than just reporting on what would have changed.

In the latest win_dsc5 code the $CheckFlag variable is being set by the following lines:

$params = Parse-Args $args -supports_check_mode $true
$CheckFlag = $params.psobject.Properties | where {$_.Name -eq "_ansible_check_mode"}

As the Parse-Args function in module_utils/powershell.ps1 is now outputting a hashtable rather than a custom PS Object the $params variable needs to be enumerated differently. I believe this is because the Parse-Args function has had an else condition added which is being hit every time.

    If ($arguments.Length -gt 0)
    {
        $params = Get-Content $arguments[0] | ConvertFrom-Json
    }
    Else {
        $params = $complex_args
    }

I'm still unsure of how the ansible executable passes args to the script(s) so I'm making slight presumptions!

I have a simple fix tested which brings this module into line with the "standard" Ansible way of setting the check flag in Windows modules (I think I used win_get_url and win_file as examples). Will submit a PR today and update this issue with some of my debugging methods.

Sholdaway avatar Apr 27 '17 08:04 Sholdaway

I am including a bit of detail about the troubleshooting process as it took me a little while to suss out what Ansible was doing and why, and these kind of notes would have been useful to me if I had come across them before I understood roughly how the module behaved.

To show the changes in the object stored in the $params object I have inserted code underneath the $params variable declaration to pipe out the contents of the object to one file, and the object type to another:

$params = Parse-Args $args -supports_check_mode $true

$params | Out-File C:\Temp\ParamsVars.txt
($params).gettype() | Out-File C:\Temp\ParamsType.txt
exit

Then I run a playbook with one win_dsc5 task (calling the xRobocopy DSC resource), and limit it to one host. The task will obviously error, but once it has done I have a couple of files with the details I need:

ParamsVars.txt

Name                           Value                                                                                    
----                           -----                                                                                    
_ansible_version               2.3.0.0                                                                                  
resource_name                  xRobocopy                                                                                
source                         \\Path\To\Octopus Tentacle Agent\3.1.7 x64                  
_ansible_module_name           win_dsc5                                                                                 
_ansible_selinux_special_fs    {fuse, nfs, vboxsf, ramfs...}                                                            
_ansible_diff                  False                                                                                    
PsDscRunAsCredential_username  MyUserNameGoesHere                                                                
_ansible_check_mode            False                                                                                    
files                          Octopus.Tentacle.3.1.7-x64.msi                                                           
_ansible_debug                 False                                                                                    
_ansible_syslog_facility       LOG_USER                                                                                 
PsDscRunAsCredential_password  MyPassGoesHere                                                                        
_ansible_verbosity             4                                                                                        
_ansible_socket                                                                                                         
_ansible_no_log                False                                                                                    
destination                    C:\Installers\OctopusTentacle         

The output above also shows that Ansible is setting the _ansible_check_mode internal argument correctly, so any problems from there on in had to be how the win_dsc5.ps1 script was processing the $params object

ParamsType.txt

IsPublic IsSerial Name                                     BaseType                                                     
-------- -------- ----                                     --------                                                     
True     True     Hashtable                                System.Object     

The current win_dsc5.ps1 is looking for the _ansible_check_mode in the PSObject, which seems to behave differently in a hashtable to how it does in a PSCustomObject

$CustomObject = New-Object -TypeName PSObject -Property @{Name = 'Sam'; Surname = 'Test'}
$CustomObject.PSObject.Properties


$CustomHash = @{Name = 'Sam'; Surname = 'Test'}
$CustomHash.PsObject.Properties

Sholdaway avatar Apr 27 '17 13:04 Sholdaway

Pull request #21 submitted

Sholdaway avatar Apr 27 '17 13:04 Sholdaway

Nice! Thanks for this!

trondhindenes avatar May 02 '17 13:05 trondhindenes