Skip to content

Commit

Permalink
Allow applying a new profile over an existing one in ***pan-os-apply-…
Browse files Browse the repository at this point in the history
…security-profile*** command (#27237)

* Add XSOAR support for updating existing profile types

* RN

* fix UT

* Update Packs/PAN-OS/ReleaseNotes/1_17_5.md

Co-authored-by: Guy Afik <[email protected]>

* fix CR

* RN

* UT was added

* Update Packs/PAN-OS/Integrations/Panorama/Panorama.py

Co-authored-by: Guy Afik <[email protected]>

* Update Packs/PAN-OS/Integrations/Panorama/Panorama.py

Co-authored-by: Guy Afik <[email protected]>

* Update Packs/PAN-OS/Integrations/Panorama/Panorama.py

Co-authored-by: Guy Afik <[email protected]>

* Update Packs/PAN-OS/Integrations/Panorama/Panorama.py

Co-authored-by: Guy Afik <[email protected]>

* Update Packs/PAN-OS/Integrations/Panorama/Panorama.py

Co-authored-by: Guy Afik <[email protected]>

* fix

* flake8

* UT stability

---------

Co-authored-by: Guy Afik <[email protected]>
  • Loading branch information
2 people authored and ostolero committed Jun 14, 2023
1 parent 459032d commit caa4581
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 12 deletions.
44 changes: 36 additions & 8 deletions Packs/PAN-OS/Integrations/Panorama/Panorama.py
Original file line number Diff line number Diff line change
Expand Up @@ -6916,14 +6916,44 @@ def get_security_profiles_command(security_profile: str = None):


@logger
def apply_security_profile(xpath: str, profile_name: str) -> Dict:
def apply_security_profile(xpath: str, profile_name: str, profile_type: str) -> Dict:
# get the rule state
params = {
'action': 'get',
'type': 'config',
'xpath': xpath,
'key': API_KEY,
}
result = http_request(URL, 'GET', params=params)

# Get all profile types already existing, so we don't override them when updating
profile_types_result = dict_safe_get(result, ['response', 'result', 'entry', 'profile-setting', 'profiles'],
default_return_value={})

# align the response for both committed and un-committed profiles
parse_pan_os_un_committed_data(profile_types_result, ['@admin', '@dirtyId', '@time'])

# remove from the types the given profile type, since we update it anyway
profile_types = {'data-filtering', 'file-blocking', 'spyware', 'url-filtering',
'virus', 'vulnerability', 'wildfire-analysis'} - {profile_type}

# first we update the given profile type with the given profile name
rule_profiles = f"<{profile_type}><member>{profile_name}</member></{profile_type}>"

# Keeping the existing profile types
for p_type in profile_types:
if p_type in profile_types_result:
p_name = profile_types_result.get(p_type, {}).get('member')
rule_profiles += f"<{p_type}><member>{p_name}</member></{p_type}>"

params = {
'action': 'set',
'type': 'config',
'xpath': xpath,
'key': API_KEY,
'element': f'<member>{profile_name}</member>'
'element': f'<profile-setting><profiles>{rule_profiles}</profiles></profile-setting>'
}

result = http_request(URL, 'POST', params=params)

return result
Expand All @@ -6933,20 +6963,18 @@ def apply_security_profile_command(args):
profile_name = args.get('profile_name')
profile_type = args.get('profile_type')
rule_name = args.get('rule_name')
pre_post = args.get('rule_name')
pre_post = args.get('pre_post')

if DEVICE_GROUP: # Panorama instance
if not pre_post:
raise Exception('Please provide the pre_post argument when applying profiles to rules in '
'Panorama instance.')
xpath = f"{XPATH_RULEBASE}{pre_post}/security/rules/entry[@name='{rule_name}']/profile-setting/" \
f"profiles/{profile_type}"
xpath = f"{XPATH_RULEBASE}{pre_post}/security/rules/entry[@name='{rule_name}']"

else: # firewall instance
xpath = f"{XPATH_RULEBASE}rulebase/security/rules/entry[@name='{rule_name}']/profile-setting/" \
f"profiles/{profile_type}"
xpath = f"{XPATH_RULEBASE}rulebase/security/rules/entry[@name='{rule_name}']"

apply_security_profile(xpath, profile_name)
apply_security_profile(xpath, profile_name, profile_type)
return_results(f'The profile {profile_name} has been applied to the rule {rule_name}')


Expand Down
53 changes: 50 additions & 3 deletions Packs/PAN-OS/Integrations/Panorama/Panorama_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -1168,7 +1168,8 @@ def test_apply_security_profiles_command_main_flow(mocker):
'device-group': 'new-device-group',
'profile_type': 'data-filtering',
'profile_name': 'test-profile',
'rule_name': 'rule-test'
'rule_name': 'rule-test',
'pre_post': 'rule-test'
}
)
mocker.patch.object(demisto, 'command', return_value='pan-os-apply-security-profile')
Expand All @@ -1181,11 +1182,57 @@ def test_apply_security_profiles_command_main_flow(mocker):
assert request_mock.call_args.kwargs['params'] == {
'action': 'set', 'type': 'config',
'xpath': "/config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='new-device-group']"
"/rule-test/security/rules/entry[@name='rule-test']/profile-setting/profiles/data-filtering",
'key': 'thisisabogusAPIKEY!', 'element': '<member>test-profile</member>'}
"/rule-test/security/rules/entry[@name='rule-test']",
'key': 'thisisabogusAPIKEY!', 'element': '<profile-setting><profiles><data-filtering>'
'<member>test-profile</member></data-filtering></profiles>'
'</profile-setting>'}
assert res.call_args.args[0] == 'The profile test-profile has been applied to the rule rule-test'


def test_apply_security_profiles_command_when_one_already_exists(mocker):
"""
Given
- integrations parameters.
- pan-os-apply-security-profile command arguments including device_group
- same profile as already exists in the rule
When -
running the pan-os-apply-security-profile command through the main flow
Then
- Ensure the request is what's already in the API (the 'element' parameter contains all profiles in the XML)
"""
from Panorama import main

mocker.patch.object(demisto, 'params', return_value=integration_panorama_params)
mocker.patch.object(
demisto,
'args',
return_value={
'device-group': 'new-device-group',
'profile_type': 'spyware',
'profile_name': 'strict',
'rule_name': 'rule-test',
'pre_post': 'rule-test'
}
)
mocker.patch('Panorama.dict_safe_get', return_value={'virus': {'member': 'Tap'}, 'spyware': {'member': 'strict'}})
mocker.patch.object(demisto, 'command', return_value='pan-os-apply-security-profile')
request_mock = mocker.patch('Panorama.http_request')

res = mocker.patch('demistomock.results')
main()

assert request_mock.call_args.kwargs['params'] == {
'action': 'set', 'type': 'config',
'xpath': "/config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='new-device-group']"
"/rule-test/security/rules/entry[@name='rule-test']",
'key': 'thisisabogusAPIKEY!',
'element': '<profile-setting><profiles><spyware><member>strict</member></spyware>'
'<virus><member>Tap</member></virus></profiles></profile-setting>'}
assert res.call_args.args[0] == 'The profile strict has been applied to the rule rule-test'


class TestPanoramaEditRuleCommand:
EDIT_SUCCESS_RESPONSE = {'response': {'@status': 'success', '@code': '20', 'msg': 'command succeeded'}}
EDIT_AUDIT_COMMENT_SUCCESS_RESPONSE = {
Expand Down
6 changes: 6 additions & 0 deletions Packs/PAN-OS/ReleaseNotes/1_17_5.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

#### Integrations

##### Palo Alto Networks PAN-OS

- Fixed an issue where the ***pan-os-apply-security-profile*** command didn't work for panorama instances.
2 changes: 1 addition & 1 deletion Packs/PAN-OS/pack_metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "PAN-OS by Palo Alto Networks",
"description": "Manage Palo Alto Networks Firewall and Panorama. For more information see Panorama documentation.",
"support": "xsoar",
"currentVersion": "1.17.4",
"currentVersion": "1.17.5",
"author": "Cortex XSOAR",
"url": "https://www.paloaltonetworks.com/cortex",
"email": "",
Expand Down

0 comments on commit caa4581

Please sign in to comment.