catocli 2.1.2__py3-none-any.whl → 2.1.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of catocli might be problematic. Click here for more details.

@@ -59,8 +59,8 @@ from ..parsers.mutation_admin import mutation_admin_parse
59
59
  from ..parsers.mutation_policy import mutation_policy_parse
60
60
  from ..parsers.mutation_accountManagement import mutation_accountManagement_parse
61
61
  from ..parsers.mutation_sandbox import mutation_sandbox_parse
62
- from ..parsers.mutation_groups import mutation_groups_parse
63
62
  from ..parsers.mutation_hardware import mutation_hardware_parse
63
+ from ..parsers.mutation_groups import mutation_groups_parse
64
64
  from ..parsers.mutation_enterpriseDirectory import mutation_enterpriseDirectory_parse
65
65
 
66
66
  def show_version_info(args, configuration=None):
@@ -85,15 +85,6 @@ def show_version_info(args, configuration=None):
85
85
  else:
86
86
  print("Unable to check for updates (check your internet connection)")
87
87
  return [{"success": True, "current_version": catocli.__version__, "latest_version": latest_version if not args.current_only else None}]
88
-
89
- def load_private_settings():
90
- # Load private settings from ~/.cato/settings.json
91
- settings_file = os.path.expanduser("~/.cato/settings.json")
92
- try:
93
- with open(settings_file, 'r') as f:
94
- return json.load(f)
95
- except (FileNotFoundError, json.JSONDecodeError):
96
- return {}
97
88
 
98
89
  def get_configuration(skip_api_key=False):
99
90
  configuration = Configuration()
@@ -200,8 +191,8 @@ mutation_admin_parser = mutation_admin_parse(mutation_subparsers)
200
191
  mutation_policy_parser = mutation_policy_parse(mutation_subparsers)
201
192
  mutation_accountManagement_parser = mutation_accountManagement_parse(mutation_subparsers)
202
193
  mutation_sandbox_parser = mutation_sandbox_parse(mutation_subparsers)
203
- mutation_groups_parser = mutation_groups_parse(mutation_subparsers)
204
194
  mutation_hardware_parser = mutation_hardware_parse(mutation_subparsers)
195
+ mutation_groups_parser = mutation_groups_parse(mutation_subparsers)
205
196
  mutation_enterpriseDirectory_parser = mutation_enterpriseDirectory_parse(mutation_subparsers)
206
197
 
207
198
 
@@ -0,0 +1,178 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ General CLI utilities for catocli
4
+
5
+ This module contains general-purpose utility functions used across the catocli
6
+ package, including settings loading and configuration management.
7
+ """
8
+
9
+ import os
10
+ import json
11
+
12
+
13
+ # Import for resource handling
14
+ try:
15
+ # Python 3.9+
16
+ from importlib.resources import files
17
+ def get_package_resource(package, filename):
18
+ return files(package).joinpath(filename).read_text(encoding='utf-8')
19
+ except ImportError:
20
+ try:
21
+ # Python 3.7-3.8
22
+ from importlib.resources import read_text
23
+ def get_package_resource(package, filename):
24
+ return read_text(package, filename, encoding='utf-8')
25
+ except ImportError:
26
+ try:
27
+ # Fallback to pkg_resources
28
+ import pkg_resources
29
+ def get_package_resource(package, filename):
30
+ return pkg_resources.resource_string(package, filename).decode('utf-8')
31
+ except ImportError:
32
+ # Final fallback - no package resources available
33
+ def get_package_resource(package, filename):
34
+ raise ImportError("No resource handling module available")
35
+
36
+
37
+ def load_cli_settings():
38
+ """
39
+ Load clisettings.json from multiple possible locations:
40
+ 1. Package resource (for installed packages)
41
+ 2. Repository location (for development)
42
+
43
+ Returns:
44
+ dict: The loaded settings or default settings if loading fails
45
+ """
46
+ settings_locations = [
47
+ # Try package resource first (for installed packages)
48
+ lambda: json.loads(get_package_resource('catocli', 'clisettings.json')),
49
+ # Try repository location (for development)
50
+ lambda: json.load(open(os.path.join(os.path.dirname(__file__), '../../clisettings.json'), 'r', encoding='utf-8'))
51
+ ]
52
+
53
+ for i, load_func in enumerate(settings_locations):
54
+ try:
55
+ settings = load_func()
56
+ if settings:
57
+ return settings
58
+ except (FileNotFoundError, json.JSONDecodeError, ImportError, OSError, ModuleNotFoundError) as e:
59
+ # Continue to next location
60
+ continue
61
+
62
+ # If all locations fail, return default settings for socket export
63
+ return {
64
+ "export_by_socket_type": {
65
+ "SOCKET_X1500": True,
66
+ "SOCKET_X1600": True,
67
+ "SOCKET_X1600_LTE": True,
68
+ "SOCKET_X1700": True
69
+ },
70
+ "default_socket_interface_map": {
71
+ "SOCKET_X1500": "LAN1",
72
+ "SOCKET_X1600": "INT_5",
73
+ "SOCKET_X1600_LTE": "INT_5",
74
+ "SOCKET_X1700": "INT_3"
75
+ }
76
+ }
77
+
78
+
79
+ def get_cli_settings_path():
80
+ """
81
+ Get the path to the CLI settings file, trying different locations.
82
+
83
+ Returns:
84
+ str or None: Path to the settings file if found, None otherwise
85
+ """
86
+ possible_paths = [
87
+ # Repository location (for development)
88
+ os.path.join(os.path.dirname(__file__), '../../clisettings.json'),
89
+ # Current directory
90
+ os.path.join(os.getcwd(), 'clisettings.json'),
91
+ ]
92
+
93
+ for path in possible_paths:
94
+ if os.path.exists(path):
95
+ return path
96
+
97
+ return None
98
+
99
+
100
+ def load_json_file(file_path, encoding='utf-8'):
101
+ """
102
+ Load a JSON file with error handling.
103
+
104
+ Args:
105
+ file_path (str): Path to the JSON file
106
+ encoding (str): File encoding (default: utf-8)
107
+
108
+ Returns:
109
+ dict or None: The loaded JSON data, or None if loading fails
110
+ """
111
+ try:
112
+ with open(file_path, 'r', encoding=encoding) as f:
113
+ return json.load(f)
114
+ except (FileNotFoundError, json.JSONDecodeError, OSError) as e:
115
+ return None
116
+
117
+
118
+ def save_json_file(data, file_path, encoding='utf-8', indent=2):
119
+ """
120
+ Save data to a JSON file with error handling.
121
+
122
+ Args:
123
+ data: Data to save
124
+ file_path (str): Path to save the JSON file
125
+ encoding (str): File encoding (default: utf-8)
126
+ indent (int): JSON indentation (default: 2)
127
+
128
+ Returns:
129
+ bool: True if successful, False otherwise
130
+ """
131
+ try:
132
+ # Ensure the directory exists
133
+ os.makedirs(os.path.dirname(file_path), exist_ok=True)
134
+
135
+ with open(file_path, 'w', encoding=encoding) as f:
136
+ json.dump(data, f, indent=indent, ensure_ascii=False)
137
+ return True
138
+ except (OSError, TypeError, ValueError) as e:
139
+ return False
140
+
141
+
142
+ def load_private_settings():
143
+ """
144
+ Load private settings from ~/.cato/settings.json in an OS-compatible way.
145
+
146
+ This function constructs the path to ~/.cato/settings.json using os.path methods
147
+ for cross-platform compatibility (Windows, Mac, Linux).
148
+
149
+ Returns:
150
+ dict: The privateCommands section from the settings file, or empty dict if not found
151
+ """
152
+ # Use os.path.join for OS-compatible path construction
153
+ cato_dir = os.path.join(os.path.expanduser("~"), ".cato")
154
+ settings_file = os.path.join(cato_dir, "settings.json")
155
+
156
+ try:
157
+ with open(settings_file, 'r', encoding='utf-8') as f:
158
+ settings = json.load(f)
159
+ return settings.get('privateCommands', {})
160
+ except (FileNotFoundError, json.JSONDecodeError, KeyError, OSError):
161
+ return {}
162
+
163
+
164
+ def ensure_directory_exists(directory_path):
165
+ """
166
+ Ensure a directory exists, creating it if necessary.
167
+
168
+ Args:
169
+ directory_path (str): Path to the directory
170
+
171
+ Returns:
172
+ bool: True if directory exists or was created successfully
173
+ """
174
+ try:
175
+ os.makedirs(directory_path, exist_ok=True)
176
+ return True
177
+ except OSError:
178
+ return False
catocli/__init__.py CHANGED
@@ -1,2 +1,2 @@
1
- __version__ = "2.1.2"
1
+ __version__ = "2.1.3"
2
2
  __cato_host__ = "https://api.catonetworks.com/api/v1/graphql2"
@@ -6,6 +6,7 @@ from datetime import datetime
6
6
  from graphql_client.api.call_api import ApiClient, CallApi
7
7
  from graphql_client.api_client import ApiException
8
8
  from ..customLib import writeDataToFile, makeCall, getAccountID
9
+ from ....Utils.cliutils import load_cli_settings
9
10
 
10
11
  def export_socket_site_to_json(args, configuration):
11
12
  """
@@ -20,9 +21,8 @@ def export_socket_site_to_json(args, configuration):
20
21
  }
21
22
 
22
23
  try:
23
- settings = {}
24
- with open(os.path.join(os.path.dirname(__file__), '../../../../settings.json'), 'r', encoding='utf-8') as f:
25
- settings = json.load(f)
24
+ # Load CLI settings using the robust function
25
+ settings = load_cli_settings()
26
26
 
27
27
  account_id = getAccountID(args, configuration)
28
28
  # Get account snapshot with siteIDs if provided
@@ -4,21 +4,9 @@ Private commands parser for custom GraphQL payloads
4
4
  Dynamically loads commands from ~/.cato/settings.json
5
5
  """
6
6
 
7
- import os
8
- import json
9
7
  import argparse
10
8
  from ..customParserApiClient import createPrivateRequest, get_private_help
11
-
12
-
13
- def load_private_settings():
14
- """Load private settings from ~/.cato/settings.json"""
15
- settings_file = os.path.expanduser("~/.cato/settings.json")
16
- try:
17
- with open(settings_file, 'r') as f:
18
- settings = json.load(f)
19
- return settings.get('privateCommands', {})
20
- except (FileNotFoundError, json.JSONDecodeError, KeyError):
21
- return {}
9
+ from ...Utils.cliutils import load_private_settings
22
10
 
23
11
 
24
12
  def private_parse(subparsers):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: catocli
3
- Version: 2.1.2
3
+ Version: 2.1.3
4
4
  Summary: Cato Networks cli wrapper for the GraphQL API.
5
5
  Home-page: https://github.com/Cato-Networks/cato-cli
6
6
  Author: Cato Networks
@@ -1,6 +1,7 @@
1
- catocli/__init__.py,sha256=nkeG61dZacf80zgL7kiI_S6xtj6mfFsjFdXgBQaOcNI,85
1
+ catocli/__init__.py,sha256=SHWJi8J--jgEDRdBfW_GHi46aMM7q2x6f5m6yC9wL3s,85
2
2
  catocli/__main__.py,sha256=6Z0ns_k_kUcz1Qtrn1u7UyUnqB-3e85jM_nppOwFsv4,217
3
- catocli/Utils/clidriver.py,sha256=HvEGccIuWf6A0g4Gebcgd_XkMWoxA0ENmBrOumyJX4M,15490
3
+ catocli/Utils/clidriver.py,sha256=U2lntPXwRpTlnktU_WABhXuTDX_uws8IrzpmgSCXDJc,15184
4
+ catocli/Utils/cliutils.py,sha256=kj8huRnccTzjLaHYLQmNXQ2RivGlVPFcXqHAMiiJyqo,5626
4
5
  catocli/Utils/profile_manager.py,sha256=Stch-cU2rLA7r07hETIRsvG_JxpQx3Q42QwpfD7Qd2I,6379
5
6
  catocli/Utils/version_checker.py,sha256=tCtsCn7xxMIxOm6cWJSA_yPt0j4mNMK4iWSJej0yM6A,6696
6
7
  catocli/parsers/customParserApiClient.py,sha256=NHJhssY_0LrL8V9h7NucMztR95D44_NwKlpKLN9ACnU,49007
@@ -12,12 +13,12 @@ catocli/parsers/custom/customLib.py,sha256=Nv-agL_ewpe1x6GbwWCRb_Ey-NVW_w9L6qWwE
12
13
  catocli/parsers/custom/export_rules/__init__.py,sha256=Cci1LwMN9VzwPuHOXqUDFORujDI96dJuN-YSccGlQZU,2564
13
14
  catocli/parsers/custom/export_rules/export_rules.py,sha256=gXig4NC29yC5nW48ri-j0FEnaTz_kxKiuLF5y-5fZ_4,15646
14
15
  catocli/parsers/custom/export_sites/__init__.py,sha256=WnTRNA4z4IS0rKR9r_UfuGv3bxp8nlt4YNH1Sed4toU,1378
15
- catocli/parsers/custom/export_sites/export_sites.py,sha256=eGWW9swDB-wxFLxh7XNGJGCnW6ynwtD3HNIyyWYIdq8,24608
16
+ catocli/parsers/custom/export_sites/export_sites.py,sha256=5dgrpWTVyWXa4sVhCJ2hOlvJOpyDssSBIFSdDo0OI1M,24575
16
17
  catocli/parsers/custom/import_rules_to_tf/__init__.py,sha256=jFCFceFv8zDW7nGLZOXkFE6NXAMPYRwKQwTbhSawYdM,3908
17
18
  catocli/parsers/custom/import_rules_to_tf/import_rules_to_tf.py,sha256=WlyTDxUtWchu9CDs73ILHDfNXCAh7jFARBEKk5WWhwM,18714
18
19
  catocli/parsers/custom/import_sites_to_tf/__init__.py,sha256=0EyCGY2qV4wxMoFfqBPs5FoMc0Ufr7J7Ciygb6Xx8Fc,2925
19
20
  catocli/parsers/custom/import_sites_to_tf/import_sites_to_tf.py,sha256=KND-eQOS_rFYVAX01Gm5ChxE8DtHZ1edS0SizoBqyx4,42880
20
- catocli/parsers/custom_private/__init__.py,sha256=0pvXnC9B9_hbMgN26urIk9BnO1jjjgQttKygPriYnfE,4176
21
+ catocli/parsers/custom_private/__init__.py,sha256=rLhlAc8G7YvAyPmCXpUmLXIy4_N1gN0I5GWKX9srMxE,3826
21
22
  catocli/parsers/mutation_accountManagement/README.md,sha256=8ipbdTU8FAAfiH3IYlTZkTbLpPtO0fMblra7Zi8vwAI,249
22
23
  catocli/parsers/mutation_accountManagement/__init__.py,sha256=QChMssZKAnKrQ-xbXUYpgzmKa6OvtKw_jZXa2WufbJ8,5462
23
24
  catocli/parsers/mutation_accountManagement_addAccount/README.md,sha256=5PNnx2oY8JmoxEdJekUdmvsHnBccdaHeCYIVsAYXNBI,814
@@ -346,7 +347,7 @@ catocli/parsers/query_xdr_stories/README.md,sha256=eQJ81YiergQEhABkxi1yyzE_UXtS0
346
347
  catocli/parsers/query_xdr_story/README.md,sha256=_JYyMJ8GYOZ1dv61QqLyhVoEubXAm2p3QqFKdfohQOE,813
347
348
  catocli/parsers/raw/README.md,sha256=qvDLcg7U12yqacIQStOPtkqTsTLltJ06SSVmbqvlZhY,739
348
349
  catocli/parsers/raw/__init__.py,sha256=nub9Dth2s9WMXIlKA_BQKetooLjDYg9pREy01G6Rnb4,1107
349
- catocli-2.1.2.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
350
+ catocli-2.1.3.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
350
351
  graphql_client/__init__.py,sha256=2nxD4YsWoOnALXi5cXbmtIN_i0NL_eyDTQRTxs52mkI,315
351
352
  graphql_client/api_client.py,sha256=2Rc1Zo1xH9Jnk1AO68kLSofTShkZwSVF-WkVtczfIc4,5786
352
353
  graphql_client/api_client_types.py,sha256=dM3zl6FA5SSp6nR6KmLfTL1BKaXX9uPMCZAm4v_FiUs,11569
@@ -604,7 +605,7 @@ models/query.socketPortMetricsTimeSeries.json,sha256=PHT_x1YaP8NQpaHXA4VWsZ4kC7W
604
605
  models/query.subDomains.json,sha256=BkReQmylHZMv1iIakX984na9EKd_m0sPC0a-COsCxRI,7036
605
606
  models/query.xdr.stories.json,sha256=a3rQ9j8Ru-iidGztB1yFnYSTTlJpPcDkhoI3phMdByk,714509
606
607
  models/query.xdr.story.json,sha256=A3M-_cBIfup6vxG5nvAEH0EGRdEwkg_-G2lQR6eveB8,152375
607
- schema/catolib.py,sha256=0BYjM2_Bpg4klAc_uu0NrE27H3jYC8Xi_lplWb5dNSA,71518
608
+ schema/catolib.py,sha256=uLDSVKF7No9JhWrxsiWMJ9vJZmc-9iKvDjDzIgyinXg,71215
608
609
  schema/importSchema.py,sha256=LvXjylxsOWDcdceDE8nazOG1xcstxLGwyoVWSzW2Eg4,2508
609
610
  scripts/catolib.py,sha256=6QaGZaHj1waZuta8gUFsfXmyoDiLabpU9gwnyq7pSXg,2145
610
611
  scripts/export_if_rules_to_json.py,sha256=sTYzUbAtiFTy9vKpnyO8Sljshvg0qKd2gadanpeRVAM,10076
@@ -652,8 +653,8 @@ vendor/urllib3/util/timeout.py,sha256=4eT1FVeZZU7h7mYD1Jq2OXNe4fxekdNvhoWUkZusRp
652
653
  vendor/urllib3/util/url.py,sha256=wHORhp80RAXyTlAIkTqLFzSrkU7J34ZDxX-tN65MBZk,15213
653
654
  vendor/urllib3/util/util.py,sha256=j3lbZK1jPyiwD34T8IgJzdWEZVT-4E-0vYIJi9UjeNA,1146
654
655
  vendor/urllib3/util/wait.py,sha256=_ph8IrUR3sqPqi0OopQgJUlH4wzkGeM5CiyA7XGGtmI,4423
655
- catocli-2.1.2.dist-info/METADATA,sha256=BjsH_7ulOhm7DQq-IavFWgGguc8_SOADiPm62lx4sUg,1286
656
- catocli-2.1.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
657
- catocli-2.1.2.dist-info/entry_points.txt,sha256=p4k9Orre6aWcqVrNmBbckmCs39h-1naMxRo2AjWmWZ4,50
658
- catocli-2.1.2.dist-info/top_level.txt,sha256=F4qSgcjcW5wR9EFrO8Ud06F7ZQGFr04a9qALNQDyVxU,52
659
- catocli-2.1.2.dist-info/RECORD,,
656
+ catocli-2.1.3.dist-info/METADATA,sha256=H6wiAK-yoJ97WgeMD_6cOI19d_WW5QvFY64Kk_aICrs,1286
657
+ catocli-2.1.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
658
+ catocli-2.1.3.dist-info/entry_points.txt,sha256=p4k9Orre6aWcqVrNmBbckmCs39h-1naMxRo2AjWmWZ4,50
659
+ catocli-2.1.3.dist-info/top_level.txt,sha256=F4qSgcjcW5wR9EFrO8Ud06F7ZQGFr04a9qALNQDyVxU,52
660
+ catocli-2.1.3.dist-info/RECORD,,
schema/catolib.py CHANGED
@@ -94,7 +94,7 @@ def parseSchema(schema):
94
94
  print(" - Loading settings and initializing...")
95
95
 
96
96
  # Load settings to get childOperationParent and childOperationObjects configuration
97
- settings = loadJSON("../settings.json")
97
+ settings = loadJSON("../clisettings.json")
98
98
  childOperationParent = settings.get("childOperationParent", {})
99
99
  childOperationObjects = settings.get("childOperationObjects", {})
100
100
 
@@ -786,15 +786,6 @@ def show_version_info(args, configuration=None):
786
786
  else:
787
787
  print("Unable to check for updates (check your internet connection)")
788
788
  return [{"success": True, "current_version": catocli.__version__, "latest_version": latest_version if not args.current_only else None}]
789
-
790
- def load_private_settings():
791
- # Load private settings from ~/.cato/settings.json
792
- settings_file = os.path.expanduser("~/.cato/settings.json")
793
- try:
794
- with open(settings_file, 'r') as f:
795
- return json.load(f)
796
- except (FileNotFoundError, json.JSONDecodeError):
797
- return {}
798
789
 
799
790
  def get_configuration(skip_api_key=False):
800
791
  configuration = Configuration()