This commit is contained in:
Evert Hessel 2023-02-28 11:24:56 +00:00 committed by GitHub
commit 9b7792abce
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 202 additions and 6 deletions

View file

@ -0,0 +1,4 @@
---
minor_changes:
- firewalld - Added parameter ``forward`` to support enabling/disabling intra-zone
forwarding.

View file

@ -118,6 +118,21 @@ Parameters
<div>The masquerade setting you would like to enable/disable to/from zones within firewalld.</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>forward</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">string</span>
</div>
</td>
<td>
</td>
<td>
<div>Whether intra zone forwarding should be enabled/disabled for a zone in firewalld.</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
@ -456,6 +471,12 @@ Examples
permanent: yes
zone: dmz
- ansible.posix.firewalld:
forward: yes
state: enabled
permanent: yes
zone: dmz
- ansible.posix.firewalld:
zone: custom
state: present

View file

@ -127,9 +127,16 @@ class FirewallTransaction(object):
def get_fw_zone_settings(self):
if self.fw_offline:
fw_zone = self.fw.config.get_zone(self.zone)
fw_settings = FirewallClientZoneSettings(
list(self.fw.config.get_zone_config(fw_zone))
)
# If firewalld version is 0.9.0 or higher retrieve the configuration
# using the get_zone_config_dict call, otherwise the returned value
# for the 'forward' field is always zero.
if LooseVersion(FW_VERSION) >= LooseVersion("0.9.0"):
fw_settings = FirewallClientZoneSettings(self.fw.config.get_zone_config_dict(fw_zone))
else:
fw_settings = FirewallClientZoneSettings(
list(self.fw.config.get_zone_config(fw_zone))
)
else:
fw_zone = self.fw.config().getZoneByName(self.zone)
fw_settings = fw_zone.getSettings()

View file

@ -106,6 +106,11 @@ options:
description:
- The masquerade setting you would like to enable/disable to/from zones within firewalld.
type: str
forward:
description:
- Whether intra zone forwarding should be enabled/disabled for a zone in firewalld.
This parameter supports on python-firewall 0.9.0 or later.
type: bool
offline:
description:
- Whether to run this module even when firewalld is offline.
@ -183,6 +188,12 @@ EXAMPLES = r'''
permanent: true
zone: dmz
- ansible.posix.firewalld:
forward: yes
state: enabled
permanent: yes
zone: custom
- ansible.posix.firewalld:
zone: custom
state: present
@ -218,10 +229,12 @@ EXAMPLES = r'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.parsing.convert_bool import boolean
from ansible_collections.ansible.posix.plugins.module_utils.firewalld import FirewallTransaction, fw_offline
from ansible_collections.ansible.posix.plugins.module_utils.version import StrictVersion
try:
from firewall.client import Rich_Rule
from firewall.client import FirewallClientZoneSettings
from firewall.config import VERSION as FIREWALLD_VERSION
except ImportError:
# The import errors are handled via FirewallTransaction, don't need to
# duplicate that here
@ -386,6 +399,49 @@ class MasqueradeTransaction(FirewallTransaction):
self.update_fw_settings(fw_zone, fw_settings)
class ForwardTransaction(FirewallTransaction):
"""
ForwardTransaction
"""
def __init__(self, module, action_args=None, zone=None, desired_state=None, permanent=False, immediate=False):
super(ForwardTransaction, self).__init__(
module, action_args=action_args, desired_state=desired_state, zone=zone, permanent=permanent, immediate=immediate
)
self.enabled_msg = "Enabled intra zone forwarding on zone %s" % self.zone
self.disabled_msg = "Disabled intra zone forwarding on zone %s" % self.zone
def get_enabled_immediate(self):
if self.fw.queryForward(self.zone) is True:
return True
else:
return False
def get_enabled_permanent(self):
fw_zone, fw_settings = self.get_fw_zone_settings()
if fw_settings.getForward() is True:
return True
else:
return False
def set_enabled_immediate(self):
self.fw.addForward(self.zone)
def set_enabled_permanent(self):
fw_zone, fw_settings = self.get_fw_zone_settings()
fw_settings.setForward(True)
self.update_fw_settings(fw_zone, fw_settings)
def set_disabled_immediate(self):
self.fw.removeForward(self.zone)
def set_disabled_permanent(self):
fw_zone, fw_settings = self.get_fw_zone_settings()
fw_settings.setForward(False)
self.update_fw_settings(fw_zone, fw_settings)
class PortTransaction(FirewallTransaction):
"""
PortTransaction
@ -759,6 +815,7 @@ def main():
timeout=dict(type='int', default=0),
interface=dict(type='str'),
masquerade=dict(type='str'),
forward=dict(type='bool'),
offline=dict(type='bool'),
target=dict(type='str', choices=['default', 'ACCEPT', 'DROP', '%%REJECT%%']),
),
@ -770,7 +827,7 @@ def main():
),
mutually_exclusive=[
['icmp_block', 'icmp_block_inversion', 'service', 'port', 'port_forward', 'rich_rule',
'interface', 'masquerade', 'source', 'target']
'interface', 'masquerade', 'forward', 'source', 'target']
],
)
@ -780,6 +837,7 @@ def main():
timeout = module.params['timeout']
interface = module.params['interface']
masquerade = module.params['masquerade']
forward = module.params['forward']
# Sanity checks
FirewallTransaction.sanity_check(module)
@ -830,7 +888,7 @@ def main():
modification = False
if any([icmp_block, icmp_block_inversion, service, port, port_forward, rich_rule,
interface, masquerade, source, target]):
interface, masquerade, forward, source, target]):
modification = True
if modification and desired_state in ['absent', 'present'] and target is None:
module.fail_json(
@ -1002,6 +1060,23 @@ def main():
'The type of the option will be changed from string to boolean in a future release. '
'To avoid unexpected behavior, please change the value to boolean.' % masquerade)
if forward is not None:
if StrictVersion(FIREWALLD_VERSION) < StrictVersion('0.9.0'):
module.fail_json(msg='Intra zone forwarding requires firewalld>=0.9.0. Current version is {0}.'.format(FIREWALLD_VERSION))
transaction = ForwardTransaction(
module,
action_args=(),
zone=zone,
desired_state=desired_state,
permanent=permanent,
immediate=immediate,
)
changed, transaction_msgs = transaction.run()
msgs = msgs + transaction_msgs
if target is not None:
transaction = ZoneTargetTransaction(

View file

@ -0,0 +1,86 @@
# Test playbook for the firewalld module - forward operations
# (c) 2017, Adam Miller <admiller@redhat.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
- name: query firewalld version
package_facts:
- name: run tests if intra zone forwarding is supported
block:
# Starting with firewalld 1.0.0 intra-zone forwarding is enabled by default.
# Ensure it is disabled before starting our tests.
- name: ensure forwarding starts disabled
firewalld:
forward: yes
permanent: true
state: disabled
- name: firewalld forward test permanent enabled
firewalld:
forward: yes
permanent: true
state: enabled
register: result
- name: assert firewalld forward test permanent enabled worked
assert:
that:
- result is changed
- name: firewalld forward test permanent enabled rerun (verify not changed)
firewalld:
forward: yes
permanent: true
state: enabled
register: result
- name: assert firewalld forward test permanent enabled rerun worked (verify not changed)
assert:
that:
- result is not changed
- name: firewalld forward test permanent disabled
firewalld:
forward: no
permanent: true
state: disabled
register: result
- name: assert firewalld forward test permanent disabled worked
assert:
that:
- result is changed
- name: firewalld forward test permanent disabled rerun (verify not changed)
firewalld:
forward: no
permanent: true
state: disabled
register: result
- name: assert firewalld forward test permanent disabled rerun worked (verify not changed)
assert:
that:
- result is not changed
when: ansible_facts.packages.firewalld[0].version is version('0.9.0', '>=')
- name: run tests if intra zone forwarding is not supported
block:
- name: try to enable intra zone forwarding
firewalld:
forward: yes
permanent: yes
state: enabled
ignore_errors: yes
register: result
- name: assert unsupported firewalld version
assert:
that:
- result is failed
- "'Intra zone forwarding requires firewalld>=0.9.0. Current version is' in result.msg"
when: ansible_facts.packages.firewalld[0].version is version('0.9.0', '<')

View file

@ -24,3 +24,6 @@
# firewalld port forwarding operation test cases
- include_tasks: port_forward_test_cases.yml
# firewalld zone forwarding operation test cases
- include_tasks: forward_test_cases.yml

View file

@ -82,4 +82,4 @@
assert:
that:
- result is not changed
- "result.msg == 'parameters are mutually exclusive: icmp_block|icmp_block_inversion|service|port|port_forward|rich_rule|interface|masquerade|source|target'"
- "result.msg == 'parameters are mutually exclusive: icmp_block|icmp_block_inversion|service|port|port_forward|rich_rule|interface|masquerade|forward|source|target'"