From bf43eb92f50ea8edc9e7b704ef91b3121ec972f0 Mon Sep 17 00:00:00 2001 From: Dag Wieers <dag@wieers.com> Date: Tue, 13 Jun 2017 18:32:22 +0200 Subject: [PATCH] win_firewall: check-mode support, integration tests (#25127) * win_firewall: check-mode support, integration tests This PR includes: - Check-mode implementation - Documentation improvements - Ensure module output is consistent (no matter what profiles are provided) - Fixed indentation - Cosmetic changes - Integration tests * win_firewall: check-mode support, integration tests This PR includes: - Check-mode implementation - Documentation improvements - Ensure module output is consistent (no matter what profiles are provided) - Fixed indentation - Cosmetic changes - Integration tests --- lib/ansible/modules/windows/win_firewall.ps1 | 70 ++++--- lib/ansible/modules/windows/win_firewall.py | 51 ++--- test/integration/targets/win_firewall/aliases | 1 + .../targets/win_firewall/tasks/main.yml | 52 +++++ .../targets/win_firewall/tasks/tests.yml | 185 ++++++++++++++++++ 5 files changed, 306 insertions(+), 53 deletions(-) create mode 100644 test/integration/targets/win_firewall/aliases create mode 100644 test/integration/targets/win_firewall/tasks/main.yml create mode 100644 test/integration/targets/win_firewall/tasks/tests.yml diff --git a/lib/ansible/modules/windows/win_firewall.ps1 b/lib/ansible/modules/windows/win_firewall.ps1 index c33789c02cb..dbfca5b5f5c 100644 --- a/lib/ansible/modules/windows/win_firewall.ps1 +++ b/lib/ansible/modules/windows/win_firewall.ps1 @@ -19,50 +19,60 @@ # WANT_JSON # POWERSHELL_COMMON +$ErrorActionPreference = "Stop" +$firewall_profiles = @('Domain', 'Private', 'Public') -# get params -$params = Parse-Args $args -supports_check_mode $false +$params = Parse-Args $args -supports_check_mode $true +$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false -$profiles = Get-AnsibleParam -obj $params -name "profiles" -type "list" -default [ "Public", "Domain", "Private" ] -$wantedstate = Get-AnsibleParam -obj $params -name "state" -type "str" -failifempty $true -validateset 'enabled', 'disabled' +$profiles = Get-AnsibleParam -obj $params -name "profiles" -type "list" -default @("Domain", "Private", "Public") +$state = Get-AnsibleParam -obj $params -name "state" -type "str" -failifempty $true -validateset 'disabled','enabled' $result = @{ changed = $false + profiles = $profiles + state = $state +} +if ($PSVersionTable.PSVersion -lt [Version]"5.0") { + Fail-Json $result "win_firewall requires Windows Management Framework 5 or higher." } Try { - ForEach($profile in $profiles) + ForEach ($profile in $firewall_profiles) { - { - - $currentstate = (Get-NetFirewallProfile -Name $profile).Enabled - - if ($wantedstate -eq 'enabled') - { - if ($currentstate -eq $false) - { - Set-NetFirewallProfile -name $profile -Enabled true - $result.enabled = $true - $result.changed = $true - } - } - else - { - if ($currentstate -eq $true) - { - Set-NetFirewallProfile -name $profile -Enabled false - $result.enabled = $false - $result.changed = $true + $currentstate = (Get-NetFirewallProfile -Name $profile).Enabled + $result.$profile = @{ + enabled = ($currentstate -eq 1) + considered = ($profiles -contains $profile) + currentstate = $currentstate } - } + if ($profiles -notcontains $profile) { + continue + } - } -} -Catch { + if ($state -eq 'enabled') { + + if ($currentstate -eq $false) { + Set-NetFirewallProfile -name $profile -Enabled true -WhatIf:$check_mode + $result.changed = $true + $result.$profile.enabled = $true + } + + } else { + + if ($currentstate -eq $true) { + Set-NetFirewallProfile -name $profile -Enabled false -WhatIf:$check_mode + $result.changed = $true + $result.$profile.enabled = $false + } + + } + } +} Catch { Fail-Json $result "an error occurred when attempting to change firewall status for profile $profile $($_.Exception.Message)" } -Exit-Json $result \ No newline at end of file +Exit-Json $result diff --git a/lib/ansible/modules/windows/win_firewall.py b/lib/ansible/modules/windows/win_firewall.py index 5c09d69af16..fe13cc50da9 100644 --- a/lib/ansible/modules/windows/win_firewall.py +++ b/lib/ansible/modules/windows/win_firewall.py @@ -28,55 +28,60 @@ ANSIBLE_METADATA = {'metadata_version': '1.0', DOCUMENTATION = r''' --- module: win_firewall -version_added: "2.4" -short_description: Manages Windows Firewall +version_added: '2.4' +short_description: Enable or disable the Windows Firewall description: - - Manages Windows Firewall +- Enable or Disable Windows Firewall profiles. options: - profile: + profiles: description: - - specify the profile to change + - Specify one or more profiles to change. choices: - - Public - Domain - Private + - Public + default: [Domain, Private, Public] state: description: - - set state of firewall for given profile + - Set state of firewall for given profile. choices: - enabled - disabled - -author: "Michael Eaton (@MichaelEaton83)" +author: Michael Eaton (@MichaelEaton83) ''' EXAMPLES = r''' -- name: Enable all firewalls +- name: Enable firewall for Domain, Public and Private profiles win_firewall: - state: enabled - profiles: - - Domain - - Public - - Private + state: enabled + profiles: + - Domain + - Private + - Public tags: enable_firewall - name: Disable Domain firewall win_firewall: - state: disabled - profiles: - - Domain + state: disabled + profiles: + - Domain tags: disable_firewall ''' RETURN = r''' -profile: - description: chosen profile - returned: always - type: string - sample: Domain enabled: description: current firewall status for chosen profile (after any potential change) returned: always type: bool sample: true +profiles: + description: chosen profile + returned: always + type: string + sample: Domain +state: + description: desired state of the given firewall profile(s) + returned: always + type: list + sample: enabled ''' diff --git a/test/integration/targets/win_firewall/aliases b/test/integration/targets/win_firewall/aliases new file mode 100644 index 00000000000..ee0ed5974e9 --- /dev/null +++ b/test/integration/targets/win_firewall/aliases @@ -0,0 +1 @@ +windows/ci/group2 diff --git a/test/integration/targets/win_firewall/tasks/main.yml b/test/integration/targets/win_firewall/tasks/main.yml new file mode 100644 index 00000000000..1c42dccf4a1 --- /dev/null +++ b/test/integration/targets/win_firewall/tasks/main.yml @@ -0,0 +1,52 @@ +# NOTE: The win_firewall module only works on WMF 5+ + +- setup: + +- name: Test Windows capabilities + raw: Get-Command Get-NetFirewallProfile -ErrorAction SilentlyContinue; return $? + failed_when: no + register: get_netfirewallprofile + +- name: Only run tests when Windows is capable + when: get_netfirewallprofile.rc == 0 and ansible_powershell_version >= 5 + block: + - name: Turn off Windows Firewall (begin) + win_firewall: + profiles: [ Domain, Private, Public ] + state: disabled + register: firewall_off + + - name: Test firewall_off + assert: + that: + - not firewall_off.Domain.enabled + - not firewall_off.Private.enabled + - not firewall_off.Public.enabled + + + - name: Test in normal mode + include: tests.yml + vars: + in_check_mode: no + + + - name: Test in check-mode + include: tests.yml + vars: + in_check_mode: yes + check_mode: yes + + + - name: Turn on Windows Firewall (end) + win_firewall: + profiles: [ Domain, Private, Public ] + state: enabled + register: firewall_on + + - name: Test firewall_on + assert: + that: + - firewall_on|changed + - firewall_on.Domain.enabled + - firewall_on.Private.enabled + - firewall_on.Public.enabled diff --git a/test/integration/targets/win_firewall/tasks/tests.yml b/test/integration/targets/win_firewall/tasks/tests.yml new file mode 100644 index 00000000000..9d38dcb537c --- /dev/null +++ b/test/integration/targets/win_firewall/tasks/tests.yml @@ -0,0 +1,185 @@ +# We start with firewall turned off + +- name: Turn off Windows Firewall again + win_firewall: + profiles: [ Domain, Private, Public ] + state: disabled + register: firewall_off_again + +- name: Test firewall_off_again + assert: + that: + - not firewall_off_again|changed + - not firewall_off_again.Domain.enabled + - not firewall_off_again.Private.enabled + - not firewall_off_again.Public.enabled + +- name: Turn on Windows Firewall on Public + win_firewall: + profiles: [ Public ] + state: enabled + register: firewall_public_on + +- name: Test firewall_public_on + assert: + that: + - firewall_public_on|changed + - not firewall_public_on.Domain.enabled + - not firewall_public_on.Private.enabled + - firewall_public_on.Public.enabled + + +- name: Turn on Windows Firewall on Public again + win_firewall: + profiles: [ Public ] + state: enabled + register: firewall_public_on_again + +- name: Test firewall_public_on_again (normal mode) + assert: + that: + - not firewall_public_on_again|changed + - not firewall_public_on_again.Domain.enabled + - not firewall_public_on_again.Private.enabled + - firewall_public_on_again.Public.enabled + when: not in_check_mode + +- name: Test firewall_public_on_again (check-mode) + assert: + that: + - firewall_public_on_again|changed + - not firewall_public_on_again.Domain.enabled + - not firewall_public_on_again.Private.enabled + - firewall_public_on_again.Public.enabled + when: in_check_mode + + +# On purpose not a list +- name: Turn on Windows Firewall on Domain + win_firewall: + profiles: Domain + state: enabled + register: firewall_domain_on + +- name: Test firewall_domain_on (normal mode) + assert: + that: + - firewall_domain_on|changed + - firewall_domain_on.Domain.enabled + - not firewall_domain_on.Private.enabled + - firewall_domain_on.Public.enabled + when: not in_check_mode + +- name: Test firewall_domain_on (check-mode) + assert: + that: + - firewall_domain_on|changed + - firewall_domain_on.Domain.enabled + - not firewall_domain_on.Private.enabled + - not firewall_domain_on.Public.enabled + when: in_check_mode + + +- name: Turn on Windows Firewall on Domain again + win_firewall: + profiles: [ Domain ] + state: enabled + register: firewall_domain_on_again + +- name: Test firewall_domain_on_again (normal mode) + assert: + that: + - not firewall_domain_on_again|changed + - firewall_domain_on.Domain.enabled + - not firewall_domain_on.Private.enabled + - firewall_domain_on.Public.enabled + when: not in_check_mode + +- name: Test firewall_domain_on_again (check-mode) + assert: + that: + - firewall_domain_on_again|changed + - firewall_domain_on.Domain.enabled + - not firewall_domain_on.Private.enabled + - not firewall_domain_on.Public.enabled + when: in_check_mode + + +- name: Turn on Windows Firewall + win_firewall: + profiles: [ Domain, Private, Public ] + state: enabled + register: firewall_on + +- name: Test firewall_on + assert: + that: + - firewall_on|changed + - firewall_on.Domain.enabled + - firewall_on.Private.enabled + - firewall_on.Public.enabled + + +# On purpose no profiles added +- name: Turn on Windows Firewall again + win_firewall: + state: enabled + register: firewall_on_again + +- name: Test firewall_on_again (normal mode) + assert: + that: + - not firewall_on_again|changed + - firewall_on_again.Domain.enabled + - firewall_on_again.Private.enabled + - firewall_on_again.Public.enabled + when: not in_check_mode + +- name: Test firewall_on_again (check-mode) + assert: + that: + - firewall_on_again|changed + - firewall_on_again.Domain.enabled + - firewall_on_again.Private.enabled + - firewall_on_again.Public.enabled + when: in_check_mode + + +# On purpose no profiles added +- name: Turn off Windows Firewall + win_firewall: + state: disabled + register: firewall_off2 + +- name: Test firewall_off2 (normal mode) + assert: + that: + - firewall_off2|changed + - not firewall_off2.Domain.enabled + - not firewall_off2.Private.enabled + - not firewall_off2.Public.enabled + when: not in_check_mode + +- name: Test firewall_off2 (check-mode) + assert: + that: + - not firewall_off2|changed + - not firewall_off2.Domain.enabled + - not firewall_off2.Private.enabled + - not firewall_off2.Public.enabled + when: in_check_mode + + +- name: Turn off Windows Firewall again + win_firewall: + profiles: [ Domain, Private, Public ] + state: disabled + register: firewall_off2_again + +- name: Test firewall_off2_again (normal mode) + assert: + that: + - not firewall_off2_again|changed + - not firewall_off2_again.Domain.enabled + - not firewall_off2_again.Private.enabled + - not firewall_off2_again.Public.enabled