Пример #1
0
def main():

    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', 'present', 'absent'],
                   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)

    if fw_offline:
        # Pre-run version checking
        if FW_VERSION < "0.3.9":
            module.fail_json(
                msg=
                'unsupported version of firewalld, offline operations require >= 0.3.9'
            )
    else:
        # Pre-run version checking
        if FW_VERSION < "0.2.11":
            module.fail_json(
                msg='unsupported version of firewalld, requires >= 0.2.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 >= 0.2.11"
                             % FW_VERSION)

    if import_failure:
        module.fail_json(
            msg=
            'firewalld and its python module are required for this module, version 0.2.11 or newer required (0.3.9 or newer for offline operations)'
        )

    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']

    # If neither permanent or immediate is provided, assume immediate (as
    # written in the module's docs)
    if not permanent and not immediate:
        immediate = True

    # Verify required params are provided
    if immediate and fw_offline:
        module.fail(
            msg=
            'firewall is not currently running, unable to perform immediate actions without a running firewall daemon'
        )

    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'].strip().split('/')
        if protocol is None:
            module.fail_json(msg='improper port format (missing protocol?)')
    else:
        port = None

    # If we weren't provided a zone, then just use the system default
    if module.params['zone'] is not None:
        zone = module.params['zone']
    else:
        if fw_offline:
            zone = fw.get_default_zone()
        else:
            zone = fw.getDefaultZone()

    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'
        )
    elif modification_count > 0 and desired_state in ['absent', 'present']:
        module.fail_json(
            msg=
            'absent and present state can only be used in zone level operations'
        )

    if service is not None:

        transaction = ServiceTransaction(fw,
                                         action_args=(service, timeout),
                                         zone=zone,
                                         desired_state=desired_state,
                                         permanent=permanent,
                                         immediate=immediate,
                                         fw_offline=fw_offline)

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

    if source is not None:

        transaction = SourceTransaction(fw,
                                        action_args=(source, ),
                                        zone=zone,
                                        desired_state=desired_state,
                                        permanent=permanent,
                                        immediate=immediate,
                                        fw_offline=fw_offline)

        changed, transaction_msgs = transaction.run()
        msgs = msgs + transaction_msgs

    if port is not None:

        transaction = PortTransaction(fw,
                                      action_args=(port, protocol, timeout),
                                      zone=zone,
                                      desired_state=desired_state,
                                      permanent=permanent,
                                      immediate=immediate,
                                      fw_offline=fw_offline)

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

    if rich_rule is not None:

        transaction = RichRuleTransaction(fw,
                                          action_args=(rich_rule, timeout),
                                          zone=zone,
                                          desired_state=desired_state,
                                          permanent=permanent,
                                          immediate=immediate,
                                          fw_offline=fw_offline)

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

    if interface is not None:

        transaction = InterfaceTransaction(fw,
                                           action_args=(interface, ),
                                           zone=zone,
                                           desired_state=desired_state,
                                           permanent=permanent,
                                           immediate=immediate,
                                           fw_offline=fw_offline)

        changed, transaction_msgs = transaction.run()
        msgs = msgs + transaction_msgs

    if masquerade is not None:

        transaction = MasqueradeTransaction(fw,
                                            action_args=(),
                                            zone=zone,
                                            desired_state=desired_state,
                                            permanent=permanent,
                                            immediate=immediate,
                                            fw_offline=fw_offline)

        changed, transaction_msgs = transaction.run()
        msgs = msgs + transaction_msgs
    ''' If there are no changes within the zone we are operating on the zone itself '''
    if modification_count == 0 and desired_state in ['absent', 'present']:

        transaction = ZoneTransaction(fw,
                                      action_args=(),
                                      zone=zone,
                                      desired_state=desired_state,
                                      permanent=permanent,
                                      immediate=immediate,
                                      fw_offline=fw_offline)

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

    if fw_offline:
        msgs.append("(offline operation: only on-disk configs were altered)")

    module.exit_json(changed=changed, msg=', '.join(msgs))
Пример #2
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 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))
def main():
    module = AnsibleModule(
        argument_spec=dict(
            challenge=dict(required=True, choices=['tls-alpn-01'], type='str'),
            challenge_data=dict(required=True, type='dict'),
            private_key_src=dict(type='path'),
            private_key_content=dict(type='str', no_log=True),
        ),
        required_one_of=(['private_key_src', 'private_key_content'], ),
        mutually_exclusive=(['private_key_src', 'private_key_content'], ),
    )
    if not HAS_CRYPTOGRAPHY:
        module.fail(msg='cryptography >= 1.3 is required for this module.')

    try:
        # Get parameters
        challenge = module.params['challenge']
        challenge_data = module.params['challenge_data']

        # Get hold of private key
        private_key_content = module.params.get('private_key_content')
        if private_key_content is None:
            private_key_content = read_file(module.params['private_key_src'])
        else:
            private_key_content = to_bytes(private_key_content)
        try:
            private_key = cryptography.hazmat.primitives.serialization.load_pem_private_key(
                private_key_content,
                password=None,
                backend=_cryptography_backend)
        except Exception as e:
            raise ModuleFailException(
                'Error while loading private key: {0}'.format(e))

        # Some common attributes
        domain = to_text(challenge_data['resource'])
        subject = issuer = cryptography.x509.Name([
            cryptography.x509.NameAttribute(
                cryptography.x509.oid.NameOID.COMMON_NAME, domain),
        ])
        not_valid_before = datetime.datetime.utcnow()
        not_valid_after = datetime.datetime.utcnow() + datetime.timedelta(
            days=10)

        # Generate regular self-signed certificate
        regular_certificate = cryptography.x509.CertificateBuilder(
        ).subject_name(subject).issuer_name(issuer).public_key(
            private_key.public_key()).serial_number(
                cryptography.x509.random_serial_number()).not_valid_before(
                    not_valid_before).not_valid_after(
                        not_valid_after).add_extension(
                            cryptography.x509.SubjectAlternativeName(
                                [cryptography.x509.DNSName(domain)]),
                            critical=False,
                        ).sign(private_key,
                               cryptography.hazmat.primitives.hashes.SHA256(),
                               _cryptography_backend)

        # Process challenge
        if challenge == 'tls-alpn-01':
            value = base64.b64decode(challenge_data['resource_value'])
            challenge_certificate = cryptography.x509.CertificateBuilder(
            ).subject_name(subject).issuer_name(issuer).public_key(
                private_key.public_key()).serial_number(
                    cryptography.x509.random_serial_number()).not_valid_before(
                        not_valid_before).not_valid_after(
                            not_valid_after).add_extension(
                                cryptography.x509.SubjectAlternativeName(
                                    [cryptography.x509.DNSName(domain)]),
                                critical=False,
                            ).add_extension(
                                cryptography.x509.UnrecognizedExtension(
                                    cryptography.x509.ObjectIdentifier(
                                        "1.3.6.1.5.5.7.1.31"),
                                    encode_octet_string(value),
                                ),
                                critical=True,
                            ).sign(
                                private_key,
                                cryptography.hazmat.primitives.hashes.SHA256(),
                                _cryptography_backend)

        module.exit_json(
            changed=True,
            domain=domain,
            challenge_certificate=challenge_certificate.public_bytes(
                cryptography.hazmat.primitives.serialization.Encoding.PEM),
            regular_certificate=regular_certificate.public_bytes(
                cryptography.hazmat.primitives.serialization.Encoding.PEM))
    except ModuleFailException as e:
        e.do_fail(module)
Пример #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 main():

    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
    )

    if import_failure:
        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 >= 0.3.9')
    else:
        # Pre-run version checking
        if FW_VERSION < "0.2.11":
            module.fail_json(msg='unsupported version of firewalld, requires >= 0.2.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 >= 0.2.11" % FW_VERSION)

    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']

    # If neither permanent or immediate is provided, assume immediate (as
    # written in the module's docs)
    if not permanent and not immediate:
        immediate = True

    # Verify required params are provided
    if immediate and fw_offline:
        module.fail(msg='firewall is not currently running, unable to perform immediate actions without a running firewall daemon')

    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'].strip().split('/')
        if protocol is None:
            module.fail_json(msg='improper port format (missing protocol?)')
    else:
        port = None

    # If we weren't provided a zone, then just use the system default
    if module.params['zone'] is not None:
        zone = module.params['zone']
    else:
        if fw_offline:
            zone = fw.get_default_zone()
        else:
            zone = fw.getDefaultZone()

    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:

        transaction = ServiceTransaction(
            fw,
            action_args=(service, timeout),
            zone=zone,
            desired_state=desired_state,
            permanent=permanent,
            immediate=immediate,
            fw_offline=fw_offline
        )

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

    if source is not None:

        transaction = SourceTransaction(
            fw,
            action_args=(source,),
            zone=zone,
            desired_state=desired_state,
            permanent=permanent,
            immediate=immediate,
            fw_offline=fw_offline
        )

        changed, transaction_msgs = transaction.run()
        msgs = msgs + transaction_msgs

    if port is not None:

        transaction = PortTransaction(
            fw,
            action_args=(port, protocol, timeout),
            zone=zone,
            desired_state=desired_state,
            permanent=permanent,
            immediate=immediate,
            fw_offline=fw_offline
        )

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

    if rich_rule is not None:

        transaction = RichRuleTransaction(
            fw,
            action_args=(rich_rule, timeout),
            zone=zone,
            desired_state=desired_state,
            permanent=permanent,
            immediate=immediate,
            fw_offline=fw_offline
        )

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

    if interface is not None:

        transaction = InterfaceTransaction(
            fw,
            action_args=(interface,),
            zone=zone,
            desired_state=desired_state,
            permanent=permanent,
            immediate=immediate,
            fw_offline=fw_offline
        )

        changed, transaction_msgs = transaction.run()
        msgs = msgs + transaction_msgs

    if masquerade is not None:

        transaction = MasqueradeTransaction(
            fw,
            action_args=(),
            zone=zone,
            desired_state=desired_state,
            permanent=permanent,
            immediate=immediate,
            fw_offline=fw_offline
        )

        changed, transaction_msgs = transaction.run()
        msgs = msgs + transaction_msgs

    if fw_offline:
        msgs.append("(offline operation: only on-disk configs were altered)")

    module.exit_json(changed=changed, msg=', '.join(msgs))