Repository: ansible/ansible-modules-extras

Issue:
iptables module: add possibility to INSERT rules (right now is only APPEND)
<!--- Verify first that your issue/request is not already reported in GitHub -->
##### ISSUE TYPE

<!--- Pick one below and delete the rest: -->
- Feature Idea
##### COMPONENT NAME

<!--- Name of the plugin/module/task -->

iptables
##### ANSIBLE VERSION

```
ansible 2.0.1.0
```
##### CONFIGURATION

<!---
Mention any settings you have changed/added/removed in ansible.cfg
(or using the ANSIBLE_* environment variables).
-->
##### OS / ENVIRONMENT

N/A

<!---
Mention the OS you are running Ansible from, and the OS you are
managing, or say “N/A” for anything that is not platform-specific.
-->
##### SUMMARY
##### STEPS TO REPRODUCE
##### EXPECTED RESULTS
##### ACTUAL RESULTS



Discussion:

Resolving patch:
diff --git a/system/iptables.py b/system/iptables.py
--- a/system/iptables.py
+++ b/system/iptables.py
@@ -56,6 +56,14 @@
     required: false
     default: present
     choices: [ "present", "absent" ]
+  action:
+    version_added: "2.2"
+    description:
+      - Whether the rule should be appended at the bottom or inserted at the
+        top. If the rule already exists the chain won't be modified.
+    required: false
+    default: append
+    choices: [ "append", "insert" ]
   ip_version:
     description:
       - Which version of the IP protocol this rule should apply to.
@@ -364,6 +372,11 @@ def append_rule(iptables_path, module, params):
     module.run_command(cmd, check_rc=True)
 
 
+def insert_rule(iptables_path, module, params):
+    cmd = push_arguments(iptables_path, '-I', params)
+    module.run_command(cmd, check_rc=True)
+
+
 def remove_rule(iptables_path, module, params):
     cmd = push_arguments(iptables_path, '-D', params)
     module.run_command(cmd, check_rc=True)
@@ -375,6 +388,7 @@ def main():
         argument_spec=dict(
             table=dict(required=False, default='filter', choices=['filter', 'nat', 'mangle', 'raw', 'security']),
             state=dict(required=False, default='present', choices=['present', 'absent']),
+            action=dict(required=False, default='append', type='str', choices=['append', 'insert']),
             ip_version=dict(required=False, default='ipv4', choices=['ipv4', 'ipv6']),
             chain=dict(required=True, default=None, type='str'),
             protocol=dict(required=False, default=None, type='str'),
@@ -413,6 +427,7 @@ def main():
         rule=' '.join(construct_rule(module.params)),
         state=module.params['state'],
     )
+    insert = (module.params['action'] == 'insert')
     ip_version = module.params['ip_version']
     iptables_path = module.get_bin_path(BINS[ip_version], True)
     rule_is_present = check_present(iptables_path, module, module.params)
@@ -430,7 +445,10 @@ def main():
         module.exit_json(**args)
 
     if should_be_present:
-        append_rule(iptables_path, module, module.params)
+        if insert:
+            insert_rule(iptables_path, module, module.params)
+        else:
+            append_rule(iptables_path, module, module.params)
     else:
         remove_rule(iptables_path, module, module.params)
 


Test patch: