Skip to content

Commit

Permalink
Add accept_license option to win_psmodule (#411)
Browse files Browse the repository at this point in the history
* setup a moudle that requires license acceptance

* add tests for accept_license option

* add changelog fragment

* remove check mode checks

* fix nuspec

* add license URL

* finish(?) license requirements

* add license.txt

* fixups

* try newer nuspec schema

* use PSGet format 2.0

* check for specific license failure message in test

* add accept_license option

* fix formatting

* add note about check mode
  • Loading branch information
briantist authored Jul 11, 2022
1 parent b5b7718 commit 8ebbf99
Show file tree
Hide file tree
Showing 8 changed files with 128 additions and 19 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
minor_changes:
- win_psmodule module - add ``accept_license`` option to allow for installing modules that require license acceptance (https://github.com/ansible-collections/community.windows/issues/340).
13 changes: 10 additions & 3 deletions plugins/modules/win_psmodule.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ $state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "prese
$allow_clobber = Get-AnsibleParam -obj $params -name "allow_clobber" -type "bool" -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
$accept_license = Get-AnsibleParam -obj $params -name "accept_license" -type "bool" -default $false

$result = @{changed = $false
output = ""
Expand Down Expand Up @@ -64,7 +65,8 @@ Function Install-PrereqModule {
Param(
[Switch]$TestInstallationOnly,
[bool]$AllowClobber,
[Bool]$CheckMode
[Bool]$CheckMode,
[bool]$AcceptLicense
)

# Those are minimum required versions of modules.
Expand All @@ -90,6 +92,7 @@ Function Install-PrereqModule {
MinimumVersion = $PrereqModules[$Name]
Force = $true
WhatIf = $CheckMode
AcceptLicense = $AcceptLicense
}
$installCmd = Get-Command -Name Install-Module
if ($installCmd.Parameters.ContainsKey('SkipPublisherCheck')) {
Expand Down Expand Up @@ -212,7 +215,8 @@ Function Install-PsModule {
[Bool]$AllowClobber,
[Bool]$SkipPublisherCheck,
[Bool]$AllowPrerelease,
[Bool]$CheckMode
[Bool]$CheckMode,
[Bool]$AcceptLicense
)

$getParams = @{
Expand All @@ -232,6 +236,7 @@ Function Install-PsModule {
Name = $Name
WhatIf = $CheckMode
Force = $true
AcceptLicense = $AcceptLicense
}

[String[]]$ParametersNames = @("RequiredVersion", "MinimumVersion", "MaximumVersion", "AllowPrerelease",
Expand Down Expand Up @@ -458,7 +463,7 @@ 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 -AllowClobber $allow_clobber -CheckMode $check_mode
Install-PrereqModule -AllowClobber $allow_clobber -CheckMode $check_mode -AcceptLicense $accept_license
}

Import-Module -Name PackageManagement, PowerShellGet
Expand All @@ -483,6 +488,7 @@ if ($state -eq "present") {
AllowPrerelease = $allow_prerelease
CheckMode = $check_mode
Credential = $repo_credential
AcceptLicense = $accept_license
}
Install-PsModule @ht
}
Expand Down Expand Up @@ -528,6 +534,7 @@ elseif ( $state -eq "latest") {
AllowPrerelease = $allow_prerelease
CheckMode = $check_mode
Credential = $repo_credential
AcceptLicense = $accept_license
}
Install-PsModule @ht
}
Expand Down
12 changes: 12 additions & 0 deletions plugins/modules/win_psmodule.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,18 @@
type: str
required: no
version_added: '1.10.0'
accept_license:
description:
- Accepts the module's license.
- Required for modules that require license acceptance, since interactively answering the prompt is not possible.
- Corresponds to the C(-AcceptLicense) parameter of C(Install-Module).
- >-
Installation of a module or a dependency that requires license acceptance cannot be detected in check mode,
but will cause a failure at runtime unless I(accept_license=true).
type: bool
required: no
default: false
version_added: '1.11.0'
url:
description:
- URL of the custom repository to register.
Expand Down
21 changes: 21 additions & 0 deletions tests/integration/targets/win_psmodule/files/module/license.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2019 Ansible

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
<metadata>
<id>--- NAME ---</id>
<version>--- VERSION ---</version>
<authors>Ansible</authors>
<owners>Ansible</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<requireLicenseAcceptance>--- LICACC ---</requireLicenseAcceptance>
<licenseUrl>https://choosealicense.com/licenses/mit/</licenseUrl>
<description>Test for Ansible win_ps* modules</description>
<releaseNotes></releaseNotes>
<copyright>Copyright (c) 2019 Ansible, licensed under MIT.</copyright>
<tags>PSModule PSIncludes_Function PSFunction_--- FUNCTION --- PSCommand_--- FUNCTION ---</tags>
<tags>PowerShellGetFormatVersion_2.0 PSModule PSIncludes_Function PSFunction_--- FUNCTION --- PSCommand_--- FUNCTION ---</tags>
</metadata>
</package>
30 changes: 18 additions & 12 deletions tests/integration/targets/win_psmodule/files/setup_modules.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ $template_path = $args[0]
$template_manifest = Join-Path -Path $template_path -ChildPath template.psd1
$template_script = Join-Path -Path $template_path -ChildPath template.psm1
$template_nuspec = Join-Path -Path $template_path -ChildPath template.nuspec
$template_license = Join-Path -Path $template_path -ChildPath license.txt
$nuget_exe = Join-Path -Path $template_path -ChildPath nuget.exe
$sign_cert = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2 -ArgumentList @(
(Join-Path -Path $template_path -ChildPath sign.pfx),
Expand All @@ -14,14 +15,15 @@ $sign_cert = New-Object -TypeName System.Security.Cryptography.X509Certificates.
)

$packages = @(
@{ name = "ansible-test1"; version = "1.0.0"; repo = "PSRepo 1"; function = "Get-AnsibleTest1" },
@{ name = "ansible-test1"; version = "1.0.5"; repo = "PSRepo 1"; function = "Get-AnsibleTest1" },
@{ name = "ansible-test1"; version = "1.1.0"; repo = "PSRepo 1"; function = "Get-AnsibleTest1" },
@{ name = "ansible-test2"; version = "1.0.0"; repo = "PSRepo 1"; function = "Get-AnsibleTest2" },
@{ name = "ansible-test2"; version = "1.0.0"; repo = "PSRepo 2"; function = "Get-AnsibleTest2" },
@{ name = "ansible-test2"; version = "1.0.1"; repo = "PSRepo 1"; function = "Get-AnsibleTest2"; signed = $false },
@{ name = "ansible-test2"; version = "1.1.0"; prerelease = "beta1"; repo = "PSRepo 1"; function = "Get-AnsibleTest2" },
@{ name = "ansible-test1"; version = "1.0.0"; repo = "PSRepo 1"; function = "Get-AnsibleTest1" }
@{ name = "ansible-test1"; version = "1.0.5"; repo = "PSRepo 1"; function = "Get-AnsibleTest1" }
@{ name = "ansible-test1"; version = "1.1.0"; repo = "PSRepo 1"; function = "Get-AnsibleTest1" }
@{ name = "ansible-test2"; version = "1.0.0"; repo = "PSRepo 1"; function = "Get-AnsibleTest2" }
@{ name = "ansible-test2"; version = "1.0.0"; repo = "PSRepo 2"; function = "Get-AnsibleTest2" }
@{ name = "ansible-test2"; version = "1.0.1"; repo = "PSRepo 1"; function = "Get-AnsibleTest2"; signed = $false }
@{ name = "ansible-test2"; version = "1.1.0"; prerelease = "beta1"; repo = "PSRepo 1"; function = "Get-AnsibleTest2" }
@{ name = "ansible-clobber"; version = "0.1.0"; repo = "PSRepo 1"; function = "Enable-PSTrace" }
@{ name = "ansible-licensed" ; version = "1.1.1"; repo = "PSRepo 1" ; require_license = $true; function = "Get-AnsibleLicensed" }
)

foreach ($package in $packages) {
Expand All @@ -31,21 +33,24 @@ foreach ($package in $packages) {
}
New-Item -Path $tmp_dir -ItemType Directory > $null

Copy-Item -LiteralPath $template_license -Destination $tmp_dir -Force

try {
$ps_data = @("LicenseUri = 'https://choosealicense.com/licenses/mit/'")
$nuget_version = $package.version
if ($package.ContainsKey("prerelease")) {
$ps_data = "Prerelease = '$($package.prerelease)'"
$ps_data += "Prerelease = '$($package.prerelease)'"
$nuget_version = "$($package.version)-$($package.prerelease)"
}
else {
$ps_data = ""
$nuget_version = $package.version
if ($package.ContainsKey("require_license")) {
$ps_data += "RequireLicenseAcceptance = `$$($package.require_license)"
}

$manifest = [System.IO.File]::ReadAllText($template_manifest)
$manifest = $manifest.Replace('--- NAME ---', $package.name).Replace('--- VERSION ---', $package.version)
$manifest = $manifest.Replace('--- GUID ---', [Guid]::NewGuid()).Replace('--- FUNCTION ---', $package.function)

$manifest = $manifest.Replace('--- PS_DATA ---', $ps_data)
$manifest = $manifest.Replace('--- PS_DATA ---', $ps_data -join "`n")
$manifest_path = Join-Path -Path $tmp_dir -ChildPath "$($package.name).psd1"
Set-Content -Path $manifest_path -Value $manifest

Expand All @@ -68,6 +73,7 @@ foreach ($package in $packages) {
$nuspec = [System.IO.File]::ReadAllText($template_nuspec)
$nuspec = $nuspec.Replace('--- NAME ---', $package.name).Replace('--- VERSION ---', $nuget_version)
$nuspec = $nuspec.Replace('--- FUNCTION ---', $package.function)
$nuspec = $nuspec.Replace('--- LICACC ---', ($package.require_license -as [bool]).ToString().ToLower())
Set-Content -Path (Join-Path -Path $tmp_dir -ChildPath "$($package.name).nuspec") -Value $nuspec

&$nuget_exe pack "$tmp_dir\$($package.name).nuspec" -outputdirectory $tmp_dir
Expand Down
59 changes: 59 additions & 0 deletions tests/integration/targets/win_psmodule/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,65 @@
- dep_repo_add.deprecations[0].msg == 'Adding a repo with this module is deprecated, the repository parameter should only be used to select a repo. Use community.windows.win_psrepository to manage repos'
- dep_repo_add.deprecations[0].date == '2021-07-01'

### licensed module checks
# it is not known in check mode that a module requires
# license acceptance, so we don't do check mode tests
# for that scenario

- name: install module requiring license acceptance (no param)
win_psmodule:
name: ansible-licensed
state: present
register: install_licensed
ignore_errors: yes

- name: get result of install package
ansible.windows.win_shell: (Get-Module -ListAvailable -Name ansible-licensed | Measure-Object).Count
register: install_actual_check

- name: assert install package (failure)
assert:
that:
- install_licensed is failed
- '"License Acceptance is required for module" in install_licensed.msg'
- install_actual_check.stdout | trim | int == 0

- name: install module requiring license acceptance
win_psmodule:
name: ansible-licensed
state: present
accept_license: true
register: install_licensed

- name: get result of install package
ansible.windows.win_shell: Import-Module -Name ansible-licensed; Get-AnsibleLicensed | ConvertTo-Json
register: install_actual

- name: assert install package
assert:
that:
- install_licensed is changed
- install_actual.stdout | from_json == {"Name":"ansible-licensed","Version":"1.1.1","Repo":"PSRepo 1"}

- name: install module requiring license acceptance (idempotence)
win_psmodule:
name: ansible-licensed
state: present
accept_license: true
register: install_licensed

- name: get result of install package (idempotence)
ansible.windows.win_shell: Import-Module -Name ansible-licensed; Get-AnsibleLicensed | ConvertTo-Json
register: install_actual

- name: assert install package (idempotence)
assert:
that:
- install_licensed is not changed
- install_actual.stdout | from_json == {"Name":"ansible-licensed","Version":"1.1.1","Repo":"PSRepo 1"}

### end licensed module checks

- name: install package (check mode)
win_psmodule:
name: ansible-test1
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/targets/win_psmodule/tasks/setup.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
# ansible-test2 - 1.0.1 (Not signed for skip_publisher tests)
# ansible-test2 - 1.1.0-beta1
# ansible-clobber - 0.1.0
#
# ansible-licensed - 1.1.1 (requires license acceptance)
# PSRepo 2 contains
# ansible-test2 - 1.0.0
#
Expand Down

0 comments on commit 8ebbf99

Please sign in to comment.