Add new feature to firewalld module allowing the default zone to be set.

This commit is contained in:
Gregory Furlong 2022-12-14 16:59:19 -05:00
parent 090706b581
commit 628a53eb1a
4 changed files with 176 additions and 3 deletions

View file

@ -222,6 +222,7 @@ from ansible_collections.ansible.posix.plugins.module_utils.firewalld import Fir
try:
from firewall.client import Rich_Rule
from firewall.client import FirewallClientZoneSettings
from firewall.config import FALLBACK_ZONE
except ImportError:
# The import errors are handled via FirewallTransaction, don't need to
# duplicate that here
@ -695,6 +696,45 @@ class ZoneTransaction(FirewallTransaction):
zone_obj = self.fw.config().getZoneByName(self.zone)
zone_obj.remove()
class DefaultZoneTransaction(FirewallTransaction):
"""
DefaultZoneTransaction
"""
def __init__(self, module, action_args=None, zone=None, desired_state=None, permanent=False, immediate=False):
super(DefaultZoneTransaction, self).__init__(
module, action_args=action_args, desired_state=desired_state, zone=zone, permanent=permanent, immediate=immediate
)
self.upstream_default_zone = FALLBACK_ZONE
self.enabled_msg = "Updated default zone to %s" % self.zone
self.disabled_msg = "Reverted default zone from %s to upstream default %s" % (self.zone, self.upstream_default_zone)
self.tx_not_permanent_error_msg = "Zone operations must be permanent. " \
"Make sure you didn't set the 'permanent' flag to 'false' or the 'immediate' flag to 'true'."
def get_enabled_immediate(self):
self.module.fail_json(msg=self.tx_not_permanent_error_msg)
def get_enabled_permanent(self):
default_zone = self.fw.get_default_zone() if fw_offline else self.fw.getDefaultZone()
return self.zone == default_zone
def set_enabled_immediate(self):
self.module.fail_json(msg=self.tx_not_permanent_error_msg)
def set_enabled_permanent(self):
if fw_offline:
self.fw.set_default_zone(self.zone)
else:
self.fw.setDefaultZone(self.zone)
def set_disabled_immediate(self):
self.module.fail_json(msg=self.tx_not_permanent_error_msg)
def set_disabled_permanent(self):
if fw_offline:
self.fw.set_default_zone(self.upstream_default_zone)
else:
self.fw.setDefaultZone(self.upstream_default_zone)
class ForwardPortTransaction(FirewallTransaction):
"""
@ -732,7 +772,6 @@ class ForwardPortTransaction(FirewallTransaction):
fw_settings.removeForwardPort(port, proto, toport, toaddr)
self.update_fw_settings(fw_zone, fw_settings)
def main():
module = AnsibleModule(
@ -751,6 +790,7 @@ def main():
timeout=dict(type='int', default=0),
interface=dict(type='str'),
masquerade=dict(type='str'),
default=dict(type='bool'),
offline=dict(type='bool'),
target=dict(type='str', choices=['default', 'ACCEPT', 'DROP', '%%REJECT%%']),
),
@ -758,11 +798,12 @@ def main():
required_by=dict(
interface=('zone',),
target=('zone',),
default=('zone',),
source=('permanent',),
),
mutually_exclusive=[
['icmp_block', 'icmp_block_inversion', 'service', 'port', 'port_forward', 'rich_rule',
'interface', 'masquerade', 'source', 'target']
'interface', 'masquerade', 'source', 'target','default']
],
)
@ -772,6 +813,7 @@ def main():
timeout = module.params['timeout']
interface = module.params['interface']
masquerade = module.params['masquerade']
default = module.params['default']
# Sanity checks
FirewallTransaction.sanity_check(module)
@ -1008,6 +1050,20 @@ def main():
changed, transaction_msgs = transaction.run()
msgs = msgs + transaction_msgs
if default is not None:
expected_state = 'enabled' if (desired_state == 'enabled') == default else 'disabled'
transaction = DefaultZoneTransaction(
module,
action_args=(),
zone=zone,
desired_state=expected_state,
permanent=permanent,
immediate=immediate,
)
changed, transaction_msgs = transaction.run()
msgs = msgs + transaction_msgs
''' If there are no changes within the zone we are operating on the zone itself '''
if not modification and desired_state in ['absent', 'present']:

View file

@ -40,6 +40,8 @@
state: stopped
- import_tasks: run_all_tests.yml
# FIXME currently fails when the daemon is running AND executed inside a container
- import_tasks: zone_default_test_cases.yml
when: check_output.rc == 0
when:

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|source|target|default'"

View file

@ -0,0 +1,115 @@
# Test playbook for the firewalld module - zone default operations
# (c) 2022, Gregory Furlong <gnfzdz@fzdz.io>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
- name: Set default zone to trusted (default - true / state - enabled)
block:
- name: Update default zone to trusted
ansible.posix.firewalld:
zone: trusted
default: True
permanent: True
state: enabled
register: result
- name: Default zone is trusted
ansible.builtin.assert:
that:
- result is changed
- name: Update default zone to trusted (verify not changed)
ansible.posix.firewalld:
zone: trusted
default: True
permanent: True
state: enabled
register: result
- name: Default zone is trusted (verify not changed)
ansible.builtin.assert:
that:
- result is not changed
- name: Revert default zone to upstream default (default - false / state - enabled)
block:
- name: Revert default zone to upstream default
ansible.posix.firewalld:
zone: trusted
default: False
permanent: True
state: enabled
register: result
- name: Default zone is reverted
ansible.builtin.assert:
that:
- result is changed
- name: Revert default zone to upstream default (verify not changed)
ansible.posix.firewalld:
zone: trusted
default: False
permanent: True
state: enabled
register: result
- name: Default zone is reverted (verify not changed)
ansible.builtin.assert:
that:
- result is not changed
- name: Set default zone to trusted (default - false / state - disabled)
block:
- name: Update default zone to trusted
ansible.posix.firewalld:
zone: trusted
default: False
permanent: True
state: disabled
register: result
- name: Default zone is trusted
ansible.builtin.assert:
that:
- result is changed
- name: Update default zone to trusted (verify not changed)
ansible.posix.firewalld:
zone: trusted
default: False
permanent: True
state: disabled
register: result
- name: Default zone is trusted (verify not changed)
ansible.builtin.assert:
that:
- result is not changed
- name: Revert default zone to upstream default (default - true / state - disabled)
block:
- name: Revert default zone to upstream default
ansible.posix.firewalld:
zone: trusted
default: True
permanent: True
state: disabled
register: result
- name: Default zone is reverted
ansible.builtin.assert:
that:
- result is changed
- name: Revert default zone to upstream default (verify not changed)
ansible.posix.firewalld:
zone: trusted
default: True
permanent: True
state: disabled
register: result
- name: Default zone is reverted (verify not changed)
ansible.builtin.assert:
that:
- result is not changed