예제 #1
0
def main():
    # Create a connection to a firewall and a rulebase to work inside
    fw = Firewall(HOSTNAME, USERNAME, PASSWORD)
    rulebase = fw.add(Rulebase())

    # Fetch all the security rules from the firewall into a list
    rules = SecurityRule.refreshall(rulebase, add=False)

    print(f"Checking {len(rules)} rules...")

    # Iterate over the list and collect names of rules that are
    # missing the log forwarding profile
    for rule in rules:
        if rule.log_setting != LOG_PROFILE:
            print(f"Found rule to configure: {rule.name}")
            rulebase.add(SecurityRule(rule.name, log_setting=LOG_PROFILE))

    # At this point, we've added SecurityRule objects to the Firewall
    # for each rule that doesn't have the right log forwarding profile.
    # The next step is to push all that configuration to the live device
    # at once using the 'create_similar()' method.

    # This takes the first SecurityRule to change and calls 'create_similar()'.
    # When 'create_similar()' is called, all the SecurityRules are pushed
    # to the firewall at once. The method is additive, so the existing security
    # rules will not change, except for the 'log_setting' parameter which
    # contains the log forwarding profile name.
    if len(rulebase.children) == 0:
        print("No changes needed")
        return

    rulebase.children[0].create_similar()

    # Now, trigger a commit
    # In this case, we'll wait for the commit to finish and trigger an exception
    # if the commit finished with any errors.
    print("Starting commit")
    fw.commit(sync=True, exception=True)
    print("Commit finished successfully")
예제 #2
0
def test_rulebase_hit_count_refresh_for_multiple_attached_security_rules():
    n1 = "foo"
    elm1 = _hit_count_elm(
        name=n1,
        hit_count=42,
        rule_creation_timestamp=1599752499,
        rule_modification_timestamp=1599752499,
    )
    e1 = HitCount(name=n1, elm=elm1)

    n2 = "bar"
    elm2 = _hit_count_elm(
        name=n2,
        hit_count=24,
        rule_creation_timestamp=1234,
        rule_modification_timestamp=5678,
    )
    e2 = HitCount(name=n2, elm=elm2)

    fw, rb = _hit_count_fw_setup(elm1, elm2)
    o1 = SecurityRule(n1)
    rb.add(o1)

    o2 = SecurityRule(n2)
    rb.add(o2)

    assert not o1.opstate.hit_count.hit_count
    assert not o2.opstate.hit_count.hit_count

    ans = rb.opstate.hit_count.refresh("security")

    assert len(ans) == 2
    assert o1.uid in ans
    _hit_count_eq(e1, ans[o1.uid])
    _hit_count_eq(e1, o1.opstate.hit_count)
    assert o2.uid in ans
    _hit_count_eq(e2, ans[o2.uid])
    _hit_count_eq(e2, o2.opstate.hit_count)
예제 #3
0
def test_current_audit_comment():
    expected = "Hello, world"

    fw = _fw()
    rb = Rulebase()
    fw.add(rb)
    obj = SecurityRule("foo")
    rb.add(obj)
    fw.op = mock.Mock(return_value=ET.fromstring(
        "\n".join([
            "<response>",
            "<result>",
            "<entry>",
            "<xpath>{0}</xpath>".format(obj.xpath()),
            "<dirtyId>17</dirtyId>",
            "<comment>{0}</comment>".format(expected),
            "<prevdirtyId>0</prevdirtyId>",
            "</entry>",
            "</result>",
            "</response>",
        ]), ), )

    assert expected == obj.opstate.audit_comment.current()
예제 #4
0
def test_rulebase_hit_count_refresh_for_all_rules_updates_attached_rule():
    n1 = "intrazone-default"
    elm1 = _hit_count_elm(
        name=n1,
        hit_count=1,
        rule_creation_timestamp=1599752499,
        rule_modification_timestamp=1599752499,
    )
    e1 = HitCount(name=n1, elm=elm1)

    n2 = "interzone-default"
    elm2 = _hit_count_elm(
        name=n2,
        hit_count=2,
        rule_creation_timestamp=1599752499,
        rule_modification_timestamp=1599752499,
    )
    e2 = HitCount(name=n2, elm=elm2)

    name = "bar"
    elm3 = _hit_count_elm(
        name=name,
        hit_count=24,
        rule_creation_timestamp=1234,
        rule_modification_timestamp=5678,
    )
    expected = HitCount(name=name, elm=elm3)

    fw, rb = _hit_count_fw_setup(elm1, elm2, elm3)
    o = SecurityRule(name)
    rb.add(o)

    assert not o.opstate.hit_count.hit_count

    ans = rb.opstate.hit_count.refresh("security", all_rules=True)

    assert len(ans) == 3
    assert n1 in ans
    _hit_count_eq(e1, ans[n1])
    assert n2 in ans
    _hit_count_eq(e2, ans[n2])
    assert o.uid in ans
    _hit_count_eq(expected, ans[o.uid])
    _hit_count_eq(expected, o.opstate.hit_count)
예제 #5
0
def test_rulebase_hit_count_refresh_for_single_attached_security_rule():
    name = "intrazone-default"
    elm = _hit_count_elm(
        name=name,
        rule_creation_timestamp=1599752499,
        rule_modification_timestamp=1599752499,
    )
    expected = HitCount(name=name, elm=elm)

    fw, rb = _hit_count_fw_setup(elm)
    o = SecurityRule(name)
    rb.add(o)

    assert not o.opstate.hit_count.rule_creation_timestamp

    ans = rb.opstate.hit_count.refresh("security")

    assert len(ans) == 1
    assert o.uid in ans
    _hit_count_eq(expected, ans[o.uid])
    _hit_count_eq(expected, o.opstate.hit_count)
예제 #6
0
def test_security_rule_hit_count_refresh():
    name = "foo"
    elm = _hit_count_elm(
        name=name,
        hit_count=1,
        last_hit_timestamp=21,
        last_reset_timestamp=22,
        first_hit_timestamp=23,
        rule_creation_timestamp=24,
        rule_modification_timestamp=25,
    )
    expected = HitCount(name=name, elm=elm)

    fw, rb = _hit_count_fw_setup(elm)
    o = SecurityRule(name)
    rb.add(o)

    assert not o.opstate.hit_count.rule_creation_timestamp

    o.opstate.hit_count.refresh()

    _hit_count_eq(expected, o.opstate.hit_count)
예제 #7
0
def main():
    helper = get_connection(
        vsys=True,
        device_group=True,
        rulebase=True,
        with_classic_provider_spec=True,
        error_on_firewall_shared=True,
        argument_spec=dict(
            rule_name=dict(),
            names=dict(type='list', elements='str'),
            details=dict(default=False, type='bool', aliases=['all_details']),
            match_rules=dict(type='dict',
                             options=dict(source_zone=dict(type='str',
                                                           required=True),
                                          source_ip=dict(type='str',
                                                         required=True),
                                          source_user=dict(type='str'),
                                          destination_zone=dict(type='str',
                                                                required=True),
                                          destination_ip=dict(type='str',
                                                              required=True),
                                          destination_port=dict(type='str',
                                                                required=True),
                                          protocol=dict(
                                              type='str',
                                              choices=['tcp', 'udp', 'icmp'],
                                              required=True),
                                          application=dict(type='str'),
                                          category=dict(type='str'),
                                          show_all=dict(type='bool'))),
        ),
    )

    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'),
        ('type', 'rule_type'),
        ('tag', 'tag_name'),
        ('group', 'group_profile'),
        ('virus', 'antivirus'),
    )

    names = module.params['names']
    details = module.params['details']

    if module.params.get('all_details'):
        module.deprecate('Please use details instead of all_details.',
                         version='3.0.0',
                         collection_name='paloaltonetworks.panos')

    if module.params['rule_name']:
        module.deprecate(
            'Please use the names parameter instead of rule_name.',
            version='3.0.0',
            collection_name='paloaltonetworks.panos')

        names = [module.params['rule_name']]

    if module.params['match_rules']:
        names = match_rules(module, parent.nearest_pandevice())

    if names is None and details is False:
        # Didn't specify specific rules, so just return list of rule names.
        listing = SecurityRule.refreshall(parent, name_only=True)
        module.exit_json(changed=False, rule_names=[r.name for r in listing])

    elif module.params['match_rules'] and details is False:
        # match_rules was set, but not details, so return list of rule names.
        module.exit_json(changed=False, rule_names=names)

    else:
        # Return full policy details.  Will return full policy details even if
        # details is False if specific rules are given, because returning the
        # user's list of rules back to them is pointless.
        if names is None:
            listing = SecurityRule.refreshall(parent)
            rules = [rule.about() for rule in listing]
        else:
            rules = []
            for name in names:
                rule = SecurityRule(name)
                parent.add(rule)

                try:
                    rule.refresh()
                except PanDeviceError as e:
                    module.fail_json(msg='Failed refresh: {0}'.format(e))

                rules.append(rule.about())

        # Fix up names in returned dict.
        for rule in rules:
            for p, a in renames:
                rule[a] = rule[p]
                del rule[p]

        module.exit_json(changed=False, rule_details=rules)
예제 #8
0
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',
            version='3.0.0',
            collection_name='paloaltonetworks.panos')

    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, encoding='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',
                version='3.0.0',
                collection_name='paloaltonetworks.panos',
            )
            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))
예제 #9
0
def test_audit_comment_history():
    fw = _fw()
    rb = Rulebase()
    fw.add(rb)
    obj = SecurityRule("my policy")
    rb.add(obj)
    fw.xapi.log = mock.Mock(return_value=ET.fromstring("""
<response status="success"><result>
  <job>
    <tenq>10:28:38</tenq>
    <tdeq>10:28:38</tdeq>
    <tlast>10:28:38</tlast>
    <status>FIN</status>
    <id>729</id>
  </job>
  <log>
    <logs count="2" progress="100">
      <entry logid="6947456634637516808">
        <domain>1</domain>
        <receive_time>2021/04/05 15:21:50</receive_time>
        <serial>unknown</serial>
        <seqno>2306</seqno>
        <actionflags>0x0</actionflags>
        <is-logging-service>no</is-logging-service>
        <type>CONFIG</type>
        <subtype>1</subtype>
        <config_ver>16</config_ver>
        <time_generated>2021/04/05 15:21:50</time_generated>
        <dg_hier_level_1>0</dg_hier_level_1>
        <dg_hier_level_2>0</dg_hier_level_2>
        <dg_hier_level_3>0</dg_hier_level_3>
        <dg_hier_level_4>0</dg_hier_level_4>
        <device_name>PA-VM</device_name>
        <vsys_id>0</vsys_id>
        <host>174.87.104.22</host>
        <cmd>audit-commit</cmd>
        <admin>admin1</admin>
        <client>Web</client>
        <result>Succeeded</result>
        <path> vsys  vsys1 rulebase security rules  my policy</path>
        <dg_id>0</dg_id>
        <comment>newest comment</comment>
        <before-change-preview>d0c5e58b-63d1-475b-a9b3-25f169ee296e</before-change-preview>
        <after-change-preview>d0c5e58b-63d1-475b-a9b3-25f169ee296e</after-change-preview>
        <full-path>/config/devices/entry[@name='localhost.localdomain']/vsys/entry[@name='vsys1']/rulebase/security/rules/entry[@name='my policy']</full-path>
      </entry>
      <entry logid="6947456634637516805">
        <domain>1</domain>
        <receive_time>2021/04/05 14:57:40</receive_time>
        <serial>unknown</serial>
        <seqno>2303</seqno>
        <actionflags>0x0</actionflags>
        <is-logging-service>no</is-logging-service>
        <type>CONFIG</type>
        <subtype>1</subtype>
        <config_ver>15</config_ver>
        <time_generated>2021/04/05 14:57:40</time_generated>
        <dg_hier_level_1>0</dg_hier_level_1>
        <dg_hier_level_2>0</dg_hier_level_2>
        <dg_hier_level_3>0</dg_hier_level_3>
        <dg_hier_level_4>0</dg_hier_level_4>
        <device_name>PA-VM</device_name>
        <vsys_id>0</vsys_id>
        <host>174.87.104.22</host>
        <cmd>audit-commit</cmd>
        <admin>admin2</admin>
        <client>Web</client>
        <result>Succeeded</result>
        <path> vsys  vsys1 rulebase security rules  my policy</path>
        <dg_id>0</dg_id>
        <comment>initial comment</comment>
        <before-change-preview>d0c5e58b-63d1-475b-a9b3-25f169ee296e</before-change-preview>
        <after-change-preview>d0c5e58b-63d1-475b-a9b3-25f169ee296e</after-change-preview>
        <full-path>/config/devices/entry[@name='localhost.localdomain']/vsys/entry[@name='vsys1']/rulebase/security/rules/entry[@name='my policy']</full-path>
      </entry>
    </logs>
  </log>
  <meta>
    <devices>
      <entry name="localhost.localdomain">
        <hostname>localhost.localdomain</hostname>
        <vsys>
          <entry name="vsys1">
            <display-name>vsys1</display-name>
          </entry>
        </vsys>
      </entry>
    </devices>
  </meta>
</result></response>
        """), )
    t1 = datetime(2021, 4, 5, 15, 21, 50)
    t2 = datetime(2021, 4, 5, 14, 57, 40)

    ans = obj.opstate.audit_comment.history()

    assert len(ans) == 2
    assert ans[0].admin == "admin1"
    assert ans[0].comment == "newest comment"
    assert ans[0].config_version == 16
    assert ans[0].time == t1
    assert ans[1].admin == "admin2"
    assert ans[1].comment == "initial comment"
    assert ans[1].config_version == 15
    assert ans[1].time == t2
예제 #10
0
def main():
    helper = get_connection(
        vsys=True,
        device_group=True,
        rulebase=True,
        with_state=True,
        with_classic_provider_spec=True,
        error_on_firewall_shared=True,
        argument_spec=dict(
            rule_name=dict(required=True),
            source_zone=dict(type="list", elements="str", default=["any"]),
            source_ip=dict(type="list", elements="str", default=["any"]),
            source_user=dict(type="list", elements="str", default=["any"]),
            hip_profiles=dict(type="list", elements="str", default=["any"]),
            destination_zone=dict(type="list", elements="str", default=["any"]),
            destination_ip=dict(type="list", elements="str", default=["any"]),
            application=dict(type="list", elements="str", default=["any"]),
            service=dict(type="list", elements="str", default=["application-default"]),
            category=dict(type="list", elements="str", default=["any"]),
            action=dict(
                default="allow",
                choices=[
                    "allow",
                    "deny",
                    "drop",
                    "reset-client",
                    "reset-server",
                    "reset-both",
                ],
            ),
            log_setting=dict(),
            log_start=dict(type="bool", default=False),
            log_end=dict(type="bool", default=True),
            description=dict(),
            rule_type=dict(
                default="universal", choices=["universal", "intrazone", "interzone"]
            ),
            tag_name=dict(type="list", elements="str"),
            negate_source=dict(type="bool", default=False),
            negate_destination=dict(type="bool", default=False),
            disabled=dict(type="bool", default=False),
            schedule=dict(),
            icmp_unreachable=dict(type="bool"),
            disable_server_response_inspection=dict(type="bool", default=False),
            group_profile=dict(),
            antivirus=dict(),
            spyware=dict(),
            vulnerability=dict(),
            url_filtering=dict(),
            file_blocking=dict(),
            wildfire_analysis=dict(),
            data_filtering=dict(),
            target=dict(type="list", elements="str"),
            negate_target=dict(type="bool"),
            location=dict(choices=["top", "bottom", "before", "after"]),
            existing_rule=dict(),
            commit=dict(type="bool", default=False),
            # TODO(gfreeman) - remove this in the next role release.
            devicegroup=dict(),
        ),
    )
    module = AnsibleModule(
        argument_spec=helper.argument_spec,
        supports_check_mode=True,
        required_one_of=helper.required_one_of,
    )

    # TODO(gfreeman) - remove when devicegroup is removed.
    if module.params["devicegroup"] is not None:
        module.deprecate(
            'Param "devicegroup" is deprecated; use "device_group"',
            version="3.0.0",
            collection_name="paloaltonetworks.panos",
        )
        if module.params["device_group"] is not None:
            msg = [
                'Both "devicegroup" and "device_group" are specified',
                "Specify one or the other, not both.",
            ]
            module.fail_json(msg=". ".join(msg))
        module.params["device_group"] = module.params["devicegroup"]

    # Verify imports, build pandevice object tree.
    parent = helper.get_pandevice_parent(module)

    # Set the SecurityRule object params.
    rule_spec = {
        "name": module.params["rule_name"],
        "fromzone": module.params["source_zone"],
        "tozone": module.params["destination_zone"],
        "source": module.params["source_ip"],
        "source_user": module.params["source_user"],
        "hip_profiles": module.params["hip_profiles"],
        "destination": module.params["destination_ip"],
        "application": module.params["application"],
        "service": module.params["service"],
        "category": module.params["category"],
        "action": module.params["action"],
        "log_setting": module.params["log_setting"],
        "log_start": module.params["log_start"],
        "log_end": module.params["log_end"],
        "description": module.params["description"],
        "type": module.params["rule_type"],
        "tag": module.params["tag_name"],
        "negate_source": module.params["negate_source"],
        "negate_destination": module.params["negate_destination"],
        "disabled": module.params["disabled"],
        "schedule": module.params["schedule"],
        "icmp_unreachable": module.params["icmp_unreachable"],
        "disable_server_response_inspection": module.params[
            "disable_server_response_inspection"
        ],
        "group": module.params["group_profile"],
        "virus": module.params["antivirus"],
        "spyware": module.params["spyware"],
        "vulnerability": module.params["vulnerability"],
        "url_filtering": module.params["url_filtering"],
        "file_blocking": module.params["file_blocking"],
        "wildfire_analysis": module.params["wildfire_analysis"],
        "data_filtering": module.params["data_filtering"],
        "target": module.params["target"],
        "negate_target": module.params["negate_target"],
    }

    # Other module info.
    location = module.params["location"]
    existing_rule = module.params["existing_rule"]
    commit = module.params["commit"]

    # Retrieve the current rules.
    try:
        rules = SecurityRule.refreshall(parent, add=False)
    except PanDeviceError as e:
        module.fail_json(msg="Failed refresh: {0}".format(e))

    # Create new rule object from the params.
    new_rule = SecurityRule(**rule_spec)
    parent.add(new_rule)

    # Which action shall we take on the rule object?
    changed, diff = helper.apply_state(new_rule, rules, module)

    # Move the rule to the correct spot, if applicable.
    if module.params["state"] == "present":
        changed |= helper.apply_position(new_rule, location, existing_rule, module)

    # Optional commit.
    if changed and commit:
        helper.commit(module)

    # Done.
    module.exit_json(changed=changed, diff=diff, msg="Done")
예제 #11
0
def main():
    helper = get_connection(
        vsys=True,
        device_group=True,
        rulebase=True,
        with_state=True,
        with_classic_provider_spec=True,
        error_on_firewall_shared=True,
        argument_spec=dict(
            rule_name=dict(required=True),
            source_zone=dict(type='list', elements='str', default=['any']),
            source_ip=dict(type='list', elements='str', default=["any"]),
            source_user=dict(type='list', elements='str', default=['any']),
            hip_profiles=dict(type='list', elements='str', default=['any']),
            destination_zone=dict(type='list', elements='str',
                                  default=['any']),
            destination_ip=dict(type='list', elements='str', default=["any"]),
            application=dict(type='list', elements='str', default=['any']),
            service=dict(type='list',
                         elements='str',
                         default=['application-default']),
            category=dict(type='list', elements='str', default=['any']),
            action=dict(
                default='allow',
                choices=[
                    'allow', 'deny', 'drop', 'reset-client', 'reset-server',
                    'reset-both'
                ],
            ),
            log_setting=dict(),
            log_start=dict(type='bool', default=False),
            log_end=dict(type='bool', default=True),
            description=dict(),
            rule_type=dict(default='universal',
                           choices=['universal', 'intrazone', 'interzone']),
            tag_name=dict(type='list', elements='str'),
            negate_source=dict(type='bool', default=False),
            negate_destination=dict(type='bool', default=False),
            disabled=dict(type='bool', default=False),
            schedule=dict(),
            icmp_unreachable=dict(type='bool'),
            disable_server_response_inspection=dict(type='bool',
                                                    default=False),
            group_profile=dict(),
            antivirus=dict(),
            spyware=dict(),
            vulnerability=dict(),
            url_filtering=dict(),
            file_blocking=dict(),
            wildfire_analysis=dict(),
            data_filtering=dict(),
            target=dict(type='list', elements='str'),
            negate_target=dict(type='bool'),
            location=dict(choices=['top', 'bottom', 'before', 'after']),
            existing_rule=dict(),
            commit=dict(type='bool', default=False),

            # TODO(gfreeman) - remove this in the next role release.
            devicegroup=dict(),
        ),
    )
    module = AnsibleModule(
        argument_spec=helper.argument_spec,
        supports_check_mode=True,
        required_one_of=helper.required_one_of,
    )

    # TODO(gfreeman) - remove when devicegroup is removed.
    if module.params['devicegroup'] is not None:
        module.deprecate(
            'Param "devicegroup" is deprecated; use "device_group"',
            version='3.0.0',
            collection_name='paloaltonetworks.panos')
        if module.params['device_group'] is not None:
            msg = [
                'Both "devicegroup" and "device_group" are specified',
                'Specify one or the other, not both.',
            ]
            module.fail_json(msg='. '.join(msg))
        module.params['device_group'] = module.params['devicegroup']

    # Verify imports, build pandevice object tree.
    parent = helper.get_pandevice_parent(module)

    # Set the SecurityRule object params.
    rule_spec = {
        'name':
        module.params['rule_name'],
        'fromzone':
        module.params['source_zone'],
        'tozone':
        module.params['destination_zone'],
        'source':
        module.params['source_ip'],
        'source_user':
        module.params['source_user'],
        'hip_profiles':
        module.params['hip_profiles'],
        'destination':
        module.params['destination_ip'],
        'application':
        module.params['application'],
        'service':
        module.params['service'],
        'category':
        module.params['category'],
        'action':
        module.params['action'],
        'log_setting':
        module.params['log_setting'],
        'log_start':
        module.params['log_start'],
        'log_end':
        module.params['log_end'],
        'description':
        module.params['description'],
        'type':
        module.params['rule_type'],
        'tag':
        module.params['tag_name'],
        'negate_source':
        module.params['negate_source'],
        'negate_destination':
        module.params['negate_destination'],
        'disabled':
        module.params['disabled'],
        'schedule':
        module.params['schedule'],
        'icmp_unreachable':
        module.params['icmp_unreachable'],
        'disable_server_response_inspection':
        module.params['disable_server_response_inspection'],
        'group':
        module.params['group_profile'],
        'virus':
        module.params['antivirus'],
        'spyware':
        module.params['spyware'],
        'vulnerability':
        module.params['vulnerability'],
        'url_filtering':
        module.params['url_filtering'],
        'file_blocking':
        module.params['file_blocking'],
        'wildfire_analysis':
        module.params['wildfire_analysis'],
        'data_filtering':
        module.params['data_filtering'],
        'target':
        module.params['target'],
        'negate_target':
        module.params['negate_target'],
    }

    # Other module info.
    location = module.params['location']
    existing_rule = module.params['existing_rule']
    commit = module.params['commit']

    # Retrieve the current rules.
    try:
        rules = SecurityRule.refreshall(parent, add=False)
    except PanDeviceError as e:
        module.fail_json(msg='Failed refresh: {0}'.format(e))

    # Create new rule object from the params.
    new_rule = SecurityRule(**rule_spec)
    parent.add(new_rule)

    # Which action shall we take on the rule object?
    changed, diff = helper.apply_state(new_rule, rules, module)

    # Move the rule to the correct spot, if applicable.
    if module.params['state'] == 'present':
        changed |= helper.apply_position(new_rule, location, existing_rule,
                                         module)

    # Optional commit.
    if changed and commit:
        helper.commit(module)

    # Done.
    module.exit_json(changed=changed, diff=diff, msg='Done')
예제 #12
0
def main():
    helper = get_connection(
        vsys=True,
        device_group=True,
        rulebase=True,
        with_classic_provider_spec=True,
        error_on_firewall_shared=True,
        argument_spec=dict(
            rule_name=dict(),
            names=dict(type="list", elements="str"),
            details=dict(default=False, type="bool", aliases=["all_details"]),
            match_rules=dict(
                type="dict",
                options=dict(
                    source_zone=dict(type="str", required=True),
                    source_ip=dict(type="str", required=True),
                    source_user=dict(type="str"),
                    destination_zone=dict(type="str", required=True),
                    destination_ip=dict(type="str", required=True),
                    destination_port=dict(type="str", required=True),
                    protocol=dict(type="str",
                                  choices=["tcp", "udp", "icmp"],
                                  required=True),
                    application=dict(type="str"),
                    category=dict(type="str"),
                    show_all=dict(type="bool"),
                ),
            ),
        ),
    )

    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"),
        ("type", "rule_type"),
        ("tag", "tag_name"),
        ("group", "group_profile"),
        ("virus", "antivirus"),
    )

    names = module.params["names"]
    details = module.params["details"]

    if module.params.get("all_details"):
        module.deprecate(
            "Please use details instead of all_details.",
            version="3.0.0",
            collection_name="paloaltonetworks.panos",
        )

    if module.params["rule_name"]:
        module.deprecate(
            "Please use the names parameter instead of rule_name.",
            version="3.0.0",
            collection_name="paloaltonetworks.panos",
        )

        names = [module.params["rule_name"]]

    if module.params["match_rules"]:
        names = match_rules(module, parent.nearest_pandevice())

    if names is None and details is False:
        # Didn't specify specific rules, so just return list of rule names.
        listing = SecurityRule.refreshall(parent, name_only=True)
        module.exit_json(changed=False, rule_names=[r.name for r in listing])

    elif module.params["match_rules"] and details is False:
        # match_rules was set, but not details, so return list of rule names.
        module.exit_json(changed=False, rule_names=names)

    else:
        # Return full policy details.  Will return full policy details even if
        # details is False if specific rules are given, because returning the
        # user's list of rules back to them is pointless.
        if names is None:
            listing = SecurityRule.refreshall(parent)
            rules = [rule.about() for rule in listing]
        else:
            rules = []
            for name in names:
                rule = SecurityRule(name)
                parent.add(rule)

                try:
                    rule.refresh()
                except PanDeviceError as e:
                    module.fail_json(msg="Failed refresh: {0}".format(e))

                rules.append(rule.about())

        # Fix up names in returned dict.
        for rule in rules:
            for p, a in renames:
                rule[a] = rule[p]
                del rule[p]

        module.exit_json(changed=False, rule_details=rules)