Skip to content

Commit 031bf86

Browse files
authored
Add nat-rule CRUD module (#100)
* Add new nat module * Support nat-rule relative positioning + bug fix
1 parent cb4cd3f commit 031bf86

File tree

8 files changed

+323
-39
lines changed

8 files changed

+323
-39
lines changed

plugins/module_utils/checkpoint.py

Lines changed: 74 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -672,13 +672,13 @@ def api_call(module, api_call_object):
672672

673673
# returns a generator of the entire rulebase
674674
def get_rulebase_generator(
675-
connection, version, layer, show_rulebase_command, rules_amount
675+
connection, version, show_rulebase_identifier_payload, show_rulebase_command, rules_amount
676676
):
677677
offset = 0
678678
limit = 100
679679
while True:
680680
payload_for_show_rulebase = {
681-
"name": layer,
681+
**show_rulebase_identifier_payload, # package or layer
682682
"limit": limit,
683683
"offset": offset,
684684
}
@@ -702,15 +702,15 @@ def get_rulebase_generator(
702702

703703
# get 'to' or 'from' of given section
704704
def get_edge_position_in_section(
705-
connection, version, layer, section_name, edge
705+
connection, version, identifier, section_name, edge
706706
):
707707
code, response = send_request(
708708
connection,
709709
version,
710710
"show-layer-structure",
711-
{"name": layer, "details-level": "uid"},
711+
{"name": identifier, "details-level": "uid"},
712712
)
713-
if response["code"] == "generic_err_command_not_found":
713+
if 'code' in response and response["code"] == "generic_err_command_not_found":
714714
raise ValueError(
715715
"The use of the relative_position field with a section as its value is available only for"
716716
" version 1.7.1 with JHF take 42 and above"
@@ -724,13 +724,12 @@ def get_edge_position_in_section(
724724

725725

726726
# return the total amount of rules in the rulebase of the given layer
727-
def get_rules_amount(connection, version, layer, show_rulebase_command):
728-
payload_for_show_obj_rulebase = {"name": layer, "limit": 0}
727+
def get_rules_amount(connection, version, show_rulebase_payload, show_rulebase_command):
729728
code, response = send_request(
730729
connection,
731730
version,
732731
show_rulebase_command,
733-
payload_for_show_obj_rulebase,
732+
{**show_rulebase_payload, "limit": 0},
734733
)
735734
return int(response["total"])
736735

@@ -750,17 +749,18 @@ def keep_searching_rulebase(
750749

751750

752751
def relative_position_is_section(
753-
connection, version, layer, relative_position
752+
connection, version, api_call_object, layer_or_package_payload, relative_position
754753
):
755754
if "top" in relative_position or "bottom" in relative_position:
756755
return True
757756

757+
show_section_command = "show-access-section" if 'access' in api_call_object else "show-nat-section"
758758
relative_position_value = list(relative_position.values())[0]
759759
code, response = send_request(
760760
connection,
761761
version,
762-
"show-access-section",
763-
{"layer": layer, "name": relative_position_value},
762+
show_section_command,
763+
{**layer_or_package_payload, "name": relative_position_value},
764764
)
765765
if code == 200:
766766
return True
@@ -774,8 +774,11 @@ def get_number_and_section_from_relative_position(
774774
rulebase,
775775
above_relative_position,
776776
pos_before_relative_empty_section,
777+
api_call_object,
778+
prev_section=None,
779+
current_section=None,
777780
):
778-
section_name = None
781+
section_name = current_section
779782
position = None
780783
for rules in rulebase:
781784
if "rulebase" in rules:
@@ -796,7 +799,7 @@ def get_number_and_section_from_relative_position(
796799
from_value = get_edge_position_in_section(
797800
connection,
798801
version,
799-
payload["layer"],
802+
list(get_relevant_layer_or_package_identifier(api_call_object, payload).values())[0],
800803
rules["name"],
801804
"from",
802805
)
@@ -811,10 +814,12 @@ def get_number_and_section_from_relative_position(
811814
section_name,
812815
above_relative_position,
813816
pos_before_relative_empty_section,
817+
prev_section,
814818
)
815819

816820
# we update this only after the 'above' case since the section that should be returned in that case isn't
817821
# the one we are currently iterating over (but the one beforehand)
822+
prev_section = section_name
818823
section_name = rules["name"]
819824

820825
if (
@@ -833,7 +838,7 @@ def get_number_and_section_from_relative_position(
833838
to_value = get_edge_position_in_section(
834839
connection,
835840
version,
836-
payload["layer"],
841+
list(get_relevant_layer_or_package_identifier(api_call_object, payload).values())[0],
837842
section_name,
838843
"to",
839844
)
@@ -856,6 +861,7 @@ def get_number_and_section_from_relative_position(
856861
section_name,
857862
above_relative_position,
858863
pos_before_relative_empty_section,
864+
prev_section,
859865
)
860866

861867
# setting a rule 'below' a section is equivalent to setting the rule at the top of that section
@@ -885,6 +891,7 @@ def get_number_and_section_from_relative_position(
885891
section_name,
886892
above_relative_position,
887893
pos_before_relative_empty_section,
894+
prev_section,
888895
)
889896

890897
if len(rules["rulebase"]) != 0:
@@ -911,6 +918,7 @@ def get_number_and_section_from_relative_position(
911918
section_name,
912919
above_relative_position,
913920
pos_before_relative_empty_section,
921+
prev_section,
914922
)
915923
elif (
916924
"above" in payload["position"]
@@ -926,6 +934,7 @@ def get_number_and_section_from_relative_position(
926934
section_name,
927935
above_relative_position,
928936
pos_before_relative_empty_section,
937+
prev_section,
929938
)
930939

931940
else: # cases relevant for relative-position=rule
@@ -945,6 +954,7 @@ def get_number_and_section_from_relative_position(
945954
section_name,
946955
above_relative_position,
947956
pos_before_relative_empty_section,
957+
prev_section,
948958
)
949959
elif (
950960
"above" in payload["position"]
@@ -960,14 +970,16 @@ def get_number_and_section_from_relative_position(
960970
section_name,
961971
above_relative_position,
962972
pos_before_relative_empty_section,
973+
prev_section,
963974
)
964975

965976
return (
966977
position,
967978
section_name,
968979
above_relative_position,
969980
pos_before_relative_empty_section,
970-
) # None, None, False/True, x>=1
981+
prev_section,
982+
) # None, None, False/True, x>=1, None
971983

972984

973985
# get the position in integer format and the section it is.
@@ -983,17 +995,18 @@ def get_number_and_section_from_position(
983995
position = 1
984996
return position, section_name
985997
elif position == "bottom":
998+
show_rulebase_payload = get_relevant_show_rulebase_identifier_payload(api_call_object, payload)
986999
position = get_rules_amount(
9871000
connection,
9881001
version,
989-
payload["layer"],
1002+
show_rulebase_payload,
9901003
show_rulebase_command,
9911004
)
9921005
code, response = send_request(
9931006
connection,
9941007
version,
9951008
show_rulebase_command,
996-
{"name": payload["layer"], "offset": position - 1},
1009+
{**show_rulebase_payload, "offset": position - 1},
9971010
)
9981011
rulebase = reversed(response["rulebase"])
9991012
else: # is a number so we need to get the section (if exists) of the rule in that position
@@ -1038,12 +1051,13 @@ def get_number_and_section_from_position(
10381051
# no from-to in empty sections so can't infer the position from them -> need to keep track of the position
10391052
# before the empty relative section
10401053
pos_before_relative_empty_section = 1
1054+
show_rulebase_payload = get_relevant_show_rulebase_identifier_payload(api_call_object, payload)
10411055
if not search_entire_rulebase:
10421056
code, response = send_request(
10431057
connection,
10441058
version,
10451059
show_rulebase_command,
1046-
{"name": payload["layer"]},
1060+
show_rulebase_payload,
10471061
)
10481062
rulebase = response["rulebase"]
10491063
(
@@ -1058,37 +1072,46 @@ def get_number_and_section_from_position(
10581072
rulebase,
10591073
above_relative_position,
10601074
pos_before_relative_empty_section,
1075+
api_call_object,
10611076
)
10621077
else:
1078+
layer_or_package_payload = get_relevant_layer_or_package_identifier(api_call_object, payload)
10631079
rules_amount = get_rules_amount(
10641080
connection,
10651081
version,
1066-
payload["layer"],
1082+
show_rulebase_payload,
10671083
show_rulebase_command,
10681084
)
10691085
relative_pos_is_section = relative_position_is_section(
1070-
connection, version, payload["layer"], payload["position"]
1086+
connection, version, api_call_object, layer_or_package_payload, payload["position"]
10711087
)
10721088
rulebase_generator = get_rulebase_generator(
10731089
connection,
10741090
version,
1075-
payload["layer"],
1091+
show_rulebase_payload,
10761092
show_rulebase_command,
10771093
rules_amount,
10781094
)
1095+
# need to keep track of the previous section in case the iteration starts with a new section and
1096+
# we want to set the rule above a section - so the section the rule should be at is the previous one
1097+
prev_section = None
10791098
for rulebase in rulebase_generator:
10801099
(
10811100
position,
10821101
section_name,
10831102
above_relative_position,
10841103
pos_before_relative_empty_section,
1104+
prev_section,
10851105
) = get_number_and_section_from_relative_position(
10861106
payload,
10871107
connection,
10881108
version,
10891109
rulebase,
10901110
above_relative_position,
10911111
pos_before_relative_empty_section,
1112+
api_call_object,
1113+
prev_section,
1114+
section_name,
10921115
)
10931116
if not keep_searching_rulebase(
10941117
position,
@@ -1104,16 +1127,8 @@ def get_number_and_section_from_position(
11041127

11051128
# build the show rulebase payload
11061129
def build_rulebase_payload(api_call_object, payload, position_number):
1107-
rulebase_payload = {
1108-
"name": payload["layer"],
1109-
"offset": position_number - 1,
1110-
"limit": 1,
1111-
}
1112-
1113-
if api_call_object == "threat-exception":
1114-
rulebase_payload["rule-name"] = payload["rule-name"]
1115-
1116-
return rulebase_payload
1130+
show_rulebase_required_identifiers_payload = get_relevant_show_rulebase_identifier_payload(api_call_object, payload)
1131+
return {**show_rulebase_required_identifiers_payload, 'offset': position_number - 1, 'limit': 1}
11171132

11181133

11191134
def build_rulebase_command(api_call_object):
@@ -1157,13 +1172,36 @@ def get_relevant_show_rulebase_command(api_call_object):
11571172
return "show-threat-rulebase"
11581173
elif api_call_object == "threat-exception":
11591174
return "show-threat-rule-exception-rulebase"
1175+
elif api_call_object == 'nat-rule':
1176+
return 'show-nat-rulebase'
1177+
# uncomment code below when https module is added as a crud module
1178+
# elif api_call_object == 'https-rule':
1179+
# return 'show-https-rulebase'
1180+
11601181

1182+
# returns the show rulebase payload with the relevant required identifiers params
1183+
def get_relevant_show_rulebase_identifier_payload(api_call_object, payload):
1184+
if api_call_object == 'nat-rule':
1185+
show_rulebase_payload = {'package': payload['package']}
1186+
1187+
else:
1188+
show_rulebase_payload = {'name': payload['layer']}
1189+
1190+
if api_call_object == 'threat-exception':
1191+
show_rulebase_payload['rule-name'] = payload['rule-name']
1192+
1193+
return show_rulebase_payload
1194+
1195+
1196+
# returns the show section/rule payload with the relevant required identifying package/layer
1197+
def get_relevant_layer_or_package_identifier(api_call_object, payload):
1198+
if 'nat' in api_call_object:
1199+
identifier = {'package': payload['package']}
1200+
1201+
else:
1202+
identifier = {'layer': payload['layer']}
11611203

1162-
# uncomment code below when https & nat modules are added as crud modules
1163-
# elif api_call_object == 'nat-rule':
1164-
# return 'show-nat-rulebase'
1165-
# elif api_call_object == 'https-rule':
1166-
# return 'show-https-rulebase'
1204+
return identifier
11671205

11681206

11691207
# is the param position (if the user inserted it) equals between the object and the user input, as well as the section the rule is in
@@ -1345,7 +1383,6 @@ def call_is_plural(api_call_object, payload):
13451383
elif (
13461384
"nat" in api_call_object
13471385
and payload.get("name") is None
1348-
and payload.get("uid") is None
13491386
and payload.get("rule-number") is None
13501387
):
13511388
is_plural = True

plugins/modules/cp_mgmt_add_nat_rule.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@
3636
- All operations are performed over Web Services API.
3737
version_added: "2.0.0"
3838
author: "Or Soffer (@chkp-orso)"
39+
deprecated:
40+
alternative: cp_mgmt_nat_rule
41+
why: Newer and updated module released with more functionality.
42+
removed_at_date: '2024-11-01'
3943
options:
4044
package:
4145
description:

plugins/modules/cp_mgmt_administrator.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ def main():
206206
email=dict(type="str"),
207207
expiration_date=dict(type="str"),
208208
multi_domain_profile=dict(type="str"),
209-
must_change_password=dict(type="bool"),
209+
must_change_password=dict(type="bool", no_log=False),
210210
password=dict(type="str", no_log=True),
211211
password_hash=dict(type="str", no_log=True),
212212
permissions_profile=dict(type="str"),

plugins/modules/cp_mgmt_delete_nat_rule.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@
3636
- All operations are performed over Web Services API.
3737
version_added: "2.0.0"
3838
author: "Or Soffer (@chkp-orso)"
39+
deprecated:
40+
alternative: cp_mgmt_nat_rule
41+
why: Newer and updated module released with more functionality.
42+
removed_at_date: '2024-11-01'
3943
options:
4044
rule_number:
4145
description:

plugins/modules/cp_mgmt_domain_permissions_profile.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,8 @@
461461
462462
- name: set-domain-permissions-profile
463463
cp_mgmt_domain_permissions_profile:
464-
access_control.policy_layers: By Selected Profile In A Layer Editor
464+
access_control:
465+
policy_layers: By Selected Profile In A Layer Editor
465466
name: read profile
466467
permission_type: customized
467468
state: present

0 commit comments

Comments
 (0)