예제 #1
0
# Imports
try:
    import firewall.config
    FW_VERSION = firewall.config.VERSION

    from firewall.client import Rich_Rule
    from firewall.client import FirewallClient
    from firewall.client import FirewallClientZoneSettings
    from firewall.errors import FirewallError
    fw = None
    fw_offline = False
    import_failure = False

    try:
        fw = FirewallClient()
        fw.getDefaultZone()
    except (AttributeError, FirewallError):
        # Firewalld is not currently running, permanent-only operations
        fw_offline = True

        # Import other required parts of the firewalld API
        #
        # NOTE:
        #  online and offline operations do not share a common firewalld API
        from firewall.core.fw_test import Firewall_test
        fw = Firewall_test()
        fw.start()

except ImportError:
    import_failure = True
# (c) 2017, Michael Scherer ([email protected])

#TODO DOCUMENTATION, example, license

from ansible.module_utils.basic import AnsibleModule

HAVE_FIREWALLD = True
FIREWALLD_RUNNING = True
try:
    import firewall.config
    FW_VERSION = firewall.config.VERSION

    from firewall.client import FirewallClient, FirewallClientZoneSettings
    try:
        fw = FirewallClient()
        fw.getDefaultZone()
    except AttributeError:
        FIREWALLD_RUNNING = False
except ImportError:
    HAVE_FIREWALLD = False


def main():

    module = AnsibleModule(
        argument_spec=dict(
            name=dict(required=True),
            state=dict(choices=['present', 'absent'], required=True),
            no_reload=dict(type='bool', default='no'),
        ),
        supports_check_mode=False
예제 #3
0
파일: firewalld.py 프로젝트: zdoop/ansible
def main():
    global module

    ## make module global so we don't have to pass it to action_handler every
    ## function call
    global module
    module = AnsibleModule(argument_spec=dict(
        service=dict(required=False, default=None),
        port=dict(required=False, default=None),
        rich_rule=dict(required=False, default=None),
        zone=dict(required=False, default=None),
        immediate=dict(type='bool', default=False),
        source=dict(required=False, default=None),
        permanent=dict(type='bool', required=False, default=None),
        state=dict(choices=['enabled', 'disabled'], required=True),
        timeout=dict(type='int', required=False, default=0),
        interface=dict(required=False, default=None),
        masquerade=dict(required=False, default=None),
        offline=dict(type='bool', required=False, default=None),
    ),
                           supports_check_mode=True)

    ## Handle running (online) daemon vs non-running (offline) daemon
    global fw
    global fw_offline
    global Rich_Rule
    global FirewallClientZoneSettings

    ## Imports
    try:
        import firewall.config
        FW_VERSION = firewall.config.VERSION

        from firewall.client import Rich_Rule
        from firewall.client import FirewallClient
        fw = None
        fw_offline = False

        try:
            fw = FirewallClient()
            fw.getDefaultZone()
        except AttributeError:
            ## Firewalld is not currently running, permanent-only operations

            ## Import other required parts of the firewalld API
            ##
            ## NOTE:
            ##  online and offline operations do not share a common firewalld API
            from firewall.core.fw_test import Firewall_test
            from firewall.client import FirewallClientZoneSettings
            fw = Firewall_test()
            fw.start()
            fw_offline = True

    except ImportError:
        ## Make python 2.4 shippable ci tests happy
        e = sys.exc_info()[1]
        module.fail_json(
            msg=
            'firewalld and its python 2 module are required for this module, version 2.0.11 or newer required '
            '(3.0.9 or newer for offline operations) \n %s' % e)

    if fw_offline:
        ## Pre-run version checking
        if FW_VERSION < "0.3.9":
            module.fail_json(
                msg=
                'unsupported version of firewalld, offline operations require >= 3.0.9'
            )
    else:
        ## Pre-run version checking
        if FW_VERSION < "0.2.11":
            module.fail_json(
                msg='unsupported version of firewalld, requires >= 2.0.11')

        ## Check for firewalld running
        try:
            if fw.connected is False:
                module.fail_json(
                    msg=
                    'firewalld service must be running, or try with offline=true'
                )
        except AttributeError:
            module.fail_json(msg="firewalld connection can't be established,\
                    installed version (%s) likely too old. Requires firewalld >= 2.0.11"
                             % FW_VERSION)

    ## Verify required params are provided
    if module.params['source'] is None and module.params['permanent'] is None:
        module.fail_json(msg='permanent is a required parameter')

    if module.params['interface'] is not None and module.params['zone'] is None:
        module.fail(msg='zone is a required parameter')

    if module.params['immediate'] and fw_offline:
        module.fail(
            msg=
            'firewall is not currently running, unable to perform immediate actions without a running firewall daemon'
        )

    ## Global Vars
    changed = False
    msgs = []
    service = module.params['service']
    rich_rule = module.params['rich_rule']
    source = module.params['source']

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

    if module.params['zone'] is not None:
        zone = module.params['zone']
    else:
        if fw_offline:
            zone = fw.get_default_zone()
        else:
            zone = fw.getDefaultZone()

    permanent = module.params['permanent']
    desired_state = module.params['state']
    immediate = module.params['immediate']
    timeout = module.params['timeout']
    interface = module.params['interface']
    masquerade = module.params['masquerade']

    modification_count = 0
    if service is not None:
        modification_count += 1
    if port is not None:
        modification_count += 1
    if rich_rule is not None:
        modification_count += 1
    if interface is not None:
        modification_count += 1
    if masquerade is not None:
        modification_count += 1

    if modification_count > 1:
        module.fail_json(
            msg=
            'can only operate on port, service, rich_rule or interface at once'
        )

    if service is not None:
        if immediate and permanent:
            is_enabled_permanent = action_handler(
                get_service_enabled_permanent, (zone, service))
            is_enabled_immediate = action_handler(get_service_enabled,
                                                  (zone, service))
            msgs.append('Permanent and Non-Permanent(immediate) operation')

            if desired_state == "enabled":
                if not is_enabled_permanent or not is_enabled_immediate:
                    if module.check_mode:
                        module.exit_json(changed=True)
                if not is_enabled_permanent:
                    action_handler(set_service_enabled_permanent,
                                   (zone, service))
                    changed = True
                if not is_enabled_immediate:
                    action_handler(set_service_enabled,
                                   (zone, service, timeout))
                    changed = True

            elif desired_state == "disabled":
                if is_enabled_permanent or is_enabled_immediate:
                    if module.check_mode:
                        module.exit_json(changed=True)
                if is_enabled_permanent:
                    action_handler(set_service_disabled_permanent,
                                   (zone, service))
                    changed = True
                if is_enabled_immediate:
                    action_handler(set_service_disabled, (zone, service))
                    changed = True

        elif permanent and not immediate:
            is_enabled = action_handler(get_service_enabled_permanent,
                                        (zone, service))
            msgs.append('Permanent operation')

            if desired_state == "enabled":
                if is_enabled is False:
                    if module.check_mode:
                        module.exit_json(changed=True)

                    action_handler(set_service_enabled_permanent,
                                   (zone, service))
                    changed = True
            elif desired_state == "disabled":
                if is_enabled is True:
                    if module.check_mode:
                        module.exit_json(changed=True)

                    action_handler(set_service_disabled_permanent,
                                   (zone, service))
                    changed = True
        elif immediate and not permanent:
            is_enabled = action_handler(get_service_enabled, (zone, service))
            msgs.append('Non-permanent operation')

            if desired_state == "enabled":
                if is_enabled is False:
                    if module.check_mode:
                        module.exit_json(changed=True)

                    action_handler(set_service_enabled,
                                   (zone, service, timeout))
                    changed = True
            elif desired_state == "disabled":
                if is_enabled is True:
                    if module.check_mode:
                        module.exit_json(changed=True)

                    action_handler(set_service_disabled, (zone, service))
                    changed = True

        if changed is True:
            msgs.append("Changed service %s to %s" % (service, desired_state))

    # FIXME - source type does not handle non-permanent mode, this was an
    #         oversight in the past.
    if source is not None:
        is_enabled = action_handler(get_source, (zone, source))
        if desired_state == "enabled":
            if is_enabled is False:
                if module.check_mode:
                    module.exit_json(changed=True)

                action_handler(add_source, (zone, source))
                changed = True
                msgs.append("Added %s to zone %s" % (source, zone))
        elif desired_state == "disabled":
            if is_enabled is True:
                if module.check_mode:
                    module.exit_json(changed=True)

                action_handler(remove_source, (zone, source))
                changed = True
                msgs.append("Removed %s from zone %s" % (source, zone))

    if port is not None:
        if immediate and permanent:
            is_enabled_permanent = action_handler(get_port_enabled_permanent,
                                                  (zone, [port, protocol]))
            is_enabled_immediate = action_handler(get_port_enabled,
                                                  (zone, [port, protocol]))
            msgs.append('Permanent and Non-Permanent(immediate) operation')

            if desired_state == "enabled":
                if not is_enabled_permanent or not is_enabled_immediate:
                    if module.check_mode:
                        module.exit_json(changed=True)
                if not is_enabled_permanent:
                    action_handler(set_port_enabled_permanent,
                                   (zone, port, protocol))
                    changed = True
                if not is_enabled_immediate:
                    action_handler(set_port_enabled,
                                   (zone, port, protocol, timeout))
                    changed = True

            elif desired_state == "disabled":
                if is_enabled_permanent or is_enabled_immediate:
                    if module.check_mode:
                        module.exit_json(changed=True)
                if is_enabled_permanent:
                    action_handler(set_port_disabled_permanent,
                                   (zone, port, protocol))
                    changed = True
                if is_enabled_immediate:
                    action_handler(set_port_disabled, (zone, port, protocol))
                    changed = True

        elif permanent and not immediate:
            is_enabled = action_handler(get_port_enabled_permanent,
                                        (zone, [port, protocol]))
            msgs.append('Permanent operation')

            if desired_state == "enabled":
                if is_enabled is False:
                    if module.check_mode:
                        module.exit_json(changed=True)

                    action_handler(set_port_enabled_permanent,
                                   (zone, port, protocol))
                    changed = True
            elif desired_state == "disabled":
                if is_enabled is True:
                    if module.check_mode:
                        module.exit_json(changed=True)

                    action_handler(set_port_disabled_permanent,
                                   (zone, port, protocol))
                    changed = True
        if immediate and not permanent:
            is_enabled = action_handler(get_port_enabled,
                                        (zone, [port, protocol]))
            msgs.append('Non-permanent operation')

            if desired_state == "enabled":
                if is_enabled is False:
                    if module.check_mode:
                        module.exit_json(changed=True)

                    action_handler(set_port_enabled,
                                   (zone, port, protocol, timeout))
                    changed = True
            elif desired_state == "disabled":
                if is_enabled is True:
                    if module.check_mode:
                        module.exit_json(changed=True)

                    action_handler(set_port_disabled, (zone, port, protocol))
                    changed = True

        if changed is True:
            msgs.append("Changed port %s to %s" % ("%s/%s" % (port, protocol), \
                        desired_state))

    if rich_rule is not None:
        if immediate and permanent:
            is_enabled_permanent = action_handler(
                get_rich_rule_enabled_permanent, (zone, rich_rule))
            is_enabled_immediate = action_handler(get_rich_rule_enabled,
                                                  (zone, rich_rule))
            msgs.append('Permanent and Non-Permanent(immediate) operation')

            if desired_state == "enabled":
                if not is_enabled_permanent or not is_enabled_immediate:
                    if module.check_mode:
                        module.exit_json(changed=True)
                if not is_enabled_permanent:
                    action_handler(set_rich_rule_enabled_permanent,
                                   (zone, rich_rule))
                    changed = True
                if not is_enabled_immediate:
                    action_handler(set_rich_rule_enabled,
                                   (zone, rich_rule, timeout))
                    changed = True

            elif desired_state == "disabled":
                if is_enabled_permanent or is_enabled_immediate:
                    if module.check_mode:
                        module.exit_json(changed=True)
                if is_enabled_permanent:
                    action_handler(set_rich_rule_disabled_permanent,
                                   (zone, rich_rule))
                    changed = True
                if is_enabled_immediate:
                    action_handler(set_rich_rule_disabled, (zone, rich_rule))
                    changed = True
        if permanent and not immediate:
            is_enabled = action_handler(get_rich_rule_enabled_permanent,
                                        (zone, rich_rule))
            msgs.append('Permanent operation')

            if desired_state == "enabled":
                if is_enabled is False:
                    if module.check_mode:
                        module.exit_json(changed=True)

                    action_handler(set_rich_rule_enabled_permanent,
                                   (zone, rich_rule))
                    changed = True
            elif desired_state == "disabled":
                if is_enabled is True:
                    if module.check_mode:
                        module.exit_json(changed=True)

                    action_handler(set_rich_rule_disabled_permanent,
                                   (zone, rich_rule))
                    changed = True
        if immediate and not permanent:
            is_enabled = action_handler(get_rich_rule_enabled,
                                        (zone, rich_rule))
            msgs.append('Non-permanent operation')

            if desired_state == "enabled":
                if is_enabled is False:
                    if module.check_mode:
                        module.exit_json(changed=True)

                    action_handler(set_rich_rule_enabled,
                                   (zone, rich_rule, timeout))
                    changed = True
            elif desired_state == "disabled":
                if is_enabled is True:
                    if module.check_mode:
                        module.exit_json(changed=True)

                    action_handler(set_rich_rule_disabled, (zone, rich_rule))
                    changed = True

        if changed is True:
            msgs.append("Changed rich_rule %s to %s" %
                        (rich_rule, desired_state))

    if interface is not None:
        if immediate and permanent:
            is_enabled_permanent = action_handler(get_interface_permanent,
                                                  (zone, interface))
            is_enabled_immediate = action_handler(get_interface,
                                                  (zone, interface))
            msgs.append('Permanent and Non-Permanent(immediate) operation')

            if desired_state == "enabled":
                if not is_enabled_permanent or not is_enabled_immediate:
                    if module.check_mode:
                        module.exit_json(changed=True)
                if not is_enabled_permanent:
                    change_zone_of_interface_permanent(zone, interface)
                    changed = True
                if not is_enabled_immediate:
                    change_zone_of_interface(zone, interface)
                    changed = True
                if changed:
                    msgs.append("Changed %s to zone %s" % (interface, zone))

            elif desired_state == "disabled":
                if is_enabled_permanent or is_enabled_immediate:
                    if module.check_mode:
                        module.exit_json(changed=True)
                if is_enabled_permanent:
                    remove_interface_permanent(zone, interface)
                    changed = True
                if is_enabled_immediate:
                    remove_interface(zone, interface)
                    changed = True
                if changed:
                    msgs.append("Removed %s from zone %s" % (interface, zone))

        elif permanent and not immediate:
            is_enabled = action_handler(get_interface_permanent,
                                        (zone, interface))
            msgs.append('Permanent operation')
            if desired_state == "enabled":
                if is_enabled is False:
                    if module.check_mode:
                        module.exit_json(changed=True)

                    change_zone_of_interface_permanent(zone, interface)
                    changed = True
                    msgs.append("Changed %s to zone %s" % (interface, zone))
            elif desired_state == "disabled":
                if is_enabled is True:
                    if module.check_mode:
                        module.exit_json(changed=True)

                    remove_interface_permanent(zone, interface)
                    changed = True
                    msgs.append("Removed %s from zone %s" % (interface, zone))
        elif immediate and not permanent:
            is_enabled = action_handler(get_interface, (zone, interface))
            msgs.append('Non-permanent operation')
            if desired_state == "enabled":
                if is_enabled is False:
                    if module.check_mode:
                        module.exit_json(changed=True)

                    change_zone_of_interface(zone, interface)
                    changed = True
                    msgs.append("Changed %s to zone %s" % (interface, zone))
            elif desired_state == "disabled":
                if is_enabled is True:
                    if module.check_mode:
                        module.exit_json(changed=True)

                    remove_interface(zone, interface)
                    changed = True
                    msgs.append("Removed %s from zone %s" % (interface, zone))

    if masquerade is not None:

        if immediate and permanent:
            is_enabled_permanent = action_handler(
                get_masquerade_enabled_permanent, (zone, ))
            is_enabled_immediate = action_handler(get_masquerade_enabled,
                                                  (zone, ))
            msgs.append('Permanent and Non-Permanent(immediate) operation')

            if desired_state == "enabled":
                if not is_enabled_permanent or not is_enabled_immediate:
                    if module.check_mode:
                        module.exit_json(changed=True)
                if not is_enabled_permanent:
                    action_handler(set_masquerade_permanent, (zone, True))
                    changed = True
                if not is_enabled_immediate:
                    action_handler(set_masquerade_enabled, (zone, ))
                    changed = True
                if changed:
                    msgs.append("Added masquerade to zone %s" % (zone))

            elif desired_state == "disabled":
                if is_enabled_permanent or is_enabled_immediate:
                    if module.check_mode:
                        module.exit_json(changed=True)
                if is_enabled_permanent:
                    action_handler(set_masquerade_permanent, (zone, False))
                    changed = True
                if is_enabled_immediate:
                    action_handler(set_masquerade_disabled, (zone, ))
                    changed = True
                if changed:
                    msgs.append("Removed masquerade from zone %s" % (zone))

        elif permanent and not immediate:
            is_enabled = action_handler(get_masquerade_enabled_permanent,
                                        (zone, ))
            msgs.append('Permanent operation')

            if desired_state == "enabled":
                if is_enabled is False:
                    if module.check_mode:
                        module.exit_json(changed=True)

                    action_handler(set_masquerade_permanent, (zone, True))
                    changed = True
                    msgs.append("Added masquerade to zone %s" % (zone))
            elif desired_state == "disabled":
                if is_enabled is True:
                    if module.check_mode:
                        module.exit_json(changed=True)

                    action_handler(set_masquerade_permanent, (zone, False))
                    changed = True
                    msgs.append("Removed masquerade from zone %s" % (zone))
        elif immediate and not permanent:
            is_enabled = action_handler(get_masquerade_enabled, (zone, ))
            msgs.append('Non-permanent operation')

            if desired_state == "enabled":
                if is_enabled is False:
                    if module.check_mode:
                        module.exit_json(changed=True)

                    action_handler(set_masquerade_enabled, (zone))
                    changed = True
                    msgs.append("Added masquerade to zone %s" % (zone))
            elif desired_state == "disabled":
                if is_enabled is True:
                    if module.check_mode:
                        module.exit_json(changed=True)

                    action_handler(set_masquerade_disabled, (zone))
                    changed = True
                    msgs.append("Removed masquerade from zone %s" % (zone))

    if fw_offline:
        msgs.append("(offline operation: only on-disk configs were altered)")
    module.exit_json(changed=changed, msg=', '.join(msgs))
예제 #4
0
def main():
    global module

    ## make module global so we don't have to pass it to action_handler every
    ## function call
    global module
    module = AnsibleModule(
        argument_spec = dict(
            service=dict(required=False,default=None),
            port=dict(required=False,default=None),
            rich_rule=dict(required=False,default=None),
            zone=dict(required=False,default=None),
            immediate=dict(type='bool',default=False),
            source=dict(required=False,default=None),
            permanent=dict(type='bool',required=False,default=None),
            state=dict(choices=['enabled', 'disabled'], required=True),
            timeout=dict(type='int',required=False,default=0),
            interface=dict(required=False,default=None),
            masquerade=dict(required=False,default=None),
            offline=dict(type='bool',required=False,default=None),
        ),
        supports_check_mode=True
    )

    ## Handle running (online) daemon vs non-running (offline) daemon
    global fw
    global fw_offline
    global Rich_Rule
    global FirewallClientZoneSettings

    ## Imports
    try:
        import firewall.config
        FW_VERSION = firewall.config.VERSION

        from firewall.client import Rich_Rule
        from firewall.client import FirewallClient
        fw = None
        fw_offline = False

        try:
            fw = FirewallClient()
            fw.getDefaultZone()
        except AttributeError:
            ## Firewalld is not currently running, permanent-only operations

            ## Import other required parts of the firewalld API
            ##
            ## NOTE:
            ##  online and offline operations do not share a common firewalld API
            from firewall.core.fw_test import Firewall_test
            from firewall.client import FirewallClientZoneSettings
            fw = Firewall_test()
            fw.start()
            fw_offline = True

    except ImportError:
        ## Make python 2.4 shippable ci tests happy
        e = sys.exc_info()[1]
        module.fail_json(msg='firewalld and its python 2 module are required for this module, version 2.0.11 or newer required (3.0.9 or newer for offline operations) \n %s' % e)

    if fw_offline:
        ## Pre-run version checking
        if FW_VERSION < "0.3.9":
            module.fail_json(msg='unsupported version of firewalld, offline operations require >= 3.0.9')
    else:
        ## Pre-run version checking
        if FW_VERSION < "0.2.11":
            module.fail_json(msg='unsupported version of firewalld, requires >= 2.0.11')

        ## Check for firewalld running
        try:
            if fw.connected == False:
                module.fail_json(msg='firewalld service must be running, or try with offline=true')
        except AttributeError:
            module.fail_json(msg="firewalld connection can't be established,\
                    installed version (%s) likely too old. Requires firewalld >= 2.0.11" % FW_VERSION)


    ## Verify required params are provided
    if module.params['source'] == None and module.params['permanent'] == None:
        module.fail_json(msg='permanent is a required parameter')

    if module.params['interface'] != None and module.params['zone'] == None:
        module.fail(msg='zone is a required parameter')

    if module.params['immediate'] and fw_offline:
        module.fail(msg='firewall is not currently running, unable to perform immediate actions without a running firewall daemon')

    ## Global Vars
    changed=False
    msgs = []
    service = module.params['service']
    rich_rule = module.params['rich_rule']
    source = module.params['source']

    if module.params['port'] != None:
        port, protocol = module.params['port'].split('/')
        if protocol == None:
            module.fail_json(msg='improper port format (missing protocol?)')
    else:
        port = None

    if module.params['zone'] != None:
        zone = module.params['zone']
    else:
        if fw_offline:
            zone = fw.get_default_zone()
        else:
            zone = fw.getDefaultZone()

    permanent = module.params['permanent']
    desired_state = module.params['state']
    immediate = module.params['immediate']
    timeout = module.params['timeout']
    interface = module.params['interface']
    masquerade = module.params['masquerade']

    modification_count = 0
    if service != None:
        modification_count += 1
    if port != None:
        modification_count += 1
    if rich_rule != None:
        modification_count += 1
    if interface != None:
        modification_count += 1
    if masquerade != None:
        modification_count += 1

    if modification_count > 1:
        module.fail_json(msg='can only operate on port, service, rich_rule or interface at once')

    if service != None:
        if immediate and permanent:
            is_enabled_permanent = action_handler(
                get_service_enabled_permanent,
                (zone, service)
            )
            is_enabled_immediate = action_handler(
                get_service_enabled,
                (zone, service)
            )
            msgs.append('Permanent and Non-Permanent(immediate) operation')

            if desired_state == "enabled":
                if not is_enabled_permanent or not is_enabled_immediate:
                    if module.check_mode:
                        module.exit_json(changed=True)
                if not is_enabled_permanent:
                    action_handler(
                        set_service_enabled_permanent,
                        (zone, service)
                    )
                    changed=True
                if not is_enabled_immediate:
                    action_handler(
                        set_service_enabled,
                        (zone, service, timeout)
                    )
                    changed=True


            elif desired_state == "disabled":
                if is_enabled_permanent or is_enabled_immediate:
                    if module.check_mode:
                        module.exit_json(changed=True)
                if is_enabled_permanent:
                    action_handler(
                        set_service_disabled_permanent,
                        (zone, service)
                    )
                    changed=True
                if is_enabled_immediate:
                    action_handler(
                        set_service_disabled,
                        (zone, service)
                    )
                    changed=True

        elif permanent and not immediate:
            is_enabled = action_handler(
                get_service_enabled_permanent,
                (zone, service)
            )
            msgs.append('Permanent operation')

            if desired_state == "enabled":
                if is_enabled == False:
                    if module.check_mode:
                        module.exit_json(changed=True)

                    action_handler(
                        set_service_enabled_permanent,
                        (zone, service)
                    )
                    changed=True
            elif desired_state == "disabled":
                if is_enabled == True:
                    if module.check_mode:
                        module.exit_json(changed=True)

                    action_handler(
                        set_service_disabled_permanent,
                        (zone, service)
                    )
                    changed=True
        elif immediate and not permanent:
            is_enabled = action_handler(
                get_service_enabled,
                (zone, service)
            )
            msgs.append('Non-permanent operation')


            if desired_state == "enabled":
                if is_enabled == False:
                    if module.check_mode:
                        module.exit_json(changed=True)

                    action_handler(
                        set_service_enabled,
                        (zone, service, timeout)
                    )
                    changed=True
            elif desired_state == "disabled":
                if is_enabled == True:
                    if module.check_mode:
                        module.exit_json(changed=True)

                    action_handler(
                        set_service_disabled,
                        (zone, service)
                    )
                    changed=True

        if changed == True:
            msgs.append("Changed service %s to %s" % (service, desired_state))

    # FIXME - source type does not handle non-permanent mode, this was an
    #         oversight in the past.
    if source != None:
        is_enabled = action_handler(get_source, (zone, source))
        if desired_state == "enabled":
            if is_enabled == False:
                if module.check_mode:
                    module.exit_json(changed=True)

                action_handler(add_source, (zone, source))
                changed=True
                msgs.append("Added %s to zone %s" % (source, zone))
        elif desired_state == "disabled":
            if is_enabled == True:
                if module.check_mode:
                    module.exit_json(changed=True)

                action_handler(remove_source, (zone, source))
                changed=True
                msgs.append("Removed %s from zone %s" % (source, zone))

    if port != None:
        if immediate and permanent:
            is_enabled_permanent = action_handler(
                get_port_enabled_permanent,
                (zone,[port, protocol])
            )
            is_enabled_immediate = action_handler(
                get_port_enabled,
                (zone, [port, protocol])
            )
            msgs.append('Permanent and Non-Permanent(immediate) operation')

            if desired_state == "enabled":
                if not is_enabled_permanent or not is_enabled_immediate:
                    if module.check_mode:
                        module.exit_json(changed=True)
                if not is_enabled_permanent:
                    action_handler(
                        set_port_enabled_permanent,
                        (zone, port, protocol)
                    )
                    changed=True
                if not is_enabled_immediate:
                    action_handler(
                        set_port_enabled,
                        (zone, port, protocol, timeout)
                    )
                    changed=True

            elif desired_state == "disabled":
                if is_enabled_permanent or is_enabled_immediate:
                    if module.check_mode:
                        module.exit_json(changed=True)
                if is_enabled_permanent:
                    action_handler(
                        set_port_disabled_permanent,
                        (zone, port, protocol)
                    )
                    changed=True
                if is_enabled_immediate:
                    action_handler(
                        set_port_disabled,
                        (zone, port, protocol)
                    )
                    changed=True

        elif permanent and not immediate:
            is_enabled = action_handler(
                get_port_enabled_permanent,
                (zone, [port, protocol])
            )
            msgs.append('Permanent operation')

            if desired_state == "enabled":
                if is_enabled == False:
                    if module.check_mode:
                        module.exit_json(changed=True)

                    action_handler(
                        set_port_enabled_permanent,
                        (zone, port, protocol)
                    )
                    changed=True
            elif desired_state == "disabled":
                if is_enabled == True:
                    if module.check_mode:
                        module.exit_json(changed=True)

                    action_handler(
                        set_port_disabled_permanent,
                        (zone, port, protocol)
                    )
                    changed=True
        if immediate and not permanent:
            is_enabled = action_handler(
                get_port_enabled,
                (zone, [port,protocol])
            )
            msgs.append('Non-permanent operation')

            if desired_state == "enabled":
                if is_enabled == False:
                    if module.check_mode:
                        module.exit_json(changed=True)

                    action_handler(
                        set_port_enabled,
                        (zone, port, protocol, timeout)
                    )
                    changed=True
            elif desired_state == "disabled":
                if is_enabled == True:
                    if module.check_mode:
                        module.exit_json(changed=True)

                    action_handler(
                        set_port_disabled,
                        (zone, port, protocol)
                    )
                    changed=True

        if changed == True:
            msgs.append("Changed port %s to %s" % ("%s/%s" % (port, protocol), \
                        desired_state))

    if rich_rule != None:
        if immediate and permanent:
            is_enabled_permanent = action_handler(
                get_rich_rule_enabled_permanent,
                (zone, rich_rule)
            )
            is_enabled_immediate = action_handler(
                get_rich_rule_enabled,
                (zone, rich_rule)
            )
            msgs.append('Permanent and Non-Permanent(immediate) operation')

            if desired_state == "enabled":
                if not is_enabled_permanent or not is_enabled_immediate:
                    if module.check_mode:
                        module.exit_json(changed=True)
                if not is_enabled_permanent:
                    action_handler(
                        set_rich_rule_enabled_permanent,
                        (zone, rich_rule)
                    )
                    changed=True
                if not is_enabled_immediate:
                    action_handler(
                        set_rich_rule_enabled,
                        (zone, rich_rule, timeout)
                    )
                    changed=True

            elif desired_state == "disabled":
                if is_enabled_permanent or is_enabled_immediate:
                    if module.check_mode:
                        module.exit_json(changed=True)
                if is_enabled_permanent:
                    action_handler(
                        set_rich_rule_disabled_permanent,
                        (zone, rich_rule)
                    )
                    changed=True
                if is_enabled_immediate:
                    action_handler(
                        set_rich_rule_disabled,
                        (zone, rich_rule)
                    )
                    changed=True
        if permanent and not immediate:
            is_enabled = action_handler(
                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)

                    action_handler(
                        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)

                    action_handler(
                        set_rich_rule_disabled_permanent,
                        (zone, rich_rule)
                    )
                    changed=True
        if immediate and not permanent:
            is_enabled = action_handler(
                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)

                    action_handler(
                        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)

                    action_handler(
                        set_rich_rule_disabled,
                        (zone, rich_rule)
                    )
                    changed=True

        if changed == True:
            msgs.append("Changed rich_rule %s to %s" % (rich_rule, desired_state))

    if interface != None:
        if immediate and permanent:
            is_enabled_permanent = action_handler(
                get_interface_permanent,
                (zone, interface)
            )
            is_enabled_immediate = action_handler(
                get_interface,
                (zone, interface)
            )
            msgs.append('Permanent and Non-Permanent(immediate) operation')

            if desired_state == "enabled":
                if not is_enabled_permanent or not is_enabled_immediate:
                    if module.check_mode:
                        module.exit_json(changed=True)
                if not is_enabled_permanent:
                    change_zone_of_interface_permanent(zone, interface)
                    changed=True
                if not is_enabled_immediate:
                    change_zone_of_interface(zone, interface)
                    changed=True
                if changed:
                    msgs.append("Changed %s to zone %s" % (interface, zone))

            elif desired_state == "disabled":
                if is_enabled_permanent or is_enabled_immediate:
                    if module.check_mode:
                        module.exit_json(changed=True)
                if is_enabled_permanent:
                    remove_interface_permanent(zone, interface)
                    changed=True
                if is_enabled_immediate:
                    remove_interface(zone, interface)
                    changed=True
                if changed:
                    msgs.append("Removed %s from zone %s" % (interface, zone))

        elif permanent and not immediate:
            is_enabled = action_handler(
                get_interface_permanent,
                (zone, interface)
            )
            msgs.append('Permanent operation')
            if desired_state == "enabled":
                if is_enabled == False:
                    if module.check_mode:
                        module.exit_json(changed=True)

                    change_zone_of_interface_permanent(zone, interface)
                    changed=True
                    msgs.append("Changed %s to zone %s" % (interface, zone))
            elif desired_state == "disabled":
                if is_enabled == True:
                    if module.check_mode:
                        module.exit_json(changed=True)

                    remove_interface_permanent(zone, interface)
                    changed=True
                    msgs.append("Removed %s from zone %s" % (interface, zone))
        elif immediate and not permanent:
            is_enabled = action_handler(
                get_interface,
                (zone, interface)
            )
            msgs.append('Non-permanent operation')
            if desired_state == "enabled":
                if is_enabled == False:
                    if module.check_mode:
                        module.exit_json(changed=True)

                    change_zone_of_interface(zone, interface)
                    changed=True
                    msgs.append("Changed %s to zone %s" % (interface, zone))
            elif desired_state == "disabled":
                if is_enabled == True:
                    if module.check_mode:
                        module.exit_json(changed=True)

                    remove_interface(zone, interface)
                    changed=True
                    msgs.append("Removed %s from zone %s" % (interface, zone))

    if masquerade != None:

        if immediate and permanent:
            is_enabled_permanent = action_handler(
                get_masquerade_enabled_permanent,
                (zone)
            )
            is_enabled_immediate = action_handler(get_masquerade_enabled, (zone))
            msgs.append('Permanent and Non-Permanent(immediate) operation')

            if desired_state == "enabled":
                if not is_enabled_permanent or not is_enabled_immediate:
                    if module.check_mode:
                        module.exit_json(changed=True)
                if not is_enabled_permanent:
                    action_handler(set_masquerade_permanent, (zone, True))
                    changed=True
                if not is_enabled_immediate:
                    action_handler(set_masquerade_enabled, (zone))
                    changed=True
                if changed:
                    msgs.append("Added masquerade to zone %s" % (zone))

            elif desired_state == "disabled":
                if is_enabled_permanent or is_enabled_immediate:
                    if module.check_mode:
                        module.exit_json(changed=True)
                if is_enabled_permanent:
                    action_handler(set_masquerade_permanent, (zone, False))
                    changed=True
                if is_enabled_immediate:
                    action_handler(set_masquerade_disabled, (zone))
                    changed=True
                if changed:
                    msgs.append("Removed masquerade from zone %s" % (zone))

        elif permanent and not immediate:
            is_enabled = action_handler(get_masquerade_enabled_permanent, (zone))
            msgs.append('Permanent operation')

            if desired_state == "enabled":
                if is_enabled == False:
                    if module.check_mode:
                        module.exit_json(changed=True)

                    action_handler(set_masquerade_permanent, (zone, True))
                    changed=True
                    msgs.append("Added masquerade to zone %s" % (zone))
            elif desired_state == "disabled":
                if is_enabled == True:
                    if module.check_mode:
                        module.exit_json(changed=True)

                    action_handler(set_masquerade_permanent, (zone, False))
                    changed=True
                    msgs.append("Removed masquerade from zone %s" % (zone))
        elif immediate and not permanent:
            is_enabled = action_handler(get_masquerade_enabled, (zone))
            msgs.append('Non-permanent operation')

            if desired_state == "enabled":
                if is_enabled == False:
                    if module.check_mode:
                        module.exit_json(changed=True)

                    action_handler(set_masquerade_enabled, (zone))
                    changed=True
                    msgs.append("Added masquerade to zone %s" % (zone))
            elif desired_state == "disabled":
                if is_enabled == True:
                    if module.check_mode:
                        module.exit_json(changed=True)

                    action_handler(set_masquerade_disabled, (zone))
                    changed=True
                    msgs.append("Removed masquerade from zone %s" % (zone))

    if fw_offline:
        msgs.append("(offline operation: only on-disk configs were altered)")
    module.exit_json(changed=changed, msg=', '.join(msgs))
예제 #5
0
    def installFirewall(self):
        """install firewall"""
        log.debug1("%s.installFirewall()", self._log_prefix)

        # are there any firewall settings to apply?
        if len(self._settings["firewall"]["services"]) + \
           len(self._settings["firewall"]["ports"]) < 1:
            return

        # create firewall client
        fw = FirewallClient()
        log.debug2("TRACE: Firewall client created")

        # Make sure firewalld is running by getting the
        # default zone
        try:
            default_zone = fw.getDefaultZone()
        except DBusException:
            # firewalld is not running
            log.error("Firewalld is not running or rolekit cannot access it")
            raise

        # save changes to the firewall
        try:
            fw_changes = self._settings["firewall-changes"]
        except KeyError:
            fw_changes = { }

        log.debug2("TRACE: Checking for zones: {}".format(self._settings))

        try:
            zones = self._settings["firewall_zones"]
        except KeyError:
            zones = []

        # if firewall_zones setting is empty, use default zone
        if len(zones) < 1:
            zones = [ default_zone ]

        log.debug2("TRACE: default zone {}".format(zones[0]))

        for zone in zones:
            log.debug2("TRACE: Processing zone {0}".format(zone))
            # get permanent zone settings, run-time settings do not need a
            # special treatment
            z_perm = fw.config().getZoneByName(zone).getSettings()

            for service in self._settings["firewall"]["services"]:
                try:
                    fw.addService(zone, service, 0)
                except Exception as e:
                    if not "ALREADY_ENABLED" in str(e):
                        raise
                else:
                    fw_changes.setdefault(zone, {}).setdefault("services", {}).setdefault(service, []).append("runtime")

                if not z_perm.queryService(service):
                    z_perm.addService(service)
                    fw_changes.setdefault(zone, {}).setdefault("services", {}).setdefault(service, []).append("permanent")

            for port_proto in self._settings["firewall"]["ports"]:
                port, proto = port_proto.split("/")

                try:
                    fw.addPort(zone, port, proto, 0)
                except Exception as e:
                    if not "ALREADY_ENABLED" in str(e):
                        raise
                else:
                    fw_changes.setdefault(zone, {}).setdefault("ports", {}).setdefault(port_proto, []).append("runtime")

                if not z_perm.queryPort(port, proto):
                    z_perm.addPort(port, proto)
                    fw_changes.setdefault(zone, {}).setdefault("ports", {}).setdefault(port_proto, []).append("permanent")

            fw.config().getZoneByName(zone).update(z_perm)

        self._settings["firewall-changes"] = fw_changes
        self._settings.write()
예제 #6
0
def main():
    module = AnsibleModule(
        argument_spec=dict(
            service=dict(required=False, type="list", default=[]),
            port=dict(required=False, type="list", default=[]),
            trust=dict(required=False, type="list", default=[]),
            trust_by_mac=dict(required=False, type="list", default=[]),
            masq=dict(required=False, type="list", default=[]),
            masq_by_mac=dict(required=False, type="list", default=[]),
            forward_port=dict(required=False, type="list", default=[]),
            forward_port_by_mac=dict(required=False, type="list", default=[]),
            zone=dict(required=False, type="str", default=None),
            state=dict(choices=["enabled", "disabled"], required=True),
        ),
        required_one_of=([
            "service",
            "port",
            "trust",
            "trust_by_mac",
            "masq",
            "masq_by_mac",
            "forward_prot",
        ], ),
        supports_check_mode=True,
    )

    if not HAS_FIREWALLD and not HAS_SYSTEM_CONFIG_FIREWALL:
        module.fail_json(msg="No firewall backend could be imported.")

    service = module.params["service"]
    port = []
    for port_proto in module.params["port"]:
        _port, _protocol = port_proto.split("/")
        if _protocol is None:
            module.fail_json(msg="improper port format (missing protocol?)")
        port.append((_port, _protocol))
    trust = module.params["trust"]
    trust_by_mac = []
    for item in module.params["trust_by_mac"]:
        _interface = get_device_for_mac(item)
        if _interface is None:
            module.fail_json(msg="MAC address not found %s" % item)
        trust_by_mac.append(_interface)
    masq = module.params["masq"]
    masq_by_mac = []
    for item in module.params["masq_by_mac"]:
        _interface = get_device_for_mac(item)
        if _interface is None:
            module.fail_json(msg="MAC address not found %s" % item)
        masq_by_mac.append(_interface)
    forward_port = []
    for item in module.params["forward_port"]:
        args = item.split(";")
        if len(args) == 4:
            _interface, __port, _to_port, _to_addr = args
        elif len(args) == 3:
            _interface = ""
            __port, _to_port, _to_addr = args
        else:
            module.fail_json(msg="improper forward_port format: %s" % item)
        _port, _protocol = __port.split("/")
        if _protocol is None:
            module.fail_json(
                msg="improper forward port format (missing protocol?)")
        if _to_port == "":
            _to_port = None
        if _to_addr == "":
            _to_addr = None
        forward_port.append((_interface, _port, _protocol, _to_port, _to_addr))

    forward_port_by_mac = []
    for item in module.params["forward_port_by_mac"]:
        args = item.split(";")
        if len(args) != 4:
            module.fail_json(msg="improper forward_port_by_mac format")
        _mac_addr, __port, _to_port, _to_addr = args
        _port, _protocol = __port.split("/")
        if _protocol is None:
            module.fail_json(
                msg="improper forward_port_by_mac format (missing protocol?)")
        if _to_port == "":
            _to_port = None
        if _to_addr == "":
            _to_addr = None
        _interface = get_device_for_mac(_mac_addr)
        if _interface is None:
            module.fail_json(msg="MAC address not found %s" % _mac_addr)
        forward_port_by_mac.append(
            (_interface, _port, _protocol, _to_port, _to_addr))
    zone = module.params["zone"]
    if HAS_SYSTEM_CONFIG_FIREWALL and zone is not None:
        module.fail_json(
            msg="Zone can not be used with system-config-firewall/lokkit.")
    desired_state = module.params["state"]

    if HAS_FIREWALLD:
        fw = FirewallClient()

        def exception_handler(exception_message):
            module.fail_json(msg=exception_message)

        fw.setExceptionHandler(exception_handler)

        if not fw.connected:
            module.fail_json(msg="firewalld service must be running")

        trusted_zone = "trusted"
        external_zone = "external"
        if zone is not None:
            if zone not in fw.getZones():
                module.fail_json(msg="Runtime zone '%s' does not exist." %
                                 zone)
            if zone not in fw.config().getZoneNames():
                module.fail_json(msg="Permanent zone '%s' does not exist." %
                                 zone)
        else:
            zone = fw.getDefaultZone()
        fw_zone = fw.config().getZoneByName(zone)
        fw_settings = fw_zone.getSettings()

        changed = False
        changed_zones = {}

        # service
        for item in service:
            if desired_state == "enabled":
                if not fw.queryService(zone, item):
                    fw.addService(zone, item)
                    changed = True
                if not fw_settings.queryService(item):
                    fw_settings.addService(item)
                    changed = True
                    changed_zones[fw_zone] = fw_settings
            elif desired_state == "disabled":
                if fw.queryService(zone, item):
                    fw.removeService(zone, item)
                if fw_settings.queryService(item):
                    fw_settings.removeService(item)
                    changed = True
                    changed_zones[fw_zone] = fw_settings

        # port
        for _port, _protocol in port:
            if desired_state == "enabled":
                if not fw.queryPort(zone, _port, _protocol):
                    fw.addPort(zone, _port, _protocol)
                    changed = True
                if not fw_settings.queryPort(_port, _protocol):
                    fw_settings.addPort(_port, _protocol)
                    changed = True
                    changed_zones[fw_zone] = fw_settings
            elif desired_state == "disabled":
                if fw.queryPort(zone, _port, _protocol):
                    fw.removePort(zone, _port, _protocol)
                    changed = True
                if fw_settings.queryPort(_port, _protocol):
                    fw_settings.removePort(_port, _protocol)
                    changed = True
                    changed_zones[fw_zone] = fw_settings

        # trust, trust_by_mac
        if len(trust) > 0 or len(trust_by_mac) > 0:
            items = trust
            if len(trust_by_mac) > 0:
                items.extend(trust_by_mac)

            if zone != trusted_zone:
                _fw_zone = fw.config().getZoneByName(trusted_zone)
                if _fw_zone in changed_zones:
                    _fw_settings = changed_zones[_fw_zone]
                else:
                    _fw_settings = _fw_zone.getSettings()
            else:
                _fw_zone = fw_zone
                _fw_settings = fw_settings

            for item in items:
                if desired_state == "enabled":
                    if try_set_zone_of_interface(trusted_zone, item):
                        changed = True
                    else:
                        if not fw.queryInterface(trusted_zone, item):
                            fw.changeZoneOfInterface(trusted_zone, item)
                            changed = True
                        if not _fw_settings.queryInterface(item):
                            _fw_settings.addInterface(item)
                            changed = True
                            changed_zones[_fw_zone] = _fw_settings
                elif desired_state == "disabled":
                    if try_set_zone_of_interface("", item):
                        if module.check_mode:
                            module.exit_json(changed=True)
                    else:
                        if fw.queryInterface(trusted_zone, item):
                            fw.removeInterface(trusted_zone, item)
                            changed = True
                        if _fw_settings.queryInterface(item):
                            _fw_settings.removeInterface(item)
                            changed = True
                            changed_zones[_fw_zone] = _fw_settings

        # masq, masq_by_mac
        if len(masq) > 0 or len(masq_by_mac) > 0:
            items = masq
            if len(masq_by_mac) > 0:
                items.extend(masq_by_mac)

            if zone != external_zone:
                _fw_zone = fw.config().getZoneByName(external_zone)
                if _fw_zone in changed_zones:
                    _fw_settings = changed_zones[_fw_zone]
                else:
                    _fw_settings = _fw_zone.getSettings()
            else:
                _fw_zone = fw_zone
                _fw_settings = fw_settings

            for item in items:
                if desired_state == "enabled":
                    if try_set_zone_of_interface(external_zone, item):
                        changed = True
                    else:
                        if not fw.queryInterface(external_zone, item):
                            fw.changeZoneOfInterface(external_zone, item)
                            changed = True
                        if not _fw_settings.queryInterface(item):
                            _fw_settings.addInterface(item)
                            changed = True
                            changed_zones[_fw_zone] = _fw_settings
                elif desired_state == "disabled":
                    if try_set_zone_of_interface("", item):
                        if module.check_mode:
                            module.exit_json(changed=True)
                    else:
                        if fw.queryInterface(external_zone, item):
                            fw.removeInterface(external_zone, item)
                            changed = True
                        if _fw_settings.queryInterface(item):
                            _fw_settings.removeInterface(item)
                            changed = True
                            changed_zones[_fw_zone] = _fw_settings

        # forward_port, forward_port_by_mac
        if len(forward_port) > 0 or len(forward_port_by_mac) > 0:
            items = forward_port
            if len(forward_port_by_mac) > 0:
                items.extend(forward_port_by_mac)

            for _interface, _port, _protocol, _to_port, _to_addr in items:
                if _interface != "":
                    _zone = fw.getZoneOfInterface(_interface)
                else:
                    _zone = zone
                if _zone != "" and _zone != zone:
                    _fw_zone = fw.config().getZoneByName(_zone)
                    if _fw_zone in changed_zones:
                        _fw_settings = changed_zones[_fw_zone]
                    else:
                        _fw_settings = _fw_zone.getSettings()
                else:
                    _fw_zone = fw_zone
                    _fw_settings = fw_settings

                if desired_state == "enabled":
                    if not fw.queryForwardPort(_zone, _port, _protocol,
                                               _to_port, _to_addr):
                        fw.addForwardPort(_zone, _port, _protocol, _to_port,
                                          _to_addr)
                        changed = True
                    if not _fw_settings.queryForwardPort(
                            _port, _protocol, _to_port, _to_addr):
                        _fw_settings.addForwardPort(_port, _protocol, _to_port,
                                                    _to_addr)
                        changed = True
                        changed_zones[_fw_zone] = _fw_settings
                elif desired_state == "disabled":
                    if fw.queryForwardPort(_zone, _port, _protocol, _to_port,
                                           _to_addr):
                        fw.removeForwardPort(_zone, _port, _protocol, _to_port,
                                             _to_addr)
                        changed = True
                    if _fw_settings.queryForwardPort(_port, _protocol,
                                                     _to_port, _to_addr):
                        _fw_settings.removeForwardPort(_port, _protocol,
                                                       _to_port, _to_addr)
                        changed = True
                        changed_zones[_fw_zone] = _fw_settings

        # apply changes
        if changed:
            for _zone in changed_zones:
                _zone.update(changed_zones[_zone])
            module.exit_json(changed=True)

    elif HAS_SYSTEM_CONFIG_FIREWALL:
        (config, old_config, _) = fw_lokkit.loadConfig(args=[],
                                                       dbus_parser=True)

        changed = False

        # service
        for item in service:
            if config.services is None:
                config.services = []

            if desired_state == "enabled":
                if item not in config.services:
                    config.services.append(item)
                    changed = True
            elif desired_state == "disabled":
                if item in config.services:
                    config.services.remove(item)
                    changed = True

        # port
        for _port, _protocol in port:
            if config.ports is None:
                config.ports = []

            _range = getPortRange(_port)
            if _range < 0:
                module.fail_json(msg="invalid port definition %s" % _port)
            elif _range is None:
                module.fail_json(msg="port _range is not unique.")
            elif len(_range) == 2 and _range[0] >= _range[1]:
                module.fail_json(msg="invalid port range %s" % _port)
            port_proto = (_range, _protocol)
            if desired_state == "enabled":
                if port_proto not in config.ports:
                    config.ports.append(port_proto)
                    changed = True
            elif desired_state == "disabled":
                if port_proto in config.ports:
                    config.ports.remove(port_proto)
                    changed = True

        # trust, trust_by_mac
        if len(trust) > 0 or len(trust_by_mac) > 0:
            if config.trust is None:
                config.trust = []

            items = trust
            if len(trust_by_mac) > 0:
                items.extend(trust_by_mac)

            for item in items:
                if desired_state == "enabled":
                    if item not in config.trust:
                        config.trust.append(item)
                        changed = True
                elif desired_state == "disabled":
                    if item in config.trust:
                        config.trust.remove(item)
                        changed = True

        # masq, masq_by_mac
        if len(masq) > 0 or len(masq_by_mac) > 0:
            if config.masq is None:
                config.masq = []

            items = masq
            if len(masq_by_mac) > 0:
                items.extend(masq_by_mac)

            for item in items:
                if desired_state == "enabled":
                    if item not in config.masq:
                        config.masq.append(item)
                        changed = True
                elif desired_state == "disabled":
                    if item in config.masq:
                        config.masq.remove(item)
                        changed = True

        # forward_port, forward_port_by_mac
        if len(forward_port) > 0 or len(forward_port_by_mac) > 0:
            if config.forward_port is None:
                config.forward_port = []

            items = forward_port
            if len(forward_port_by_mac) > 0:
                items.extend(forward_port_by_mac)

            for _interface, _port, _protocol, _to_port, _to_addr in items:
                _range = getPortRange(_port)
                if _range < 0:
                    module.fail_json(msg="invalid port definition")
                elif _range is None:
                    module.fail_json(msg="port _range is not unique.")
                elif len(_range) == 2 and _range[0] >= _range[1]:
                    module.fail_json(msg="invalid port range")
                fwd_port = {
                    "if": _interface,
                    "port": _range,
                    "proto": _protocol
                }
                if _to_port is not None:
                    _range = getPortRange(_to_port)
                    if _range < 0:
                        module.fail_json(msg="invalid port definition %s" %
                                         _to_port)
                    elif _range is None:
                        module.fail_json(msg="port _range is not unique.")
                    elif len(_range) == 2 and _range[0] >= _range[1]:
                        module.fail_json(msg="invalid port range")
                    fwd_port["toport"] = _range
                if _to_addr is not None:
                    fwd_port["toaddr"] = _to_addr

                if desired_state == "enabled":
                    if fwd_port not in config.forward_port:
                        config.forward_port.append(fwd_port)
                        changed = True
                elif desired_state == "disabled":
                    if fwd_port in config.forward_port:
                        config.forward_port.remove(fwd_port)
                        changed = True

        # apply changes
        if changed:
            fw_lokkit.updateFirewall(config, old_config)
            if module.check_mode:
                module.exit_json(changed=True)

    else:
        module.fail_json(msg="No firewalld and system-config-firewall")

    module.exit_json(changed=False)
예제 #7
0
def main():
    module = AnsibleModule(argument_spec=dict(
        service=dict(required=False, type='list', default=[]),
        port=dict(required=False, type='list', default=[]),
        trust=dict(required=False, type='list', default=[]),
        trust_by_mac=dict(required=False, type='list', default=[]),
        masq=dict(required=False, type='list', default=[]),
        masq_by_mac=dict(required=False, type='list', default=[]),
        forward_port=dict(required=False, type='list', default=[]),
        forward_port_by_mac=dict(required=False, type='list', default=[]),
        state=dict(choices=['enabled', 'disabled'], required=True),
    ),
                           required_one_of=([
                               'service', 'port', 'trust', 'trust_by_mac',
                               'masq', 'masq_by_mac', 'forward_prot'
                           ], ),
                           supports_check_mode=True)

    if not HAS_FIREWALLD and not HAS_SYSTEM_CONFIG_FIREWALL:
        module.fail_json(msg='No firewall backend could be imported.')

    service = module.params['service']
    port = []
    for port_proto in module.params['port']:
        _port, _protocol = port_proto.split('/')
        if _protocol is None:
            module.fail_json(msg='improper port format (missing protocol?)')
        port.append((_port, _protocol))
    trust = module.params['trust']
    trust_by_mac = []
    for item in module.params['trust_by_mac']:
        _interface = get_device_for_mac(item)
        if _interface is None:
            module.fail_json(msg='MAC address not found %s' % item)
        trust_by_mac.append(_interface)
    masq = module.params['masq']
    masq_by_mac = []
    for item in module.params['masq_by_mac']:
        _interface = get_device_for_mac(item)
        if _interface is None:
            module.fail_json(msg='MAC address not found %s' % item)
        masq_by_mac.append(_interface)
    forward_port = []
    for item in module.params['forward_port']:
        args = item.split(";")
        if len(args) != 4:
            module.fail_json(msg='improper forward_port format: %s' % item)
        _interface, __port, _to_port, _to_addr = args
        _port, _protocol = __port.split('/')
        if _protocol is None:
            module.fail_json(msg='improper port format (missing protocol?)')
        if _to_port == "":
            _to_port = None
        if _to_addr == "":
            _to_addr = None
        forward_port.append((_interface, _port, _protocol, _to_port, _to_addr))

    forward_port_by_mac = []
    for item in module.params['forward_port_by_mac']:
        args = item.split(";")
        if len(args) != 4:
            module.fail_json(msg='improper forward_port_by_mac format')
        _mac_addr, __port, _to_port, _to_addr = args
        _port, _protocol = __port.split('/')
        if _protocol is None:
            module.fail_json(msg='improper port format (missing protocol?)')
        if _to_port == "":
            _to_port = None
        if _to_addr == "":
            _to_addr = None
        _interface = get_device_for_mac(_mac_addr)
        if _interface is None:
            module.fail_json(msg='MAC address not found %s' % _mac_addr)
        forward_port_by_mac.append(
            (_interface, _port, _protocol, _to_port, _to_addr))
    desired_state = module.params['state']

    if HAS_FIREWALLD:
        fw = FirewallClient()

        def exception_handler(exception_message):
            module.fail_json(msg=exception_message)

        fw.setExceptionHandler(exception_handler)

        if not fw.connected:
            module.fail_json(msg='firewalld service must be running')

        trusted_zone = "trusted"
        external_zone = "external"
        default_zone = fw.getDefaultZone()
        fw_zone = fw.config().getZoneByName(default_zone)
        fw_settings = fw_zone.getSettings()

        changed = False
        changed_zones = {}

        # service
        for item in service:
            if desired_state == "enabled":
                if not fw.queryService(default_zone, item):
                    fw.addService(default_zone, item)
                    changed = True
                if not fw_settings.queryService(item):
                    fw_settings.addService(item)
                    changed = True
                    changed_zones[fw_zone] = fw_settings
            elif desired_state == "disabled":
                if fw.queryService(default_zone, item):
                    fw.removeService(default_zone, item)
                if fw_settings.queryService(item):
                    fw_settings.removeService(item)
                    changed = True
                    changed_zones[fw_zone] = fw_settings

        # port
        for _port, _protocol in port:
            if desired_state == "enabled":
                if not fw.queryPort(default_zone, _port, _protocol):
                    fw.addPort(default_zone, _port, _protocol)
                    changed = True
                if not fw_settings.queryPort(_port, _protocol):
                    fw_settings.addPort(_port, _protocol)
                    changed = True
                    changed_zones[fw_zone] = fw_settings
            elif desired_state == "disabled":
                if fw.queryPort(default_zone, _port, _protocol):
                    fw.removePort(default_zone, _port, _protocol)
                    changed = True
                if fw_settings.queryPort(_port, _protocol):
                    fw_settings.removePort(_port, _protocol)
                    changed = True
                    changed_zones[fw_zone] = fw_settings

        # trust, trust_by_mac
        if len(trust) > 0 or len(trust_by_mac) > 0:
            items = trust
            if len(trust_by_mac) > 0:
                items.extend(trust_by_mac)

            if default_zone != trusted_zone:
                fw_zone = fw.config().getZoneByName(trusted_zone)
                fw_settings = fw_zone.getSettings()

            for item in items:
                if desired_state == "enabled":
                    if try_set_zone_of_interface(trusted_zone, item):
                        changed = True
                    else:
                        if not fw.queryInterface(trusted_zone, item):
                            fw.changeZoneOfInterface(trusted_zone, item)
                            changed = True
                        if not fw_settings.queryInterface(item):
                            fw_settings.addInterface(item)
                            changed = True
                            changed_zones[fw_zone] = fw_settings
                elif desired_state == "disabled":
                    if try_set_zone_of_interface("", item):
                        if module.check_mode:
                            module.exit_json(changed=True)
                    else:
                        if fw.queryInterface(trusted_zone, item):
                            fw.removeInterface(trusted_zone, item)
                            changed = True
                        if fw_settings.queryInterface(item):
                            fw_settings.removeInterface(item)
                            changed = True
                            changed_zones[fw_zone] = fw_settings

        # masq, masq_by_mac
        if len(masq) > 0 or len(masq_by_mac) > 0:
            items = masq
            if len(masq_by_mac) > 0:
                items.extend(masq_by_mac)

            if default_zone != external_zone:
                fw_zone = fw.config().getZoneByName(external_zone)
                fw_settings = fw_zone.getSettings()

            for item in items:
                if desired_state == "enabled":
                    if try_set_zone_of_interface(external_zone, item):
                        changed = True
                    else:
                        if not fw.queryInterface(external_zone, item):
                            fw.changeZoneOfInterface(external_zone, item)
                            changed = True
                        if not fw_settings.queryInterface(item):
                            fw_settings.addInterface(item)
                            changed = True
                            changed_zones[fw_zone] = fw_settings
                elif desired_state == "disabled":
                    if try_set_zone_of_interface("", item):
                        if module.check_mode:
                            module.exit_json(changed=True)
                    else:
                        if fw.queryInterface(external_zone, item):
                            fw.removeInterface(external_zone, item)
                            changed = True
                        if fw_settings.queryInterface(item):
                            fw_settings.removeInterface(item)
                            changed = True
                            changed_zones[fw_zone] = fw_settings

        # forward_port, forward_port_by_mac
        if len(forward_port) > 0 or len(forward_port_by_mac) > 0:
            items = forward_port
            if len(forward_port_by_mac) > 0:
                items.extend(forward_port_by_mac)

            for _interface, _port, _protocol, _to_port, _to_addr in items:
                if _interface != "":
                    _zone = fw.getZoneOfInterface(_interface)
                    if _zone != "" and _zone != default_zone:
                        fw_zone = fw.config().getZoneByName(_zone)
                        fw_settings = fw_zone.getSettings()

                if desired_state == "enabled":
                    if not fw.queryForwardPort(_zone, _port, _protocol,
                                               _to_port, _to_addr):
                        fw.addForwardPort(_zone, _port, _protocol, _to_port,
                                          _to_addr)
                        changed = True
                    if not fw_settings.queryForwardPort(
                            _port, _protocol, _to_port, _to_addr):
                        fw_settings.addForwardPort(_port, _protocol, _to_port,
                                                   _to_addr)
                        changed = True
                        changed_zones[fw_zone] = fw_settings
                elif desired_state == "disabled":
                    if fw.queryForwardPort(_zone, _port, _protocol, _to_port,
                                           _to_addr):
                        fw.removeForwardPort(_zone, _port, _protocol, _to_port,
                                             _to_addr)
                        changed = True
                    if fw_settings.queryForwardPort(_port, _protocol, _to_port,
                                                    _to_addr):
                        fw_settings.removeForwardPort(_port, _protocol,
                                                      _to_port, _to_addr)
                        changed = True
                        changed_zones[fw_zone] = fw_settings

        # apply changes
        if changed:
            for _zone in changed_zones:
                _zone.update(changed_zones[_zone])
            if module.check_mode:
                module.exit_json(changed=True)

    elif HAS_SYSTEM_CONFIG_FIREWALL:
        (config, old_config, _) = fw_lokkit.loadConfig(args=[],
                                                       dbus_parser=True)

        changed = False

        # service
        for item in service:
            if config.services is None:
                config.services = []

            if desired_state == "enabled":
                if item not in config.services:
                    config.services.append(item)
                    changed = True
            elif desired_state == "disabled":
                if item in config.services:
                    config.services.remove(item)
                    changed = True

        # port
        for _port, _protocol in port:
            if config.ports is None:
                config.ports = []

            _range = getPortRange(_port)
            if _range < 0:
                module.fail_json(msg='invalid port definition %s' % _port)
            elif _range is None:
                module.fail_json(msg='port _range is not unique.')
            elif len(_range) == 2 and _range[0] >= _range[1]:
                module.fail_json(msg='invalid port range %s' % _port)
            port_proto = (_range, _protocol)
            if desired_state == "enabled":
                if port_proto not in config.ports:
                    config.ports.append(port_proto)
                    changed = True
            elif desired_state == "disabled":
                if port_proto in config.ports:
                    config.ports.remove(port_proto)
                    changed = True

        # trust, trust_by_mac
        if len(trust) > 0 or len(trust_by_mac) > 0:
            if config.trust is None:
                config.trust = []

            items = trust
            if len(trust_by_mac) > 0:
                items.extend(trust_by_mac)

            for item in items:
                if desired_state == "enabled":
                    if item not in config.trust:
                        config.trust.append(item)
                        changed = True
                elif desired_state == "disabled":
                    if item in config.trust:
                        config.trust.remove(item)
                        changed = True

        # masq, masq_by_mac
        if len(masq) > 0 or len(masq_by_mac) > 0:
            if config.masq is None:
                config.masq = []

            items = masq
            if len(masq_by_mac) > 0:
                items.extend(masq_by_mac)

            for item in items:
                if desired_state == "enabled":
                    if item not in config.masq:
                        config.masq.append(item)
                        changed = True
                elif desired_state == "disabled":
                    if item in config.masq:
                        config.masq.remove(item)
                        changed = True

        # forward_port, forward_port_by_mac
        if len(forward_port) > 0 or len(forward_port_by_mac) > 0:
            if config.forward_port is None:
                config.forward_port = []

            items = forward_port
            if len(forward_port_by_mac) > 0:
                items.extend(forward_port_by_mac)

            for _interface, _port, _protocol, _to_port, _to_addr in items:
                _range = getPortRange(_port)
                if _range < 0:
                    module.fail_json(msg='invalid port definition')
                elif _range is None:
                    module.fail_json(msg='port _range is not unique.')
                elif len(_range) == 2 and _range[0] >= _range[1]:
                    module.fail_json(msg='invalid port range')
                fwd_port = {
                    "if": _interface,
                    "port": _range,
                    "proto": _protocol
                }
                if _to_port is not None:
                    _range = getPortRange(_to_port)
                    if _range < 0:
                        module.fail_json(msg='invalid port definition %s' % \
                                         _to_port)
                    elif _range is None:
                        module.fail_json(msg='port _range is not unique.')
                    elif len(_range) == 2 and _range[0] >= _range[1]:
                        module.fail_json(msg='invalid port range')
                    fwd_port["toport"] = _range
                if _to_addr is not None:
                    fwd_port["toaddr"] = _to_addr

                if desired_state == "enabled":
                    if fwd_port not in config.forward_port:
                        config.forward_port.append(fwd_port)
                        changed = True
                elif desired_state == "disabled":
                    if fwd_port in config.forward_port:
                        config.forward_port.remove(fwd_port)
                        changed = True

        # apply changes
        if changed:
            fw_lokkit.updateFirewall(config, old_config)
            if module.check_mode:
                module.exit_json(changed=True)

    else:
        module.fail_json(msg='No firewalld and system-config-firewall')

    module.exit_json(changed=False)