Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 84 additions & 3 deletions plugins/modules/firewalld.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@
- Name of a port or port range to add/remove to/from firewalld.
- Must be in the form PORT/PROTOCOL or PORT-PORT/PROTOCOL for port ranges.
type: str
source_port:
description:
- Name of a source port or port range to add/remove to/from firewalld.
- Must be in the form PORT/PROTOCOL or PORT-PORT/PROTOCOL for port ranges.
type: str
port_forward:
description:
- Port and protocol to forward using firewalld.
Expand Down Expand Up @@ -185,6 +190,13 @@
permanent: true
state: enabled

- name: Permit traffic in home zone from port 20561/udp
ansible.posix.firewalld:
source_port: 20561/udp
zone: home
permanent: true
state: enabled

- name: Permit traffic in dmz zone on http service
ansible.posix.firewalld:
zone: dmz
Expand Down Expand Up @@ -552,6 +564,43 @@ def set_disabled_permanent(self, port, protocol, timeout):
self.update_fw_settings(fw_zone, fw_settings)


class SourcePortTransaction(FirewallTransaction):
"""
SourcePortTransaction
"""

def __init__(self, module, action_args=None, zone=None, desired_state=None, permanent=False, immediate=False):
super(SourcePortTransaction, self).__init__(
module, action_args=action_args, desired_state=desired_state, zone=zone, permanent=permanent, immediate=immediate
)

def get_enabled_immediate(self, port, protocol, timeout):
if self.fw_offline:
dummy, fw_settings = self.get_fw_zone_settings()
return fw_settings.querySourcePort(port=port, protocol=protocol)
return self.fw.querySourcePort(zone=self.zone, port=port, protocol=protocol)

def get_enabled_permanent(self, port, protocol, timeout):
dummy, fw_settings = self.get_fw_zone_settings()
return fw_settings.querySourcePort(port=port, protocol=protocol)

def set_enabled_immediate(self, port, protocol, timeout):
self.fw.addSourcePort(zone=self.zone, port=port, protocol=protocol, timeout=timeout)

def set_enabled_permanent(self, port, protocol, timeout):
fw_zone, fw_settings = self.get_fw_zone_settings()
fw_settings.addSourcePort(port=port, protocol=protocol)
self.update_fw_settings(fw_zone, fw_settings)

def set_disabled_immediate(self, port, protocol, timeout):
self.fw.removeSourcePort(zone=self.zone, port=port, protocol=protocol)

def set_disabled_permanent(self, port, protocol, timeout):
fw_zone, fw_settings = self.get_fw_zone_settings()
fw_settings.removeSourcePort(port=port, protocol=protocol)
self.update_fw_settings(fw_zone, fw_settings)


class InterfaceTransaction(FirewallTransaction):
"""
InterfaceTransaction
Expand Down Expand Up @@ -879,6 +928,7 @@ def main():
service=dict(type='str'),
protocol=dict(type='str'),
port=dict(type='str'),
source_port=dict(type='str'),
port_forward=dict(type='list', elements='dict'),
rich_rule=dict(type='str'),
zone=dict(type='str'),
Expand All @@ -900,8 +950,8 @@ def main():
source=('permanent',),
),
mutually_exclusive=[
['icmp_block', 'icmp_block_inversion', 'service', 'protocol', 'port', 'port_forward', 'rich_rule',
'interface', 'forward', 'masquerade', 'source', 'target']
['icmp_block', 'icmp_block_inversion', 'service', 'protocol', 'port', 'source_port', 'port_forward',
'rich_rule', 'interface', 'forward', 'masquerade', 'source', 'target']
],
)

Expand Down Expand Up @@ -957,6 +1007,17 @@ def main():
else:
port_protocol = None

source_port = None
if module.params['source_port'] is not None:
if '/' in module.params['source_port']:
source_port, source_port_protocol = module.params['source_port'].strip().split('/')
else:
source_port_protocol = None
if not source_port_protocol:
module.fail_json(msg='improper source_port format (missing protocol?)')
else:
source_port_protocol = None

port_forward_toaddr = ''
port_forward = None
if module.params['port_forward'] is not None:
Expand All @@ -973,7 +1034,7 @@ def main():
port_forward_toaddr = port_forward['toaddr']

modification = False
if any([icmp_block, icmp_block_inversion, service, protocol, port, port_forward, rich_rule,
if any([icmp_block, icmp_block_inversion, service, protocol, port, source_port, port_forward, rich_rule,
interface, forward, masquerade, source, target]):
modification = True
if modification and desired_state in ['absent', 'present'] and target is None:
Expand Down Expand Up @@ -1079,6 +1140,26 @@ def main():
)
)

if source_port is not None:

transaction = SourcePortTransaction(
module,
action_args=(source_port, source_port_protocol, timeout),
zone=zone,
desired_state=desired_state,
permanent=permanent,
immediate=immediate,
)

changed, transaction_msgs = transaction.run()
msgs = msgs + transaction_msgs
if changed is True:
msgs.append(
"Changed source_port %s to %s" % (
"%s/%s" % (source_port, source_port_protocol), desired_state
)
)

if port_forward is not None:
transaction = ForwardPortTransaction(
module,
Expand Down
4 changes: 4 additions & 0 deletions tests/integration/targets/firewalld/tasks/run_all_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@
- name: Include port test cases for firewalld module
ansible.builtin.include_tasks: port_test_cases.yml

# firewalld source_port operation test cases
- name: Include source_port test cases for firewalld module
ansible.builtin.include_tasks: source_port_test_cases.yml

# firewalld source operation test cases
- name: Include source test cases for firewalld module
ansible.builtin.include_tasks: source_test_cases.yml
Expand Down
107 changes: 107 additions & 0 deletions tests/integration/targets/firewalld/tasks/source_port_test_cases.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
---
# Test playbook for the firewalld module - source_port operations

- name: Firewalld source_port range test permanent enabled
ansible.posix.firewalld:
source_port: 5500-6850/tcp
permanent: true
state: enabled
register: result

- name: Assert firewalld source_port range test permanent enabled worked
ansible.builtin.assert:
that:
- result is changed

- name: Firewalld source_port range test permanent enabled rerun (verify not changed)
ansible.posix.firewalld:
source_port: 5500-6850/tcp
permanent: true
state: enabled
register: result

- name: Assert firewalld source_port range test permanent enabled rerun worked (verify not changed)
ansible.builtin.assert:
that:
- result is not changed

- name: Firewalld source_port test permanent enabled
ansible.posix.firewalld:
source_port: 6900/tcp
permanent: true
state: enabled
register: result

- name: Assert firewalld source_port test permanent enabled worked
ansible.builtin.assert:
that:
- result is changed

- name: Firewalld source_port test permanent enabled
ansible.posix.firewalld:
source_port: 6900/tcp
permanent: true
state: enabled
register: result

- name: Assert firewalld source_port test permanent enabled worked
ansible.builtin.assert:
that:
- result is not changed

- name: Firewalld source_port test disabled
ansible.posix.firewalld:
source_port: "{{ item }}"
permanent: true
state: disabled
loop:
- 6900/tcp
- 5500-6850/tcp

- name: Firewalld source_port test permanent enabled
ansible.posix.firewalld:
source_port: 8081/tcp
permanent: true
state: enabled
register: result

- name: Assert firewalld source_port test permanent enabled worked
ansible.builtin.assert:
that:
- result is changed

- name: Firewalld source_port test permanent enabled rerun (verify not changed)
ansible.posix.firewalld:
source_port: 8081/tcp
permanent: true
state: enabled
register: result

- name: Assert firewalld source_port test permanent enabled rerun worked (verify not changed)
ansible.builtin.assert:
that:
- result is not changed

- name: Firewalld source_port test permanent disabled
ansible.posix.firewalld:
source_port: 8081/tcp
permanent: true
state: disabled
register: result

- name: Assert firewalld source_port test permanent disabled worked
ansible.builtin.assert:
that:
- result is changed

- name: Firewalld source_port test permanent disabled rerun (verify not changed)
ansible.posix.firewalld:
source_port: 8081/tcp
permanent: true
state: disabled
register: result

- name: Assert firewalld source_port test permanent disabled rerun worked (verify not changed)
ansible.builtin.assert:
that:
- result is not changed
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,4 @@
- result is not changed
- >
result.msg == 'parameters are mutually exclusive:
icmp_block|icmp_block_inversion|service|protocol|port|port_forward|rich_rule|interface|forward|masquerade|source|target'
icmp_block|icmp_block_inversion|service|protocol|port|source_port|port_forward|rich_rule|interface|forward|masquerade|source|target'
Loading