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")
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)
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()
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)
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)
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)
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)
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))
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
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")
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')
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)