diff --git a/lib/ansible/modules/windows/win_psmodule.ps1 b/lib/ansible/modules/windows/win_psmodule.ps1 index ac03580dfe2..1e7f058c247 100644 --- a/lib/ansible/modules/windows/win_psmodule.ps1 +++ b/lib/ansible/modules/windows/win_psmodule.ps1 @@ -1,65 +1,312 @@ #!powershell +# Copyright: (c) 2018, Wojciech Sciesinski # Copyright: (c) 2017, Daniele Lazzari # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) #Requires -Module Ansible.ModuleUtils.Legacy -# win_psmodule (Powershell modules Additions/Removal) +# win_psmodule (Windows PowerShell modules Additions/Removals/Updates) -$params = Parse-Args $args -supports_check_mode $true +$params = Parse-Args -arguments $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 +$required_version = Get-AnsibleParam -obj $params -name "required_version" -type "str" +$minimum_version = Get-AnsibleParam -obj $params -name "minimum_version" -type "str" +$maximum_version = Get-AnsibleParam -obj $params -name "maximum_version" -type "str" $repo = Get-AnsibleParam -obj $params -name "repository" -type "str" -$url = Get-AnsibleParam -obj $params -name "url" -type "str" -$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "present" -validateset "present", "absent" +$url = Get-AnsibleParam -obj $params -name "url" -type str +$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "present" -validateset "present", "absent", "latest" $allow_clobber = Get-AnsibleParam -obj $params -name "allow_clobber" -type "bool" -default $false -$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -default $false +$skip_publisher_check = Get-AnsibleParam -obj $params -name "skip_publisher_check" -type "bool" -default $false +$allow_prerelease = Get-AnsibleParam -obj $params -name "allow_prerelease" -type "bool" -default $false -$result = @{"changed" = $false - "output" = "" - "nuget_changed" = $false - "repository_changed" = $false} +$result = @{changed = $false + output = "" + nuget_changed = $false + repository_changed = $false} Function Install-NugetProvider { - param( - [bool]$CheckMode + Param( + [Bool]$CheckMode ) - $PackageProvider = Get-PackageProvider -ListAvailable|?{($_.name -eq 'Nuget') -and ($_.version -ge "2.8.5.201")} - if (!($PackageProvider)){ - try{ - Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force -ErrorAction Stop -WhatIf:$CheckMode | out-null - $result.changed = $true - $result.nuget_changed = $true - } - catch{ - $ErrorMessage = "Problems adding package provider: $($_.Exception.Message)" - Fail-Json $result $ErrorMessage - } + $PackageProvider = Get-PackageProvider -ListAvailable | Where-Object { ($_.name -eq 'Nuget') -and ($_.version -ge "2.8.5.201") } + if (-not($PackageProvider)){ + try { + Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force -WhatIf:$CheckMode | out-null + $result.changed = $true + $result.nuget_changed = $true + } + catch [ System.Exception ] { + $ErrorMessage = "Problems adding package provider: $($_.Exception.Message)" + Fail-Json $result $ErrorMessage + } } } +Function Install-PrereqModule { + Param( + [Switch]$TestInstallationOnly, + [Bool]$CheckMode + ) + + # Those are minimum required versions of modules. + $PrereqModules = @{ + PackageManagement = '1.1.7' + PowerShellGet = '1.6.0' + } + + [Bool]$PrereqModulesInstalled = $true + + ForEach ( $Name in $PrereqModules.Keys ) { + + $ExistingPrereqModule = Get-Module -ListAvailable | Where-Object { ($_.name -eq $Name) -and ($_.version -ge $PrereqModules[$Name]) } + + if ( -not $ExistingPrereqModule ) { + if ( $TestInstallationOnly ) { + $PrereqModulesInstalled = $false + } + else { + try { + Install-Module -Name $Name -MinimumVersion $PrereqModules[$Name] -Force -WhatIf:$CheckMode | Out-Null + + if ( $Name -eq 'PowerShellGet' ) { + # An order has to be reverted due to dependency + Remove-Module -Name PowerShellGet, PackageManagement -Force + Import-Module -Name PowerShellGet, PackageManagement -Force + } + + $result.changed = $true + } + catch [ System.Exception ] { + $ErrorMessage = "Problems adding a prerequisite module $Name $($_.Exception.Message)" + Fail-Json $result $ErrorMessage + } + } + } + } + + if ( $TestInstallationOnly ) { + $PrereqModulesInstalled + } +} + +Function Get-PsModule { + Param( + [Parameter(Mandatory=$true)] + [String]$Name, + [String]$RequiredVersion, + [String]$MinimumVersion, + [String]$MaximumVersion + ) + + $ExistingModule = @{ + Exists = $false + Version = "" + } + + $ExistingModules = Get-Module -Listavailable | Where-Object {($_.name -eq $Name)} + $ExistingModulesCount = $($ExistingModules | Measure-Object).Count + + if ( $ExistingModulesCount -gt 0 ) { + + $ExistingModules | Add-Member -MemberType ScriptProperty -Name FullVersion -Value { if ( $null -ne ( $this.PrivateData ) ) { [String]"$($this.Version)-$(($this | Select-Object -ExpandProperty PrivateData).PSData.Prerelease)".TrimEnd('-') } else { [String]"$($this.Version)" } } + + if ( -not ($RequiredVersion -or + $MinimumVersion -or + $MaximumVersion) ) { + + $ReturnedModule = $ExistingModules | Select-Object -First 1 + } + elseif ( $RequiredVersion ) { + $ReturnedModule = $ExistingModules | Where-Object -FilterScript { $_.FullVersion -eq $RequiredVersion } + } + elseif ( $MinimumVersion -and $MaximumVersion ) { + $ReturnedModule = $ExistingModules | Where-Object -FilterScript { $MinimumVersion -le $_.Version -and $MaximumVersion -ge $_.Version } | Select-Object -First 1 + } + elseif ( $MinimumVersion ) { + $ReturnedModule = $ExistingModules | Where-Object -FilterScript { $MinimumVersion -le $_.Version } | Select-Object -First 1 + } + elseif ( $MaximumVersion ) { + $ReturnedModule = $ExistingModules | Where-Object -FilterScript { $MaximumVersion -ge $_.Version } | Select-Object -First 1 + } + } + + $ReturnedModuleCount = ($ReturnedModule | Measure-Object).Count + + if ( $ReturnedModuleCount -eq 1 ) { + $ExistingModule.Exists = $true + $ExistingModule.Version = $ReturnedModule.FullVersion + } + + $ExistingModule +} + +Function Add-DefinedParameter { + Param ( + [Parameter(Mandatory=$true)] + [Hashtable]$Hashtable, + [Parameter(Mandatory=$true)] + [String[]]$ParametersNames + ) + + ForEach ($ParameterName in $ParametersNames) { + $ParameterVariable = Get-Variable -Name $ParameterName -ErrorAction Ignore + if ( $ParameterVariable.Value -and $Hashtable.Keys -notcontains $ParameterName ){ + $Hashtable.Add($ParameterName,$ParameterVariable.Value) + } + } + + $Hashtable +} + +Function Install-PsModule { + Param( + [Parameter(Mandatory=$true)] + [String]$Name, + [String]$RequiredVersion, + [String]$MinimumVersion, + [String]$MaximumVersion, + [String]$Repository, + [Bool]$AllowClobber, + [Bool]$SkipPublisherCheck, + [Bool]$AllowPrerelease, + [Bool]$CheckMode + ) + + $ExistingModuleBefore = Get-PsModule -Name $Name -RequiredVersion $RequiredVersion -MinimumVersion $MinimumVersion -MaximumVersion $MaximumVersion + + if ( -not $ExistingModuleBefore.Exists ) { + try { + # Install NuGet provider if needed. + Install-NugetProvider -CheckMode $CheckMode + + $ht = @{ + Name = $Name + WhatIf = $CheckMode + Force = $true + } + + [String[]]$ParametersNames = @("RequiredVersion","MinimumVersion","MaximumVersion","AllowPrerelease","AllowClobber","SkipPublisherCheck","Repository") + + $ht = Add-DefinedParameter -Hashtable $ht -ParametersNames $ParametersNames + + Install-Module @ht -ErrorVariable ErrorDetails | out-null + + $result.changed = $true + $result.output = "Module $($Name) installed" + } + catch [ System.Exception ] { + $ErrorMessage = "Problems installing $($Name) module: $($_.Exception.Message)" + Fail-Json $result $ErrorMessage + } + } + else { + $result.output = "Module $($Name) already present" + } +} + +Function Remove-PsModule { + Param( + [Parameter(Mandatory=$true)] + [String]$Name, + [String]$RequiredVersion, + [String]$MinimumVersion, + [String]$MaximumVersion, + [Bool]$CheckMode + ) + # If module is present, uninstalls it. + if (Get-Module -Listavailable | Where-Object {$_.name -eq $Name}) { + try { + $ht = @{ + Name = $Name + Confirm = $false + Force = $true + } + + $ExistingModuleBefore = Get-PsModule -Name $Name -RequiredVersion $RequiredVersion -MinimumVersion $MinimumVersion -MaximumVersion $MaximumVersion + + [String[]]$ParametersNames = @("RequiredVersion","MinimumVersion","MaximumVersion") + + $ht = Add-DefinedParameter -Hashtable $ht -ParametersNames $ParametersNames + + if ( -not ( $RequiredVersion -or $MinimumVersion -or $MaximumVersion ) ) { + $ht.Add("AllVersions", $true) + } + + if ( $ExistingModuleBefore.Exists) { + # The Force parameter overwrite the WhatIf parameter + if ( -not $CheckMode ) { + Uninstall-Module @ht -ErrorVariable ErrorDetails | out-null + } + $result.changed = $true + $result.output = "Module $($Name) removed" + } + } + catch [ System.Exception ] { + $ErrorMessage = "Problems uninstalling $($Name) module: $($_.Exception.Message)" + Fail-Json $result $ErrorMessage + } + } + else { + $result.output = "Module $($Name) removed" + } +} + +Function Find-LatestPsModule { + Param( + [Parameter(Mandatory=$true)] + [String]$Name, + [String]$Repository, + [Bool]$AllowPrerelease, + [Bool]$CheckMode + ) + + try { + $ht = @{ + Name = $Name + } + + [String[]]$ParametersNames = @("AllowPrerelease","Repository") + + $ht = Add-DefinedParameter -Hashtable $ht -ParametersNames $ParametersNames + + $LatestModule = Find-Module @ht + $LatestModuleVersion = $LatestModule.Version + } + catch [ System.Exception ] { + $ErrorMessage = "Cant find the module $($Name): $($_.Exception.Message)" + Fail-Json $result $ErrorMessage + } + + $LatestModuleVersion +} + Function Install-Repository { Param( - [Parameter(Mandatory=$true)] - [string]$Name, - [Parameter(Mandatory=$true)] - [string]$Url, - [bool]$CheckMode + [Parameter(Mandatory=$true)] + [string]$Name, + [Parameter(Mandatory=$true)] + [string]$Url, + [bool]$CheckMode ) - $Repo = (Get-PSRepository).SourceLocation + # Install NuGet provider if needed. + Install-NugetProvider -CheckMode $CheckMode + + $Repos = (Get-PSRepository).SourceLocation # If repository isn't already present, try to register it as trusted. - if ($Repo -notcontains $Url){ + if ($Repos -notcontains $Url){ try { - if (!($CheckMode)) { - Register-PSRepository -Name $Name -SourceLocation $Url -InstallationPolicy Trusted -ErrorAction Stop + if ( -not ($CheckMode) ) { + Register-PSRepository -Name $Name -SourceLocation $Url -InstallationPolicy Trusted -ErrorAction Stop } $result.changed = $true $result.repository_changed = $true } catch { - $ErrorMessage = "Problems adding $($Name) repository: $($_.Exception.Message)" + $ErrorMessage = "Problems registering $($Name) repository: $($_.Exception.Message)" Fail-Json $result $ErrorMessage } } @@ -67,120 +314,143 @@ Function Install-Repository { Function Remove-Repository{ Param( - [Parameter(Mandatory=$true)] - [string]$Name, - [bool]$CheckMode + [Parameter(Mandatory=$true)] + [string]$Name, + [bool]$CheckMode ) - $Repo = (Get-PSRepository).SourceLocation + $Repo = (Get-PSRepository).Name # Try to remove the repository if ($Repo -contains $Name){ - try { - if (!($CheckMode)) { + try { + if ( -not ($CheckMode) ) { Unregister-PSRepository -Name $Name -ErrorAction Stop } $result.changed = $true $result.repository_changed = $true } - catch { - $ErrorMessage = "Problems removing $($Name)repository: $($_.Exception.Message)" + catch [ System.Exception ] { + $ErrorMessage = "Problems unregistering $($Name)repository: $($_.Exception.Message)" Fail-Json $result $ErrorMessage } } } -Function Install-PsModule { - param( - [Parameter(Mandatory=$true)] - [string]$Name, - [string]$Repository, - [bool]$AllowClobber, - [bool]$CheckMode - ) - if (Get-Module -Listavailable|?{$_.name -eq $Name}){ - $result.output = "Module $($Name) already present" - } - else { - try{ - # Install NuGet Provider if needed - Install-NugetProvider -CheckMode $CheckMode; - - $ht = @{ - Name = $Name; - WhatIf = $CheckMode; - ErrorAction = "Stop"; - Force = $true; - }; - - # If specified, use repository name to select module source - if ($Repository) { - $ht["Repository"] = "$Repository"; - } - - # Check Powershell Version (-AllowClobber was introduced in PowerShellGet 1.6.0) - if ("AllowClobber" -in ((Get-Command PowerShellGet\Install-Module | Select -ExpandProperty Parameters).Keys)) { - $ht['AllowClobber'] = $AllowClobber; - } - - Install-Module @ht | out-null; - - $result.output = "Module $($Name) installed" - $result.changed = $true - } - catch{ - $ErrorMessage = "Problems installing $($Name) module: $($_.Exception.Message)" - Fail-Json $result $ErrorMessage - } - } -} - -Function Remove-PsModule { - param( - [Parameter(Mandatory=$true)] - [string]$Name, - [bool]$CheckMode - ) - # If module is present, unistalls it. - if (Get-Module -Listavailable|?{$_.name -eq $Name}){ - try{ - Uninstall-Module -Name $Name -Confirm:$false -Force -ErrorAction Stop -WhatIf:$CheckMode | out-null - $result.output = "Module $($Name) removed" - $result.changed = $true - } - catch{ - $ErrorMessage = "Problems removing $($Name) module: $($_.Exception.Message)" - Fail-Json $result $ErrorMessage - } - - } - else{ - $result.output = "Module $($Name) not present" - } -} - -# Check powershell version, fail if < 5.0 +# Check PowerShell version, fail if < 5.0 and required modules are not installed $PsVersion = $PSVersionTable.PSVersion -if ($PsVersion.Major -lt 5){ - $ErrorMessage = "Powershell 5.0 or higher is needed" - Fail-Json $result $ErrorMessage +if ($PsVersion.Major -lt 5 ) { + $PrereqModulesInstalled = Install-PrereqModule -TestInstallationOnly + if ( -not $PrereqModulesInstalled ) { + $ErrorMessage = "Modules PowerShellGet and PackageManagement in versions 1.6.0 and 1.1.7 respectively have to be installed before using the win_psmodule." + Fail-Json $result $ErrorMessage + } } +if ( $required_version -and ( $minimum_version -or $maximum_version ) ) { + $ErrorMessage = "Parameters required_version and minimum/maximum_version are mutually exclusive." + Fail-Json $result $ErrorMessage +} + +if ( $allow_prerelease -and ( $minimum_version -or $maximum_version ) ) { + $ErrorMessage = "Parameters minimum_version, maximum_version can't be used with the parameter allow_prerelease." + Fail-Json $result $ErrorMessage +} + +if ( $allow_prerelease -and $state -eq "absent" ) { + $ErrorMessage = "The parameter allow_prerelease can't be used with state set to 'absent'." + Fail-Json $result $ErrorMessage +} + +if ( ($state -eq "latest") -and + ( $required_version -or $minimum_version -or $maximum_version ) ) { + $ErrorMessage = "When the parameter state is equal 'latest' you can use any of required_version, minimum_version, maximum_version." + Fail-Json $result $ErrorMessage +} + +if ( $repo -and (-not $url) ) { + $RepositoryExists = Get-PSRepository -Name $repo -ErrorAction Ignore + if ( $null -eq $RepositoryExists) { + $ErrorMessage = "The repository $repo doesn't exist." + Fail-Json $result $ErrorMessage + } + +} + +if ( ($allow_clobber -or $allow_prerelease -or $skip_publisher_check -or + $required_version -or $minimum_version -or $maximum_version) ) { + # Update the PowerShellGet and PackageManagement modules. + # It's required to support AllowClobber, AllowPrerelease parameters. + Install-PrereqModule -CheckMode $check_mode +} + +Import-Module -Name PackageManagement, PowerShellGet + if ($state -eq "present") { if (($repo) -and ($url)) { - Install-Repository -Name $repo -Url $url -CheckMode $check_mode + Install-Repository -Name $repo -Url $url -CheckMode $check_mode } else { $ErrorMessage = "Repository Name and Url are mandatory if you want to add a new repository" } - Install-PsModule -Name $Name -Repository $repo -CheckMode $check_mode -AllowClobber $allow_clobber; + if ($name) { + $ht = @{ + Name = $name + RequiredVersion = $required_version + MinimumVersion = $minimum_version + MaximumVersion = $maximum_version + Repository = $repo + AllowClobber = $allow_clobber + SkipPublisherCheck = $skip_publisher_check + AllowPrerelease = $allow_prerelease + CheckMode = $check_mode + } + Install-PsModule @ht + } } -else { - if ($repo) { +elseif ($state -eq "absent") { + if ($repo) { Remove-Repository -Name $repo -CheckMode $check_mode } - Remove-PsModule -Name $Name -CheckMode $check_mode + + if ($name) { + $ht = @{ + Name = $Name + CheckMode = $check_mode + RequiredVersion = $required_version + MinimumVersion = $minimum_version + MaximumVersion = $maximum_version + } + Remove-PsModule @ht + } +} +elseif ( $state -eq "latest") { + + $ht = @{ + Name = $Name + AllowPrerelease = $allow_prerelease + Repository = $repo + CheckMode = $check_mode + } + + $LatestVersion = Find-LatestPsModule @ht + + $ExistingModule = Get-PsModule $Name + + if ( $LatestVersion.Version -ne $ExistingModule.Version ) { + + $ht = @{ + Name = $Name + RequiredVersion = $LatestVersion + Repository = $repo + AllowClobber = $allow_clobber + SkipPublisherCheck = $skip_publisher_check + AllowPrerelease = $allow_prerelease + CheckMode = $check_mode + } + Install-PsModule @ht + } } Exit-Json $result diff --git a/lib/ansible/modules/windows/win_psmodule.py b/lib/ansible/modules/windows/win_psmodule.py index cbdc4093886..21312cbcb4d 100644 --- a/lib/ansible/modules/windows/win_psmodule.py +++ b/lib/ansible/modules/windows/win_psmodule.py @@ -1,6 +1,7 @@ #!/usr/bin/python # -*- coding: utf-8 -*- +# Copyright: (c) 2018, Wojciech Sciesinski # Copyright: (c) 2017, Daniele Lazzari # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) @@ -15,20 +16,58 @@ DOCUMENTATION = r''' --- module: win_psmodule version_added: "2.4" -short_description: Adds or removes a Powershell Module +short_description: Adds or removes a Windows PowerShell module description: - - This module helps to install Powershell modules and register custom modules repository on Windows Server. + - This module helps to install Windows PowerShell modules and register custom modules repository on Windows-based systems. options: name: description: - - Name of the powershell module that has to be installed. + - Name of the Windows PowerShell module that has to be installed. type: str required: yes + state: + description: + - If C(present) a new module is installed. + - If C(absent) a module is removed. + - If C(latest) a module is updated to the newest version. This option was added in version 2.8. + type: str + choices: [ absent, latest, present ] + default: present + required_version: + description: + - The exact version of the PowerShell module that has to be installed. + type: str + version_added: "2.8" + minimum_version: + description: + - The minimum version of the PowerShell module that has to be installed. + type: str + version_added: "2.8" + maximum_version: + description: + - The maximum version of the PowerShell module that has to be installed. + type: str + version_added: "2.8" allow_clobber: description: - - If C(yes) imports all commands, even if they have the same names as commands that already exists. Available only in Powershell 5.1 or higher. + - If C(yes) allows install modules that contains commands those have the same names as commands that already exists. type: bool default: no + skip_publisher_check: + description: + - If C(yes), allows you to install a different version of a module that already exists on your computer in the case when a different one + is not digitally signed by a trusted publisher and the newest existing module is digitally signed by a trusted publisher. + type: bool + default: no + version_added: "2.8" + allow_prerelease: + description: + - If C(yes) installs modules marked as prereleases. + - It doesn't work with the parameters C(minimum_version) and/or C(maximum_version). + - It doesn't work with the C(state) set to absent. + type: bool + default: no + version_added: "2.8" repository: description: - Name of the custom repository to register or use. @@ -37,50 +76,60 @@ options: description: - URL of the custom repository to register. type: str - state: - description: - - If C(present) a new module is installed. - - If C(absent) a module is removed. - type: str - choices: [ absent, present ] - default: present notes: - - Powershell 5.0 or higher is needed. + - PowerShell modules needed + - PowerShellGet >= 1.6.0 + - PackageManagement >= 1.1.7 + - PowerShell package provider needed + - NuGet >= 2.8.5.201 + - On PowerShell 5.x required modules and a package provider will be updated under the first run of the win_psmodule module. + - On PowerShell 3.x and 4.x you have to install them before using the win_psmodule. seealso: - module: win_psrepository author: +- Wojciech Sciesinski (@it-praktyk) - Daniele Lazzari (@dlazz) ''' EXAMPLES = r''' --- -- name: Add a powershell module +- name: Add a PowerShell module win_psmodule: - name: PowershellModule + name: PowerShellModule state: present -- name: Add a powershell module and register a repository +- name: Add an exact version of PowerShell module + win_psmodule: + name: PowerShellModule + required_version: "4.0.2" + state: present + +- name: Install or update an existing PowerShell module to the newest version + win_psmodule: + name: PowerShellModule + state: latest + +- name: Install newer version of built-in Windows module + win_psmodule: + name: Pester + skip_publisher_check: yes + state: present + +- name: Add a PowerShell module and register a repository win_psmodule: name: MyCustomModule repository: MyRepository - url: https://myrepo.com state: present -- name: Add a powershell module from a specific repository +- name: Add a PowerShell module from a specific repository win_psmodule: - name: PowershellModule + name: PowerShellModule repository: MyRepository state: present -- name: Remove a powershell module +- name: Remove a PowerShell module win_psmodule: - name: PowershellModule - state: absent - -- name: Remove a powershell module and a repository - win_psmodule: - name: MyCustomModule - repository: MyRepository + name: PowerShellModule state: absent ''' diff --git a/test/integration/targets/win_psmodule/defaults/main.yml b/test/integration/targets/win_psmodule/defaults/main.yml index fbfdf97cce7..9c89b53b254 100644 --- a/test/integration/targets/win_psmodule/defaults/main.yml +++ b/test/integration/targets/win_psmodule/defaults/main.yml @@ -1,7 +1,27 @@ --- - powershell_module: powershell-yaml wrong_module: powershell_yaml allow_clobber_module: PowerShellCookbook +fake_repo_name: FakeRepo custom_repo_path: C:\_repo custom_repo_name: PSRegisterRepo + +powershell_module_required_version: 0.3.4 +powershell_module_maximum_version_request: 0.2.2 +powershell_module_maximum_version_result: 0.2 +powershell_module_ultra_high_version: 15.0.0 +powershell_module_ultra_low_version: 0.0.1 + +skip_publisher_check_module: Pester + +powershell_module_2: Pester +powershell_module_2_minimum_version_request: 3.1.2 +powershell_module_2_maximum_version_request: 3.3.0 +powershell_module_2_minimum_maximum_version_result: 3.2.0 + +allow_prerelease_module: Pester +allow_prerelease_version: 4.4.0-beta2 + +myget_powershell_module: xActiveDirectory +myget_repository_name: My Get +myget_repository_url: https://www.myget.org/F/powershellgetdemo/api/v2 diff --git a/test/integration/targets/win_psmodule/meta/main.yml b/test/integration/targets/win_psmodule/meta/main.yml new file mode 100644 index 00000000000..bdea853d75a --- /dev/null +++ b/test/integration/targets/win_psmodule/meta/main.yml @@ -0,0 +1,2 @@ +dependencies: +- prepare_win_tests diff --git a/test/integration/targets/win_psmodule/tasks/clean.yml b/test/integration/targets/win_psmodule/tasks/clean.yml new file mode 100644 index 00000000000..c56d751b6b0 --- /dev/null +++ b/test/integration/targets/win_psmodule/tasks/clean.yml @@ -0,0 +1,30 @@ +# This file is part of Ansible + +# test code for the win_psmodule module when using winrm connection +# Copyright: (c) 2018, Wojciech Sciesinski +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +--- +- name: uninstall any versions of modules used for tests + win_shell: | + $ModulesToUninstall = @('powershell-yaml', 'Pester', 'PowerShellCookbook', 'xActiveDirectory') + ForEach ( $ModuleToUninstall in $ModulesToUninstall ) { + Uninstall-Module $ModuleToUninstall -AllVersions -Force -ErrorAction Ignore + } + changed_when: false + +- name: unregister the custom repo + win_psrepository: + name: "{{ item | quote }}" + state: absent + changed_when: false + with_items: + - "{{ custom_repo_name }}" + - "{{ myget_repository_name }}" + +- name: remove the custom repo folder + win_file: + path: "{{ custom_repo_path }}" + state: absent + changed_when: false + ignore_errors: yes diff --git a/test/integration/targets/win_psmodule/tasks/main.yml b/test/integration/targets/win_psmodule/tasks/main.yml index 7daa4685503..cbac2c9f92a 100644 --- a/test/integration/targets/win_psmodule/tasks/main.yml +++ b/test/integration/targets/win_psmodule/tasks/main.yml @@ -1,28 +1,95 @@ -# test code for the win_psmodule module when using winrm connection -# (c) 2017, Daniele Lazzari - # 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 . +# test code for the win_psmodule module when using winrm connection +# Copyright: (c) 2018, Wojciech Sciesinski +# Copyright: (c) 2017, Daniele Lazzari +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -- name: get facts - setup: +- name: get PowerShell version + win_shell: '$PSVersionTable.PSVersion.Major' + changed_when: false + register: powershell_major_version -- name: Perform integration tests for Powershell 5+ - when: ansible_powershell_version >= 5 +- name: update PackageManagement and PowerShellGet when PowerShell < 5.0 + when: powershell_major_version.stdout | int < 5 block: + - name: download PackageManagement + win_get_url: + url: https://s3.amazonaws.com/ansible-ci-files/test/integration/targets/win_psmodule/PackageManagement_x64.msi + dest: '{{ win_output_dir }}\PackageManagement_x64.msi' - - name: run all tasks - include: test.yml + - name: install PackageManagement + win_package: + path: '{{ win_output_dir }}\PackageManagement_x64.msi' + state: present + + - name: create the required folder + win_file: + path: 'C:\Program Files\PackageManagement\ProviderAssemblies' + state: directory + + - name: download nuget + win_get_url: + url: https://s3.amazonaws.com/ansible-ci-files/test/integration/targets/win_psmodule/nuget.exe + dest: 'C:\Program Files\PackageManagement\ProviderAssemblies\NuGet-anycpu.exe' + + - name: update NuGet provider + win_shell: 'Find-PackageProvider -Name Nuget -ForceBootstrap -IncludeDependencies' + + - name: download and save the nevest version of the PackageManagement module from PowerShell Gallery + win_shell: 'Save-Module -Name PackageManagement, PowerShellGet -Path {{ win_output_dir }} -Force' + + - name: unload PackageManagement and PowerShellGet modules + win_shell: 'Remove-Module -Name PackageManagement,PowerShellGet -Force -ErrorAction Ignore' + ignore_errors: yes + + - name: get PSModulePath + win_shell: "$($Env:PSModulePath -Split ';')[0]" + register: psmodulepath + + - name: remove older versions of the PackageManagement and PowerShellGet + win_file: + path: "{{ psmodulepath.stdout | trim }}\\{{ item }}" + state: absent + with_items: + - PackageManagement + - PowerShellGet + + - name: create required folder + win_file: + path: "{{ psmodulepath.stdout | trim }}" + state: directory + + - name: update PowerShellGet and PackageManagement modules + win_shell: 'Copy-Item -Path {{ win_output_dir }}\{{ item }} -Destination {{ psmodulepath.stdout | trim }}\ -Recurse -Force' + with_items: + - PackageManagement + - PowerShellGet + +- name: update NuGet version + when: powershell_major_version.stdout | int >= 5 + win_shell: | + $nuget_exists = (Get-PackageProvider | Where-Object { $_.Name -eq 'Nuget' } | Measure-Object).Count -eq 1 + + if ( $nuget_exists ) { + $nuget_outdated = (Get-PackageProvider -Name NuGet -ErrorAction Ignore).Version -lt [Version]"2.8.5.201" + } + + if ( -not $nuget_exists -or $nuget_outdated ) { + Find-PackageProvider -Name Nuget -ForceBootstrap -IncludeDependencies -Force + } + +- name: perform cleanup before tests run + include: clean.yml + +- name: run tests + include: tests.yml + +- name: peform legacy (backward compatibility) tests + when: powershell_major_version.stdout | int == 5 + block: + - name: perform cleanup before legacy tests run + include: clean.yml + + - name: run legacy tests + include: tests_legacy.yml diff --git a/test/integration/targets/win_psmodule/tasks/tests.yml b/test/integration/targets/win_psmodule/tasks/tests.yml new file mode 100644 index 00000000000..63370ad04cc --- /dev/null +++ b/test/integration/targets/win_psmodule/tasks/tests.yml @@ -0,0 +1,808 @@ +# This file is part of Ansible + +# test code for the win_psmodule module when using winrm connection +# Copyright: (c) 2018, Wojciech Sciesinski +# Copyright: (c) 2017, Daniele Lazzari +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +--- + +- name: "get the latest version of the {{ powershell_module }} module in PowerShell Gallery" + win_shell: "((Find-Module -Name {{ powershell_module }}).Version).ToString()" + changed_when: false + register: module_latest_version + +- name: "get {{ skip_publisher_check_module }} is preinstalled" + win_shell: "(Get-Module -Name {{ skip_publisher_check_module }} -ListAvailable -ErrorAction Ignore | Measure-Object).Count" + register: skip_publisher_module_exist + +- name: "check installing module from Powershell Gallery - without version - check mode: true" + win_psmodule: + name: "{{ powershell_module }}" + state: present + check_mode: yes + register: module_without_version_setup_1 + +- name: get result installing module from Powershell Gallery - without version + win_shell: "(Get-Module -Name {{ powershell_module }} -ListAvailable -ErrorAction Ignore | Where-Object { $_.Version -eq '{{ module_latest_version.stdout | trim }}' } | Measure-Object).Count -eq 1" + changed_when: false + register: result_module_without_version_setup_1 + +- name: "test installing module from Powershell Gallery - without version - check mode: true" + assert: + that: + - module_without_version_setup_1 is changed + - result_module_without_version_setup_1.stdout | trim | bool == false + +- name: "check installing module from Powershell Gallery - without version - check mode: false" + win_psmodule: + name: "{{ powershell_module }}" + state: present + register: module_without_version_setup_1 + +- name: "get result installing module from Powershell Gallery - without version - check mode: false" + win_shell: "(Get-Module -Name {{ powershell_module }} -ListAvailable -ErrorAction Ignore | Where-Object { $_.Version -eq '{{ module_latest_version.stdout | trim }}' } | Measure-Object).Count -eq 1" + changed_when: false + register: result_module_without_version_setup_1 + +- name: "test installing module from Powershell Gallery - without version - check mode: false" + assert: + that: + - module_without_version_setup_1 is changed + - result_module_without_version_setup_1.stdout | trim | bool == true + +- name: check idempotency installing module from PowerShell Gallery - without version + win_psmodule: + name: "{{ powershell_module }}" + state: present + register: module_without_version_setup_2 + +- name: test idempotency installing module from PowerShell Gallery - without version + assert: + that: + - module_without_version_setup_2 is not changed + +- name: "check uninstalling PowerShell module - without version - check mode: true" + win_psmodule: + name: "{{ powershell_module }}" + state: absent + check_mode: yes + register: module_uninstall_without_version + +- name: "get result uninstalling PowerShell module - without version - check mode: true" + win_shell: "(Get-Module -Name {{ powershell_module }} -ListAvailable | Measure-Object ).Count -ge 1" + changed_when: false + register: result_module_uninstall_without_version + +- name: "test uninstalling PowerShell module - without version - check mode: true" + assert: + that: + - module_uninstall_without_version is changed + - result_module_uninstall_without_version.stdout | trim | bool == true + +- name: "check uninstalling PowerShell module - without version - check mode: false" + win_psmodule: + name: "{{ powershell_module }}" + state: absent + register: module_uninstall_without_version + +- name: "get result uninstalling PowerShell module - without version - check mode: false" + win_shell: "(Get-Module -Name {{ powershell_module }} -ListAvailable | Measure-Object ).Count -eq 0" + changed_when: false + register: result_module_uninstall_without_version + +- name: "test uninstalling PowerShell module - without version - check mode: false" + assert: + that: + - module_uninstall_without_version is changed + - result_module_uninstall_without_version.stdout | trim | bool == true + +- name: check idempotency uninstalling PowerShell module - without version + win_psmodule: + name: "{{ powershell_module }}" + state: absent + register: module_uninstall_2 + +- name: test idempotency uninstalling PowerShell module - without version + assert: + that: + - module_uninstall_2 is not changed + +- name: "check installing module from Powershell Gallery - required_version - check mode: true" + win_psmodule: + name: "{{ powershell_module }}" + required_version: "{{ powershell_module_required_version }}" + state: present + check_mode: yes + register: module_required_version_setup_1 + +- name: "get result installing module from Powershell Gallery - required_version - check mode: true" + win_shell: "(Get-Module -Name {{ powershell_module }} -ListAvailable -ErrorAction Ignore | Where-Object { $_.Version -eq '{{ powershell_module_required_version }}' } | Measure-Object).Count -eq 1" + changed_when: false + register: result_module_required_version_setup_1 + +- name: "test installing module from Powershell Gallery - required_version - check mode: true" + assert: + that: + - module_required_version_setup_1 is changed + - result_module_required_version_setup_1.stdout | trim | bool == false + +- name: "check installing module from Powershell Gallery - required_version - check mode: false" + win_psmodule: + name: "{{ powershell_module }}" + required_version: "{{ powershell_module_required_version }}" + state: present + register: module_required_version_setup_1 + +- name: "get result installing module from Powershell Gallery - required_version - check mode: false" + win_shell: "(Get-Module -Name {{ powershell_module }} -ListAvailable -ErrorAction Ignore | Where-Object { $_.Version -eq '{{ powershell_module_required_version }}' } | Measure-Object).Count -eq 1" + changed_when: false + register: result_module_required_version_setup_1 + +- name: "test installing module from Powershell Gallery - required_version - check mode: false" + assert: + that: + - module_required_version_setup_1 is changed + - result_module_required_version_setup_1.stdout | trim | bool == true + +- name: check idempotency installing module from Powershell Gallery - required_version + win_psmodule: + name: "{{ powershell_module }}" + required_version: "{{ powershell_module_required_version }}" + state: present + register: module_required_version_setup_2 + +- name: test idempotency installing module from Powershell Gallery - required_version + assert: + that: + - module_required_version_setup_2 is not changed + +- name: "check uninstall PowerShell module - required_version - check mode: false" + win_psmodule: + name: "{{ powershell_module }}" + required_version: "{{ powershell_module_required_version }}" + state: absent + register: module_uninstall_required_version + +- name: "get result uninstall PowerShell module - required_version - check mode: false" + win_shell: "(Get-Module -Name {{ powershell_module }} -ListAvailable -ErrorAction Ignore | Where-Object { $_.Version -eq '{{ powershell_module_required_version }}' } | Measure-Object).Count -eq 0" + changed_when: false + register: result_module_uninstall_required_version + +- name: "test PowerShell module uninstall - required_version - check mode: false" + assert: + that: + - module_uninstall_required_version is changed + - result_module_uninstall_required_version.stdout | trim | bool == true + +- name: check installing module from Powershell Gallery - required_version but not existing + win_psmodule: + name: "{{ powershell_module }}" + required_version: "{{ powershell_module_ultra_high_version }}" + state: present + register: module_required_version_setup_3 + ignore_errors: yes + +- name: test installing module from Powershell Gallery - required_version but not existing + assert: + that: + - module_required_version_setup_3 is not changed + - module_required_version_setup_3 is failed + - "'Problems installing {{ powershell_module }} module: No match was found for the specified search criteria' in module_required_version_setup_3.msg" + +- name: "check installing module from Powershell Gallery - maximum_version - check mode: true" + win_psmodule: + name: "{{ powershell_module }}" + maximum_version: "{{ powershell_module_maximum_version_request }}" + state: present + check_mode: yes + register: module_maximum_version_setup_1 + +- name: "get result installing module from Powershell Gallery - maximum_version - check mode: true" + win_shell: "(Get-Module -Name {{ powershell_module }} -ListAvailable -ErrorAction Ignore | Where-Object { $_.Version -eq '{{ powershell_module_maximum_version_result }}' } | Measure-Object).Count -eq 1" + changed_when: false + register: result_module_maximum_version_setup_1 + +- name: "test installing module from Powershell Gallery - maximum_version - check mode: true" + assert: + that: + - module_maximum_version_setup_1 is changed + - result_module_maximum_version_setup_1.stdout | trim | bool == false + +- name: "check installing module from Powershell Gallery - maximum_version - check mode: false" + win_psmodule: + name: "{{ powershell_module }}" + maximum_version: "{{ powershell_module_maximum_version_request }}" + state: present + register: module_maximum_version_setup_1 + +- name: "get result installing module from Powershell Gallery - maximum_version - check mode: false" + win_shell: "(Get-Module -Name {{ powershell_module }} -ListAvailable -ErrorAction Ignore | Where-Object { $_.Version -eq '{{ powershell_module_maximum_version_result }}' } | Measure-Object).Count -eq 1" + changed_when: false + register: result_module_maximum_version_setup_1 + +- name: "test installing module from Powershell Gallery - maximum_version - check mode: false" + assert: + that: + - module_maximum_version_setup_1 is changed + - result_module_maximum_version_setup_1.stdout | trim | bool == true + +- name: check idempotency installing module from Powershell Gallery - maximum_version + win_psmodule: + name: "{{ powershell_module }}" + maximum_version: "{{ powershell_module_maximum_version_request }}" + state: present + register: module_maximum_version_setup_2 + +- name: test idempotency installing module from Powershell Gallery - maximum_version + assert: + that: + - module_maximum_version_setup_2 is not changed + +- name: "check uninstall PowerShell module - maximum_version - check mode: true" + win_psmodule: + name: "{{ powershell_module }}" + maximum_version: "{{ powershell_module_maximum_version_request }}" + state: absent + check_mode: yes + register: module_uninstall_maximum_version + +- name: "get result uninstall PowerShell module - maximum_version - check mode: true" + win_shell: "(Get-Module -Name {{ powershell_module }} -ListAvailable -ErrorAction Ignore | Where-Object { $_.Version -eq '{{ powershell_module_maximum_version_result }}' } | Measure-Object).Count -eq 1" + changed_when: false + register: result_module_uninstall_maximum_version + +- name: "test PowerShell module uninstall - maximum_version - check mode: true" + assert: + that: + - module_uninstall_maximum_version is changed + - result_module_uninstall_maximum_version.stdout | trim | bool == true + +- name: "check uninstall PowerShell module - maximum_version - check mode: false" + win_psmodule: + name: "{{ powershell_module }}" + maximum_version: "{{ powershell_module_maximum_version_request }}" + state: absent + register: module_uninstall_maximum_version + +- name: "get result uninstall PowerShell module - maximum_version - check mode: false" + win_shell: "(Get-Module -Name {{ powershell_module }} -ListAvailable -ErrorAction Ignore | Where-Object { $_.Version -eq '{{ powershell_module_maximum_version_result }}' } | Measure-Object).Count -eq 0" + changed_when: false + register: result_module_uninstall_maximum_version + +- name: "test PowerShell module uninstall - maximum_version - check mode: false" + assert: + that: + - module_uninstall_maximum_version is changed + - result_module_uninstall_maximum_version.stdout | trim | bool == true + +- name: check installing module from Powershell Gallery - maximum_version but not existing + win_psmodule: + name: "{{ powershell_module }}" + maximum_version: "{{ powershell_module_ultra_low_version }}" + state: present + register: module_maximum_version_setup_3 + ignore_errors: yes + +- name: test installing module from Powershell Gallery - maximum_version but not existing + assert: + that: + - module_maximum_version_setup_3 is not changed + - module_maximum_version_setup_3 is failed + + # Don't move skip_publisher_check tests below minimum_version and maximum_version tests +- name: check installing module with skip_publisher_check not active + win_psmodule: + name: "{{ skip_publisher_check_module }}" + # Adding a required version is required because the tested module + # is bundled within OS and has not be digitally signed (since 4.4.3 it's) + required_version: "4.2.0" + # Run only for systems with built'in module e.g. Windows 10 + when: skip_publisher_module_exist.stdout | int == 1 + register: fail_skip_publisher_check + ignore_errors: yes + +- name: test installing module with skip_publisher_check not active + assert: + that: + - fail_skip_publisher_check is failed + - "'being installed is not catalog signed. Ensure that the version' in fail_skip_publisher_check.msg" + when: skip_publisher_module_exist.stdout | int >= 1 + +- name: "check installing module with skip_publisher_check active - check mode: true" + win_psmodule: + name: "{{ skip_publisher_check_module }}" + # Adding a required version is required because the tested module + # is bundled within OS and has not be digitally signed (since 4.4.3 it's) + required_version: "4.2.0" + skip_publisher_check: yes + check_mode: yes + register: ok_skip_publisher_check + +- name: "get result installing module with skip_publisher_check active - check mode: true" + win_shell: "(Get-Module -Name {{ skip_publisher_check_module }} -ListAvailable -ErrorAction Ignore | Measure-Object).Count -eq {{ skip_publisher_module_exist.stdout | int }}" + changed_when: false + register: result_ok_skip_publisher_check + +- name: "test installing module with skip_publisher_check active - check mode: true" + assert: + that: + - ok_skip_publisher_check is changed + - result_ok_skip_publisher_check.stdout | trim | bool == true + +- name: "check installing module with skip_publisher_check active - check mode: false" + win_psmodule: + name: "{{ skip_publisher_check_module }}" + # Adding a required version is required because the tested module + # is bundled within OS and has not be digitally signed (since 4.4.3 it's) + required_version: "4.2.0" + skip_publisher_check: yes + register: ok_skip_publisher_check + +- name: "get result installing module with skip_publisher_check active - check mode: false" + win_shell: "(Get-Module -Name {{ skip_publisher_check_module }} -ListAvailable -ErrorAction Ignore | Measure-Object).Count -eq {{ skip_publisher_module_exist.stdout | int + 1 }}" + changed_when: false + register: result_ok_skip_publisher_check + +- name: "test installing module with skip_publisher_check active - check mode: false" + assert: + that: + - ok_skip_publisher_check is changed + - result_ok_skip_publisher_check.stdout | trim | bool == true + +- name: "check Powershell Gallery module setup - minimum_version and maximum_version - check mode: true" + win_psmodule: + name: "{{ powershell_module_2 }}" + minimum_version: "{{ powershell_module_2_minimum_version_request }}" + maximum_version: "{{ powershell_module_2_maximum_version_request }}" + skip_publisher_check: yes + state: present + check_mode: yes + register: module_minimum_maximim_version_setup_1 + +- name: "get result Powershell Gallery module setup - minimum_version and maximum_version - check mode: true" + win_shell: "(Get-Module -Name {{ powershell_module_2 }} -ListAvailable -ErrorAction Ignore | Where-Object { $_.Version -eq '{{ powershell_module_2_minimum_maximum_version_result }}' } | Measure-Object).Count -eq 1" + changed_when: false + register: result_module_minimum_maximim_version_setup_1 + +- name: "test Powershell Gallery module setup - minimum_version and maximum_version - check mode: true" + assert: + that: + - module_minimum_maximim_version_setup_1 is changed + - result_module_minimum_maximim_version_setup_1.stdout | trim | bool == false + +- name: "check Powershell Gallery module setup - minimum_version and maximum_version - check mode: false" + win_psmodule: + name: "{{ powershell_module_2 }}" + minimum_version: "{{ powershell_module_2_minimum_version_request }}" + maximum_version: "{{ powershell_module_2_maximum_version_request }}" + skip_publisher_check: yes + state: present + register: module_minimum_maximim_version_setup_1 + +- name: "get result Powershell Gallery module setup - minimum_version and maximum_version - check mode: false" + win_shell: "(Get-Module -Name {{ powershell_module_2 }} -ListAvailable -ErrorAction Ignore | Where-Object { $_.Version -eq '{{ powershell_module_2_minimum_maximum_version_result }}' } | Measure-Object).Count -eq 1" + changed_when: false + register: result_module_minimum_maximim_version_setup_1 + +- name: "test Powershell Gallery module setup - minimum_version and maximum_version - check mode: false" + assert: + that: + - module_minimum_maximim_version_setup_1 is changed + - result_module_minimum_maximim_version_setup_1.stdout | trim | bool == true + +- name: check idempotency reinstalling module - minimum_version and maximum_version + win_psmodule: + name: "{{ powershell_module_2 }}" + minimum_version: "{{ powershell_module_2_minimum_version_request }}" + maximum_version: "{{ powershell_module_2_maximum_version_request }}" + state: present + register: module_minimum_maximim_version_setup_2 + +- name: test idempotency reinstalling module - minimum_version and maximum_version + assert: + that: + - module_minimum_maximim_version_setup_2 is not changed + +- name: "check uninstall PowerShell module - minimum_version and maximum_version - check mode: true" + win_psmodule: + name: "{{ powershell_module_2 }}" + minimum_version: "{{ powershell_module_2_minimum_version_request }}" + maximum_version: "{{ powershell_module_2_maximum_version_request }}" + state: absent + check_mode: yes + register: module_uninstall_minimum_maximum_version + +- name: "get result uninstall PowerShell module - minimum_version and maximum_version - check mode: true" + win_shell: "(Get-Module -Name {{ powershell_module_2 }} -ListAvailable -ErrorAction Ignore | Where-Object { $_.Version -eq '{{ powershell_module_2_minimum_maximum_version_result }}' } | Measure-Object).Count -eq 1" + changed_when: false + register: result_module_uninstall_minimum_maximum_version + +- name: "test uninstall PowerShell module - minimum_version and maximum_version - check mode: true" + assert: + that: + - module_uninstall_minimum_maximum_version is changed + - result_module_uninstall_minimum_maximum_version.stdout | trim | bool == true + +- name: "check uninstall PowerShell module - minimum_version and maximum_version - check mode: false" + win_psmodule: + name: "{{ powershell_module_2 }}" + minimum_version: "{{ powershell_module_2_minimum_version_request }}" + maximum_version: "{{ powershell_module_2_maximum_version_request }}" + state: absent + register: module_uninstall_minimum_maximum_version + +- name: "get result uninstall PowerShell module - minimum_version and maximum_version - check mode: false" + win_shell: "(Get-Module -Name {{ powershell_module_2 }} -ListAvailable -ErrorAction Ignore | Where-Object { $_.Version -eq '{{ powershell_module_2_minimum_maximum_version_result }}' } | Measure-Object).Count -eq 0" + changed_when: false + register: result_module_uninstall_minimum_maximum_version + +- name: "test uninstall PowerShell module - minimum_version and maximum_version - check mode: false" + assert: + that: + - module_uninstall_minimum_maximum_version is changed + - result_module_uninstall_minimum_maximum_version.stdout | trim | bool == true + +- name: check installing module with allow_clobber not active + win_psmodule: + name: "{{ allow_clobber_module }}" + register: fail_allow_clobber + ignore_errors: yes + +- name: test installing module with allow_clobber not active + assert: + that: + - fail_allow_clobber is failed + - "'The following commands are already available on this system' in fail_allow_clobber.msg" + +- name: "check installing module with allow_clobber active - check mode: true" + win_psmodule: + name: "{{ allow_clobber_module }}" + allow_clobber: yes + check_mode: yes + register: ok_allow_clobber + +- name: "get result installing module with allow_clobber active - check mode: true" + win_shell: "(Get-Module -Name {{ allow_clobber_module }} -ListAvailable -ErrorAction Ignore | Measure-Object).Count -eq 1" + changed_when: false + register: result_ok_allow_clobber + +- name: "test installing module with allow_clobber active - check mode: true" + assert: + that: + - ok_allow_clobber is changed + - result_ok_allow_clobber.stdout | trim | bool == false + +- name: "check installing module with allow_clobber active - check mode: false" + win_psmodule: + name: "{{ allow_clobber_module }}" + allow_clobber: yes + register: ok_allow_clobber + +- name: "get result installing module with allow_clobber active - check mode: false" + win_shell: "(Get-Module -Name {{ allow_clobber_module }} -ListAvailable -ErrorAction Ignore | Measure-Object).Count -eq 1" + changed_when: false + register: result_ok_allow_clobber + +- name: "test installing module with allow_clobber active - check mode: false" + assert: + that: + - ok_allow_clobber is changed + - result_ok_allow_clobber.stdout | trim | bool == true + +- name: "check uninstall PowerShell module allow_clobber - check mode: true" + win_psmodule: + name: "{{ allow_clobber_module }}" + state: absent + check_mode: yes + register: module_uninstall_4 + +- name: "get uninstall PowerShell module allow_clobber - check mode: true" + win_shell: "(Get-Module -Name {{ allow_clobber_module }} -ListAvailable -ErrorAction Ignore | Measure-Object).Count -eq 1" + register: result_module_uninstall_4 + +- name: "test uninstall PowerShell module allow_clobber - check mode: true" + assert: + that: + - module_uninstall_4 is changed + - result_module_uninstall_4.stdout | trim | bool == true + +- name: "check uninstall PowerShell module allow_clobber - check mode: false" + win_psmodule: + name: "{{ allow_clobber_module }}" + state: absent + register: module_uninstall_4 + +- name: "get uninstall PowerShell module allow_clobber - check mode: false" + win_shell: "(Get-Module -Name {{ allow_clobber_module }} -ListAvailable -ErrorAction Ignore | Measure-Object).Count -eq 0" + register: result_module_uninstall_4 + +- name: "test uninstall PowerShell module allow_clobber - check mode: false" + assert: + that: + - module_uninstall_4 is changed + - result_module_uninstall_4.stdout | trim | bool == true + +- name: check installing module with allow_prerelease not active + win_psmodule: + name: "{{ allow_prerelease_module }}" + required_version: "{{ allow_prerelease_version }}" + allow_prerelease: no + skip_publisher_check: yes + register: fail_allow_prerelease + ignore_errors: yes + +- name: test installing module with allow_prerelease not active + assert: + that: + - fail_allow_prerelease is failed + +- name: "check installing prerelease module with allow_prerelease active - check mode: true" + win_psmodule: + name: "{{ allow_prerelease_module }}" + required_version: "{{ allow_prerelease_version }}" + allow_prerelease: yes + skip_publisher_check: yes + check_mode: yes + register: ok_allow_prerelease + +- name: "test installing prerelease module with allow_prerelease active - check mode: true" + assert: + that: + - ok_allow_prerelease is changed + +- name: "check installing prerelease module with allow_prerelease active - check mode: false" + win_psmodule: + name: "{{ allow_prerelease_module }}" + required_version: "{{ allow_prerelease_version }}" + allow_prerelease: yes + skip_publisher_check: yes + register: ok_allow_prerelease + +- name: "test installing prerelease module with allow_prerelease active - check mode: false" + assert: + that: + - ok_allow_prerelease is changed + +- name: check installing module with a wrong name + win_psmodule: + name: "{{ wrong_module }}" + state: present + ignore_errors: yes + register: module_fail + +- name: test installing module with a wrong name + assert: + that: + - module_fail is failed + - "'Problems installing {{ wrong_module }} module: No match was found for the specified search criteria' in module_fail.msg" + +- name: check installing module from Powershell Gallery - without version 3 + win_psmodule: + name: "{{ powershell_module }}" + state: present + register: module_without_version_setup_3 + +- name: get result installing module from Powershell Gallery - without version 3 + win_shell: "(Get-Module -Name {{ powershell_module }} -ListAvailable -ErrorAction Ignore | Where-Object { $_.Version -eq '{{ module_latest_version.stdout | trim }}' } | Measure-Object).Count -eq 1" + changed_when: false + register: result_module_without_version_setup_3 + +- name: test Powershell Gallery module setup - without version 3 + assert: + that: + - module_without_version_setup_3 is changed + - result_module_without_version_setup_3.stdout | trim | bool == true + +- name: check installing module from Powershell Gallery - required_version 4 + win_psmodule: + name: "{{ powershell_module }}" + required_version: "{{ powershell_module_required_version }}" + state: present + register: module_required_version_setup_4 + +- name: get result installing module from Powershell Gallery - required_version 4 + win_shell: "(Get-Module -Name {{ powershell_module }} -ListAvailable -ErrorAction Ignore | Where-Object { $_.Version -eq '{{ powershell_module_required_version }}' } | Measure-Object).Count -eq 1" + changed_when: false + register: result_module_required_version_setup_4 + +- name: test installing module from Powershell Gallery - required_version 4 + assert: + that: + - module_required_version_setup_4 is changed + - result_module_required_version_setup_4.stdout | trim | bool == true + +- name: "check uninstall PowerShell module - required_version - check mode: true" + win_psmodule: + name: "{{ powershell_module }}" + required_version: "{{ powershell_module_required_version }}" + state: absent + check_mode: yes + register: module_uninstall_required_version + +- name: "get result uninstall PowerShell module - required_version - check mode: true" + win_shell: "(Get-Module -Name {{ powershell_module }} -ListAvailable -ErrorAction Ignore | Where-Object { $_.Version -eq '{{ powershell_module_required_version }}' } | Measure-Object).Count -eq 1" + changed_when: false + register: result_module_uninstall_required_version + +- name: "test PowerShell module uninstall - required_version - check mode: true" + assert: + that: + - module_uninstall_required_version is changed + - result_module_uninstall_required_version.stdout | trim | bool == true + +- name: "check uninstall PowerShell module - minimum_version - ultra high version - check mode: true" + win_psmodule: + name: "{{ powershell_module }}" + minimum_version: "{{ powershell_module_ultra_high_version }}" + state: absent + check_mode: yes + register: module_uninstall_minimum_version + +- name: "test Powershell Gallery module setup - minimum_version - ultra high version - check mode: true" + assert: + that: + - module_uninstall_minimum_version is not changed + +- name: "check uninstall PowerShell module - minimum_version - ultra high version - check mode: false" + win_psmodule: + name: "{{ powershell_module }}" + minimum_version: "{{ powershell_module_ultra_high_version }}" + state: absent + register: module_uninstall_minimum_version + +- name: "test Powershell Gallery module setup - minimum_version - ultra high version - check mode: false" + assert: + that: + - module_uninstall_minimum_version is not changed + +- name: check fake custom ps repository registration attempt + win_psmodule: + name: "{{ wrong_module }}" + repository: "{{ fake_repo_name }}" + ignore_errors: yes + register: fake_repo_fail + +- name: test fake custom ps repository registration attempt + assert: + that: + - fake_repo_fail is failed + +- name: check installing module from the My Get repository and registering that repository at the same time + win_psmodule: + name: "{{ myget_powershell_module }}" + repository: "{{ myget_repository_name }}" + url: "{{ myget_repository_url }}" + state: present + register: adding_repository + +- name: get installing module from the My Get repository and registering that repository at the same time + win_shell: | + $repo = Get-PSRepository -Name {{ myget_repository_name | quote }} -ErrorAction Ignore + $module = Get-Module -Name {{ myget_powershell_module }} -ListAvailable + ($repo | Measure-Object).Count + $repo.SourceLocation + $repo.InstallationPolicy + ($module | Measure-Object).Count + register: result_adding_repository + +- name: test installing module from the My Get repository and registering that repository at the same time + assert: + that: + - adding_repository is changed + - result_adding_repository.stdout_lines[0] == '1' + - result_adding_repository.stdout_lines[1] == myget_repository_url + - result_adding_repository.stdout_lines[2] == 'Trusted' + - result_adding_repository.stdout_lines[3] == '1' + +- name: check uninstalling module from the My Get repository and unregistering that repository at the same time + win_psmodule: + name: "{{ myget_powershell_module }}" + repository: "{{ myget_repository_name }}" + state: absent + register: removing_repository + +- name: get uninstalling module from the My Get repository and registering that repository at the same time + win_shell: | + $repo = Get-PSRepository -Name {{ myget_repository_name | quote }} -ErrorAction Ignore + $module = Get-Module -Name {{ myget_powershell_module }} -ListAvailable + ($repo | Measure-Object).Count + ($module | Measure-Object).Count + register: result_removing_repository + +- name: test uninstalling module from the My Get repository and registering that repository at the same time + assert: + that: + - removing_repository is changed + - result_removing_repository.stdout_lines[0] == '0' + - result_removing_repository.stdout_lines[1] == '0' + +# I don't know why Publish-Module doesn't work correctly under Ansible and PowerShell 3.0 +- name: check operations related to the custom repository + when: powershell_major_version.stdout | int >= 4 + block: + - name: "check sample module is uninstalled - check mode: false" + win_psmodule: + name: "{{ powershell_module }}" + state: absent + register: module_uninstall_4 + + - name: "create repository path - check mode: false" + win_file: + path: "{{custom_repo_path}}" + state: directory + + - name: "copy some module to custom repo - check mode: false" + win_shell: | + $ErrorActionPreference = "Stop" + + Save-Module -Name "{{powershell_module}}" -Repository PSGallery -Path $env:Temp | Out-Null + + $repoName = "{{custom_repo_name}}" + $repoPath = "{{custom_repo_path}}" + + Register-PSRepository -Name $repoName -SourceLocation $repoPath -InstallationPolicy Trusted | Out-Null + + Publish-Module -Repository PSRegisterRepo -Path "$env:temp\Powershell-yaml" -Force -Confirm:$false -Verbose | Out-Null + + Start-Sleep -Seconds 15 + + Get-ChildItem -Path $repoPath\* -include *.nupkg | Where-Object { $_.Name -match "{{powershell_module}}" } | ForEach-Object { $_.Name } + + register: saved_package + + - name: "check installing module from custom Powershell repository - check mode: true" + win_psmodule: + name: "{{ powershell_module }}" + state: present + repository: "{{custom_repo_name}}" + check_mode: yes + register: module_from_custom_repo + + - name: "test sample module in custom repo - check mode: false" + assert: + that: + - powershell_module | lower in ((saved_package.stdout_lines | last) | lower) + + - name: "get the latest version of module in custom repo" + win_shell: "((Find-Module -Name {{ powershell_module }} -Repository {{custom_repo_name}}).Version).ToString()" + changed_when: false + register: saved_module_latest_version + + - name: "get result installing module from custom Powershell repository - check mode: true" + win_shell: "(Get-Module -Name {{ powershell_module }} -ListAvailable -ErrorAction Ignore | Where-Object { $_.Version -eq '{{ saved_module_latest_version.stdout }}' } | Measure-Object).Count -eq 1" + changed_when: false + register: result_module_from_custom_repo + + - name: "test installing module from custom Powershell repository - check mode: true" + assert: + that: + - module_from_custom_repo is changed + - result_module_from_custom_repo.stdout | trim | bool == false + + - name: "check installing module from custom Powershell repository - check mode: false" + win_psmodule: + name: "{{ powershell_module }}" + state: present + repository: "{{custom_repo_name}}" + register: module_from_custom_repo + + - name: "get result installing module from custom Powershell repository - check mode: false" + win_shell: "(Get-Module -Name {{ powershell_module }} -ListAvailable -ErrorAction Ignore | Where-Object { $_.Version -eq '{{ saved_module_latest_version.stdout }}' } | Measure-Object).Count -eq 1" + changed_when: false + register: result_module_from_custom_repo + + - name: "test installing module from custom Powershell repository - check mode: false" + assert: + that: + - module_from_custom_repo is changed + - result_module_from_custom_repo.stdout | trim | bool == true + + - name: test module was installed from custom repo + win_shell: "(Get-InstalledModule -Name {{ powershell_module }}).Repository" + register: is_package_customrepo + + - name: test sample module is installed from custom repo + assert: + that: + - is_package_customrepo.stdout_lines[0] == custom_repo_name diff --git a/test/integration/targets/win_psmodule/tasks/test.yml b/test/integration/targets/win_psmodule/tasks/tests_legacy.yml similarity index 81% rename from test/integration/targets/win_psmodule/tasks/test.yml rename to test/integration/targets/win_psmodule/tasks/tests_legacy.yml index c6b2994324b..32a70bfd51d 100644 --- a/test/integration/targets/win_psmodule/tasks/test.yml +++ b/test/integration/targets/win_psmodule/tasks/tests_legacy.yml @@ -1,5 +1,15 @@ +# This file is part of Ansible + +# test code for the win_psmodule module when using winrm connection +# Copyright: (c) 2017, Daniele Lazzari +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + --- +# The file contains tests for backward compatibility only - for Ansible < 2.8. +# They should be removed under a deprecation of the functionalities for adding/removing +# repositories. + - name: install module from Powershell Gallery win_psmodule: name: "{{ powershell_module }}" @@ -46,7 +56,7 @@ - "ok_allow_clobber is changed" - name: check wrong module install attempt - win_psmodule: + win_psmodule: name: "{{ wrong_module }}" state: present ignore_errors: yes @@ -146,35 +156,35 @@ - name: Copy some module to custom repo win_shell: | # Need PSGet 1.6.0 for publishing and named repo usage - $psg = [PSCustomObject]@{ n="PowerShellGet"; v="1.6.0"}; - Remove-Module -Name $psg.n -Force -EA SilentlyContinue; - Import-PackageProvider -Name $psg.n -RequiredVersion $psg.v -EV missingProvider -Force | Out-Null; + $psg = [PSCustomObject]@{ n="PowerShellGet"; v="1.6.0"} + Remove-Module -Name $psg.n -Force -ErrorAction SilentlyContinue + Import-PackageProvider -Name $psg.n -RequiredVersion $psg.v -ErrorVariable missingProvider -Force | Out-Null if($missingProvider){ - Install-PackageProvider -Name $psg.n -RequiredVersion $psg.v -Confirm:$false -Force | Out-Null; - + Install-PackageProvider -Name $psg.n -RequiredVersion $psg.v -Confirm:$false -Force | Out-Null + # Unload previous version - Remove-Module -Name $psg.n -Force -EA SilentlyContinue; - Import-PackageProvider -Name $psg.n -RequiredVersion $psg.v -Force | Out-Null; + Remove-Module -Name $psg.n -Force -ErrorAction SilentlyContinue; + Import-PackageProvider -Name $psg.n -RequiredVersion $psg.v -Force | Out-Null } - $modName = "{{powershell_module}}"; - $temp = $env:Temp; + $modName = "{{powershell_module}}" + $temp = $env:Temp - Save-Module -Name $modName -Repository PSGallery -Path $temp | Out-Null; + Save-Module -Name $modName -Repository PSGallery -Path $temp | Out-Null - $repoName = "{{custom_repo_name}}"; - $repoPath = "{{custom_repo_path}}"; + $repoName = "{{custom_repo_name}}" + $repoPath = "{{custom_repo_path}}" if(!(Test-Path $repoPath)){ - New-Item -Type Directory $repoPath -Force | Out-Null; + New-Item -Type Directory $repoPath -Force | Out-Null } - Register-PSRepository -Name $repoName -SourceLocation $repoPath -InstallationPolicy Trusted | Out-Null; - - Publish-Module -Path "$temp\\$modName" -Repository $repoName -Force -Confirm:$false | Out-Null; - Get-ChildItem "$repoPath\\*" | ? Name -match "$modName.*.nupkg" | % Name; - + Register-PSRepository -Name $repoName -SourceLocation $repoPath -InstallationPolicy Trusted | Out-Null + + Publish-Module -Path "$temp\\$modName" -Repository $repoName -Force -Confirm:$false | Out-Null + Get-ChildItem -Path "$repoPath\\*" | Where-Object { $_.Name -match "$modName.*.nupkg" } | ForEach-Object { $_.Name } + register: saved_package - name: Validate sample module in custom repo diff --git a/test/sanity/pslint/ignore.txt b/test/sanity/pslint/ignore.txt index dc8a96d75c2..3b5340e733a 100644 --- a/test/sanity/pslint/ignore.txt +++ b/test/sanity/pslint/ignore.txt @@ -52,7 +52,6 @@ lib/ansible/modules/windows/win_pagefile.ps1 PSAvoidUsingPositionalParameters lib/ansible/modules/windows/win_pagefile.ps1 PSAvoidUsingWMICmdlet lib/ansible/modules/windows/win_pagefile.ps1 PSUseDeclaredVarsMoreThanAssignments lib/ansible/modules/windows/win_pagefile.ps1 PSUseSupportsShouldProcess -lib/ansible/modules/windows/win_psmodule.ps1 PSAvoidUsingCmdletAliases lib/ansible/modules/windows/win_rabbitmq_plugin.ps1 PSAvoidUsingCmdletAliases lib/ansible/modules/windows/win_rabbitmq_plugin.ps1 PSAvoidUsingInvokeExpression lib/ansible/modules/windows/win_region.ps1 PSAvoidUsingEmptyCatchBlock