diff --git a/docs/docsite/rst/dev_guide/developing_modules_general_windows.rst b/docs/docsite/rst/dev_guide/developing_modules_general_windows.rst index 78dd90f9ccd..312b34c8e72 100644 --- a/docs/docsite/rst/dev_guide/developing_modules_general_windows.rst +++ b/docs/docsite/rst/dev_guide/developing_modules_general_windows.rst @@ -38,52 +38,17 @@ When creating a new module there are a few things to keep in mind: - Use the full cmdlet name instead of aliases, e.g. ``Remove-Item`` over ``rm`` - Use named parameters with cmdlets, e.g. ``Remove-Item -Path C:\temp`` over ``Remove-Item C:\temp`` -A very basic powershell module template can be found found below: +A very basic powershell module `win_environment `_ is included below. It demonstrates how to implement check-mode and diff-support, and also shows a warning to the user when a specific condition is met. -.. code-block:: powershell +.. .. include:: ../../../../lib/ansible/modules/windows/win_environment.ps1 +.. :code: powershell - #!powershell - # This file is part of Ansible +.. literalinclude:: ../../../../lib/ansible/modules/windows/win_environment.ps1 + :language: powershell - # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +A slightly more advanced module is `win_uri `_ which additionally shows how to use different parameter types (bool, str, int, list, dict, path) and a selection of choices for parameters, how to fail a module and how to handle exceptions. - #Requires -Module Ansible.ModuleUtils.Legacy.psm1 - - $ErrorActionPreference = 'Stop' - - $params = Parse-Args -arguments $args -supports_check_mode $true - $check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false - $diff_mode = Get-AnsibleParam -obj $params -name "_ansible_diff" -type "bool" -default $false - - # these are your module parameters, there are various types which can be - # used to format your parameters. You can also set mandatory parameters - # with -failifempty, set defaults with -default and set choices with - # -validateset. - $string = Get-AnsibleParam -obj $params -name "string" -type "str" -failifempty $true - $bool = Get-AnsibleParam -obj $params -name "bool" -type "bool" -default $false - $int = Get-AnsibleParam -obj $params -name "int" -type "int" - $path = Get-AnsibleParam -obj $params -name "path" -type "path" - $list = Get-AnsibleParam -obj $params -name "list" -type "list" - $choices = Get-AnsibleParam -obj $params -name "choices" -type "str" -default "present" -validateset "absent","present" - - $result = @{ - changed = $false - } - - if ($diff_mode) { - $result.diff = @{} - } - - # code goes here - - # you can add/set new result objects with - $result.changed = $true - $result.new_result = "Hi" - - Exit-Json -obj $result - - -When in doubt, look at some of the core modules and see how things have been +When in doubt, look at some of the other core modules and see how things have been implemented there. Sometimes there are multiple ways that Windows offers to complete a task; this diff --git a/lib/ansible/modules/windows/win_environment.ps1 b/lib/ansible/modules/windows/win_environment.ps1 index 012c2654417..48479231c7b 100644 --- a/lib/ansible/modules/windows/win_environment.ps1 +++ b/lib/ansible/modules/windows/win_environment.ps1 @@ -1,86 +1,67 @@ #!powershell -# This file is part of Ansible -# -# Copyright 2015, Jon Hawkesworth (@jhawkesworth) -# -# 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 . -# WANT_JSON -# POWERSHELL_COMMON +# Copyright: (c) 2015, Jon Hawkesworth (@jhawkesworth) +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -$params = Parse-Args $args -supports_check_mode $true +#Requires -Module Ansible.ModuleUtils.Legacy.psm1 + +$ErrorActionPreference = "Stop" + +$params = Parse-Args -arguments $args -supports_check_mode $true $check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false -$diff_support = Get-AnsibleParam -obj $params -name "_ansible_diff" -type "bool" -default $false +$diff_mode = Get-AnsibleParam -obj $params -name "_ansible_diff" -type "bool" -default $false $name = Get-AnsibleParam -obj $params -name "name" -type "str" -failifempty $true -$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "present" -validateset "present","absent" +$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "present" -validateset "absent","present" $value = Get-AnsibleParam -obj $params -name "value" -type "str" $level = Get-AnsibleParam -obj $params -name "level" -type "str" -validateSet "machine","user","process" -failifempty $true $before_value = [Environment]::GetEnvironmentVariable($name, $level) -# When removing environment, set value to $null if set -if ($state -eq "absent" -and $value) { - $value = $null -} - $result = @{ before_value = $before_value changed = $false - level = $level - name = $name value = $value } -if ($diff_support) { - $result.diff = @{} +# When removing environment, set value to $null if set +if ($state -eq "absent" -and $value) { + Add-Warning -obj $result -message "When removing environment variable '$name' it should not have a value '$value' set" + $value = $null } if ($state -eq "present" -and $before_value -ne $value) { + if (-not $check_mode) { [Environment]::SetEnvironmentVariable($name, $value, $level) } $result.changed = $true - if ($diff_support) { + if ($diff_mode) { if ($before_value -eq $null) { - $result.diff.prepared = @" -[$level] -+$NAME = $value -"@ + $result.diff = @{ + prepared = " [$level]`n+$name = $value`n" + } } else { - $result.diff.prepared = @" -[$level] --$NAME = $before_value -+$NAME = $value -"@ + $result.diff = @{ + prepared = " [$level]`n-$name = $before_value`n+$name = $value`n" + } } } } elseif ($state -eq "absent" -and $before_value -ne $null) { + if (-not $check_mode) { [Environment]::SetEnvironmentVariable($name, $null, $level) } $result.changed = $true - if ($diff_support) { - $result.diff.prepared = @" -[$level] --$NAME = $before_value -"@ + if ($diff_mode) { + $result.diff = @{ + prepared = " [$level]`n-$name = $before_value`n" + } } } -Exit-Json $result +Exit-Json -obj $result diff --git a/lib/ansible/modules/windows/win_environment.py b/lib/ansible/modules/windows/win_environment.py index c85b108a067..59d1616bf1c 100644 --- a/lib/ansible/modules/windows/win_environment.py +++ b/lib/ansible/modules/windows/win_environment.py @@ -1,81 +1,56 @@ #!/usr/bin/python # -*- coding: utf-8 -*- -# (c) 2015, Jon Hawkesworth (@jhawkesworth) -# -# 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 . - -# this is a windows documentation stub. actual code lives in the .ps1 -# file of the same name +# Copyright: (c) 2015, Jon Hawkesworth (@jhawkesworth) +# 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_environment -version_added: "2.0" -short_description: Modifies environment variables on windows hosts. +version_added: '2.0' +short_description: Modify environment variables on windows hosts description: - - Uses .net Environment to set or remove environment variables and can set at User, Machine or Process level. - - User level environment variables will be set, but not available until the user has logged off and on again. +- Uses .net Environment to set or remove environment variables and can set at User, Machine or Process level. +- User level environment variables will be set, but not available until the user has logged off and on again. options: state: description: - - present to ensure environment variable is set, or absent to ensure it is removed - required: false + - Set to C(present) to ensure environment variable is set. + - Set to C(absent) to ensure it is removed. + choices: [ absent, present ] default: present - choices: - - present - - absent name: description: - - The name of the environment variable + - The name of the environment variable. required: true - default: no default value: description: - - The value to store in the environment variable. Can be omitted for state=absent - required: false - default: no default + - The value to store in the environment variable. + - Can be omitted for C(state=absent). level: description: - - The level at which to set the environment variable. - - Use 'machine' to set for all users. - - Use 'user' to set for the current user that ansible is connected as. - - Use 'process' to set for the current process. Probably not that useful. + - The level at which to set the environment variable. + - Use C(machine) to set for all users. + - Use C(user) to set for the current user that ansible is connected as. + - Use C(process) to set for the current process. Probably not that useful. + choices: [ machine, user, process ] required: true - default: no default - choices: - - machine - - process - - user -author: "Jon Hawkesworth (@jhawkesworth)" +author: +- Jon Hawkesworth (@jhawkesworth) notes: - - This module is best-suited for setting the entire value of an - environment variable. For safe element-based management of - path-like environment vars, use the M(win_path) module. - - This module does not broadcast change events. - This means that the minority of windows applications which can have - their environment changed without restarting will not be notified and - therefore will need restarting to pick up new environment settings. - User level environment variables will require the user to log out - and in again before they become available. +- This module is best-suited for setting the entire value of an + environment variable. For safe element-based management of + path-like environment vars, use the M(win_path) module. +- This module does not broadcast change events. + This means that the minority of windows applications which can have + their environment changed without restarting will not be notified and + therefore will need restarting to pick up new environment settings. + User level environment variables will require the user to log out + and in again before they become available. ''' EXAMPLES = r''' @@ -95,24 +70,12 @@ EXAMPLES = r''' RETURN = r''' before_value: - description: - - the value of the environment key before a change, this is null if it didn't - exist + description: the value of the environment key before a change, this is null if it didn't exist returned: always type: string sample: C:\Windows\System32 -level: - description: the level set when calling the module - returned: always - type: string - sample: machine -name: - description: the name of the environment key the module checked - returned: always - type: string - sample: JAVA_HOME value: - description: the value the environment key has been set to + description: the value the environment key has been set to, this is null if removed returned: always type: string sample: C:\Program Files\jdk1.8 diff --git a/lib/ansible/modules/windows/win_uri.ps1 b/lib/ansible/modules/windows/win_uri.ps1 index d84b224a18b..78c17605984 100644 --- a/lib/ansible/modules/windows/win_uri.ps1 +++ b/lib/ansible/modules/windows/win_uri.ps1 @@ -1,26 +1,13 @@ #!powershell -# This file is part of Ansible -# -# Copyright 2015, Corwin Brown -# Copyright 2017, Dag Wieers -# -# 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 . -# WANT_JSON -# POWERSHELL_COMMON +# Copyright: (c) 2015, Corwin Brown +# Copyright: (c) 2017, Dag Wieers (@dagwieers) +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +#Requires -Module Ansible.ModuleUtils.Legacy.psm1 $ErrorActionPreference = "Stop" + $safe_methods = @("GET", "HEAD") $content_keys = @("Content", "Images", "InputFields", "Links", "RawContent") @@ -29,7 +16,7 @@ Function ConvertTo-SnakeCase($input_string) { return $snake_case.ToLower() } -$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 $url = Get-AnsibleParam -obj $params -name "url" -type "str" -failifempty $true @@ -56,12 +43,12 @@ $client_cert = Get-AnsibleParam -obj $params -name "client_cert" -type "path" if ($creates -and (Test-Path -Path $creates)) { $result.skipped = $true - Exit-Json $result "The 'creates' file or directory ($creates) already exists." + Exit-Json -obj $result -message "The 'creates' file or directory ($creates) already exists." } if ($removes -and -not (Test-Path -Path $removes)) { $result.skipped = $true - Exit-Json $result "The 'removes' file or directory ($removes) does not exist." + Exit-Json -obj $result -message "The 'removes' file or directory ($removes) does not exist." } $result = @{ @@ -110,7 +97,7 @@ if ($client_cert) { Try { $webrequest_opts.Certificate = Get-PfxCertificate -FilePath $client_cert } Catch { - Fail-Json $result "Failed to read client certificate '$client_cert'" + Fail-Json -obj $result -message "Failed to read client certificate '$client_cert'" } } @@ -127,6 +114,8 @@ if ($dest -and -not $check_mode) { if ($user -and $password) { $webrequest_opts.Credential = New-Object System.Management.Automation.PSCredential($user, $($password | ConvertTo-SecureString -AsPlainText -Force)) +} elif ($user -or $password) { + Add-Warning -obj $result -message "Both 'user' and 'password' parameters are required together, skipping authentication" } try { @@ -137,7 +126,6 @@ try { # TODO: When writing to a file, this is not idempotent ! # FIXME: Assume a change when we are writing to a file -# FIXME: Implement diff-mode if ($dest) { $result.changed = $true } @@ -151,7 +139,7 @@ ForEach ($prop in $response.psobject.properties) { } if ($status_code -notcontains $response.StatusCode) { - Fail-Json $result "Status code of request '$($response.StatusCode)' is not in list of valid status codes $status_code." + Fail-Json -obj $result -message "Status code of request '$($response.StatusCode)' is not in list of valid status codes $status_code." } -Exit-Json $result +Exit-Json -obj $result diff --git a/lib/ansible/modules/windows/win_uri.py b/lib/ansible/modules/windows/win_uri.py index 42b0c66d590..9d5dc0ab29c 100644 --- a/lib/ansible/modules/windows/win_uri.py +++ b/lib/ansible/modules/windows/win_uri.py @@ -1,26 +1,9 @@ #!/usr/bin/python # -*- coding: utf-8 -*- -# (c) 2015, Corwin Brown -# (c) 2017, Dag Wieers -# -# 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 . - -# this is a windows documentation stub. actual code lives in the .ps1 -# file of the same name +# Copyright: (c) 2015, Corwin Brown +# Copyright: (c) 2017, Dag Wieers (@dagwieers) +# 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'], diff --git a/test/integration/targets/win_environment/tasks/main.yml b/test/integration/targets/win_environment/tasks/main.yml index c5ebac6daf2..d379e5776b8 100644 --- a/test/integration/targets/win_environment/tasks/main.yml +++ b/test/integration/targets/win_environment/tasks/main.yml @@ -45,9 +45,6 @@ that: - create_machine|changed - create_machine.before_value == None - - create_machine.level == 'machine' - - create_machine.name == test_environment_name - - create_machine.value == test_machine_environment_value - create_machine_actual.stdout == "{{test_machine_environment_value}}\r\n" - name: create test environment value for machine again @@ -67,9 +64,6 @@ that: - not create_machine_again|changed - create_machine_again.before_value == test_machine_environment_value - - create_machine_again.level == 'machine' - - create_machine_again.name == test_environment_name - - create_machine_again.value == test_machine_environment_value - create_machine_actual_again.stdout == "{{test_machine_environment_value}}\r\n" - name: change test environment value for machine check @@ -90,9 +84,6 @@ that: - change_machine_check|changed - change_machine_check.before_value == test_machine_environment_value - - change_machine_check.level == 'machine' - - change_machine_check.name == test_environment_name - - change_machine_check.value == test_new_machine_environment_value - change_machine_actual_check.stdout == "{{test_machine_environment_value}}\r\n" - name: change test environment value for machine @@ -112,9 +103,6 @@ that: - change_machine|changed - change_machine.before_value == test_machine_environment_value - - change_machine.level == 'machine' - - change_machine.name == test_environment_name - - change_machine.value == test_new_machine_environment_value - change_machine_actual.stdout == "{{test_new_machine_environment_value}}\r\n" - name: change test environment value for machine again @@ -134,9 +122,6 @@ that: - not change_machine_again|changed - change_machine_again.before_value == test_new_machine_environment_value - - change_machine_again.level == 'machine' - - change_machine_again.name == test_environment_name - - change_machine_again.value == test_new_machine_environment_value - change_machine_actual_again.stdout == "{{test_new_machine_environment_value}}\r\n" - name: create test environment value for user check @@ -175,9 +160,6 @@ that: - create_user|changed - create_user.before_value == None - - create_user.level == 'user' - - create_user.name == test_environment_name - - create_user.value == test_user_environment_value - create_user_actual.stdout == "{{test_user_environment_value}}\r\n" - name: create test environment value for user again @@ -197,9 +179,6 @@ that: - not create_user_again|changed - create_user_again.before_value == test_user_environment_value - - create_user_again.level == 'user' - - create_user_again.name == test_environment_name - - create_user_again.value == test_user_environment_value - create_user_actual_again.stdout == "{{test_user_environment_value}}\r\n" - name: change test environment value for user check @@ -220,9 +199,6 @@ that: - change_user_check|changed - change_user_check.before_value == test_user_environment_value - - change_user_check.level == 'user' - - change_user_check.name == test_environment_name - - change_user_check.value == test_new_user_environment_value - change_user_actual_check.stdout == "{{test_user_environment_value}}\r\n" - name: change test environment value for user @@ -242,9 +218,6 @@ that: - change_user|changed - change_user.before_value == test_user_environment_value - - change_user.level == 'user' - - change_user.name == test_environment_name - - change_user.value == test_new_user_environment_value - change_user_actual.stdout == "{{test_new_user_environment_value}}\r\n" - name: change test environment value for user again @@ -264,9 +237,6 @@ that: - not change_user_again|changed - change_user_again.before_value == test_new_user_environment_value - - change_user_again.level == 'user' - - change_user_again.name == test_environment_name - - change_user_again.value == test_new_user_environment_value - change_user_actual_again.stdout == "{{test_new_user_environment_value}}\r\n" - name: cleanup test changes