Skip to content

Instantly share code, notes, and snippets.

@zoni
Created November 26, 2013 09:20
Show Gist options
  • Save zoni/7655561 to your computer and use it in GitHub Desktop.
Save zoni/7655561 to your computer and use it in GitHub Desktop.
Ansible module to manage iptables rules
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Ansible module to manage iptables rules
Written by Nick Groenen <zoni@zoni.nl>. If you get your hands on a
copy of this code, please feel free to do with it whatever you like.
"""
DOCUMENTATION = '''
---
module: iptables
short_description: Manage iptables rules
description:
- Adds and removes iptables files to and from C({{iptables_fragments_dir}}) (ipv4) or C({{ip6tables_fragments_dir}}) (ipv6)
author: Nick Groenen
version_added: "1.3"
notes:
- Relies on the C(firewall_setup) and C(firewall_activate) roles being applied to target hosts
options:
fragment_dir:
description:
- The directory where this iptables fragment should be placed
required: false
ipversion:
description:
- Target the IP version this rule is for
required: false
default: "4"
choices: ["4", "6"]
table:
description:
- The table this rule applies to
choices: ["filter", "nat", "mangle", "raw", "security"]
default: filter
state:
description:
- The state this rules fragment should be in
choices: ["present", "absent"]
default: present
rules:
description:
- The rules that should be in this fragment
required: true
'''
EXAMPLES = '''
- name: Allow all IPv4 traffic coming in on port 80 (http)
iptables: >
state=present
ipversion=4
name=50_allow_all_traffic_on_port_80
rules="-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT"
'''
import os
def main():
module = AnsibleModule(
argument_spec = dict(
fragment_dir = dict(required=False, type='str', default=None),
ipversion = dict(required=False, choices=["4", "6"], type='str', default="4"),
state = dict(choices=['present', 'absent'], default='present', type='str'),
name = dict(required=True, type='str'),
table = dict(choices=["filter", "nat", "mangle", "raw", "security"], default="filter", type='str'),
rules = dict(required=True, type='str')
),
supports_check_mode = True,
)
check_mode = module.check_mode
changed = False
params = module.params
ipversion = module.params['ipversion']
state = module.params['state']
name = module.params['name']
table = module.params['table']
rules = module.params['rules']
try:
if ipversion == "4":
fragment_dir = (params['fragment_dir'] if params['fragment_dir'] is not None
else '/etc/iptables/fragments.v4/')
else:
fragment_dir = (params['fragment_dir'] if params['fragment_dir'] is not None
else '/etc/iptables/fragments.v6/')
fragment_path = os.path.join(fragment_dir, "_".join((table, name)))
if not rules.endswith("\n"):
rules += "\n"
done = False
if params['state'] == "present":
if os.path.exists(fragment_path):
# Fragment already exists. Check if it's changed.
current = open(fragment_path, 'r').read()
if current == rules:
done = True
if not done:
# Fragment changed or didn't exist at all
changed = True
if not check_mode:
with open(fragment_path, "w") as f:
f.write(rules)
else:
if os.path.exists(fragment_path):
changed = True
if not check_mode:
os.unlink(fragment_path)
except Exception as e:
msg="An exception occurred during module execution: %s: %s" % (type(e), e)
module.fail_json(msg=msg)
else:
module.exit_json(changed=changed)
# include magic from lib/ansible/module_common.py
#<<INCLUDE_ANSIBLE_MODULE_COMMON>>
if not os.environ.get('running_tests', False):
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment