forked from ansible/ansible
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Win chocolatey facts module (ansible#46610)
* add module win_chocolatey_facts * rename example name * fix ansible-test errors * add integration tests * fix integration test * implementation of improvement proposals * implementation feedback * implementation feedback * fix trailing-whitespace * implementation feedback * fix version * fix lint * add test targets * Updated modules docs and tests Co-authored-by: Simon Baerlocher <[email protected]>
- Loading branch information
1 parent
a7425a7
commit bc6d441
Showing
4 changed files
with
391 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,182 @@ | ||
#!powershell | ||
|
||
# Copyright: (c) 2018, Ansible Project | ||
# Copyright: (c) 2018, Simon Baerlocher <[email protected]> | ||
# Copyright: (c) 2018, ITIGO AG <[email protected]> | ||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) | ||
|
||
#Requires -Module Ansible.ModuleUtils.ArgvParser | ||
#Requires -Module Ansible.ModuleUtils.CommandUtil | ||
#Requires -Module Ansible.ModuleUtils.Legacy | ||
|
||
$ErrorActionPreference = "Stop" | ||
Set-StrictMode -Version 2.0 | ||
|
||
# Create a new result object | ||
$result = @{ | ||
changed = $false | ||
ansible_facts = @{ | ||
ansible_chocolatey = @{ | ||
config = @{} | ||
feature = @{} | ||
sources = @() | ||
packages = @() | ||
} | ||
} | ||
} | ||
|
||
$choco_app = Get-Command -Name choco.exe -CommandType Application -ErrorAction SilentlyContinue | ||
if (-not $choco_app) { | ||
Fail-Json -obj $result -message "Failed to find Chocolatey installation, make sure choco.exe is in the PATH env value" | ||
} | ||
|
||
Function Get-ChocolateyFeature { | ||
|
||
param($choco_app) | ||
|
||
$command = Argv-ToString -arguments $choco_app.Path, "feature", "list", "-r" | ||
$res = Run-Command -command $command | ||
if ($res.rc -ne 0) { | ||
$result.stdout = $res.stdout | ||
$result.stderr = $res.stderr | ||
$result.rc = $res.rc | ||
Fail-Json -obj $result -message "Failed to list Chocolatey features, see stderr" | ||
} | ||
|
||
$feature_info = @{} | ||
$res.stdout -split "`r`n" | Where-Object { $_ -ne "" } | ForEach-Object { | ||
$feature_split = $_ -split "\|" | ||
$feature_info."$($feature_split[0])" = $feature_split[1] -eq "Enabled" | ||
} | ||
$result.ansible_facts.ansible_chocolatey.feature = $feature_info | ||
} | ||
|
||
Function Get-ChocolateyConfig { | ||
|
||
param($choco_app) | ||
|
||
$choco_config_path = "$(Split-Path -Path (Split-Path -Path $choco_app.Path))\config\chocolatey.config" | ||
if (-not (Test-Path -Path $choco_config_path)) { | ||
Fail-Json -obj $result -message "Expecting Chocolatey config file to exist at '$choco_config_path'" | ||
} | ||
|
||
try { | ||
[xml]$choco_config = Get-Content -Path $choco_config_path | ||
} catch { | ||
Fail-Json -obj $result -message "Failed to parse Chocolatey config file at '$choco_config_path': $($_.Exception.Message)" | ||
} | ||
|
||
$config_info = @{} | ||
foreach ($config in $choco_config.chocolatey.config.GetEnumerator()) { | ||
# try and parse as a boot, then an int, fallback to string | ||
try { | ||
$value = [System.Boolean]::Parse($config.value) | ||
} catch { | ||
try { | ||
$value = [System.Int32]::Parse($config.value) | ||
} catch { | ||
$value = $config.value | ||
} | ||
} | ||
$config_info."$($config.key)" = $value | ||
} | ||
$result.ansible_facts.ansible_chocolatey.config = $config_info | ||
} | ||
|
||
Function Get-ChocolateyPackages { | ||
|
||
param($choco_app) | ||
|
||
$command = Argv-ToString -arguments $choco_app.Path, "list", "--local-only", "-r" | ||
$res = Run-Command -command $command | ||
if ($res.rc -ne 0) { | ||
$result.stdout = $res.stdout | ||
$result.stderr = $res.stderr | ||
$result.rc = $res.rc | ||
Fail-Json -obj $result -message "Failed to list Chocolatey Packages, see stderr" | ||
} | ||
|
||
$packages_info = [System.Collections.ArrayList]@() | ||
$res.stdout -split "`r`n" | Where-Object { $_ -ne "" } | ForEach-Object { | ||
$packages_split = $_ -split "\|" | ||
$package_info = @{ | ||
package = $packages_split[0] | ||
version = $packages_split[1] | ||
} | ||
$packages_info.Add($package_info) > $null | ||
} | ||
$result.ansible_facts.ansible_chocolatey.packages = $packages_info | ||
} | ||
|
||
Function Get-ChocolateySources { | ||
param($choco_app) | ||
|
||
$choco_config_path = "$(Split-Path -Path (Split-Path -Path $choco_app.Path))\config\chocolatey.config" | ||
if (-not (Test-Path -LiteralPath $choco_config_path)) { | ||
Fail-Json -obj $result -message "Expecting Chocolatey config file to exist at '$choco_config_path'" | ||
} | ||
|
||
try { | ||
[xml]$choco_config = Get-Content -Path $choco_config_path | ||
} catch { | ||
Fail-Json -obj $result -message "Failed to parse Chocolatey config file at '$choco_config_path': $($_.Exception.Message)" | ||
} | ||
|
||
$sources = [System.Collections.ArrayList]@() | ||
foreach ($xml_source in $choco_config.chocolatey.sources.GetEnumerator()) { | ||
$source_username = $xml_source.Attributes.GetNamedItem("user") | ||
if ($null -ne $source_username) { | ||
$source_username = $source_username.Value | ||
} | ||
|
||
# 0.9.9.9+ | ||
$priority = $xml_source.Attributes.GetNamedItem("priority") | ||
if ($null -ne $priority) { | ||
$priority = [int]$priority.Value | ||
} | ||
|
||
# 0.9.10+ | ||
$certificate = $xml_source.Attributes.GetNamedItem("certificate") | ||
if ($null -ne $certificate) { | ||
$certificate = $certificate.Value | ||
} | ||
|
||
# 0.10.4+ | ||
$bypass_proxy = $xml_source.Attributes.GetNamedItem("bypassProxy") | ||
if ($null -ne $bypass_proxy) { | ||
$bypass_proxy = [System.Convert]::ToBoolean($bypass_proxy.Value) | ||
} | ||
$allow_self_service = $xml_source.Attributes.GetNamedItem("selfService") | ||
if ($null -ne $allow_self_service) { | ||
$allow_self_service = [System.Convert]::ToBoolean($allow_self_service.Value) | ||
} | ||
|
||
# 0.10.8+ | ||
$admin_only = $xml_source.Attributes.GetNamedItem("adminOnly") | ||
if ($null -ne $admin_only) { | ||
$admin_only = [System.Convert]::ToBoolean($admin_only.Value) | ||
} | ||
|
||
$source_info = @{ | ||
name = $xml_source.id | ||
source = $xml_source.value | ||
disabled = [System.Convert]::ToBoolean($xml_source.disabled) | ||
source_username = $source_username | ||
priority = $priority | ||
certificate = $certificate | ||
bypass_proxy = $bypass_proxy | ||
allow_self_service = $allow_self_service | ||
admin_only = $admin_only | ||
} | ||
$sources.Add($source_info) > $null | ||
} | ||
$result.ansible_facts.ansible_chocolatey.sources = $sources | ||
} | ||
|
||
Get-ChocolateyConfig -choco_app $choco_app | ||
Get-ChocolateyFeature -choco_app $choco_app | ||
Get-ChocolateyPackages -choco_app $choco_app | ||
Get-ChocolateySources -choco_app $choco_app | ||
|
||
# Return result | ||
Exit-Json -obj $result |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
#!/usr/bin/python | ||
# -*- coding: utf-8 -*- | ||
|
||
# Copyright: (c) 2018, Ansible Project | ||
# Copyright: (c) 2018, Simon Baerlocher <[email protected]> | ||
# Copyright: (c) 2018, ITIGO AG <[email protected]> | ||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) | ||
|
||
ANSIBLE_METADATA = {'metadata_version': '1.1', | ||
'status': ['preview'], | ||
'supported_by': 'community'} | ||
|
||
DOCUMENTATION = r''' | ||
--- | ||
module: win_chocolatey_facts | ||
version_added: '2.8' | ||
short_description: Create a facts collection for Chocolatey | ||
description: | ||
- This module shows information from Chocolatey, such as installed packages, configuration, feature and sources. | ||
author: | ||
- Simon Bärlocher (@sbaerlocher) | ||
- ITIGO AG (@itigoag) | ||
notes: | ||
- Chocolatey must be installed beforehand, use M(win_chocolatey) to do this. | ||
''' | ||
|
||
EXAMPLES = r''' | ||
- name: Gather facts from chocolatey | ||
win_chocolatey_facts: | ||
- name: Displays the Configuration | ||
debug: | ||
var: ansible_chocolatey.config | ||
- name: Displays the Feature | ||
debug: | ||
var: ansible_chocolatey.feature | ||
- name: Displays the Sources | ||
debug: | ||
var: ansible_chocolatey.sources | ||
- name: Displays the Packages | ||
debug: | ||
var: ansible_chocolatey.packages | ||
''' | ||
|
||
RETURN = r''' | ||
ansible_facts: | ||
description: Detailed information about the Chocolatey installation | ||
returned: always | ||
type: complex | ||
contains: | ||
ansible_chocolatey: | ||
description: Detailed information about the Chocolatey installation | ||
returned: always | ||
type: complex | ||
contains: | ||
config: | ||
description: Detailed information about stored the configurations | ||
returned: always | ||
type: dict | ||
sample: | ||
commandExecutionTimeoutSeconds: 2700 | ||
containsLegacyPackageInstalls: true | ||
feature: | ||
description: Detailed information about enabled and disabled features | ||
returned: always | ||
type: dict | ||
sample: | ||
allowEmptyCheckums: false | ||
autoUninstaller: true | ||
failOnAutoUninstaller: false | ||
sources: | ||
description: List of Chocolatey sources | ||
returned: always | ||
type: complex | ||
contains: | ||
admin_only: | ||
description: Is the source visible to Administrators only | ||
returned: always | ||
type: bool | ||
sample: false | ||
allow_self_service: | ||
description: Is the source allowed to be used with self-service | ||
returned: always | ||
type: bool | ||
sample: false | ||
bypass_proxy: | ||
description: Can the source explicitly bypass configured proxies | ||
returned: always | ||
type: bool | ||
sample: true | ||
certificate: | ||
description: Pth to a PFX certificate for X509 authenticated feeds | ||
returned: always | ||
type: string | ||
sample: C:\chocolatey\cert.pfx | ||
disabled: | ||
description: Is the source disabled | ||
returned: always | ||
type: bool | ||
sample: false | ||
name: | ||
description: Name of the source | ||
returned: always | ||
type: string | ||
sample: chocolatey | ||
priority: | ||
description: The priority order of this source, lower is better, 0 is no priority | ||
returned: always | ||
type: int | ||
sample: 0 | ||
source: | ||
description: The source, can be a folder/file or an url | ||
returned: always | ||
type: string | ||
sample: https://chocolatey.org/api/v2/ | ||
source_username: | ||
description: Username used to access authenticated feeds | ||
returned: always | ||
type: string | ||
sample: username | ||
packages: | ||
description: List of installed Packages | ||
returned: alway | ||
type: complex | ||
contains: | ||
package: | ||
description: Name of the package | ||
returned: always | ||
type: string | ||
sample: vscode | ||
version: | ||
description: Version of the package | ||
returned: always | ||
type: string | ||
sample: '1.27.2' | ||
''' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
shippable/windows/group4 |
69 changes: 69 additions & 0 deletions
69
test/integration/targets/win_chocolatey_facts/tasks/main.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
--- | ||
- name: ensure Chocolatey is installed | ||
win_chocolatey: | ||
name: chocolatey | ||
state: present | ||
|
||
- name: create test source | ||
win_chocolatey_source: | ||
name: test|repo # use a pipe as that's a delimiter with Chocolatey, test edge case | ||
state: disabled | ||
admin_only: yes | ||
allow_self_service: yes | ||
bypass_proxy: yes | ||
priority: 9 | ||
source: http://test-server/chocolatey | ||
source_username: test-user | ||
source_password: password | ||
certificate: C:\temp\cert.pfx | ||
|
||
|
||
- name: set a config value | ||
win_chocolatey_config: | ||
name: proxyUser | ||
state: present | ||
value: test-user | ||
|
||
- block: | ||
- name: Gather facts from chocolatey | ||
win_chocolatey_facts: | ||
|
||
always: | ||
- name: remove test source | ||
win_chocolatey_source: | ||
name: test|repo | ||
state: absent | ||
|
||
- name: unset config value | ||
win_chocolatey_config: | ||
name: proxyUser | ||
state: absent | ||
|
||
- name: assert facts from chocolatey | ||
assert: | ||
that: | ||
- ansible_chocolatey is not changed | ||
- ansible_chocolatey.config.commandExecutionTimeoutSeconds == 2700 | ||
- ansible_chocolatey.config.proxyBypassOnLocal == True | ||
- ansible_chocolatey.config.proxyUser == 'test-user' | ||
- ansible_chocolatey.feature.checksumFiles == true | ||
- ansible_chocolatey.packages[0].package == 'chocolatey' | ||
- ansible_chocolatey.packages[0].version is defined | ||
- ansible_chocolatey.sources[0].admin_only == False | ||
- ansible_chocolatey.sources[0].allow_self_service == False | ||
- ansible_chocolatey.sources[0].bypass_proxy == False | ||
- ansible_chocolatey.sources[0].certificate == None | ||
- ansible_chocolatey.sources[0].disabled == False | ||
- ansible_chocolatey.sources[0].name == 'chocolatey' | ||
- ansible_chocolatey.sources[0].priority == 0 | ||
- ansible_chocolatey.sources[0].source == 'https://chocolatey.org/api/v2/' | ||
- ansible_chocolatey.sources[0].source_username == None | ||
- ansible_chocolatey.sources[1].admin_only == True | ||
- ansible_chocolatey.sources[1].allow_self_service == True | ||
- ansible_chocolatey.sources[1].bypass_proxy == True | ||
- ansible_chocolatey.sources[1].certificate == 'C:\\temp\\cert.pfx' | ||
- ansible_chocolatey.sources[1].disabled == True | ||
- ansible_chocolatey.sources[1].name == 'test|repo' | ||
- ansible_chocolatey.sources[1].priority == 9 | ||
- ansible_chocolatey.sources[1].source == 'http://test-server/chocolatey' | ||
- ansible_chocolatey.sources[1].source_username == 'test-user' |