Repository: ansible/ansible

Issue:
win_firewall_rule fails when locale isn't English
_From @ilpianista on November 29, 2016 10:45_

##### ISSUE TYPE
 - Bug Report

##### COMPONENT NAME
win_firewall_rule

##### ANSIBLE VERSION
```
ansible 2.2.0.0
```

##### OS / ENVIRONMENT
Target host is Windows 7 with German language.

##### SUMMARY
I've a task to open a firewall port.
The rule creation succeeded, but on the next execution of the same task it fails because win_firewall_rule tries to parse the output which is in German and not in English as the module does expect.

##### STEPS TO REPRODUCE
The rule is e.g.
```
name: Open required port on the firewall
win_firewall_rule: name="Foo 8080" localport="8080" protocol=TCP action=allow direction=In profile=public enable=yes state=present force=true
```
##### EXPECTED RESULTS
Task returns ok on every execution.

##### ACTUAL RESULTS
Task fails on rule check.

_Copied from original issue: ansible/ansible-modules-extras#3563_


Discussion:
_From @ansibot on November 29, 2016 10:57_

<!-- @ilpianista: Thanks for filing this bug report! -->
@TimothyVandenbrande ping, this issue is waiting for your response.
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: issue_bug_new --->
cc @ar7z1
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->
I reproduced the issue and working on a fix.

Resolving patch:
diff --git a/lib/ansible/modules/windows/win_firewall_rule.py b/lib/ansible/modules/windows/win_firewall_rule.py
--- a/lib/ansible/modules/windows/win_firewall_rule.py
+++ b/lib/ansible/modules/windows/win_firewall_rule.py
@@ -29,100 +29,98 @@
 author: Timothy Vandenbrande
 short_description: Windows firewall automation
 description:
-    - allows you to create/remove/update firewall rules
+    - Allows you to create/remove/update firewall rules
 options:
-    enable:
+    enabled:
         description:
-            - is this firewall rule enabled or disabled
-        default: true
-        required: false
+            - Is this firewall rule enabled or disabled
+        default: 'yes'
+        choices: [ 'no', 'yes' ]
+        aliases: [ 'enable' ]
     state:
         description:
-            - should this rule be added or removed
+            - Should this rule be added or removed
         default: "present"
-        required: true
         choices: ['present', 'absent']
     name:
         description:
-            - the rules name
-        default: null
+            - The rules name
         required: true
     direction:
         description:
-            - is this rule for inbound or outbound traffic
-        default: null
+            - Is this rule for inbound or outbound traffic
         required: true
         choices: ['in', 'out']
     action:
         description:
-            - what to do with the items this rule is for
-        default: null
+            - What to do with the items this rule is for
         required: true
         choices: ['allow', 'block', 'bypass']
     description:
         description:
-            - description for the firewall rule
-        default: null
-        required: false
+            - Description for the firewall rule
     localip:
         description:
-            - the local ip address this rule applies to
+            - The local ip address this rule applies to
         default: 'any'
-        required: false
     remoteip:
         description:
-            - the remote ip address/range this rule applies to
+            - The remote ip address/range this rule applies to
         default: 'any'
-        required: false
     localport:
         description:
-            - the local port this rule applies to
-        default: 'any'
-        required: false
+            - The local port this rule applies to
     remoteport:
         description:
-            - the remote port this rule applies to
-        default: 'any'
-        required: false
+            - The remote port this rule applies to
     program:
         description:
-            - the program this rule applies to
-        default: null
-        required: false
+            - The program this rule applies to
     service:
         description:
-            - the service this rule applies to
-        default: 'any'
-        required: false
+            - The service this rule applies to
     protocol:
         description:
-            - the protocol this rule applies to
+            - The protocol this rule applies to
         default: 'any'
-        required: false
-    profile:
+    profiles:
         description:
-            - the profile this rule applies to, e.g. Domain,Private,Public
-        default: 'any'
-        required: false
+            - The profile this rule applies to
+        default: 'domain,private,public'
+        aliases: [ 'profile' ]
     force:
         description:
-            - Enforces the change if a rule with different values exists
-        default: false
-        required: false
-
-
+            - Replace any existing rule by removing it first.
+        default: 'no'
+        choices: [ 'no', 'yes' ]
+notes:
+- The implementation uses C(netsh advfirewall) underneath, a pure-Powershell
+  reimplementation would be more powerful.
+- Modifying existing firewall rules is not possible, the module does allow
+  replacing complete rules based on name, but that works by removing the
+  existing rule completely, and recreating it with provided information
+  (when using C(force)).
 '''
 
 EXAMPLES = r'''
-- name: Firewall rule to allow smtp on TCP port 25
-  action: win_firewall_rule
-  args:
-      name: smtp
-      enable: yes
-      state: present
-      localport: 25
-      action: allow
-      direction: In
-      protocol: TCP
+- name: Firewall rule to allow SMTP on TCP port 25
+  win_firewall_rule:
+    name: SMTP
+    localport: 25
+    action: allow
+    direction: in
+    protocol: tcp
+    state: present
+    enabled: yes
 
+- name: Firewall rule to allow RDP on TCP port 3389
+  win_firewall_rule:
+    name: Remote Desktop
+    localport: 3389
+    action: allow
+    direction: in
+    protocol: tcp
+    profiles: private
+    state: present
+    enabled: yes
 '''


Test patch:
diff --git a/test/integration/targets/win_firewall_rule/tasks/main.yml b/test/integration/targets/win_firewall_rule/tasks/main.yml
--- a/test/integration/targets/win_firewall_rule/tasks/main.yml
+++ b/test/integration/targets/win_firewall_rule/tasks/main.yml
@@ -3,7 +3,7 @@
     name: http
     state: absent
     action: "{{ item }}"
-    direction: In
+    direction: in
   with_items:
      - allow
      - block
@@ -11,90 +11,86 @@
 - name: Add firewall rule
   win_firewall_rule:
     name: http
-    enable: yes
+    enabled: yes
     state: present
     localport: 80
     action: allow
-    direction: In
-    protocol: TCP
+    direction: in
+    protocol: tcp
   register: add_firewall_rule
 
 - name: Check that creating new firewall rule succeeds with a change
   assert:
     that:
-    - add_firewall_rule.failed == false
     - add_firewall_rule.changed == true
 
 - name: Add same firewall rule (again)
   win_firewall_rule:
     name: http
-    enable: yes
+    enabled: yes
     state: present
     localport: 80
     action: allow
-    direction: In
-    protocol: TCP
+    direction: in
+    protocol: tcp
   register: add_firewall_rule_again
 
 - name: Check that creating same firewall rule succeeds without a change
   assert:
     that:
-    - add_firewall_rule_again.failed == false
     - add_firewall_rule_again.changed == false
 
 - name: Remove firewall rule
   win_firewall_rule:
     name: http
-    enable: yes
+    enabled: yes
     state: absent
     localport: 80
     action: allow
-    direction: In
-    protocol: TCP
+    direction: in
+    protocol: tcp
   register: remove_firewall_rule
 
 - name: Check that removing existing firewall rule succeeds with a change
   assert:
     that:
-    - remove_firewall_rule.failed == false
     - remove_firewall_rule.changed == true
 
 - name: Remove absent firewall rule
   win_firewall_rule:
     name: http
-    enable: yes
+    enabled: yes
     state: absent
     localport: 80
     action: allow
-    direction: In
-    protocol: TCP
+    direction: in
+    protocol: tcp
   register: remove_absent_firewall_rule
 
 - name: Check that removing non existing firewall rule succeeds without a change
   assert:
     that:
-    - remove_absent_firewall_rule.failed == false
     - remove_absent_firewall_rule.changed == false
 
 - name: Add firewall rule
   win_firewall_rule:
     name: http
-    enable: yes
+    enabled: yes
     state: present
     localport: 80
     action: allow
-    direction: In
-    protocol: TCP
+    direction: in
+    protocol: tcp
 
 - name: Add different firewall rule
   win_firewall_rule:
     name: http
-    enable: yes
+    enabled: yes
     state: present
     localport: 80
     action: block
-    direction: In
-    protocol: TCP
+    direction: in
+    protocol: tcp
   ignore_errors: yes
   register: add_different_firewall_rule_without_force
 
@@ -103,143 +99,136 @@
     that:
     - add_different_firewall_rule_without_force.failed == true
     - add_different_firewall_rule_without_force.changed == false
-    - add_different_firewall_rule_without_force.difference == ["block"]
 
 - name: Add different firewall rule with force setting
   win_firewall_rule:
     name: http
-    enable: yes
+    enabled: yes
     state: present
     localport: 80
     action: block
-    direction: In
-    protocol: TCP
+    direction: in
+    protocol: tcp
     force: yes
   register: add_different_firewall_rule_with_force
 
 - name: Check that creating different firewall rule with enabling force setting succeeds
   assert:
     that:
-    - add_different_firewall_rule_with_force.failed == false
     - add_different_firewall_rule_with_force.changed == true
-    - add_different_firewall_rule_with_force.difference == ["block"]
 
 - name: Add firewall rule when remoteip is range
   win_firewall_rule:
     name: http
-    enable: yes
+    enabled: yes
     state: present
     localport: 80
     remoteip: 192.168.0.1-192.168.0.5
     action: allow
-    direction: In
-    protocol: TCP
+    direction: in
+    protocol: tcp
     force: yes
 
 - name: Add same firewall rule when remoteip is range (again)
   win_firewall_rule:
     name: http
-    enable: yes
+    enabled: yes
     state: present
     localport: 80
     remoteip: 192.168.0.1-192.168.0.5
     action: allow
-    direction: In
-    protocol: TCP
+    direction: in
+    protocol: tcp
   register: add_firewall_rule_with_range_remoteip_again
 
 - name: Check that creating same firewall rule when remoteip is range succeeds without a change
   assert:
     that:
-    - add_firewall_rule_with_range_remoteip_again.failed == false
     - add_firewall_rule_with_range_remoteip_again.changed == false
 
 - name: Add firewall rule when remoteip in CIDR notation
   win_firewall_rule:
     name: http
-    enable: yes
+    enabled: yes
     state: present
     localport: 80
     remoteip: 192.168.0.0/24
     action: allow
-    direction: In
-    protocol: TCP
+    direction: in
+    protocol: tcp
     force: yes
 
 - name: Add same firewall rule when remoteip in CIDR notation (again)
   win_firewall_rule:
     name: http
-    enable: yes
+    enabled: yes
     state: present
     localport: 80
     remoteip: 192.168.0.0/24
     action: allow
-    direction: In
-    protocol: TCP
+    direction: in
+    protocol: tcp
   register: add_firewall_rule_with_cidr_remoteip_again
 
 - name: Check that creating same firewall rule succeeds without a change when remoteip in CIDR notation
   assert:
     that:
-    - add_firewall_rule_with_cidr_remoteip_again.failed == false
     - add_firewall_rule_with_cidr_remoteip_again.changed == false
 
 - name: Add firewall rule when remoteip contains a netmask
   win_firewall_rule:
     name: http
-    enable: yes
+    enabled: yes
     state: present
     localport: 80
     remoteip: 192.168.0.0/255.255.255.0
     action: allow
-    direction: In
-    protocol: TCP
+    direction: in
+    protocol: tcp
     force: yes
 
 - name: Add same firewall rule when remoteip contains a netmask (again)
   win_firewall_rule:
     name: http
-    enable: yes
+    enabled: yes
     state: present
     localport: 80
     remoteip: 192.168.0.0/255.255.255.0
     action: allow
-    direction: In
-    protocol: TCP
+    direction: in
+    protocol: tcp
   register: add_firewall_rule_remoteip_contains_netmask_again
 
 - name: Check that creating same firewall rule succeeds without a change when remoteip contains a netmask
   assert:
     that:
-    - add_firewall_rule_remoteip_contains_netmask_again.failed == false
     - add_firewall_rule_remoteip_contains_netmask_again.changed == false
 
 - name: Add firewall rule when remoteip is IPv4
   win_firewall_rule:
     name: http
-    enable: yes
+    enabled: yes
     state: present
     localport: 80
     remoteip: 192.168.0.1
     action: allow
-    direction: In
-    protocol: TCP
+    direction: in
+    protocol: tcp
     force: yes
 
 - name: Add same firewall rule when remoteip is IPv4 (again)
   win_firewall_rule:
     name: http
-    enable: yes
+    enabled: yes
     state: present
     localport: 80
     remoteip: 192.168.0.1
     action: allow
-    direction: In
-    protocol: TCP
+    direction: in
+    protocol: tcp
   register: add_firewall_rule_with_ipv4_remoteip_again
 
 - name: Check that creating same firewall rule when remoteip is IPv4 succeeds without a change
   assert:
     that:
-    - add_firewall_rule_with_ipv4_remoteip_again.failed == false
     - add_firewall_rule_with_ipv4_remoteip_again.changed == false