From 9755d2dbbcecf016dff1329e57b60ef502386b3d Mon Sep 17 00:00:00 2001 From: Dag Wieers Date: Wed, 15 Mar 2017 03:01:03 +0100 Subject: [PATCH] win_feature: Clean up and check-mode support (#21351) * Clean up parameter handling and added check-mode support Changes include: - Remove trailing semi-colons - Replaced PSObjects into normal hashes - Make use of Get-AnsibleParam and types - Added check-mode support * Implemented -WhatIf:$check_mode support * powershell.ps1: Ensure Fail-Json() works with Hashtables Without this change a dictionary $result object would be emptied if it is anything but a PSCustomObject. Now we also support Hashtables. * Revert to original formatting --- lib/ansible/modules/windows/win_feature.ps1 | 94 ++++++++++----------- lib/ansible/modules/windows/win_feature.py | 9 -- 2 files changed, 46 insertions(+), 57 deletions(-) diff --git a/lib/ansible/modules/windows/win_feature.ps1 b/lib/ansible/modules/windows/win_feature.ps1 index 8f1510ca0fd..03378978ae2 100644 --- a/lib/ansible/modules/windows/win_feature.ps1 +++ b/lib/ansible/modules/windows/win_feature.ps1 @@ -19,47 +19,43 @@ # WANT_JSON # POWERSHELL_COMMON -Import-Module Servermanager; +Import-Module Servermanager -$params = Parse-Args $args; - -$result = New-Object PSObject -Property @{ +$result = @{ changed = $false } -$name = Get-Attr $params "name" -failifempty $true +$params = Parse-Args $args -supports_check_mode $true +$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false + +$name = Get-AnsibleParam -obj $params -name "name" -type "str" -failifempty $true +$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "present" -validateset "present","absent" +$restart = Get-AnsibleParam -obj $params -name "restart" -type "bool" -default $false +$includesubfeatures = Get-AnsibleParam -obj $params -name "include_sub_features" -type "bool" -default $false +$includemanagementtools = Get-AnsibleParam -obj $params -name "include_management_tools" -type "bool" -default $false +$source = Get-AnsibleParam -obj $params -name "source" -type "str" $name = $name -split ',' | % { $_.Trim() } -$state = Get-Attr $params "state" "present" -$state = $state.ToString().ToLower() -If (($state -ne 'present') -and ($state -ne 'absent')) { - Fail-Json $result "state is '$state'; must be 'present' or 'absent'" -} - -$restart = Get-Attr $params "restart" $false | ConvertTo-Bool -$includesubfeatures = Get-Attr $params "include_sub_features" $false | ConvertTo-Bool -$includemanagementtools = Get-Attr $params "include_management_tools" $false | ConvertTo-Bool -$source = Get-Attr $params "source" $false # Determine which cmdlets we need to work with. Then we can set options appropriate for the cmdlet $installWF= $false $addWF = $false try { - # We can infer uninstall/remove if install/add cmdlets exist - if (Get-Command "Install-WindowsFeature" -ErrorAction SilentlyContinue) { - $addCmdlet = "Install-WindowsFeature" - $removeCmdlet = "Uninstall-WindowsFeature" - $installWF = $true + # We can infer uninstall/remove if install/add cmdlets exist + if (Get-Command "Install-WindowsFeature" -ErrorAction SilentlyContinue) { + $addCmdlet = "Install-WindowsFeature" + $removeCmdlet = "Uninstall-WindowsFeature" + $installWF = $true } elseif (Get-Command "Add-WindowsFeature" -ErrorAction SilentlyContinue) { $addCmdlet = "Add-WindowsFeature" $removeCmdlet = "Remove-WindowsFeature" - $addWF = $true + $addWF = $true } else { - throw [System.Exception] "Not supported on this version of Windows" + throw [System.Exception] "Not supported on this version of Windows" } } catch { @@ -67,24 +63,25 @@ catch { } -If ($state -eq "present") { - - # Base params to cover both Add/Install-WindowsFeature +If ($state -eq "present") { + + # Base params to cover both Add/Install-WindowsFeature $InstallParams = @{ - "Name"=$name; - "Restart"=$Restart; - "IncludeAllSubFeature"=$includesubfeatures; - "ErrorAction"="SilentlyContinue" + Name = $name + Restart = $restart + IncludeAllSubFeature = $includesubfeatures + ErrorAction = "SilentlyContinue" + WhatIf = $check_mode } - + # IncludeManagementTools and source are options only for Install-WindowsFeature if ($installWF) { - + if ($source) { - if (!(test-path $source)) { + if (-not (Test-Path -Path $source)) { Fail-Json $result "Failed to find source path $source" } - + $InstallParams.add("Source",$source) } @@ -92,9 +89,9 @@ If ($state -eq "present") { $InstallParams.add("IncludeManagementTools",$includemanagementtools) } } - + try { - $featureresult = Invoke-Expression "$addCmdlet @InstallParams" + $featureresult = Invoke-Expression "$addCmdlet @InstallParams" } catch { Fail-Json $result $_.Exception.Message @@ -102,14 +99,15 @@ If ($state -eq "present") { } ElseIf ($state -eq "absent") { - $UninstallParams = @{ - "Name"=$name; - "Restart"=$Restart; - "ErrorAction"="SilentlyContinue" + $UninstallParams = @{ + Name = $name + Restart = $restart + ErrorAction = "SilentlyContinue" + WhatIf = $check_mode } - - try { - $featureresult = Invoke-Expression "$removeCmdlet @UninstallParams" + + try { + $featureresult = Invoke-Expression "$removeCmdlet @UninstallParams" } catch { Fail-Json $result $_.Exception.Message @@ -125,13 +123,13 @@ If ($featureresult.FeatureResult) ForEach ($item in $featureresult.FeatureResult) { $message = @() ForEach ($msg in $item.Message) { - $message += New-Object PSObject -Property @{ + $message += @{ message_type = $msg.MessageType.ToString() error_code = $msg.ErrorCode text = $msg.Text } } - $installed_features += New-Object PSObject -Property @{ + $installed_features += @{ id = $item.Id display_name = $item.DisplayName message = $message @@ -143,10 +141,10 @@ If ($featureresult.FeatureResult) $result.changed = $true } -Set-Attr $result "feature_result" $installed_features -Set-Attr $result "success" ($featureresult.Success.ToString() | ConvertTo-Bool) -Set-Attr $result "exitcode" $featureresult.ExitCode.ToString() -Set-Attr $result "restart_needed" ($featureresult.RestartNeeded.ToString() | ConvertTo-Bool) +$result.feature_result = $installed_features +$result.success = ($featureresult.Success.ToString() | ConvertTo-Bool) +$result.exitcode = $featureresult.ExitCode.ToString() +$result.restart_needed = ($featureresult.RestartNeeded.ToString() | ConvertTo-Bool) If ($result.success) { Exit-Json $result diff --git a/lib/ansible/modules/windows/win_feature.py b/lib/ansible/modules/windows/win_feature.py index 124e38f196a..6b2045fc6e6 100644 --- a/lib/ansible/modules/windows/win_feature.py +++ b/lib/ansible/modules/windows/win_feature.py @@ -38,11 +38,9 @@ options: description: - Names of roles or features to install as a single feature or a comma-separated list of features required: true - default: null state: description: - State of the features or roles on the system - required: false choices: - present - absent @@ -53,16 +51,12 @@ options: choices: - yes - no - default: null - required: false include_sub_features: description: - Adds all subfeatures of the specified feature choices: - yes - no - default: null - required: false include_management_tools: description: - Adds the corresponding management tools to the specified feature. @@ -70,13 +64,10 @@ options: choices: - yes - no - default: null - required: false source: description: - Specify a source to install the feature from. - Not supported in Windows 2008. If present when using Windows 2008 this option will be ignored. - required: false choices: [ ' {driveletter}:\sources\sxs', ' {IP}\Share\sources\sxs' ] version_added: "2.1" author: