Merge pull request #4424 from localvoid/firewalld-rich_rules

Add support for Rich Rules in firewalld module
This commit is contained in:
Michael DeHaan 2013-10-27 08:55:22 -07:00
commit 8bcd697816

View file

@ -36,6 +36,11 @@ options:
- "Name of a port to add/remove to/from firewalld must be in the form PORT/PROTOCOL" - "Name of a port to add/remove to/from firewalld must be in the form PORT/PROTOCOL"
required: false required: false
default: null default: null
rich_rule:
description:
- "Rich rule to add/remove to/from firewalld"
required: false
default: null
zone: zone:
description: description:
- 'The firewalld zone to add/remove to/from (NOTE: default zone can be configured per system but "public" is default from upstream. Available choices can be extended based on per-system configs, listed here are "out of the box" defaults).' - 'The firewalld zone to add/remove to/from (NOTE: default zone can be configured per system but "public" is default from upstream. Available choices can be extended based on per-system configs, listed here are "out of the box" defaults).'
@ -67,6 +72,7 @@ EXAMPLES = '''
- firewalld: service=https permanent=true state=enabled - firewalld: service=https permanent=true state=enabled
- firewalld: port=8081/tcp permanent=true state=disabled - firewalld: port=8081/tcp permanent=true state=disabled
- firewalld: zone=dmz service=http permanent=true state=enabled - firewalld: zone=dmz service=http permanent=true state=enabled
- firewalld: rich_rule='rule service name="ftp" audit limit value="1/m" accept' permanent=true state=enabled
''' '''
import os import os
@ -154,12 +160,50 @@ def set_service_disabled_permanent(zone, service):
fw_settings.removeService(service) fw_settings.removeService(service)
fw_zone.update(fw_settings) fw_zone.update(fw_settings)
####################
# rich rule handling
#
def get_rich_rule_enabled(zone, rule):
if rule in fw.getRichRules(zone):
return True
else:
return False
def set_rich_rule_enabled(zone, rule, timeout):
fw.addRichRule(zone, rule, timeout)
def set_rich_rule_disabled(zone, rule):
fw.removeRichRule(zone, rule)
def get_rich_rule_enabled_permanent(zone, rule):
fw_zone = fw.config().getZoneByName(zone)
fw_settings = fw_zone.getSettings()
if rule in fw_settings.getRichRules():
return True
else:
return False
def set_rich_rule_enabled_permanent(zone, rule):
fw_zone = fw.config().getZoneByName(zone)
fw_settings = fw_zone.getSettings()
fw_settings.addRichRule(rule)
fw_zone.update(fw_settings)
def set_rich_rule_disabled_permanent(zone, rule):
fw_zone = fw.config().getZoneByName(zone)
fw_settings = fw_zone.getSettings()
fw_settings.removeRichRule(rule)
fw_zone.update(fw_settings)
def main(): def main():
module = AnsibleModule( module = AnsibleModule(
argument_spec = dict( argument_spec = dict(
service=dict(required=False,default=None), service=dict(required=False,default=None),
port=dict(required=False,default=None), port=dict(required=False,default=None),
rich_rule=dict(required=False,default=None),
zone=dict(required=False,default=None), zone=dict(required=False,default=None),
permanent=dict(type='bool',required=True), permanent=dict(type='bool',required=True),
state=dict(choices=['enabled', 'disabled'], required=True), state=dict(choices=['enabled', 'disabled'], required=True),
@ -176,6 +220,7 @@ def main():
changed=False changed=False
msgs = [] msgs = []
service = module.params['service'] service = module.params['service']
rich_rule = module.params['rich_rule']
if module.params['port'] != None: if module.params['port'] != None:
port, protocol = module.params['port'].split('/') port, protocol = module.params['port'].split('/')
@ -201,8 +246,16 @@ def main():
module.fail_json(msg="firewalld connection can't be established,\ module.fail_json(msg="firewalld connection can't be established,\
version likely too old. Requires firewalld >= 2.0.11") version likely too old. Requires firewalld >= 2.0.11")
if service != None and port != None: modification_count = 0
module.fail_json(msg='can only operate on port or service at once') if service != None:
modification_count += 1
if port != None:
modification_count += 1
if rich_rule != None:
modification_count += 1
if modification_count > 1:
module.fail_json(msg='can only operate on port, service or rich_rule at once')
if service != None: if service != None:
if permanent: if permanent:
@ -288,6 +341,47 @@ def main():
msgs.append("Changed port %s to %s" % ("%s/%s" % (port, protocol), \ msgs.append("Changed port %s to %s" % ("%s/%s" % (port, protocol), \
desired_state)) desired_state))
if rich_rule != None:
if permanent:
is_enabled = get_rich_rule_enabled_permanent(zone, rich_rule)
msgs.append('Permanent operation')
if desired_state == "enabled":
if is_enabled == False:
if module.check_mode:
module.exit_json(changed=True)
set_rich_rule_enabled_permanent(zone, rich_rule)
changed=True
elif desired_state == "disabled":
if is_enabled == True:
if module.check_mode:
module.exit_json(changed=True)
set_rich_rule_disabled_permanent(zone, rich_rule)
changed=True
else:
is_enabled = get_rich_rule_enabled(zone, rich_rule)
msgs.append('Non-permanent operation')
if desired_state == "enabled":
if is_enabled == False:
if module.check_mode:
module.exit_json(changed=True)
set_rich_rule_enabled(zone, rich_rule, timeout)
changed=True
elif desired_state == "disabled":
if is_enabled == True:
if module.check_mode:
module.exit_json(changed=True)
set_rich_rule_disabled(zone, rich_rule)
changed=True
if changed == True:
msgs.append("Changed rich_rule %s to %s" % (rich_rule, desired_state))
module.exit_json(changed=changed, msg=', '.join(msgs)) module.exit_json(changed=changed, msg=', '.join(msgs))