Skip to content

Commit 7e28d37

Browse files
committed
feat: add the possibility to requests all access rules at once
1 parent 05e5e3a commit 7e28d37

File tree

1 file changed

+261
-4
lines changed

1 file changed

+261
-4
lines changed

pycheckpoint_api/management/access_control_nat/access_rule.py

Lines changed: 261 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import logging
2+
import time
13
from typing import List, Union
24

35
from box import Box
@@ -7,6 +9,8 @@
79

810
from ..exception import MandatoryFieldMissing
911

12+
logger = logging.getLogger(__name__)
13+
1014

1115
class AccessRule(APIEndpoint):
1216
def add(
@@ -473,6 +477,7 @@ def show_access_rulebase(
473477
self,
474478
name: str = None,
475479
uid: str = None,
480+
show_all: bool = False,
476481
filter_results: str = None,
477482
filter_settings: dict = None,
478483
limit: int = 50,
@@ -485,16 +490,17 @@ def show_access_rulebase(
485490
hits_settings: dict = None,
486491
**kw,
487492
) -> Box:
488-
"""
489-
Shows the entire Access Rules layer. This layer is divided into sections. An Access Rule may be within a section,
493+
"""Shows the entire Access Rules layer. This layer is divided into sections. An Access Rule may be within a section,
490494
or independent of a section (in which case it is said to be under the "global" section). The reply features
491495
a list of objects. Each object may be a section of the layer, with all its rules in, or a rule itself,
492496
for the case of rules which are under the global section. An optional "filter" field may be added in order
493497
to filter out only those rules that match a search criteria.
494498
495499
Args:
496500
name (str, optional): Object name. Must be unique in the domain.
497-
uid (str, optional): Object unique identifier.
501+
uid (str, optional): Object unique identifier.
502+
show_all (bool, optional): Indicates if you want to shown all objects or not. If yes, `offset` will be ignored.\
503+
Defaults to False
498504
filter_results (str, optional): Search expression to filter objects by.\
499505
The provided text should be exactly the same as it would be given in SmartConsole Object Explorer.\
500506
The logical operators in the expression ('AND', 'OR') should be provided in capital letters.\
@@ -529,7 +535,98 @@ def show_access_rulebase(
529535
:obj:`Box`: The response from the server
530536
531537
Examples:
532-
>>>
538+
>>> firewall.access_control_nat.access_rule.show_access_rulebase()
539+
540+
"""
541+
542+
if show_all:
543+
return self._show_all_access_rulebase(
544+
name=name,
545+
uid=uid,
546+
filter_results=filter_results,
547+
filter_settings=filter_settings,
548+
limit=limit,
549+
order=order,
550+
package=package,
551+
show_as_ranges=show_as_ranges,
552+
show_hits=show_hits,
553+
use_object_dictionnary=use_object_dictionnary,
554+
hits_settings=hits_settings,
555+
**kw,
556+
)
557+
else:
558+
return self._show_partial_access_rulebase(
559+
name=name,
560+
uid=uid,
561+
filter_results=filter_results,
562+
filter_settings=filter_settings,
563+
limit=limit,
564+
offset=offset,
565+
order=order,
566+
package=package,
567+
show_as_ranges=show_as_ranges,
568+
show_hits=show_hits,
569+
use_object_dictionnary=use_object_dictionnary,
570+
hits_settings=hits_settings,
571+
**kw,
572+
)
573+
574+
def _show_partial_access_rulebase(
575+
self,
576+
name: str = None,
577+
uid: str = None,
578+
filter_results: str = None,
579+
filter_settings: dict = None,
580+
limit: int = 50,
581+
offset: int = 0,
582+
order: List[dict] = None,
583+
package: str = None,
584+
show_as_ranges: bool = False,
585+
show_hits: bool = None,
586+
use_object_dictionnary: bool = None,
587+
hits_settings: dict = None,
588+
**kw,
589+
) -> Box:
590+
"""Retrieve partially objects
591+
592+
Args:
593+
name (str, optional): Object name. Must be unique in the domain.
594+
uid (str, optional): Object unique identifier.
595+
filter_results (str, optional): Search expression to filter objects by.\
596+
The provided text should be exactly the same as it would be given in SmartConsole Object Explorer.\
597+
The logical operators in the expression ('AND', 'OR') should be provided in capital letters.\
598+
he search involves both a IP search and a textual search in name, comment, tags etc.
599+
filter_settings (str, optional): Sets filter preferences.
600+
limit (int, optional): The maximal number of returned results. Defaults to 50 (between 1 and 500)
601+
offset (int, optional): Number of the results to initially skip. Defaults to 0
602+
order (List[dict], optional): Sorts results by the given field. By default the results are sorted in the \
603+
descending order by the session publish time.
604+
package (str, optional): Name of the package.
605+
show_as_ranges (bool, optional): When true, the source, destination and services & applications parameters are\
606+
displayed as ranges of IP addresses and port numbers rather than network objects. Objects that are not represented\
607+
using IP addresses or port numbers are presented as objects. In addition, the response of each rule does not\
608+
contain the parameters: source, source-negate, destination, destination-negate, service and service-negate,\
609+
but instead it contains the parameters: source-ranges, destination-ranges and service-ranges.\
610+
Note: Requesting to show rules as ranges is limited up to 20 rules per request, otherwise an error is returned.\
611+
If you wish to request more rules, use the offset and limit parameters to limit your request.
612+
show_hits (bool, optional): N/A
613+
use_object_dictionnary (bool, optional): N/A
614+
hits_settings (dict, optional): N/A
615+
616+
Keyword Args:
617+
**details_level (str, optional):
618+
The level of detail for some of the fields in the response can vary from showing only the UID value\
619+
of the object to a fully detailed representation of the object.
620+
**show_membership (bool, optional):
621+
Indicates whether to calculate and show "groups" field for every object in reply.
622+
**dereference_group_members (bool, optional):
623+
Indicates whether to dereference "members" field by details level for every object in reply.
624+
625+
Returns:
626+
:obj:`Box`: The response from the server
627+
628+
Examples:
629+
>>> firewall.access_control_nat.access_rule._show_partial_access_rulebase()
533630
"""
534631
# Main request parameters
535632
payload = {}
@@ -571,3 +668,163 @@ def show_access_rulebase(
571668
payload.update(sanitize_secondary_parameters(secondary_parameters, **kw))
572669

573670
return self._post("show-access-rulebase", json=payload)
671+
672+
def _show_all_access_rulebase(
673+
self,
674+
name: str = None,
675+
uid: str = None,
676+
filter_results: str = None,
677+
filter_settings: dict = None,
678+
limit: int = 50,
679+
order: List[dict] = None,
680+
package: str = None,
681+
show_as_ranges: bool = False,
682+
show_hits: bool = None,
683+
use_object_dictionnary: bool = None,
684+
hits_settings: dict = None,
685+
**kw,
686+
) -> Box:
687+
"""Retrieve all objects
688+
689+
Args:
690+
name (str, optional): Object name. Must be unique in the domain.
691+
uid (str, optional): Object unique identifier.
692+
filter_results (str, optional): Search expression to filter objects by.\
693+
The provided text should be exactly the same as it would be given in SmartConsole Object Explorer.\
694+
The logical operators in the expression ('AND', 'OR') should be provided in capital letters.\
695+
he search involves both a IP search and a textual search in name, comment, tags etc.
696+
filter_settings (str, optional): Sets filter preferences.
697+
limit (int, optional): The maximal number of returned results. Defaults to 50 (between 1 and 500)
698+
offset (int, optional): Number of the results to initially skip. Defaults to 0
699+
order (List[dict], optional): Sorts results by the given field. By default the results are sorted in the \
700+
descending order by the session publish time.
701+
package (str, optional): Name of the package.
702+
show_as_ranges (bool, optional): When true, the source, destination and services & applications parameters are\
703+
displayed as ranges of IP addresses and port numbers rather than network objects. Objects that are not represented\
704+
using IP addresses or port numbers are presented as objects. In addition, the response of each rule does not\
705+
contain the parameters: source, source-negate, destination, destination-negate, service and service-negate,\
706+
but instead it contains the parameters: source-ranges, destination-ranges and service-ranges.\
707+
Note: Requesting to show rules as ranges is limited up to 20 rules per request, otherwise an error is returned.\
708+
If you wish to request more rules, use the offset and limit parameters to limit your request.
709+
show_hits (bool, optional): N/A
710+
use_object_dictionnary (bool, optional): N/A
711+
hits_settings (dict, optional): N/A
712+
713+
Keyword Args:
714+
**details_level (str, optional):
715+
The level of detail for some of the fields in the response can vary from showing only the UID value\
716+
of the object to a fully detailed representation of the object.
717+
**show_membership (bool, optional):
718+
Indicates whether to calculate and show "groups" field for every object in reply.
719+
**dereference_group_members (bool, optional):
720+
Indicates whether to dereference "members" field by details level for every object in reply.
721+
722+
Returns:
723+
:obj:`Box`: The response from the server
724+
725+
Examples:
726+
>>> firewall.access_control_nat.access_rule._show_all_access_rulebase()
727+
"""
728+
all_rules = None
729+
730+
# Get a timer
731+
timer_start = time.time()
732+
733+
# Made a first request to determine the total number of objects
734+
resp = self._show_partial_access_rulebase(
735+
name=name,
736+
uid=uid,
737+
filter_results=filter_results,
738+
filter_settings=filter_settings,
739+
limit=limit,
740+
offset=0,
741+
order=order,
742+
package=package,
743+
show_as_ranges=show_as_ranges,
744+
show_hits=show_hits,
745+
use_object_dictionnary=use_object_dictionnary,
746+
hits_settings=hits_settings,
747+
**kw,
748+
)
749+
750+
# Add the first results
751+
all_rules = resp
752+
753+
# Evaluate the number of requests to be done
754+
number_requests = int(resp.total / limit) + 1
755+
756+
logger.info(
757+
"access-rules - Total: "
758+
+ str(resp.total)
759+
+ " - Number of requests to do: "
760+
+ str(number_requests)
761+
+ " (limit set to "
762+
+ str(limit)
763+
+ "/request) - In progress..."
764+
)
765+
logger.debug(
766+
"access-rules - 1/"
767+
+ str(number_requests)
768+
+ " (limit set to "
769+
+ str(limit)
770+
+ "/request) exported... (offset:0)"
771+
)
772+
773+
for i in range(1, number_requests):
774+
resp = self._show_partial_access_rulebase(
775+
name=name,
776+
uid=uid,
777+
filter_results=filter_results,
778+
filter_settings=filter_settings,
779+
limit=limit,
780+
offset=i * limit,
781+
order=order,
782+
package=package,
783+
show_as_ranges=show_as_ranges,
784+
show_hits=show_hits,
785+
use_object_dictionnary=use_object_dictionnary,
786+
hits_settings=hits_settings,
787+
**kw,
788+
)
789+
790+
logger.debug(
791+
"access-rules - "
792+
+ str(i + 1)
793+
+ "/"
794+
+ str(number_requests)
795+
+ " (limit set to "
796+
+ str(limit)
797+
+ "/request) exported... (offset:"
798+
+ str(i)
799+
+ ")"
800+
)
801+
802+
all_rules.rulebase += resp.rulebase
803+
804+
# Finalize the output
805+
all_rules.to = all_rules.total
806+
807+
# End timer
808+
timer_diff = time.time() - timer_start
809+
810+
timer_text = ""
811+
812+
if round(timer_diff % 60) != 0:
813+
timer_text = (
814+
str(int(timer_diff / 60)) + "min " + str(round(timer_diff % 60)) + "s"
815+
) # pragma: no cover
816+
else:
817+
timer_text = "<1s"
818+
819+
logger.info(
820+
"access-rules - Total: "
821+
+ str(resp.total)
822+
+ " - Number of requests done: "
823+
+ str(number_requests)
824+
+ " (limit set to "
825+
+ str(limit)
826+
+ "/request) - Done in "
827+
+ timer_text
828+
)
829+
830+
return all_rules

0 commit comments

Comments
 (0)