Win chocolatey facts module (#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 <sbaerlocher@users.noreply.github.com>
pull/46595/head
Jordan Borean 6 years ago committed by GitHub
parent a7425a7e79
commit bc6d441cf2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,182 @@
#!powershell
# Copyright: (c) 2018, Ansible Project
# Copyright: (c) 2018, Simon Baerlocher <s.baerlocher@sbaerlocher.ch>
# Copyright: (c) 2018, ITIGO AG <opensource@itigo.ch>
# 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

@ -0,0 +1,139 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright: (c) 2018, Ansible Project
# Copyright: (c) 2018, Simon Baerlocher <s.baerlocher@sbaerlocher.ch>
# Copyright: (c) 2018, ITIGO AG <opensource@itigo.ch>
# 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'
'''

@ -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'
Loading…
Cancel
Save