Created
November 26, 2013 09:20
-
-
Save zoni/7655561 to your computer and use it in GitHub Desktop.
Ansible module to manage iptables rules
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
""" | |
Ansible module to manage iptables rules | |
Written by Nick Groenen <[email protected]>. 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