catocli 2.1.2__py3-none-any.whl → 2.1.4__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.

Files changed (98) hide show
  1. catocli/Utils/clidriver.py +18 -18
  2. catocli/Utils/cliutils.py +165 -0
  3. catocli/Utils/csv_formatter.py +652 -0
  4. catocli/__init__.py +1 -1
  5. catocli/parsers/custom/export_rules/__init__.py +0 -4
  6. catocli/parsers/custom/export_sites/__init__.py +4 -3
  7. catocli/parsers/custom/export_sites/export_sites.py +198 -55
  8. catocli/parsers/custom/import_sites_to_tf/import_sites_to_tf.py +473 -393
  9. catocli/parsers/customParserApiClient.py +444 -38
  10. catocli/parsers/custom_private/__init__.py +19 -13
  11. catocli/parsers/mutation_accountManagement/__init__.py +21 -0
  12. catocli/parsers/mutation_accountManagement_disableAccount/README.md +15 -0
  13. catocli/parsers/mutation_admin/__init__.py +12 -0
  14. catocli/parsers/mutation_container/__init__.py +18 -0
  15. catocli/parsers/mutation_enterpriseDirectory/__init__.py +8 -0
  16. catocli/parsers/mutation_groups/__init__.py +6 -0
  17. catocli/parsers/mutation_hardware/__init__.py +2 -0
  18. catocli/parsers/mutation_policy/__init__.py +378 -0
  19. catocli/parsers/mutation_policy_antiMalwareFileHash_addRule/README.md +20 -0
  20. catocli/parsers/mutation_policy_antiMalwareFileHash_addSection/README.md +20 -0
  21. catocli/parsers/mutation_policy_antiMalwareFileHash_createPolicyRevision/README.md +20 -0
  22. catocli/parsers/mutation_policy_antiMalwareFileHash_discardPolicyRevision/README.md +20 -0
  23. catocli/parsers/mutation_policy_antiMalwareFileHash_moveRule/README.md +20 -0
  24. catocli/parsers/mutation_policy_antiMalwareFileHash_moveSection/README.md +20 -0
  25. catocli/parsers/mutation_policy_antiMalwareFileHash_publishPolicyRevision/README.md +20 -0
  26. catocli/parsers/mutation_policy_antiMalwareFileHash_removeRule/README.md +20 -0
  27. catocli/parsers/mutation_policy_antiMalwareFileHash_removeSection/README.md +20 -0
  28. catocli/parsers/mutation_policy_antiMalwareFileHash_updatePolicy/README.md +20 -0
  29. catocli/parsers/mutation_policy_antiMalwareFileHash_updateRule/README.md +20 -0
  30. catocli/parsers/mutation_policy_antiMalwareFileHash_updateSection/README.md +20 -0
  31. catocli/parsers/mutation_sandbox/__init__.py +4 -0
  32. catocli/parsers/mutation_site/__init__.py +72 -0
  33. catocli/parsers/mutation_sites/__init__.py +72 -0
  34. catocli/parsers/mutation_xdr/__init__.py +6 -0
  35. catocli/parsers/query_accountBySubdomain/__init__.py +2 -0
  36. catocli/parsers/query_accountManagement/__init__.py +2 -0
  37. catocli/parsers/query_accountMetrics/__init__.py +6 -0
  38. catocli/parsers/query_accountRoles/__init__.py +2 -0
  39. catocli/parsers/query_accountSnapshot/__init__.py +2 -0
  40. catocli/parsers/query_admin/__init__.py +2 -0
  41. catocli/parsers/query_admins/__init__.py +2 -0
  42. catocli/parsers/query_appStats/__init__.py +6 -0
  43. catocli/parsers/query_appStatsTimeSeries/README.md +3 -0
  44. catocli/parsers/query_appStatsTimeSeries/__init__.py +6 -0
  45. catocli/parsers/query_auditFeed/__init__.py +2 -0
  46. catocli/parsers/query_catalogs/__init__.py +2 -0
  47. catocli/parsers/query_container/__init__.py +2 -0
  48. catocli/parsers/query_devices/README.md +1 -1
  49. catocli/parsers/query_devices/__init__.py +2 -0
  50. catocli/parsers/query_enterpriseDirectory/__init__.py +2 -0
  51. catocli/parsers/query_entityLookup/__init__.py +2 -0
  52. catocli/parsers/query_events/__init__.py +2 -0
  53. catocli/parsers/query_eventsFeed/__init__.py +2 -0
  54. catocli/parsers/query_eventsTimeSeries/__init__.py +2 -0
  55. catocli/parsers/query_groups/__init__.py +6 -0
  56. catocli/parsers/query_hardware/README.md +1 -1
  57. catocli/parsers/query_hardware/__init__.py +2 -0
  58. catocli/parsers/query_hardwareManagement/__init__.py +2 -0
  59. catocli/parsers/query_licensing/__init__.py +2 -0
  60. catocli/parsers/query_policy/__init__.py +37 -0
  61. catocli/parsers/query_policy_antiMalwareFileHash_policy/README.md +19 -0
  62. catocli/parsers/query_popLocations/__init__.py +2 -0
  63. catocli/parsers/query_sandbox/__init__.py +2 -0
  64. catocli/parsers/query_servicePrincipalAdmin/__init__.py +2 -0
  65. catocli/parsers/query_site/__init__.py +33 -0
  66. catocli/parsers/query_siteLocation/__init__.py +2 -0
  67. catocli/parsers/query_site_siteGeneralDetails/README.md +19 -0
  68. catocli/parsers/query_socketPortMetrics/__init__.py +2 -0
  69. catocli/parsers/query_socketPortMetricsTimeSeries/__init__.py +6 -0
  70. catocli/parsers/query_subDomains/__init__.py +2 -0
  71. catocli/parsers/query_xdr/__init__.py +4 -0
  72. catocli/parsers/raw/__init__.py +3 -1
  73. {catocli-2.1.2.dist-info → catocli-2.1.4.dist-info}/METADATA +1 -1
  74. {catocli-2.1.2.dist-info → catocli-2.1.4.dist-info}/RECORD +98 -66
  75. models/mutation.accountManagement.disableAccount.json +545 -0
  76. models/mutation.policy.antiMalwareFileHash.addRule.json +2068 -0
  77. models/mutation.policy.antiMalwareFileHash.addSection.json +1350 -0
  78. models/mutation.policy.antiMalwareFileHash.createPolicyRevision.json +1822 -0
  79. models/mutation.policy.antiMalwareFileHash.discardPolicyRevision.json +1758 -0
  80. models/mutation.policy.antiMalwareFileHash.moveRule.json +1552 -0
  81. models/mutation.policy.antiMalwareFileHash.moveSection.json +1251 -0
  82. models/mutation.policy.antiMalwareFileHash.publishPolicyRevision.json +1813 -0
  83. models/mutation.policy.antiMalwareFileHash.removeRule.json +1204 -0
  84. models/mutation.policy.antiMalwareFileHash.removeSection.json +954 -0
  85. models/mutation.policy.antiMalwareFileHash.updatePolicy.json +1834 -0
  86. models/mutation.policy.antiMalwareFileHash.updateRule.json +1757 -0
  87. models/mutation.policy.antiMalwareFileHash.updateSection.json +1105 -0
  88. models/mutation.site.updateSiteGeneralDetails.json +3 -3
  89. models/mutation.sites.updateSiteGeneralDetails.json +3 -3
  90. models/query.devices.json +249 -2
  91. models/query.hardware.json +224 -0
  92. models/query.policy.antiMalwareFileHash.policy.json +1583 -0
  93. models/query.site.siteGeneralDetails.json +899 -0
  94. schema/catolib.py +52 -14
  95. {catocli-2.1.2.dist-info → catocli-2.1.4.dist-info}/WHEEL +0 -0
  96. {catocli-2.1.2.dist-info → catocli-2.1.4.dist-info}/entry_points.txt +0 -0
  97. {catocli-2.1.2.dist-info → catocli-2.1.4.dist-info}/licenses/LICENSE +0 -0
  98. {catocli-2.1.2.dist-info → catocli-2.1.4.dist-info}/top_level.txt +0 -0
@@ -49,18 +49,18 @@ from ..parsers.query_devices import query_devices_parse
49
49
  from ..parsers.query_catalogs import query_catalogs_parse
50
50
  from ..parsers.query_site import query_site_parse
51
51
  from ..parsers.query_xdr import query_xdr_parse
52
- from ..parsers.query_policy import query_policy_parse
53
52
  from ..parsers.query_groups import query_groups_parse
53
+ from ..parsers.query_policy import query_policy_parse
54
54
  from ..parsers.mutation_xdr import mutation_xdr_parse
55
- from ..parsers.mutation_site import mutation_site_parse
56
55
  from ..parsers.mutation_sites import mutation_sites_parse
56
+ from ..parsers.mutation_site import mutation_site_parse
57
57
  from ..parsers.mutation_container import mutation_container_parse
58
58
  from ..parsers.mutation_admin import mutation_admin_parse
59
- from ..parsers.mutation_policy import mutation_policy_parse
60
59
  from ..parsers.mutation_accountManagement import mutation_accountManagement_parse
61
60
  from ..parsers.mutation_sandbox import mutation_sandbox_parse
62
- from ..parsers.mutation_groups import mutation_groups_parse
63
61
  from ..parsers.mutation_hardware import mutation_hardware_parse
62
+ from ..parsers.mutation_groups import mutation_groups_parse
63
+ from ..parsers.mutation_policy import mutation_policy_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()
@@ -143,6 +134,8 @@ parser = argparse.ArgumentParser(prog='catocli', usage='%(prog)s <operationType>
143
134
  parser.add_argument('--version', action='version', version=catocli.__version__)
144
135
  parser.add_argument('-H', '--header', action='append', dest='headers', help='Add custom headers in "Key: Value" format. Can be used multiple times.')
145
136
  parser.add_argument('--headers-file', dest='headers_file', help='Load headers from a file. Each line should contain a header in "Key: Value" format.')
137
+ parser.add_argument('-n', '--stream-events', dest='stream_events', help='Send events over network to host:port TCP')
138
+ parser.add_argument('-z', '--sentinel', dest='sentinel', help='Send events to Sentinel customerid:sharedkey')
146
139
  subparsers = parser.add_subparsers()
147
140
 
148
141
  # Version command - enhanced with update checking
@@ -190,18 +183,18 @@ query_devices_parser = query_devices_parse(query_subparsers)
190
183
  query_catalogs_parser = query_catalogs_parse(query_subparsers)
191
184
  query_site_parser = query_site_parse(query_subparsers)
192
185
  query_xdr_parser = query_xdr_parse(query_subparsers)
193
- query_policy_parser = query_policy_parse(query_subparsers)
194
186
  query_groups_parser = query_groups_parse(query_subparsers)
187
+ query_policy_parser = query_policy_parse(query_subparsers)
195
188
  mutation_xdr_parser = mutation_xdr_parse(mutation_subparsers)
196
- mutation_site_parser = mutation_site_parse(mutation_subparsers)
197
189
  mutation_sites_parser = mutation_sites_parse(mutation_subparsers)
190
+ mutation_site_parser = mutation_site_parse(mutation_subparsers)
198
191
  mutation_container_parser = mutation_container_parse(mutation_subparsers)
199
192
  mutation_admin_parser = mutation_admin_parse(mutation_subparsers)
200
- mutation_policy_parser = mutation_policy_parse(mutation_subparsers)
201
193
  mutation_accountManagement_parser = mutation_accountManagement_parse(mutation_subparsers)
202
194
  mutation_sandbox_parser = mutation_sandbox_parse(mutation_subparsers)
203
- mutation_groups_parser = mutation_groups_parse(mutation_subparsers)
204
195
  mutation_hardware_parser = mutation_hardware_parse(mutation_subparsers)
196
+ mutation_groups_parser = mutation_groups_parse(mutation_subparsers)
197
+ mutation_policy_parser = mutation_policy_parse(mutation_subparsers)
205
198
  mutation_enterpriseDirectory_parser = mutation_enterpriseDirectory_parse(mutation_subparsers)
206
199
 
207
200
 
@@ -285,7 +278,14 @@ def main(args=None):
285
278
  print(response)
286
279
  else:
287
280
  if response!=None:
288
- print(json.dumps(response[0], sort_keys=True, indent=4))
281
+ # Check if this is CSV output
282
+ if (isinstance(response, list) and len(response) > 0 and
283
+ isinstance(response[0], dict) and "__csv_output__" in response[0]):
284
+ # Print CSV output directly without JSON formatting
285
+ print(response[0]["__csv_output__"], end='')
286
+ else:
287
+ # Standard JSON output
288
+ print(json.dumps(response[0], sort_keys=True, indent=4))
289
289
  except KeyboardInterrupt:
290
290
  print('Operation cancelled by user (Ctrl+C).')
291
291
  exit(130) # Standard exit code for SIGINT
@@ -0,0 +1,165 @@
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
+
65
+
66
+ def get_cli_settings_path():
67
+ """
68
+ Get the path to the CLI settings file, trying different locations.
69
+
70
+ Returns:
71
+ str or None: Path to the settings file if found, None otherwise
72
+ """
73
+ possible_paths = [
74
+ # Repository location (for development)
75
+ os.path.join(os.path.dirname(__file__), '../../clisettings.json'),
76
+ # Current directory
77
+ os.path.join(os.getcwd(), 'clisettings.json'),
78
+ ]
79
+
80
+ for path in possible_paths:
81
+ if os.path.exists(path):
82
+ return path
83
+
84
+ return None
85
+
86
+
87
+ def load_json_file(file_path, encoding='utf-8'):
88
+ """
89
+ Load a JSON file with error handling.
90
+
91
+ Args:
92
+ file_path (str): Path to the JSON file
93
+ encoding (str): File encoding (default: utf-8)
94
+
95
+ Returns:
96
+ dict or None: The loaded JSON data, or None if loading fails
97
+ """
98
+ try:
99
+ with open(file_path, 'r', encoding=encoding) as f:
100
+ return json.load(f)
101
+ except (FileNotFoundError, json.JSONDecodeError, OSError) as e:
102
+ return None
103
+
104
+
105
+ def save_json_file(data, file_path, encoding='utf-8', indent=2):
106
+ """
107
+ Save data to a JSON file with error handling.
108
+
109
+ Args:
110
+ data: Data to save
111
+ file_path (str): Path to save the JSON file
112
+ encoding (str): File encoding (default: utf-8)
113
+ indent (int): JSON indentation (default: 2)
114
+
115
+ Returns:
116
+ bool: True if successful, False otherwise
117
+ """
118
+ try:
119
+ # Ensure the directory exists
120
+ os.makedirs(os.path.dirname(file_path), exist_ok=True)
121
+
122
+ with open(file_path, 'w', encoding=encoding) as f:
123
+ json.dump(data, f, indent=indent, ensure_ascii=False)
124
+ return True
125
+ except (OSError, TypeError, ValueError) as e:
126
+ return False
127
+
128
+
129
+ def load_private_settings():
130
+ """
131
+ Load private settings from ~/.cato/settings.json in an OS-compatible way.
132
+
133
+ This function constructs the path to ~/.cato/settings.json using os.path methods
134
+ for cross-platform compatibility (Windows, Mac, Linux).
135
+
136
+ Returns:
137
+ dict: The privateCommands section from the settings file, or empty dict if not found
138
+ """
139
+ # Use os.path.join for OS-compatible path construction
140
+ cato_dir = os.path.join(os.path.expanduser("~"), ".cato")
141
+ settings_file = os.path.join(cato_dir, "settings.json")
142
+
143
+ try:
144
+ with open(settings_file, 'r', encoding='utf-8') as f:
145
+ settings = json.load(f)
146
+ return settings.get('privateCommands', {})
147
+ except (FileNotFoundError, json.JSONDecodeError, KeyError, OSError):
148
+ return {}
149
+
150
+
151
+ def ensure_directory_exists(directory_path):
152
+ """
153
+ Ensure a directory exists, creating it if necessary.
154
+
155
+ Args:
156
+ directory_path (str): Path to the directory
157
+
158
+ Returns:
159
+ bool: True if directory exists or was created successfully
160
+ """
161
+ try:
162
+ os.makedirs(directory_path, exist_ok=True)
163
+ return True
164
+ except OSError:
165
+ return False