Example #1
0
def create_nat_rule(**kwargs):
    nat_rule = NatRule(name=kwargs['rule_name'],
                       description=kwargs['description'],
                       fromzone=kwargs['source_zone'],
                       source=kwargs['source_ip'],
                       tozone=kwargs['destination_zone'],
                       destination=kwargs['destination_ip'],
                       service=kwargs['service'],
                       to_interface=kwargs['to_interface'],
                       nat_type=kwargs['nat_type'])

    # Source translation: Static IP
    if kwargs['snat_type'] in ['static-ip'] and kwargs['snat_static_address']:
        nat_rule.source_translation_type = kwargs['snat_type']
        nat_rule.source_translation_static_translated_address = kwargs[
            'snat_static_address']
        # Bi-directional flag set?
        if kwargs['snat_bidirectional']:
            nat_rule.source_translation_static_bi_directional = kwargs[
                'snat_bidirectional']

    # Source translation: Dynamic IP and port
    elif kwargs['snat_type'] in ['dynamic-ip-and-port']:
        nat_rule.source_translation_type = kwargs['snat_type']
        nat_rule.source_translation_address_type = kwargs['snat_address_type']
        # Interface address?
        if kwargs['snat_interface']:
            nat_rule.source_translation_interface = kwargs['snat_interface']
            # Interface IP?
            if kwargs['snat_interface_address']:
                nat_rule.source_translation_ip_address = kwargs[
                    'snat_interface_address']
        else:
            nat_rule.source_translation_translated_addresses = kwargs[
                'snat_dynamic_address']

    # Source translation: Dynamic IP
    elif kwargs['snat_type'] in ['dynamic-ip']:
        if kwargs['snat_dynamic_address']:
            nat_rule.source_translation_type = kwargs['snat_type']
            nat_rule.source_translation_translated_addresses = kwargs[
                'snat_dynamic_address']
        else:
            return False

    # Destination translation
    if kwargs['dnat_address']:
        nat_rule.destination_translated_address = kwargs['dnat_address']
        if kwargs['dnat_port']:
            nat_rule.destination_translated_port = kwargs['dnat_port']

    # Any tags?
    if 'tag_name' in kwargs:
        nat_rule.tag = kwargs['tag_name']

    return nat_rule
Example #2
0
def main():
    argument_spec = dict(
        ip_address=dict(required=True),
        username=dict(default='admin'),
        password=dict(required=True, no_log=True),
        api_key=dict(no_log=True),
        operation=dict(choices=['add', 'update', 'delete', 'find', 'disable']),
        state=dict(default='present', choices=['present', 'absent']),
        rule_name=dict(required=True),
        description=dict(),
        nat_type=dict(default='ipv4', choices=['ipv4', 'nat64', 'nptv6']),
        tag_name=dict(),
        source_zone=dict(type='list'),
        source_ip=dict(type='list', default=['any']),
        destination_zone=dict(),
        destination_ip=dict(type='list', default=['any']),
        service=dict(default='any'),
        to_interface=dict(default='any'),
        snat_type=dict(
            choices=['static-ip', 'dynamic-ip-and-port', 'dynamic-ip']),
        snat_address_type=dict(
            choices=['interface-address', 'translated-address'],
            default='interface-address'),
        snat_static_address=dict(),
        snat_dynamic_address=dict(type='list'),
        snat_interface=dict(),
        snat_interface_address=dict(),
        snat_bidirectional=dict(type='bool', default=False),
        dnat_address=dict(),
        dnat_port=dict(),
        devicegroup=dict(default='shared'),
        rulebase=dict(default='pre-rulebase',
                      choices=['pre-rulebase', 'post-rulebase']),
        vsys=dict(default='vsys1'),
        location=dict(default='bottom',
                      choices=['top', 'bottom', 'before', 'after']),
        existing_rule=dict(),
        commit=dict(type='bool', default=True))

    module = AnsibleModule(argument_spec=argument_spec,
                           supports_check_mode=False,
                           required_one_of=[['api_key', 'password']])
    if not HAS_LIB:
        module.fail_json(msg='Missing required libraries.')
    elif not hasattr(NatRule, 'move'):
        module.fail_json(msg='Python library pandevice needs to be updated.')

    # Get firewall / Panorama auth.
    auth = [
        module.params[x]
        for x in ('ip_address', 'username', 'password', 'api_key')
    ]

    # Get object params.
    rule_name = module.params['rule_name']
    description = module.params['description']
    tag_name = module.params['tag_name']
    source_zone = module.params['source_zone']
    source_ip = module.params['source_ip']
    destination_zone = module.params['destination_zone']
    destination_ip = module.params['destination_ip']
    service = module.params['service']
    to_interface = module.params['to_interface']
    nat_type = module.params['nat_type']
    snat_type = module.params['snat_type']
    snat_address_type = module.params['snat_address_type']
    snat_static_address = module.params['snat_static_address']
    snat_dynamic_address = module.params['snat_dynamic_address']
    snat_interface = module.params['snat_interface']
    snat_interface_address = module.params['snat_interface_address']
    snat_bidirectional = module.params['snat_bidirectional']
    dnat_address = module.params['dnat_address']
    dnat_port = module.params['dnat_port']

    # Get other info.
    operation = module.params['operation']
    state = module.params['state']
    devicegroup = module.params['devicegroup']
    vsys = module.params['vsys']
    commit = module.params['commit']
    location = module.params['location']
    existing_rule = module.params['existing_rule']

    # Sanity check the location / existing_rule params.
    if location in ('before', 'after') and not existing_rule:
        module.fail_json(
            msg=
            "'existing_rule' must be specified if location is 'before' or 'after'."
        )

    # Create the device with the appropriate pandevice type
    con = PanDevice.create_from_device(*auth)

    # Set vsys if firewall, device group if Panorama, and set the rulebase.
    parent = con
    if hasattr(con, 'refresh_devices'):
        # Panorama
        if devicegroup not in (None, 'shared'):
            dev_group = get_devicegroup(con, devicegroup)
            if not dev_group:
                module.fail_json(
                    msg=
                    '\'%s\' device group not found in Panorama. Is the name correct?'
                    % devicegroup)
            parent = dev_group
        if module.params['rulebase'] in (None, 'pre-rulebase'):
            rulebase = PreRulebase()
            parent.add(rulebase)
            parent = rulebase
        elif module.params['rulebase'] == 'post-rulebase':
            rulebase = PostRulebase()
            parent.add(rulebase)
            parent = rulebase
    else:
        # Firewall
        parent.vsys = vsys
        rulebase = Rulebase()
        parent.add(rulebase)
        parent = rulebase

    # Get the current NAT rules.
    try:
        rules = NatRule.refreshall(parent)
    except PanDeviceError as e:
        module.fail_json(msg='Failed NAT refreshall: {0}'.format(e))

    # Create the desired rule.
    new_rule = create_nat_rule(rule_name=rule_name,
                               description=description,
                               tag_name=tag_name,
                               source_zone=source_zone,
                               destination_zone=destination_zone,
                               source_ip=source_ip,
                               destination_ip=destination_ip,
                               service=service,
                               to_interface=to_interface,
                               nat_type=nat_type,
                               snat_type=snat_type,
                               snat_address_type=snat_address_type,
                               snat_static_address=snat_static_address,
                               snat_dynamic_address=snat_dynamic_address,
                               snat_interface=snat_interface,
                               snat_interface_address=snat_interface_address,
                               snat_bidirectional=snat_bidirectional,
                               dnat_address=dnat_address,
                               dnat_port=dnat_port)

    if not new_rule:
        module.fail_json(msg='Incorrect NAT rule params specified; quitting')
    parent.add(new_rule)

    # Perform the desired operation.
    changed = False
    do_move = False
    if state == 'present':
        match = find_rule(rules, new_rule)
        if match is not None:
            if not match.equal(new_rule):
                try:
                    new_rule.apply()
                except PanDeviceError as e:
                    module.fail_json(
                        msg='Failed "present" apply: {0}'.format(e))
                else:
                    changed = True
                    do_move = True
        else:
            try:
                new_rule.create()
            except PanDeviceError as e:
                module.fail_json(msg='Failed "present" create: {0}'.format(e))
            else:
                changed = True
                do_move = True
    elif state == 'absent':
        match = find_rule(rules, new_rule)
        if match is not None:
            try:
                new_rule.delete()
            except PanDeviceError as e:
                module.fail_json(msg='Failed "absent" delete: {0}'.format(e))
            else:
                changed = True
    elif operation == "find":
        # Search for the rule
        match = find_rule(rules, new_rule)
        # If found, format and return the result
        if match:
            match_dict = xmltodict.parse(match.element_str())
            module.exit_json(stdout_lines=json.dumps(match_dict, indent=2),
                             msg='Rule matched')
        else:
            module.fail_json(
                msg='Rule \'%s\' not found. Is the name correct?' % rule_name)
    elif operation == "delete":
        # Search for the object
        match = find_rule(rules, new_rule)
        if match is None:
            module.fail_json(
                msg='Rule \'%s\' not found. Is the name correct?' % rule_name)
        try:
            new_rule.delete()
        except PanDeviceError as e:
            module.fail_json(msg='Failed "delete" delete: {0}'.format(e))
        else:
            changed = True
    elif operation == "add":
        # Look for required parameters
        if not source_zone or not destination_zone or not nat_type:
            module.fail_json(
                msg=
                'Missing parameter. Required: source_zone, destination_zone, nat_type'
            )
        # Search for the rule. Fail if found.
        match = find_rule(rules, new_rule)
        if match:
            module.fail_json(
                msg=
                'Rule \'%s\' already exists. Use operation: \'update\' to change it.'
                % rule_name)
        try:
            new_rule.create()
        except PanDeviceError as e:
            module.fail_json(msg='Failed "add" create: {0}'.format(e))
        else:
            changed = True
            do_move = True
    elif operation == 'update':
        # Search for the rule. Update if found.
        match = find_rule(rulebase, rule_name)
        if not match:
            module.fail_json(
                msg=
                'Rule \'%s\' does not exist. Use operation: \'add\' to add it.'
                % rule_name)
        try:
            new_rule.apply()
        except PanDeviceError as e:
            module.fail_json(msg='Failed "update" apply: {0}'.format(e))
        else:
            changed = True
            do_move = True
    elif operation == 'disable':
        # Search for the rule, disable if found.
        match = find_rule(rules, new_rule)
        if not match:
            module.fail_json(msg='Rule \'%s\' does not exist.' % rule_name)
        if not match.disabled:
            match.disabled = True
            try:
                match.update('disabled')
            except PanDeviceError as e:
                module.fail_json(msg='Failed "disabled": {0}'.format(e))
            else:
                changed = True

    # Optional move.
    if do_move:
        try:
            new_rule.move(location, existing_rule)
        except PanDeviceError as e:
            if '{0}'.format(e) not in ACCEPTABLE_MOVE_ERRORS:
                module.fail_json(msg='Failed move: {0}'.format(e))
        else:
            changed = True

    # Optional commit.
    if changed and commit:
        try:
            con.commit(sync=True)
        except PanDeviceError as e:
            module.fail_json(msg='Failed commit: {0}'.format(e))

    module.exit_json(changed=changed, msg='Done')
Example #3
0
def main():
    helper = get_connection(
        vsys=True,
        device_group=True,
        rulebase=True,
        error_on_shared=True,
        argument_spec=dict(
            rule_name=dict(required=True),
            description=dict(),
            nat_type=dict(default='ipv4', choices=['ipv4', 'nat64', 'nptv6']),
            source_zone=dict(type='list'),
            source_ip=dict(type='list', default=['any']),
            destination_zone=dict(),
            destination_ip=dict(type='list', default=['any']),
            to_interface=dict(default='any'),
            service=dict(default='any'),
            snat_type=dict(
                choices=['static-ip', 'dynamic-ip-and-port', 'dynamic-ip']),
            snat_address_type=dict(
                choices=['interface-address', 'translated-address'],
                default='interface-address'),
            snat_static_address=dict(),
            snat_dynamic_address=dict(type='list'),
            snat_interface=dict(),
            snat_interface_address=dict(),
            snat_bidirectional=dict(type='bool'),
            dnat_address=dict(),
            dnat_port=dict(),
            tag=dict(type='list'),
            state=dict(default='present',
                       choices=['present', 'absent', 'enable', 'disable']),
            location=dict(choices=['top', 'bottom', 'before', 'after']),
            existing_rule=dict(),
            commit=dict(type='bool', default=True),

            # TODO(gfreeman) - remove later.
            tag_name=dict(),
            devicegroup=dict(),
            operation=dict(),
        ),
    )

    module = AnsibleModule(
        argument_spec=helper.argument_spec,
        supports_check_mode=True,
        required_one_of=helper.required_one_of,
    )

    # TODO(gfreeman) - remove later.
    if module.params['operation'] is not None:
        module.fail_json(msg='Param "operation" is removed; use "state"')
    if module.params['devicegroup'] is not None:
        module.deprecate(
            'Param "devicegroup" is deprecated; use "device_group"', '2.12')
        module.params['device_group'] = module.params['devicegroup']
    if module.params['tag_name'] is not None:
        tag_val = module.params['tag_name']
        module.deprecate('Param "tag_name" is deprecated; use "tag"', '2.12')
        if module.params['tag']:
            module.fail_json(
                msg='Both "tag" and "tag_name" specified, use only one')
    else:
        tag_val = module.params['tag']

    parent = helper.get_pandevice_parent(module)

    # Get object params.
    rule_name = module.params['rule_name']
    description = module.params['description']
    source_zone = module.params['source_zone']
    source_ip = module.params['source_ip']
    destination_zone = module.params['destination_zone']
    destination_ip = module.params['destination_ip']
    service = module.params['service']
    to_interface = module.params['to_interface']
    nat_type = module.params['nat_type']
    snat_type = module.params['snat_type']
    snat_address_type = module.params['snat_address_type']
    snat_static_address = module.params['snat_static_address']
    snat_dynamic_address = module.params['snat_dynamic_address']
    snat_interface = module.params['snat_interface']
    snat_interface_address = module.params['snat_interface_address']
    snat_bidirectional = module.params['snat_bidirectional']
    dnat_address = module.params['dnat_address']
    dnat_port = module.params['dnat_port']

    # Get other info.
    state = module.params['state']
    location = module.params['location']
    existing_rule = module.params['existing_rule']

    # Sanity check the location / existing_rule params.
    if location in ('before', 'after') and not existing_rule:
        module.fail_json(
            msg=
            "'existing_rule' must be specified if location is 'before' or 'after'."
        )

    # Get the current NAT rules.
    try:
        rules = NatRule.refreshall(parent)
    except PanDeviceError as e:
        module.fail_json(msg='Failed NAT refreshall: {0}'.format(e))

    # Create the desired rule.
    new_rule = create_nat_rule(rule_name=rule_name,
                               description=description,
                               tag_val=tag_val,
                               source_zone=source_zone,
                               destination_zone=destination_zone,
                               source_ip=source_ip,
                               destination_ip=destination_ip,
                               service=service,
                               to_interface=to_interface,
                               nat_type=nat_type,
                               snat_type=snat_type,
                               snat_address_type=snat_address_type,
                               snat_static_address=snat_static_address,
                               snat_dynamic_address=snat_dynamic_address,
                               snat_interface=snat_interface,
                               snat_interface_address=snat_interface_address,
                               snat_bidirectional=snat_bidirectional,
                               dnat_address=dnat_address,
                               dnat_port=dnat_port)

    if not new_rule:
        module.fail_json(msg='Incorrect NAT rule params specified; quitting')

    # Perform the desired operation.
    changed = False
    if state in ('enable', 'disable'):
        for rule in rules:
            if rule.name == new_rule.name:
                break
        else:
            module.fail_json(
                msg='Rule "{0}" not present'.format(new_rule.name))
        if state == 'enable' and rule.disabled:
            changed = True
        elif state == 'disable' and not rule.disabled:
            changed = True
        if changed:
            rule.disabled = not rule.disabled
            if not module.check_mode:
                try:
                    rule.update('disabled')
                except PanDeviceError as e:
                    module.fail_json(msg='Failed enable: {0}'.format(e))
    else:
        parent.add(new_rule)
        changed = helper.apply_state(new_rule, rules, module)
        if state == 'present':
            changed |= helper.apply_position(new_rule, location, existing_rule,
                                             module)

    if changed and module.params['commit']:
        helper.commit(module)

    module.exit_json(changed=changed, msg='Done')
Example #4
0
def main():
    helper = get_connection(
        vsys=True,
        device_group=True,
        rulebase=True,
        with_classic_provider_spec=True,
        error_on_shared=True,
        required_one_of=[
            ['listing', 'rule_name', 'rule_regex', 'uuid'],
        ],
        argument_spec=dict(
            listing=dict(type='bool'),
            rule_name=dict(),
            rule_regex=dict(),
            uuid=dict(),
        ),
    )

    module = AnsibleModule(
        argument_spec=helper.argument_spec,
        supports_check_mode=False,
        required_one_of=helper.required_one_of,
    )

    parent = helper.get_pandevice_parent(module)

    renames = (
        ('name', 'rule_name'),
        ('fromzone', 'source_zone'),
        ('tozone', 'destination_zone'),
        ('source', 'source_ip'),
        ('destination', 'destination_ip'),
        ('source_translation_type', 'snat_type'),
        ('source_translation_static_translated_address',
         'snat_static_address'),
        ('source_translation_static_bi_directional', 'snat_bidirectional'),
        ('source_translation_address_type', 'snat_address_type'),
        ('source_translation_interface', 'snat_interface'),
        ('source_translation_ip_address', 'snat_interface_address'),
        ('source_translation_translated_addresses', 'snat_dynamic_address'),
        ('destination_translated_address', 'dnat_address'),
        ('destination_translated_port', 'dnat_port'),
        ('tag', 'tag_val'),
    )

    if module.params['rule_name']:
        obj = NatRule(module.params['rule_name'])
        parent.add(obj)
        try:
            obj.refresh()
        except PanDeviceError as e:
            module.fail_json(msg='Failed refresh: {0}'.format(e))

        module.exit_json(
            changed=False,
            object=helper.to_module_dict(obj, renames),
        )

    try:
        listing = NatRule.refreshall(parent)
    except PanDeviceError as e:
        module.fail_json(msg='Failed refreshall: {0}'.format(e))

    if module.params['uuid']:
        for x in listing:
            if x.uuid == module.params['uuid']:
                module.exit_json(
                    changed=False,
                    object=helper.to_module_dict(x, renames),
                )
        module.fail_json(
            msg='No rule with uuid "{0}"'.format(module.params['uuid']))

    ans = []
    matcher = None
    if module.params['rule_regex']:
        try:
            matcher = re.compile(module.params['rule_regex'])
        except Exception as e:
            module.fail_json(msg='Invalid regex: {0}'.format(e))

    ans = [
        helper.to_module_dict(x, renames) for x in listing
        if module.params['listing'] or matcher.search(x.uid) is not None
    ]

    module.exit_json(changed=False, listing=ans)
Example #5
0
def main():
    helper = get_connection(
        vsys=True,
        rulebase=True,
        with_classic_provider_spec=True,
        panorama_error='Panorama is not supported',
        argument_spec=dict(
            rule_type=dict(default='security', choices=['security', 'nat']),
            source_zone=dict(),
            source_ip=dict(required=True),
            source_port=dict(type='int'),
            source_user=dict(),
            to_interface=dict(),
            destination_zone=dict(),
            destination_ip=dict(required=True),
            destination_port=dict(required=True, type='int'),
            application=dict(),
            protocol=dict(required=True, type='int'),
            category=dict(),

            # TODO(gfreeman) - Remove this in the next role release.
            vsys_id=dict(),
        ),
    )

    module = AnsibleModule(
        argument_spec=helper.argument_spec,
        supports_check_mode=False,
        required_one_of=helper.required_one_of,
    )

    # TODO(gfreeman) - Remove this in the next role release.
    if not HAS_LIB:
        module.fail_json(msg='Missing xmltodict library')
    if module.params['vsys_id'] is not None:
        module.fail_json(msg='Param "vsys_id" is removed; use vsys')

    parent = helper.get_pandevice_parent(module)

    params = (
        ('application', 'application', [
            'security',
        ]),
        ('category', 'category', [
            'security',
        ]),
        ('destination_ip', 'destination', ['security', 'nat']),
        ('destination_port', 'destination-port', ['security', 'nat']),
        ('source_zone', 'from', ['security', 'nat']),
        ('protocol', 'protocol', ['security', 'nat']),
        ('source_ip', 'source', ['security', 'nat']),
        ('source_user', 'source-user', [
            'security',
        ]),
        ('destination_zone', 'to', ['security', 'nat']),
        ('to_interface', 'to-interface', [
            'nat',
        ]),
    )

    cmd = []
    rtype = module.params['rule_type']

    if rtype == 'security':
        cmd.append('test security-policy-match')
        listing = SecurityRule.refreshall(parent)
    else:
        cmd.append('test nat-policy-match')
        listing = NatRule.refreshall(parent)

    for ansible_param, cmd_param, rule_types in params:
        if rtype not in rule_types or module.params[ansible_param] is None:
            continue
        cmd.append('{0} "{1}"'.format(cmd_param, module.params[ansible_param]))

    # Submit the op command with the appropriate test string
    test_string = ' '.join(cmd)
    try:
        response = helper.device.op(cmd=test_string, vsys=parent.vsys)
    except PanDeviceError as e:
        module.fail_json(msg='Failed "{0}": {1}'.format(test_string, e))

    elm = response.find('./result/rules/entry')
    if elm is not None:
        try:
            rule_name = elm.attrib['name']
        except KeyError:
            rule_name = elm.text
    else:
        module.exit_json(msg='No matching {0} rule.'.format(rtype))

    for x in listing:
        if x.name != rule_name:
            continue
        module.deprecate(
            'The "stdout_lines" output is deprecated; use "rule" instead',
            '2.12')
        module.exit_json(
            stdout_lines=json.dumps(xmltodict.parse(x.element_str()),
                                    indent=2),
            msg='Rule matched',
            rule=x.about(),
        )

    module.fail_json(
        msg='Matched "{0}" with "{1}", but wasn\'t in rulebase'.format(
            rule_name, test_string))
def main():
    helper = get_connection(
        vsys=True,
        with_classic_provider_spec=True,
        panorama_error='Panorama is not supported',
        argument_spec=dict(
            rule_type=dict(default='security', choices=['security', 'nat']),
            source_zone=dict(),
            source_ip=dict(required=True),
            source_port=dict(type='int'),
            source_user=dict(),
            to_interface=dict(),
            destination_zone=dict(),
            destination_ip=dict(required=True),
            destination_port=dict(required=True, type='int'),
            application=dict(),
            protocol=dict(required=True, type='int'),
            category=dict(),

            # TODO(gfreeman) - Remove this in the next role release.
            vsys_id=dict(),
            rulebase=dict(),
        ),
    )

    module = AnsibleModule(
        argument_spec=helper.argument_spec,
        supports_check_mode=False,
        required_one_of=helper.required_one_of,
    )

    # TODO(gfreeman) - Remove this in the next role release.
    if not HAS_LIB:
        module.fail_json(msg='Missing xmltodict library')
    if module.params['vsys_id'] is not None:
        module.fail_json(msg='Param "vsys_id" is removed; use vsys')
    if module.params['rulebase'] is not None:
        module.deprecate(
            'Param "rulebase" is deprecated and may safely be removed from your playbook',
            '2.12',
        )

    parent = helper.get_pandevice_parent(module)

    params = (
        ('application', 'application', [
            'security',
        ]),
        ('category', 'category', [
            'security',
        ]),
        ('destination_ip', 'destination', ['security', 'nat']),
        ('destination_port', 'destination-port', ['security', 'nat']),
        ('source_zone', 'from', ['security', 'nat']),
        ('protocol', 'protocol', ['security', 'nat']),
        ('source_ip', 'source', ['security', 'nat']),
        ('source_user', 'source-user', [
            'security',
        ]),
        ('destination_zone', 'to', ['security', 'nat']),
        ('to_interface', 'to-interface', [
            'nat',
        ]),
    )

    cmd = []
    rtype = module.params['rule_type']
    vsys = module.params['vsys']

    # This module used to refreshall on either the security rules or the NAT
    # rules, however if the rule matched came from Panorama, then this module
    # failed.  To account for this, instead directly query the 3 path locations
    # where the rule could exist, and return that instead.  When pandevice
    # supports querying the firewall for the pushed down Panorama config, change
    # this back to using normal pandevice objects.
    rule_locations = (
        (
            'panorama-pre-rulebase',
            "/config/panorama/vsys/entry[@name='{0}']/pre-rulebase",
        ),
        (
            'firewall-rulebase',
            "/config/devices/entry[@name='localhost.localdomain']/vsys/entry[@name='{0}']/rulebase",
        ),
        (
            'panorama-post-rulebase',
            "/config/panorama/vsys/entry[@name='{0}']/post-rulebase",
        ),
    )
    suffix = "/{0}/rules/entry[@name='{1}']"

    if rtype == 'security':
        cmd.append('test security-policy-match')
        obj = SecurityRule()
    else:
        cmd.append('test nat-policy-match')
        obj = NatRule()
    parent.add(obj)

    for ansible_param, cmd_param, rule_types in params:
        if rtype not in rule_types or module.params[ansible_param] is None:
            continue
        cmd.append('{0} "{1}"'.format(cmd_param, module.params[ansible_param]))

    # Submit the op command with the appropriate test string
    test_string = ' '.join(cmd)
    try:
        response = helper.device.op(cmd=test_string, vsys=parent.vsys)
    except PanDeviceError as e:
        module.fail_json(msg='Failed "{0}": {1}'.format(test_string, e))

    elm = response.find('./result/rules/entry')
    elm2 = response.find('./result/msg/line')
    if elm is not None:
        try:
            rule_name = elm.attrib['name']
        except KeyError:
            rule_name = elm.text
    elif elm2 is not None:
        '''
        From 8.1 (matching Panorama rule):
        NOTE: Ending newlines have been truncated to appease codestyle rules.

<response cmd="status" status="success"><result><msg><line><![CDATA["Rule Name; index: 1" {
        from L3-trust;
        source [ 10.0.0.1 1.1.1.1 ];
        source-region none;
        to L3-untrust;
        destination [ 8.8.8.8 ];
        destination-region none;
        user any;
        category any;
        application/service [0:any/tcp/any/21 1:any/tcp/any/22 ];
        action allow;
        icmp-unreachable: no
        terminal yes;
}

]]></line></msg></result></response>
        '''
        rule_name = elm2.text.split(';')[0].split('"')[1].strip()
    else:
        msg = 'No matching {0} rule; resp = {1}'.format(
            rtype,
            ET.tostring(response, enoding='utf-8'),
        )
        module.exit_json(msg=msg)
    '''
    Example response (newlines after newlines to appease pycodestyle line length limitations):

    <response cmd="status" status="success"><result><rules>\n
\t<entry>deny all and log; index: 3</entry>\n
</rules>\n
</result></response>
    '''
    tokens = rule_name.split(';')
    if len(tokens) == 2 and tokens[1].startswith(' index: '):
        rule_name = tokens[0]

    fw = obj.nearest_pandevice()
    for rulebase, prefix in rule_locations:
        xpath = prefix.format(vsys) + suffix.format(rtype, rule_name)
        ans = fw.xapi.get(xpath)
        if ans is None:
            continue
        rules = obj.refreshall_from_xml(ans.find('./result'))
        if rules:
            x = rules[0]
            module.deprecate(
                'The "stdout_lines" output is deprecated; use "rule" instead',
                '2.12',
            )
            module.exit_json(
                stdout_lines=json.dumps(xmltodict.parse(x.element_str()),
                                        indent=2),
                msg='Rule matched',
                rule=x.about(),
                rulebase=rulebase,
            )

    module.fail_json(
        msg='Matched "{0}" with "{1}", but wasn\'t in any rulebase'.format(
            rule_name, test_string))
Example #7
0
def configure_policy(device):
    web_srv = AddressObject(name='web-srv', value='192.168.45.5')
    db_srv = AddressObject(name='db-srv', value='192.168.35.5')

    device.add(web_srv)
    device.add(db_srv)

    web_srv.create()
    db_srv.create()

    service_tcp_221 = ServiceObject(name='service-tcp-221',
                                    protocol='tcp',
                                    destination_port='221')
    service_tcp_222 = ServiceObject(name='service-tcp-222',
                                    protocol='tcp',
                                    destination_port='222')

    device.add(service_tcp_221)
    device.add(service_tcp_222)

    service_tcp_221.create()
    service_tcp_222.create()

    rulebase = Rulebase()
    device.add(rulebase)

    allow_ping = SecurityRule(name='Allow ping',
                              fromzone=['any'],
                              source=['any'],
                              tozone=['any'],
                              destination=['any'],
                              application=['ping'],
                              service=['application-default'],
                              action='allow')
    ssh_inbound = SecurityRule(name='SSH inbound',
                               fromzone=['untrust'],
                               source=['any'],
                               tozone=['web', 'db'],
                               destination=['any'],
                               application=['ping', 'ssh'],
                               service=['service-tcp-221', 'service-tcp-222'],
                               action='allow')
    web_inbound = SecurityRule(name='Web inbound',
                               fromzone=['untrust'],
                               source=['any'],
                               tozone=['web'],
                               destination=['any'],
                               application=['any'],
                               service=['service-http'],
                               action='allow')
    web_to_db = SecurityRule(name='Web to DB',
                             fromzone=['any'],
                             source=['web-srv'],
                             tozone=['any'],
                             destination=['db-srv'],
                             application=['mysql'],
                             service=['application-default'],
                             action='allow')
    allow_outbound = SecurityRule(name='Allow outbound',
                                  fromzone=['web', 'db'],
                                  source=['any'],
                                  tozone=['untrust'],
                                  destination=['any'],
                                  application=['any'],
                                  service=['application-default'],
                                  action='allow')

    rulebase.add(allow_ping)
    rulebase.add(ssh_inbound)
    rulebase.add(web_inbound)
    rulebase.add(web_to_db)
    rulebase.add(allow_outbound)

    allow_ping.create()
    ssh_inbound.create()
    web_inbound.create()
    web_to_db.create()
    allow_outbound.create()

    web_ssh = NatRule(name='Web SSH',
                      fromzone=['untrust'],
                      source=['any'],
                      tozone=['untrust'],
                      destination=['192.168.55.20'],
                      service='service-tcp-221',
                      source_translation_type='dynamic-ip-and-port',
                      source_translation_address_type='interface-address',
                      source_translation_interface='ethernet1/2',
                      destination_translated_address='web-srv',
                      destination_translated_port='22')
    db_ssh = NatRule(name='DB SSH',
                     fromzone=['untrust'],
                     source=['any'],
                     tozone=['untrust'],
                     destination=['192.168.55.20'],
                     service='service-tcp-222',
                     source_translation_type='dynamic-ip-and-port',
                     source_translation_address_type='interface-address',
                     source_translation_interface='ethernet1/3',
                     destination_translated_address='db-srv',
                     destination_translated_port='22')
    wordpress_nat = NatRule(
        name='WordPress NAT',
        fromzone=['untrust'],
        source=['any'],
        tozone=['untrust'],
        destination=['192.168.55.20'],
        service='service-http',
        source_translation_type='dynamic-ip-and-port',
        source_translation_address_type='interface-address',
        source_translation_interface='ethernet1/2',
        destination_translated_address='web-srv')
    outgoing_traffic = NatRule(
        name='Outgoing traffic',
        fromzone=['web', 'db'],
        source=['any'],
        tozone=['untrust'],
        destination=['any'],
        source_translation_type='dynamic-ip-and-port',
        source_translation_address_type='interface-address',
        source_translation_interface='ethernet1/1',
    )

    rulebase.add(web_ssh)
    rulebase.add(db_ssh)
    rulebase.add(wordpress_nat)
    rulebase.add(outgoing_traffic)

    web_ssh.create()
    db_ssh.create()
    wordpress_nat.create()
    outgoing_traffic.create()