win_package - Use newer module wrapper as refactor baseline (#65586)

* win_package - Use newer module wrapper as refactor baseline

* Fix aliases in new arg spec
pull/65593/head
Jordan Borean 5 years ago committed by GitHub
parent 3919a891c2
commit f21e72d55a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,2 @@
minor_changes:
- win_package - Move across to ``Ansible.Basic`` for better invocation logging

@ -4,34 +4,58 @@
# Copyright: (c) 2017, Ansible Project # Copyright: (c) 2017, Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
#Requires -Module Ansible.ModuleUtils.Legacy #AnsibleRequires -CSharpUtil Ansible.Basic
#Requires -Module Ansible.ModuleUtils.CommandUtil #Requires -Module Ansible.ModuleUtils.AddType
#Requires -Module Ansible.ModuleUtils.ArgvParser #Requires -Module Ansible.ModuleUtils.ArgvParser
#Requires -Module Ansible.ModuleUtils.CommandUtil
$ErrorActionPreference = 'Stop' $spec = @{
options = @{
$params = Parse-Args -arguments $args -supports_check_mode $true arguments = @{ type = "raw" }
$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false expected_return_code = @{ type = "list"; elements = "int"; default = @(0, 3010) }
path = @{ type = "str"}
$arguments = Get-AnsibleParam -obj $params -name "arguments" chdir = @{ type = "path" }
$expected_return_code = Get-AnsibleParam -obj $params -name "expected_return_code" -type "list" -default @(0, 3010) product_id = @{ type = "str"; aliases = @(,"productid") }
$path = Get-AnsibleParam -obj $params -name "path" -type "str" state = @{ type = "str"; default = "present"; choices = "absent", "present"; aliases = @(,"ensure") }
$chdir = Get-AnsibleParam -obj $params -name "chdir" -type "path" username = @{ type = "str"; aliases = @(,"user_name") }
$product_id = Get-AnsibleParam -obj $params -name "product_id" -type "str" -aliases "productid" password = @{ type = "str"; no_log = $true; aliases = @(,"user_password") }
$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "present" -validateset "absent","present" -aliases "ensure" validate_certs = @{ type = "bool"; default = $true }
$username = Get-AnsibleParam -obj $params -name "username" -type "str" -aliases "user_name" creates_path = @{ type = "path" }
$password = Get-AnsibleParam -obj $params -name "password" -type "str" -failifempty ($null -ne $username) -aliases "user_password" creates_version = @{ type = "str" }
$validate_certs = Get-AnsibleParam -obj $params -name "validate_certs" -type "bool" -default $true creates_service = @{ type = "str" }
$creates_path = Get-AnsibleParam -obj $params -name "creates_path" -type "path" log_path = @{ type = "path" }
$creates_version = Get-AnsibleParam -obj $params -name "creates_version" -type "str" }
$creates_service = Get-AnsibleParam -obj $params -name "creates_service" -type "str" required_by = @{
$log_path = Get-AnsibleParam -obj $params -name "log_path" -type "path" creates_version = "creates_path"
}
$result = @{ required_if = @(
changed = $false @("state", "present", @("path")),
reboot_required = $false @("state", "absent", @("path", "product_id"), $true)
)
required_together = @(,@("username", "password"))
supports_check_mode = $true
} }
$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec)
$check_mode = $module.CheckMode
$arguments = $module.Params.arguments
$expected_return_code = $module.Params.expected_return_code
$path = $module.Params.path
$chdir = $module.Params.chdir
$product_id = $module.Params.product_id
$state = $module.Params.state
$username = $module.Params.username
$password = $module.Params.password
$validate_certs = $module.Params.validate_certs
$creates_path = $module.Params.creates_path
$creates_version = $module.Params.creates_version
$creates_service = $module.Params.creates_service
$log_path = $module.Params.log_path
$module.Result.reboot_required = $false
if ($null -ne $arguments) { if ($null -ne $arguments) {
# convert a list to a string and escape the values # convert a list to a string and escape the values
if ($arguments -is [array]) { if ($arguments -is [array]) {
@ -59,26 +83,6 @@ if ($null -ne $username) {
$credential = New-Object -TypeName PSCredential -ArgumentList $username, $sec_user_password $credential = New-Object -TypeName PSCredential -ArgumentList $username, $sec_user_password
} }
$valid_return_codes = @()
foreach ($rc in ($expected_return_code)) {
try {
$int_rc = [Int32]::Parse($rc)
$valid_return_codes += $int_rc
} catch {
Fail-Json -obj $result -message "failed to parse expected return code $rc as an integer"
}
}
if ($null -eq $path) {
if (-not ($state -eq "absent" -and $null -ne $product_id)) {
Fail-Json -obj $result -message "path can only be null when state=absent and product_id is not null"
}
}
if ($null -ne $creates_version -and $null -eq $creates_path) {
Fail-Json -obj $result -Message "creates_path must be set when creates_version is set"
}
$msi_tools = @" $msi_tools = @"
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
@ -115,7 +119,7 @@ namespace Ansible {
} }
"@ "@
Add-Type -TypeDefinition @" Add-CSharpType -AnsibleModule $module -References @"
public enum LocationType { public enum LocationType {
Empty, Empty,
Local, Local,
@ -129,7 +133,7 @@ Function Download-File($url, $path) {
try { try {
$web_client.DownloadFile($url, $path) $web_client.DownloadFile($url, $path)
} catch { } catch {
Fail-Json -obj $result -message "failed to download $url to $($path): $($_.Exception.Message)" $module.FailJson("failed to download $url to $($path): $($_.Exception.Message)", $_)
} }
} }
@ -185,7 +189,7 @@ Function Get-ProgramMetadata($state, $path, $product_id, [PSCredential]$credenti
try { try {
New-PSDrive -Name win_package -PSProvider FileSystem -Root $file_path -Credential $credential -Scope Script New-PSDrive -Name win_package -PSProvider FileSystem -Root $file_path -Credential $credential -Scope Script
} catch { } catch {
Fail-Json -obj $result -message "failed to connect network drive with credentials: $($_.Exception.Message)" $module.FailJson("failed to connect network drive with credentials: $($_.Exception.Message)", $_)
} }
$test_path = "win_package:\$file_name" $test_path = "win_package:\$file_name"
} else { } else {
@ -215,15 +219,15 @@ Function Get-ProgramMetadata($state, $path, $product_id, [PSCredential]$credenti
} else { } else {
# we can get the product_id if the path is an msi and is either a local file or unc file with credential delegation # we can get the product_id if the path is an msi and is either a local file or unc file with credential delegation
if (($metadata.msi -eq $true) -and (($metadata.location_type -eq [LocationType]::Local) -or ($metadata.location_type -eq [LocationType]::Unc -and $null -eq $credential))) { if (($metadata.msi -eq $true) -and (($metadata.location_type -eq [LocationType]::Local) -or ($metadata.location_type -eq [LocationType]::Unc -and $null -eq $credential))) {
Add-Type -TypeDefinition $msi_tools Add-CSharpType -AnsibleModule $module -References $msi_tools
try { try {
$metadata.product_id = [Ansible.MsiTools]::GetPackageProperty($path, "ProductCode") $metadata.product_id = [Ansible.MsiTools]::GetPackageProperty($path, "ProductCode")
} catch { } catch {
Fail-Json -obj $result -message "failed to get product_id from MSI at $($path): $($_.Exception.Message)" $module.FailJson("failed to get product_id from MSI at $($path): $($_.Exception.Message)", $_)
} }
} elseif ($null -eq $creates_path -and $null -eq $creates_service) { } elseif ($null -eq $creates_path -and $null -eq $creates_service) {
# we need to fail without the product id at this point # we need to fail without the product id at this point
Fail-Json $result "product_id is required when the path is not an MSI or the path is an MSI but not local" $module.FailJson("product_id is required when the path is not an MSI or the path is an MSI but not local")
} }
} }
@ -259,7 +263,7 @@ Function Get-ProgramMetadata($state, $path, $product_id, [PSCredential]$credenti
$version_matched = $creates_version -eq $existing_version $version_matched = $creates_version -eq $existing_version
$metadata.installed = $version_matched $metadata.installed = $version_matched
} else { } else {
Fail-Json -obj $result -message "creates_path must be a file not a directory when creates_version is set" $module.FailJson("creates_path must be a file not a directory when creates_version is set")
} }
} }
} }
@ -272,7 +276,7 @@ Function Get-ProgramMetadata($state, $path, $product_id, [PSCredential]$credenti
# finally throw error if path is not valid unless we want to uninstall the package and it already is # finally throw error if path is not valid unless we want to uninstall the package and it already is
if ($null -ne $metadata.path_error -and (-not ($state -eq "absent" -and $metadata.installed -eq $false))) { if ($null -ne $metadata.path_error -and (-not ($state -eq "absent" -and $metadata.installed -eq $false))) {
Fail-Json -obj $result -message $metadata.path_error $module.FailJson($metadata.path_error)
} }
return $metadata return $metadata
@ -360,7 +364,7 @@ if ($state -eq "absent") {
try { try {
$process_result = Run-Command @command_args $process_result = Run-Command @command_args
} catch { } catch {
Fail-Json -obj $result -message "failed to run uninstall process ($($command_args['command'])): $($_.Exception.Message)" $module.FailJson("failed to run uninstall process ($($command_args['command'])): $($_.Exception.Message)", $_)
} }
if (($null -ne $log_path) -and (Test-Path -LiteralPath $log_path)) { if (($null -ne $log_path) -and (Test-Path -LiteralPath $log_path)) {
@ -369,20 +373,20 @@ if ($state -eq "absent") {
$log_content = $null $log_content = $null
} }
$result.rc = $process_result.rc $module.Result.rc = $process_result.rc
if ($valid_return_codes -notcontains $process_result.rc) { if ($expected_return_code -notcontains $process_result.rc) {
$result.stdout = Convert-Encoding -string $process_result.stdout $module.Result.stdout = Convert-Encoding -string $process_result.stdout
$result.stderr = Convert-Encoding -string $process_result.stderr $module.Result.stderr = Convert-Encoding -string $process_result.stderr
if ($null -ne $log_content) { if ($null -ne $log_content) {
$result.log = $log_content $module.Result.log = $log_content
} }
Fail-Json -obj $result -message "unexpected rc from uninstall $uninstall_exe $($uninstall_arguments): see rc, stdout and stderr for more details" $module.FailJson("unexpected rc from uninstall $uninstall_exe $($uninstall_arguments): see rc, stdout and stderr for more details")
} else { } else {
$result.failed = $false $module.Result.failed = $false
} }
if ($process_result.rc -eq 3010) { if ($process_result.rc -eq 3010) {
$result.reboot_required = $true $module.Result.reboot_required = $true
} }
} }
} finally { } finally {
@ -394,7 +398,7 @@ if ($state -eq "absent") {
} }
} }
$result.changed = $true $module.Result.changed = $true
} }
} else { } else {
if ($program_metadata.installed -eq $false) { if ($program_metadata.installed -eq $false) {
@ -448,7 +452,7 @@ if ($state -eq "absent") {
try { try {
$process_result = Run-Command @command_args $process_result = Run-Command @command_args
} catch { } catch {
Fail-Json -obj $result -message "failed to run install process ($($command_args['command'])): $($_.Exception.Message)" $module.FailJson("failed to run install process ($($command_args['command'])): $($_.Exception.Message)", $_)
} }
if (($null -ne $log_path) -and (Test-Path -LiteralPath $log_path)) { if (($null -ne $log_path) -and (Test-Path -LiteralPath $log_path)) {
@ -457,20 +461,20 @@ if ($state -eq "absent") {
$log_content = $null $log_content = $null
} }
$result.rc = $process_result.rc $module.Result.rc = $process_result.rc
if ($valid_return_codes -notcontains $process_result.rc) { if ($expected_return_code -notcontains $process_result.rc) {
$result.stdout = Convert-Encoding -string $process_result.stdout $module.Result.stdout = Convert-Encoding -string $process_result.stdout
$result.stderr = Convert-Encoding -string $process_result.stderr $module.Result.stderr = Convert-Encoding -string $process_result.stderr
if ($null -ne $log_content) { if ($null -ne $log_content) {
$result.log = $log_content $module.Result.log = $log_content
} }
Fail-Json -obj $result -message "unexpected rc from install $install_exe $($install_arguments): see rc, stdout and stderr for more details" $module.FailJson("unexpected rc from install $install_exe $($install_arguments): see rc, stdout and stderr for more details")
} else { } else {
$result.failed = $false $module.Result.failed = $false
} }
if ($process_result.rc -eq 3010) { if ($process_result.rc -eq 3010) {
$result.reboot_required = $true $module.Result.reboot_required = $true
} }
} }
} finally { } finally {
@ -482,8 +486,9 @@ if ($state -eq "absent") {
} }
} }
$result.changed = $true $module.Result.changed = $true
} }
} }
Exit-Json -obj $result $module.ExitJson()

@ -13,19 +13,19 @@
state: present state: present
expected_return_code: 0,abc expected_return_code: 0,abc
register: fail_invalid_return_code register: fail_invalid_return_code
failed_when: fail_invalid_return_code.msg != 'failed to parse expected return code abc as an integer' failed_when: "'argument for list entry expected_return_code is of type System>String and we were unable to convert to in' in fail_invalid_return_code.msg"
- name: fail when path is not set and state!= absent - name: fail when path is not set and state!= absent
win_package: win_package:
state: present state: present
register: fail_no_path register: fail_no_path
failed_when: fail_no_path.msg != 'path can only be null when state=absent and product_id is not null' failed_when: 'fail_no_path.msg != "state is present but all of the following are missing: path"'
- name: fail when path is not set and state=absent but product_id is null - name: fail when path is not set and state=absent but product_id is null
win_package: win_package:
state: absent state: absent
register: fail_no_path_state_absent_no_id register: fail_no_path_state_absent_no_id
failed_when: fail_no_path_state_absent_no_id.msg != 'path can only be null when state=absent and product_id is not null' failed_when: 'fail_no_path_state_absent_no_id.msg != "state is absent but any of the following are missing: path, product_id"'
- name: fail when product_id is not set and path is not a local MSI - name: fail when product_id is not set and path is not a local MSI
win_package: win_package:
@ -70,7 +70,7 @@
state: present state: present
creates_version: 1 creates_version: 1
register: fail_creates_version_without_path register: fail_creates_version_without_path
failed_when: fail_creates_version_without_path.msg != 'creates_path must be set when creates_version is set' failed_when: "fail_creates_version_without_path.msg != \"missing parameter(s) required by 'creates_version': creates_path\""
- name: fail to check version without when path is not a file - name: fail to check version without when path is not a file
win_package: win_package:

Loading…
Cancel
Save