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
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()
@@ -840,6 +831,8 @@ parser = argparse.ArgumentParser(prog='catocli', usage='%(prog)s <operationType>
840
831
  parser.add_argument('--version', action='version', version=catocli.__version__)
841
832
  parser.add_argument('-H', '--header', action='append', dest='headers', help='Add custom headers in "Key: Value" format. Can be used multiple times.')
842
833
  parser.add_argument('--headers-file', dest='headers_file', help='Load headers from a file. Each line should contain a header in "Key: Value" format.')
834
+ parser.add_argument('-n', '--stream-events', dest='stream_events', help='Send events over network to host:port TCP')
835
+ parser.add_argument('-z', '--sentinel', dest='sentinel', help='Send events to Sentinel customerid:sharedkey')
843
836
  subparsers = parser.add_subparsers()
844
837
 
845
838
  # Version command - enhanced with update checking
@@ -944,7 +937,14 @@ def main(args=None):
944
937
  print(response)
945
938
  else:
946
939
  if response!=None:
947
- print(json.dumps(response[0], sort_keys=True, indent=4))
940
+ # Check if this is CSV output
941
+ if (isinstance(response, list) and len(response) > 0 and
942
+ isinstance(response[0], dict) and "__csv_output__" in response[0]):
943
+ # Print CSV output directly without JSON formatting
944
+ print(response[0]["__csv_output__"], end='')
945
+ else:
946
+ # Standard JSON output
947
+ print(json.dumps(response[0], sort_keys=True, indent=4))
948
948
  except KeyboardInterrupt:
949
949
  print('Operation cancelled by user (Ctrl+C).')
950
950
  exit(130) # Standard exit code for SIGINT
@@ -967,6 +967,10 @@ def writeOperationParsers(catoApiSchema):
967
967
  """Write operation parsers - thread-safe implementation"""
968
968
  parserMapping = {"query":{},"mutation":{}}
969
969
 
970
+ # Load settings to get CSV-supported operations
971
+ settings = loadJSON("../clisettings.json")
972
+ csv_supported_operations = settings.get("queryOperationCsvOutput", {})
973
+
970
974
  ## Write the raw query parser ##
971
975
  cliDriverStr =f"""
972
976
  from ..customParserApiClient import createRawRequest, get_help
@@ -976,9 +980,11 @@ def raw_parse(raw_parser):
976
980
  raw_parser.add_argument('-t', const=True, default=False, nargs='?', help='Print GraphQL query without sending API call')
977
981
  raw_parser.add_argument('-v', const=True, default=False, nargs='?', help='Verbose output')
978
982
  raw_parser.add_argument('-p', const=True, default=False, nargs='?', help='Pretty print')
983
+ raw_parser.add_argument('-n', '--stream-events', dest='stream_events', help='Send events over network to host:port TCP')
984
+ raw_parser.add_argument('-z', '--sentinel', dest='sentinel', help='Send events to Sentinel customerid:sharedkey')
979
985
  raw_parser.add_argument('-H', '--header', action='append', dest='headers', help='Add custom headers in "Key: Value" format. Can be used multiple times.')
980
986
  raw_parser.add_argument('--headers-file', dest='headers_file', help='Load headers from a file. Each line should contain a header in "Key: Value" format.')
981
- raw_parser.add_argument('--endpoint', dest='endpoint', help='Override the API endpoint URL (e.g., https://api.catonetworks.com/api/v1/graphql2)')
987
+ raw_parser.add_argument('-e', '--endpoint', dest='endpoint', help='Override the API endpoint URL (e.g., https://api.catonetworks.com/api/v1/graphql2)')
982
988
  raw_parser.set_defaults(func=createRawRequest,operation_name='raw')
983
989
  """
984
990
  parserPath = "../catocli/parsers/raw"
@@ -1000,6 +1006,8 @@ def query_siteLocation_parse(query_subparsers):
1000
1006
  query_siteLocation_parser.add_argument('-t', const=True, default=False, nargs='?', help='Print GraphQL query without sending API call')
1001
1007
  query_siteLocation_parser.add_argument('-v', const=True, default=False, nargs='?', help='Verbose output')
1002
1008
  query_siteLocation_parser.add_argument('-p', const=True, default=False, nargs='?', help='Pretty print')
1009
+ query_siteLocation_parser.add_argument('-n', '--stream-events', dest='stream_events', help='Send events over network to host:port TCP')
1010
+ query_siteLocation_parser.add_argument('-z', '--sentinel', dest='sentinel', help='Send events to Sentinel customerid:sharedkey')
1003
1011
  query_siteLocation_parser.set_defaults(func=querySiteLocation,operation_name='query.siteLocation')
1004
1012
  """
1005
1013
  parserPath = "../catocli/parsers/query_siteLocation"
@@ -1028,16 +1036,31 @@ def {parserName}_parse({operationType}_subparsers):
1028
1036
  usage=get_help("{operationType}_{operationName}"))
1029
1037
  """
1030
1038
  if "path" in parser:
1039
+ # Check if this operation supports CSV output
1040
+ operation_path = parserName.replace("_", ".")
1041
+ supports_csv = operation_path in csv_supported_operations
1042
+
1031
1043
  cliDriverStr += f"""
1032
1044
  {parserName}_parser.add_argument('json', nargs='?', default='{{}}', help='Variables in JSON format (defaults to empty object if not provided).')
1033
1045
  {parserName}_parser.add_argument('-accountID', help='The cato account ID to use for this operation. Overrides the account_id value in the profile setting. This is use for reseller and MSP accounts to run queries against cato sub accounts from the parent account.')
1034
1046
  {parserName}_parser.add_argument('-t', const=True, default=False, nargs='?', help='Print GraphQL query without sending API call')
1035
1047
  {parserName}_parser.add_argument('-v', const=True, default=False, nargs='?', help='Verbose output')
1036
1048
  {parserName}_parser.add_argument('-p', const=True, default=False, nargs='?', help='Pretty print')
1049
+ {parserName}_parser.add_argument('-n', '--stream-events', dest='stream_events', help='Send events over network to host:port TCP')
1050
+ {parserName}_parser.add_argument('-z', '--sentinel', dest='sentinel', help='Send events to Sentinel customerid:sharedkey')
1037
1051
  {parserName}_parser.add_argument('-H', '--header', action='append', dest='headers', help='Add custom headers in "Key: Value" format. Can be used multiple times.')
1038
1052
  {parserName}_parser.add_argument('--headers-file', dest='headers_file', help='Load headers from a file. Each line should contain a header in "Key: Value" format.')
1039
- {parserName}_parser.set_defaults(func=createRequest,operation_name='{parserName.replace("_",".")}')
1040
1053
  """
1054
+ # Add -f flag for CSV-supported operations
1055
+ if supports_csv:
1056
+ cliDriverStr += f"""
1057
+ {parserName}_parser.add_argument('-f', '--format', choices=['json', 'csv'], default='json', help='Output format (default: json)')
1058
+ {parserName}_parser.add_argument('--csv-filename', dest='csv_filename', help='Override CSV file name (default: accountmetrics.csv)')
1059
+ {parserName}_parser.add_argument('--append-timestamp', dest='append_timestamp', action='store_true', help='Append timestamp to the CSV file name')
1060
+ """
1061
+
1062
+ cliDriverStr += f" {parserName}_parser.set_defaults(func=createRequest,operation_name='{parserName.replace("_",".")}')"
1063
+ cliDriverStr += "\n"
1041
1064
  else:
1042
1065
  cliDriverStr += renderSubParser(parser,operationType+"_"+operationName)
1043
1066
 
@@ -1340,6 +1363,9 @@ def renderSubParser(subParser, parentParserPath):
1340
1363
  if not isinstance(subParser, dict):
1341
1364
  return ""
1342
1365
 
1366
+ settings = loadJSON("../clisettings.json")
1367
+ csv_supported_operations = settings.get("queryOperationCsvOutput", {})
1368
+
1343
1369
  cliDriverStr = f"""
1344
1370
  {parentParserPath}_subparsers = {parentParserPath}_parser.add_subparsers()
1345
1371
  """
@@ -1359,16 +1385,28 @@ def renderSubParser(subParser, parentParserPath):
1359
1385
  if isinstance(subOperation, dict) and "path" in subOperation:
1360
1386
  command = parentParserPath.replace("_"," ")+" "+subOperationName
1361
1387
  operation_path = subOperation.get("path", "")
1388
+ operation_path_csv = subParserPath.replace("_", ".")
1389
+ supports_csv = operation_path_csv in csv_supported_operations
1362
1390
  cliDriverStr += f"""
1363
1391
  {subParserPath}_parser.add_argument('json', nargs='?', default='{{}}', help='Variables in JSON format (defaults to empty object if not provided).')
1364
1392
  {subParserPath}_parser.add_argument('-accountID', help='The cato account ID to use for this operation. Overrides the account_id value in the profile setting. This is use for reseller and MSP accounts to run queries against cato sub accounts from the parent account.')
1365
1393
  {subParserPath}_parser.add_argument('-t', const=True, default=False, nargs='?', help='Print GraphQL query without sending API call')
1366
1394
  {subParserPath}_parser.add_argument('-v', const=True, default=False, nargs='?', help='Verbose output')
1367
1395
  {subParserPath}_parser.add_argument('-p', const=True, default=False, nargs='?', help='Pretty print')
1396
+ {subParserPath}_parser.add_argument('-n', '--stream-events', dest='stream_events', help='Send events over network to host:port TCP')
1397
+ {subParserPath}_parser.add_argument('-z', '--sentinel', dest='sentinel', help='Send events to Sentinel customerid:sharedkey')
1368
1398
  {subParserPath}_parser.add_argument('-H', '--header', action='append', dest='headers', help='Add custom headers in "Key: Value" format. Can be used multiple times.')
1369
1399
  {subParserPath}_parser.add_argument('--headers-file', dest='headers_file', help='Load headers from a file. Each line should contain a header in "Key: Value" format.')
1370
1400
  {subParserPath}_parser.set_defaults(func=createRequest,operation_name='{operation_path}')
1371
1401
  """
1402
+ # Add -f flag for CSV-supported operations
1403
+ if supports_csv:
1404
+ cliDriverStr += f"""
1405
+ {subParserPath}_parser.add_argument('-f', '--format', choices=['json', 'csv'], default='json', help='Output format (default: json)')
1406
+ {subParserPath}_parser.add_argument('--csv-filename', dest='csv_filename', help='Override CSV file name (default: accountmetrics.csv)')
1407
+ {subParserPath}_parser.add_argument('--append-timestamp', dest='append_timestamp', action='store_true', help='Append timestamp to the CSV file name')
1408
+ """
1409
+
1372
1410
  else:
1373
1411
  cliDriverStr += renderSubParser(subOperation,subParserPath)
1374
1412
  return cliDriverStr
@@ -1430,7 +1468,7 @@ def renderSubReadme(subParser, operationType, parentOperationPath):
1430
1468
  renderSubReadme(subOperation, operationType, subOperationPath)
1431
1469
 
1432
1470
  def main():
1433
- """Main execution function with threading support"""
1471
+ # Main execution function with threading support
1434
1472
  options = initParser()
1435
1473
 
1436
1474
  # Load the introspection schema