summaryrefslogtreecommitdiffstats
path: root/roles/os_firewall
diff options
context:
space:
mode:
Diffstat (limited to 'roles/os_firewall')
-rw-r--r--roles/os_firewall/README.md5
-rw-r--r--roles/os_firewall/defaults/main.yml8
-rwxr-xr-xroles/os_firewall/library/os_firewall_manage_iptables.py65
-rw-r--r--roles/os_firewall/meta/main.yml13
-rw-r--r--roles/os_firewall/tasks/firewall/firewalld.yml67
-rw-r--r--roles/os_firewall/tasks/firewall/iptables.yml52
-rw-r--r--roles/os_firewall/tasks/main.yml6
7 files changed, 79 insertions, 137 deletions
diff --git a/roles/os_firewall/README.md b/roles/os_firewall/README.md
index 187d74b06..43db3cc74 100644
--- a/roles/os_firewall/README.md
+++ b/roles/os_firewall/README.md
@@ -4,10 +4,13 @@ OS Firewall
OS Firewall manages firewalld and iptables firewall settings for a minimal use
case (Adding/Removing rules based on protocol and port number).
+Note: firewalld is not supported on Atomic Host
+https://bugzilla.redhat.com/show_bug.cgi?id=1403331
+
Requirements
------------
-None.
+Ansible 2.2
Role Variables
--------------
diff --git a/roles/os_firewall/defaults/main.yml b/roles/os_firewall/defaults/main.yml
index c870a301a..4c544122f 100644
--- a/roles/os_firewall/defaults/main.yml
+++ b/roles/os_firewall/defaults/main.yml
@@ -1,9 +1,7 @@
---
os_firewall_enabled: True
-# TODO: Upstream kubernetes only supports iptables currently
-# TODO: it might be possible to still use firewalld if we wire up the created
-# chains with the public zone (or the zone associated with the correct
-# interfaces)
-os_firewall_use_firewalld: False
+# firewalld is not supported on Atomic Host
+# https://bugzilla.redhat.com/show_bug.cgi?id=1403331
+os_firewall_use_firewalld: "{{ False if openshift.common.is_atomic | bool else True }}"
os_firewall_allow: []
os_firewall_deny: []
diff --git a/roles/os_firewall/library/os_firewall_manage_iptables.py b/roles/os_firewall/library/os_firewall_manage_iptables.py
index 190016c14..8ba650994 100755
--- a/roles/os_firewall/library/os_firewall_manage_iptables.py
+++ b/roles/os_firewall/library/os_firewall_manage_iptables.py
@@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
# vim: expandtab:tabstop=4:shiftwidth=4
# pylint: disable=fixme, missing-docstring
-from subprocess import call, check_output
+import subprocess
DOCUMENTATION = '''
---
@@ -29,7 +29,10 @@ class IpTablesAddRuleError(IpTablesError):
class IpTablesRemoveRuleError(IpTablesError):
- pass
+ def __init__(self, chain, msg, cmd, exit_code, output): # pylint: disable=too-many-arguments, line-too-long, redefined-outer-name
+ super(IpTablesRemoveRuleError, self).__init__(msg, cmd, exit_code,
+ output)
+ self.chain = chain
class IpTablesSaveError(IpTablesError):
@@ -37,23 +40,23 @@ class IpTablesSaveError(IpTablesError):
class IpTablesCreateChainError(IpTablesError):
- def __init__(self, chain, msg, cmd, exit_code, output): # pylint: disable=too-many-arguments, line-too-long, redefined-outer-name
+ def __init__(self, chain, msg, cmd, exit_code, output): # pylint: disable=too-many-arguments, line-too-long, redefined-outer-name
super(IpTablesCreateChainError, self).__init__(msg, cmd, exit_code,
output)
self.chain = chain
class IpTablesCreateJumpRuleError(IpTablesError):
- def __init__(self, chain, msg, cmd, exit_code, output): # pylint: disable=too-many-arguments, line-too-long, redefined-outer-name
+ def __init__(self, chain, msg, cmd, exit_code, output): # pylint: disable=too-many-arguments, line-too-long, redefined-outer-name
super(IpTablesCreateJumpRuleError, self).__init__(msg, cmd, exit_code,
output)
self.chain = chain
-# TODO: impliment rollbacks for any events that where successful and an
-# exception was thrown later. for example, when the chain is created
+# TODO: implement rollbacks for any events that were successful and an
+# exception was thrown later. For example, when the chain is created
# successfully, but the add/remove rule fails.
-class IpTablesManager(object): # pylint: disable=too-many-instance-attributes
+class IpTablesManager(object): # pylint: disable=too-many-instance-attributes
def __init__(self, module):
self.module = module
self.ip_version = module.params['ip_version']
@@ -68,8 +71,7 @@ class IpTablesManager(object): # pylint: disable=too-many-instance-attributes
def save(self):
try:
- self.output.append(check_output(self.save_cmd,
- stderr=subprocess.STDOUT))
+ self.output.append(subprocess.check_output(self.save_cmd, stderr=subprocess.STDOUT))
except subprocess.CalledProcessError as ex:
raise IpTablesSaveError(
msg="Failed to save iptables rules",
@@ -92,7 +94,7 @@ class IpTablesManager(object): # pylint: disable=too-many-instance-attributes
else:
cmd = self.cmd + ['-A'] + rule
try:
- self.output.append(check_output(cmd))
+ self.output.append(subprocess.check_output(cmd))
self.changed = True
self.save()
except subprocess.CalledProcessError as ex:
@@ -112,7 +114,7 @@ class IpTablesManager(object): # pylint: disable=too-many-instance-attributes
else:
cmd = self.cmd + ['-D'] + rule
try:
- self.output.append(check_output(cmd))
+ self.output.append(subprocess.check_output(cmd))
self.changed = True
self.save()
except subprocess.CalledProcessError as ex:
@@ -123,11 +125,19 @@ class IpTablesManager(object): # pylint: disable=too-many-instance-attributes
def rule_exists(self, rule):
check_cmd = self.cmd + ['-C'] + rule
- return True if call(check_cmd) == 0 else False
+ return True if subprocess.call(check_cmd) == 0 else False
+
+ @staticmethod
+ def port_as_argument(port):
+ if isinstance(port, int):
+ return str(port)
+ if isinstance(port, basestring): # noqa: F405
+ return port.replace('-', ":")
+ return port
def gen_rule(self, port, proto):
return [self.chain, '-p', proto, '-m', 'state', '--state', 'NEW',
- '-m', proto, '--dport', str(port), '-j', 'ACCEPT']
+ '-m', proto, '--dport', IpTablesManager.port_as_argument(port), '-j', 'ACCEPT']
def create_jump(self):
if self.check_mode:
@@ -136,10 +146,10 @@ class IpTablesManager(object): # pylint: disable=too-many-instance-attributes
else:
try:
cmd = self.cmd + ['-L', self.jump_rule_chain, '--line-numbers']
- output = check_output(cmd, stderr=subprocess.STDOUT)
+ output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
# break the input rules into rows and columns
- input_rules = [s.split() for s in output.split('\n')]
+ input_rules = [s.split() for s in to_native(output).split('\n')]
# Find the last numbered rule
last_rule_num = None
@@ -155,8 +165,7 @@ class IpTablesManager(object): # pylint: disable=too-many-instance-attributes
# Naively assume that if the last row is a REJECT or DROP rule,
# then we can insert our rule right before it, otherwise we
# assume that we can just append the rule.
- if (last_rule_num and last_rule_target
- and last_rule_target in ['REJECT', 'DROP']):
+ if (last_rule_num and last_rule_target and last_rule_target in ['REJECT', 'DROP']):
# insert rule
cmd = self.cmd + ['-I', self.jump_rule_chain,
str(last_rule_num)]
@@ -164,7 +173,7 @@ class IpTablesManager(object): # pylint: disable=too-many-instance-attributes
# append rule
cmd = self.cmd + ['-A', self.jump_rule_chain]
cmd += ['-j', self.chain]
- output = check_output(cmd, stderr=subprocess.STDOUT)
+ output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
self.changed = True
self.output.append(output)
self.save()
@@ -192,8 +201,7 @@ class IpTablesManager(object): # pylint: disable=too-many-instance-attributes
else:
try:
cmd = self.cmd + ['-N', self.chain]
- self.output.append(check_output(cmd,
- stderr=subprocess.STDOUT))
+ self.output.append(subprocess.check_output(cmd, stderr=subprocess.STDOUT))
self.changed = True
self.output.append("Successfully created chain %s" %
self.chain)
@@ -203,26 +211,26 @@ class IpTablesManager(object): # pylint: disable=too-many-instance-attributes
chain=self.chain,
msg="Failed to create chain: %s" % self.chain,
cmd=ex.cmd, exit_code=ex.returncode, output=ex.output
- )
+ )
def jump_rule_exists(self):
cmd = self.cmd + ['-C', self.jump_rule_chain, '-j', self.chain]
- return True if call(cmd) == 0 else False
+ return True if subprocess.call(cmd) == 0 else False
def chain_exists(self):
cmd = self.cmd + ['-L', self.chain]
- return True if call(cmd) == 0 else False
+ return True if subprocess.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): # pylint: disable=no-self-use
+ def gen_save_cmd(self): # pylint: disable=no-self-use
return ['/usr/libexec/iptables/iptables.init', 'save']
def main():
- module = AnsibleModule(
+ module = AnsibleModule( # noqa: F405
argument_spec=dict(
name=dict(required=True),
action=dict(required=True, choices=['add', 'remove',
@@ -231,7 +239,7 @@ def main():
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'),
+ port=dict(required=False, type='str'),
ip_version=dict(required=False, default='ipv4',
choices=['ipv4', 'ipv6']),
),
@@ -266,8 +274,9 @@ def main():
output=iptables_manager.output)
-# pylint: disable=redefined-builtin, unused-wildcard-import, wildcard-import
+# pylint: disable=redefined-builtin, unused-wildcard-import, wildcard-import, wrong-import-position
# import module snippets
-from ansible.module_utils.basic import *
+from ansible.module_utils.basic import * # noqa: F403,E402
+from ansible.module_utils._text import to_native # noqa: E402
if __name__ == '__main__':
main()
diff --git a/roles/os_firewall/meta/main.yml b/roles/os_firewall/meta/main.yml
index c93335b7b..dca5fc5ff 100644
--- a/roles/os_firewall/meta/main.yml
+++ b/roles/os_firewall/meta/main.yml
@@ -4,12 +4,13 @@ galaxy_info:
description: os_firewall
company: Red Hat, Inc.
license: Apache License, Version 2.0
- min_ansible_version: 1.7
+ min_ansible_version: 2.2
platforms:
- - name: EL
- versions:
- - 7
+ - name: EL
+ versions:
+ - 7
categories:
- - system
+ - system
+allow_duplicates: yes
dependencies:
-- { role: openshift_facts }
+ - role: openshift_facts
diff --git a/roles/os_firewall/tasks/firewall/firewalld.yml b/roles/os_firewall/tasks/firewall/firewalld.yml
index 5ddca1fc0..1101870be 100644
--- a/roles/os_firewall/tasks/firewall/firewalld.yml
+++ b/roles/os_firewall/tasks/firewall/firewalld.yml
@@ -1,88 +1,45 @@
---
- name: Install firewalld packages
- action: "{{ ansible_pkg_mgr }} name=firewalld state=present"
+ package: name=firewalld state=present
when: not openshift.common.is_containerized | bool
- register: install_result
-
-- name: Check if iptables-services is installed
- command: rpm -q iptables-services
- register: pkg_check
- failed_when: pkg_check.rc > 1
- changed_when: no
- name: Ensure iptables services are not enabled
- service:
+ systemd:
name: "{{ item }}"
state: stopped
enabled: no
+ masked: yes
with_items:
- - iptables
- - ip6tables
- when: pkg_check.rc == 0
-
-- name: Reload systemd units
- command: systemctl daemon-reload
- when: install_result | changed
-
-- name: Determine if firewalld service masked
- command: >
- systemctl is-enabled firewalld
- register: os_firewall_firewalld_masked_output
- changed_when: false
- failed_when: false
-
-- name: Unmask firewalld service
- command: >
- systemctl unmask firewalld
- when: os_firewall_firewalld_masked_output.stdout == "masked"
+ - iptables
+ - ip6tables
+ register: task_result
+ failed_when: "task_result|failed and 'could not' not in task_result.msg|lower"
- name: Start and enable firewalld service
- service:
+ systemd:
name: firewalld
state: started
enabled: yes
+ masked: no
+ daemon_reload: yes
register: result
- name: need to pause here, otherwise the firewalld service starting can sometimes cause ssh to fail
pause: seconds=10
when: result | changed
-- name: Mask iptables services
- command: systemctl mask "{{ item }}"
- register: result
- changed_when: "'iptables' in result.stdout"
- with_items:
- - 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
- name: Add firewalld allow rules
firewalld:
port: "{{ item.port }}"
- permanent: false
- state: enabled
- with_items: "{{ os_firewall_allow }}"
-
-- name: Persist firewalld allow rules
- firewalld:
- port: "{{ item.port }}"
permanent: true
+ immediate: true
state: enabled
with_items: "{{ os_firewall_allow }}"
- name: Remove firewalld allow rules
firewalld:
port: "{{ item.port }}"
- permanent: false
- state: disabled
- with_items: "{{ os_firewall_deny }}"
-
-- name: Persist removal of firewalld allow rules
- firewalld:
- port: "{{ item.port }}"
permanent: true
+ immediate: true
state: disabled
with_items: "{{ os_firewall_deny }}"
diff --git a/roles/os_firewall/tasks/firewall/iptables.yml b/roles/os_firewall/tasks/firewall/iptables.yml
index 774916798..930b32cf2 100644
--- a/roles/os_firewall/tasks/firewall/iptables.yml
+++ b/roles/os_firewall/tasks/firewall/iptables.yml
@@ -1,60 +1,28 @@
---
-- name: Check if firewalld is installed
- command: rpm -q firewalld
- register: pkg_check
- failed_when: pkg_check.rc > 1
- changed_when: no
- name: Ensure firewalld service is not enabled
- service:
+ systemd:
name: firewalld
state: stopped
enabled: no
- when: pkg_check.rc == 0
-
-# TODO: submit PR upstream to add mask/unmask to service module
-- name: Mask firewalld service
- command: systemctl mask firewalld
- register: result
- changed_when: "'firewalld' in result.stdout"
- when: pkg_check.rc == 0
- ignore_errors: yes
+ masked: yes
+ register: task_result
+ failed_when: "task_result|failed and 'could not' not in task_result.msg|lower"
- name: Install iptables packages
- action: "{{ ansible_pkg_mgr }} name={{ item }} state=present"
+ package: name={{ item }} state=present
with_items:
- - iptables
- - iptables-services
- register: install_result
+ - iptables
+ - iptables-services
when: not openshift.common.is_atomic | bool
-- name: Reload systemd units
- command: systemctl daemon-reload
- when: install_result | changed
-
-- name: Determine if iptables service masked
- command: >
- systemctl is-enabled {{ item }}
- with_items:
- - iptables
- - ip6tables
- register: os_firewall_iptables_masked_output
- changed_when: false
- failed_when: false
-
-- name: Unmask iptables service
- command: >
- systemctl unmask {{ item }}
- with_items:
- - iptables
- - ip6tables
- when: "'masked' in os_firewall_iptables_masked_output.results | map(attribute='stdout')"
-
- name: Start and enable iptables service
- service:
+ systemd:
name: iptables
state: started
enabled: yes
+ masked: no
+ daemon_reload: yes
register: result
- name: need to pause here, otherwise the iptables service starting can sometimes cause ssh to fail
diff --git a/roles/os_firewall/tasks/main.yml b/roles/os_firewall/tasks/main.yml
index 076e5e311..20efe5b0d 100644
--- a/roles/os_firewall/tasks/main.yml
+++ b/roles/os_firewall/tasks/main.yml
@@ -1,4 +1,10 @@
---
+- name: Assert - Do not use firewalld on Atomic Host
+ assert:
+ that: not os_firewall_use_firewalld | bool
+ msg: "Firewalld is not supported on Atomic Host"
+ when: openshift.common.is_atomic | bool
+
- include: firewall/firewalld.yml
when: os_firewall_enabled | bool and os_firewall_use_firewalld | bool