diff options
author | Wesley Hearn <wesley.s.hearn@gmail.com> | 2015-04-24 14:06:12 -0400 |
---|---|---|
committer | Wesley Hearn <wesley.s.hearn@gmail.com> | 2015-04-24 14:06:12 -0400 |
commit | 519e097df31e2148ac520ab273d0bd2fb2f7bb43 (patch) | |
tree | 4c5413c72a2dd2ec732730b6994a104cca6a9798 /roles/os_firewall | |
parent | db9cf8ef4f030f30391e021f360fe0c3db1dce74 (diff) | |
parent | 8ce5e1de898d2fd2c4aa4620f31b57b62ed0c5d6 (diff) | |
download | openshift-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.py | 145 | ||||
-rw-r--r-- | roles/os_firewall/meta/main.yml | 1 | ||||
-rw-r--r-- | roles/os_firewall/tasks/firewall/firewalld.yml | 6 | ||||
-rw-r--r-- | roles/os_firewall/tasks/firewall/iptables.yml | 13 |
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: |