summaryrefslogtreecommitdiffstats
path: root/roles/os_firewall
diff options
context:
space:
mode:
authorWesley Hearn <wesley.s.hearn@gmail.com>2015-04-24 14:06:12 -0400
committerWesley Hearn <wesley.s.hearn@gmail.com>2015-04-24 14:06:12 -0400
commit519e097df31e2148ac520ab273d0bd2fb2f7bb43 (patch)
tree4c5413c72a2dd2ec732730b6994a104cca6a9798 /roles/os_firewall
parentdb9cf8ef4f030f30391e021f360fe0c3db1dce74 (diff)
parent8ce5e1de898d2fd2c4aa4620f31b57b62ed0c5d6 (diff)
downloadopenshift-519e097df31e2148ac520ab273d0bd2fb2f7bb43.tar.gz
openshift-519e097df31e2148ac520ab273d0bd2fb2f7bb43.tar.bz2
openshift-519e097df31e2148ac520ab273d0bd2fb2f7bb43.tar.xz
openshift-519e097df31e2148ac520ab273d0bd2fb2f7bb43.zip
Merge pull request #188 from openshift/master
Merge master into stage
Diffstat (limited to 'roles/os_firewall')
-rwxr-xr-x[-rw-r--r--]roles/os_firewall/library/os_firewall_manage_iptables.py145
-rw-r--r--roles/os_firewall/meta/main.yml1
-rw-r--r--roles/os_firewall/tasks/firewall/firewalld.yml6
-rw-r--r--roles/os_firewall/tasks/firewall/iptables.yml13
4 files changed, 97 insertions, 68 deletions
diff --git a/roles/os_firewall/library/os_firewall_manage_iptables.py b/roles/os_firewall/library/os_firewall_manage_iptables.py
index fef710055..1cb539a8c 100644..100755
--- a/roles/os_firewall/library/os_firewall_manage_iptables.py
+++ b/roles/os_firewall/library/os_firewall_manage_iptables.py
@@ -1,6 +1,7 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
-
+# vim: expandtab:tabstop=4:shiftwidth=4
+# pylint: disable=fixme, missing-docstring
from subprocess import call, check_output
DOCUMENTATION = '''
@@ -16,6 +17,7 @@ EXAMPLES = '''
class IpTablesError(Exception):
def __init__(self, msg, cmd, exit_code, output):
+ super(IpTablesError, self).__init__(msg)
self.msg = msg
self.cmd = cmd
self.exit_code = exit_code
@@ -35,13 +37,14 @@ class IpTablesSaveError(IpTablesError):
class IpTablesCreateChainError(IpTablesError):
- def __init__(self, chain, msg, cmd, exit_code, output):
- super(IpTablesCreateChainError, self).__init__(msg, cmd, exit_code, output)
+ def __init__(self, chain, msg, cmd, exit_code, output): # pylint: disable=too-many-arguments, line-too-long
+ super(IpTablesCreateChainError, self).__init__(msg, cmd, exit_code,
+ output)
self.chain = chain
class IpTablesCreateJumpRuleError(IpTablesError):
- def __init__(self, chain, msg, cmd, exit_code, output):
+ def __init__(self, chain, msg, cmd, exit_code, output): # pylint: disable=too-many-arguments, line-too-long
super(IpTablesCreateJumpRuleError, self).__init__(msg, cmd, exit_code,
output)
self.chain = chain
@@ -50,12 +53,14 @@ class IpTablesCreateJumpRuleError(IpTablesError):
# TODO: impliment rollbacks for any events that where successful and an
# exception was thrown later. for example, when the chain is created
# successfully, but the add/remove rule fails.
-class IpTablesManager:
- def __init__(self, module, ip_version, check_mode, chain):
+class IpTablesManager(object): # pylint: disable=too-many-instance-attributes
+ def __init__(self, module):
self.module = module
- self.ip_version = ip_version
- self.check_mode = check_mode
- self.chain = chain
+ self.ip_version = module.params['ip_version']
+ self.check_mode = module.check_mode
+ self.chain = module.params['chain']
+ self.create_jump_rule = module.params['create_jump_rule']
+ self.jump_rule_chain = module.params['jump_rule_chain']
self.cmd = self.gen_cmd()
self.save_cmd = self.gen_save_cmd()
self.output = []
@@ -65,18 +70,21 @@ class IpTablesManager:
try:
self.output.append(check_output(self.save_cmd,
stderr=subprocess.STDOUT))
- except subprocess.CalledProcessError as e:
+ except subprocess.CalledProcessError as ex:
raise IpTablesSaveError(
msg="Failed to save iptables rules",
- cmd=e.cmd, exit_code=e.returncode, output=e.output)
+ cmd=ex.cmd, exit_code=ex.returncode, output=ex.output)
+
+ def verify_chain(self):
+ if not self.chain_exists():
+ self.create_chain()
+ if self.create_jump_rule and not self.jump_rule_exists():
+ self.create_jump()
def add_rule(self, port, proto):
rule = self.gen_rule(port, proto)
if not self.rule_exists(rule):
- if not self.chain_exists():
- self.create_chain()
- if not self.jump_rule_exists():
- self.create_jump_rule()
+ self.verify_chain()
if self.check_mode:
self.changed = True
@@ -87,13 +95,13 @@ class IpTablesManager:
self.output.append(check_output(cmd))
self.changed = True
self.save()
- except subprocess.CalledProcessError as e:
+ except subprocess.CalledProcessError as ex:
raise IpTablesCreateChainError(
chain=self.chain,
msg="Failed to create rule for "
- "%s %s" % (self.proto, self.port),
- cmd=e.cmd, exit_code=e.returncode,
- output=e.output)
+ "%s %s" % (proto, port),
+ cmd=ex.cmd, exit_code=ex.returncode,
+ output=ex.output)
def remove_rule(self, port, proto):
rule = self.gen_rule(port, proto)
@@ -107,31 +115,31 @@ class IpTablesManager:
self.output.append(check_output(cmd))
self.changed = True
self.save()
- except subprocess.CalledProcessError as e:
- raise IpTablesRemoveChainError(
+ except subprocess.CalledProcessError as ex:
+ raise IpTablesRemoveRuleError(
chain=self.chain,
msg="Failed to remove rule for %s %s" % (proto, port),
- cmd=e.cmd, exit_code=e.returncode, output=e.output)
+ cmd=ex.cmd, exit_code=ex.returncode, output=ex.output)
def rule_exists(self, rule):
check_cmd = self.cmd + ['-C'] + rule
- return True if subprocess.call(check_cmd) == 0 else False
+ return True if call(check_cmd) == 0 else False
def gen_rule(self, port, proto):
return [self.chain, '-p', proto, '-m', 'state', '--state', 'NEW',
'-m', proto, '--dport', str(port), '-j', 'ACCEPT']
- def create_jump_rule(self):
+ def create_jump(self):
if self.check_mode:
self.changed = True
self.output.append("Create jump rule for chain %s" % self.chain)
else:
try:
- cmd = self.cmd + ['-L', 'INPUT', '--line-numbers']
+ cmd = self.cmd + ['-L', self.jump_rule_chain, '--line-numbers']
output = check_output(cmd, stderr=subprocess.STDOUT)
# break the input rules into rows and columns
- input_rules = map(lambda s: s.split(), output.split('\n'))
+ input_rules = [s.split() for s in output.split('\n')]
# Find the last numbered rule
last_rule_num = None
@@ -144,41 +152,38 @@ class IpTablesManager:
continue
last_rule_target = rule[1]
- # Raise an exception if we do not find a valid INPUT rule
- if not last_rule_num or not last_rule_target:
- raise IpTablesCreateJumpRuleError(
- chain=self.chain,
- msg="Failed to find existing INPUT rules",
- cmd=None, exit_code=None, output=None)
-
# Naively assume that if the last row is a REJECT rule, then
# we can add insert our rule right before it, otherwise we
# assume that we can just append the rule.
- if last_rule_target == 'REJECT':
+ if (last_rule_num and last_rule_target
+ and last_rule_target == 'REJECT'):
# insert rule
- cmd = self.cmd + ['-I', 'INPUT', str(last_rule_num)]
+ cmd = self.cmd + ['-I', self.jump_rule_chain,
+ str(last_rule_num)]
else:
# append rule
- cmd = self.cmd + ['-A', 'INPUT']
+ cmd = self.cmd + ['-A', self.jump_rule_chain]
cmd += ['-j', self.chain]
output = check_output(cmd, stderr=subprocess.STDOUT)
- changed = True
+ self.changed = True
self.output.append(output)
- except subprocess.CalledProcessError as e:
- if '--line-numbers' in e.cmd:
+ self.save()
+ except subprocess.CalledProcessError as ex:
+ if '--line-numbers' in ex.cmd:
raise IpTablesCreateJumpRuleError(
chain=self.chain,
- msg="Failed to query existing INPUT rules to "
- "determine jump rule location",
- cmd=e.cmd, exit_code=e.returncode,
- output=e.output)
+ msg=("Failed to query existing " +
+ self.jump_rule_chain +
+ " rules to determine jump rule location"),
+ cmd=ex.cmd, exit_code=ex.returncode,
+ output=ex.output)
else:
raise IpTablesCreateJumpRuleError(
chain=self.chain,
- msg="Failed to create jump rule for chain %s" %
- self.chain,
- cmd=e.cmd, exit_code=e.returncode,
- output=e.output)
+ msg=("Failed to create jump rule for chain " +
+ self.chain),
+ cmd=ex.cmd, exit_code=ex.returncode,
+ output=ex.output)
def create_chain(self):
if self.check_mode:
@@ -192,27 +197,27 @@ class IpTablesManager:
self.changed = True
self.output.append("Successfully created chain %s" %
self.chain)
- except subprocess.CalledProcessError as e:
+ self.save()
+ except subprocess.CalledProcessError as ex:
raise IpTablesCreateChainError(
chain=self.chain,
msg="Failed to create chain: %s" % self.chain,
- cmd=e.cmd, exit_code=e.returncode, output=e.output
+ cmd=ex.cmd, exit_code=ex.returncode, output=ex.output
)
def jump_rule_exists(self):
- cmd = self.cmd + ['-C', 'INPUT', '-j', self.chain]
- return True if subprocess.call(cmd) == 0 else False
+ cmd = self.cmd + ['-C', self.jump_rule_chain, '-j', self.chain]
+ return True if call(cmd) == 0 else False
def chain_exists(self):
cmd = self.cmd + ['-L', self.chain]
- return True if subprocess.call(cmd) == 0 else False
+ return True if call(cmd) == 0 else False
def gen_cmd(self):
cmd = 'iptables' if self.ip_version == 'ipv4' else 'ip6tables'
return ["/usr/sbin/%s" % cmd]
- def gen_save_cmd(self):
- cmd = 'iptables' if self.ip_version == 'ipv4' else 'ip6tables'
+ def gen_save_cmd(self): # pylint: disable=no-self-use
return ['/usr/libexec/iptables/iptables.init', 'save']
@@ -220,9 +225,13 @@ def main():
module = AnsibleModule(
argument_spec=dict(
name=dict(required=True),
- action=dict(required=True, choices=['add', 'remove']),
- protocol=dict(required=True, choices=['tcp', 'udp']),
- port=dict(required=True, type='int'),
+ action=dict(required=True, choices=['add', 'remove',
+ 'verify_chain']),
+ chain=dict(required=False, default='OS_FIREWALL_ALLOW'),
+ create_jump_rule=dict(required=False, type='bool', default=True),
+ jump_rule_chain=dict(required=False, default='INPUT'),
+ protocol=dict(required=False, choices=['tcp', 'udp']),
+ port=dict(required=False, type='int'),
ip_version=dict(required=False, default='ipv4',
choices=['ipv4', 'ipv6']),
),
@@ -232,23 +241,33 @@ def main():
action = module.params['action']
protocol = module.params['protocol']
port = module.params['port']
- ip_version = module.params['ip_version']
- chain = 'OS_FIREWALL_ALLOW'
- iptables_manager = IpTablesManager(module, ip_version, module.check_mode, chain)
+ if action in ['add', 'remove']:
+ if not protocol:
+ error = "protocol is required when action is %s" % action
+ module.fail_json(msg=error)
+ if not port:
+ error = "port is required when action is %s" % action
+ module.fail_json(msg=error)
+
+ iptables_manager = IpTablesManager(module)
try:
if action == 'add':
iptables_manager.add_rule(port, protocol)
elif action == 'remove':
iptables_manager.remove_rule(port, protocol)
- except IpTablesError as e:
- module.fail_json(msg=e.msg)
+ elif action == 'verify_chain':
+ iptables_manager.verify_chain()
+ except IpTablesError as ex:
+ module.fail_json(msg=ex.msg)
return module.exit_json(changed=iptables_manager.changed,
output=iptables_manager.output)
+# pylint: disable=redefined-builtin, unused-wildcard-import, wildcard-import
# import module snippets
from ansible.module_utils.basic import *
-main()
+if __name__ == '__main__':
+ main()
diff --git a/roles/os_firewall/meta/main.yml b/roles/os_firewall/meta/main.yml
index 7a8cef6c5..8592371e8 100644
--- a/roles/os_firewall/meta/main.yml
+++ b/roles/os_firewall/meta/main.yml
@@ -1,3 +1,4 @@
+---
galaxy_info:
author: Jason DeTiberus
description: os_firewall
diff --git a/roles/os_firewall/tasks/firewall/firewalld.yml b/roles/os_firewall/tasks/firewall/firewalld.yml
index 469cfab6f..5089eb3e0 100644
--- a/roles/os_firewall/tasks/firewall/firewalld.yml
+++ b/roles/os_firewall/tasks/firewall/firewalld.yml
@@ -3,6 +3,7 @@
yum:
name: firewalld
state: present
+ register: install_result
- name: Check if iptables-services is installed
command: rpm -q iptables-services
@@ -20,6 +21,10 @@
- ip6tables
when: pkg_check.rc == 0
+- name: Reload systemd units
+ command: systemctl daemon-reload
+ when: install_result | changed
+
- name: Start and enable firewalld service
service:
name: firewalld
@@ -39,6 +44,7 @@
- iptables
- ip6tables
when: pkg_check.rc == 0
+ ignore_errors: yes
# TODO: Ansible 1.9 will eliminate the need for separate firewalld tasks for
# enabling rules and making them permanent with the immediate flag
diff --git a/roles/os_firewall/tasks/firewall/iptables.yml b/roles/os_firewall/tasks/firewall/iptables.yml
index 87e77c083..9af9d8d29 100644
--- a/roles/os_firewall/tasks/firewall/iptables.yml
+++ b/roles/os_firewall/tasks/firewall/iptables.yml
@@ -6,6 +6,7 @@
with_items:
- iptables
- iptables-services
+ register: install_result
- name: Check if firewalld is installed
command: rpm -q firewalld
@@ -20,14 +21,15 @@
enabled: no
when: pkg_check.rc == 0
-- name: Start and enable iptables services
+- name: Reload systemd units
+ command: systemctl daemon-reload
+ when: install_result | changed
+
+- name: Start and enable iptables service
service:
- name: "{{ item }}"
+ name: iptables
state: started
enabled: yes
- with_items:
- - iptables
- - ip6tables
register: result
- name: need to pause here, otherwise the iptables service starting can sometimes cause ssh to fail
@@ -40,6 +42,7 @@
register: result
changed_when: "'firewalld' in result.stdout"
when: pkg_check.rc == 0
+ ignore_errors: yes
- name: Add iptables allow rules
os_firewall_manage_iptables: