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.
- catocli/Utils/clidriver.py +18 -18
- catocli/Utils/cliutils.py +165 -0
- catocli/Utils/csv_formatter.py +652 -0
- catocli/__init__.py +1 -1
- catocli/parsers/custom/export_rules/__init__.py +0 -4
- catocli/parsers/custom/export_sites/__init__.py +4 -3
- catocli/parsers/custom/export_sites/export_sites.py +198 -55
- catocli/parsers/custom/import_sites_to_tf/import_sites_to_tf.py +473 -393
- catocli/parsers/customParserApiClient.py +444 -38
- catocli/parsers/custom_private/__init__.py +19 -13
- catocli/parsers/mutation_accountManagement/__init__.py +21 -0
- catocli/parsers/mutation_accountManagement_disableAccount/README.md +15 -0
- catocli/parsers/mutation_admin/__init__.py +12 -0
- catocli/parsers/mutation_container/__init__.py +18 -0
- catocli/parsers/mutation_enterpriseDirectory/__init__.py +8 -0
- catocli/parsers/mutation_groups/__init__.py +6 -0
- catocli/parsers/mutation_hardware/__init__.py +2 -0
- catocli/parsers/mutation_policy/__init__.py +378 -0
- catocli/parsers/mutation_policy_antiMalwareFileHash_addRule/README.md +20 -0
- catocli/parsers/mutation_policy_antiMalwareFileHash_addSection/README.md +20 -0
- catocli/parsers/mutation_policy_antiMalwareFileHash_createPolicyRevision/README.md +20 -0
- catocli/parsers/mutation_policy_antiMalwareFileHash_discardPolicyRevision/README.md +20 -0
- catocli/parsers/mutation_policy_antiMalwareFileHash_moveRule/README.md +20 -0
- catocli/parsers/mutation_policy_antiMalwareFileHash_moveSection/README.md +20 -0
- catocli/parsers/mutation_policy_antiMalwareFileHash_publishPolicyRevision/README.md +20 -0
- catocli/parsers/mutation_policy_antiMalwareFileHash_removeRule/README.md +20 -0
- catocli/parsers/mutation_policy_antiMalwareFileHash_removeSection/README.md +20 -0
- catocli/parsers/mutation_policy_antiMalwareFileHash_updatePolicy/README.md +20 -0
- catocli/parsers/mutation_policy_antiMalwareFileHash_updateRule/README.md +20 -0
- catocli/parsers/mutation_policy_antiMalwareFileHash_updateSection/README.md +20 -0
- catocli/parsers/mutation_sandbox/__init__.py +4 -0
- catocli/parsers/mutation_site/__init__.py +72 -0
- catocli/parsers/mutation_sites/__init__.py +72 -0
- catocli/parsers/mutation_xdr/__init__.py +6 -0
- catocli/parsers/query_accountBySubdomain/__init__.py +2 -0
- catocli/parsers/query_accountManagement/__init__.py +2 -0
- catocli/parsers/query_accountMetrics/__init__.py +6 -0
- catocli/parsers/query_accountRoles/__init__.py +2 -0
- catocli/parsers/query_accountSnapshot/__init__.py +2 -0
- catocli/parsers/query_admin/__init__.py +2 -0
- catocli/parsers/query_admins/__init__.py +2 -0
- catocli/parsers/query_appStats/__init__.py +6 -0
- catocli/parsers/query_appStatsTimeSeries/README.md +3 -0
- catocli/parsers/query_appStatsTimeSeries/__init__.py +6 -0
- catocli/parsers/query_auditFeed/__init__.py +2 -0
- catocli/parsers/query_catalogs/__init__.py +2 -0
- catocli/parsers/query_container/__init__.py +2 -0
- catocli/parsers/query_devices/README.md +1 -1
- catocli/parsers/query_devices/__init__.py +2 -0
- catocli/parsers/query_enterpriseDirectory/__init__.py +2 -0
- catocli/parsers/query_entityLookup/__init__.py +2 -0
- catocli/parsers/query_events/__init__.py +2 -0
- catocli/parsers/query_eventsFeed/__init__.py +2 -0
- catocli/parsers/query_eventsTimeSeries/__init__.py +2 -0
- catocli/parsers/query_groups/__init__.py +6 -0
- catocli/parsers/query_hardware/README.md +1 -1
- catocli/parsers/query_hardware/__init__.py +2 -0
- catocli/parsers/query_hardwareManagement/__init__.py +2 -0
- catocli/parsers/query_licensing/__init__.py +2 -0
- catocli/parsers/query_policy/__init__.py +37 -0
- catocli/parsers/query_policy_antiMalwareFileHash_policy/README.md +19 -0
- catocli/parsers/query_popLocations/__init__.py +2 -0
- catocli/parsers/query_sandbox/__init__.py +2 -0
- catocli/parsers/query_servicePrincipalAdmin/__init__.py +2 -0
- catocli/parsers/query_site/__init__.py +33 -0
- catocli/parsers/query_siteLocation/__init__.py +2 -0
- catocli/parsers/query_site_siteGeneralDetails/README.md +19 -0
- catocli/parsers/query_socketPortMetrics/__init__.py +2 -0
- catocli/parsers/query_socketPortMetricsTimeSeries/__init__.py +6 -0
- catocli/parsers/query_subDomains/__init__.py +2 -0
- catocli/parsers/query_xdr/__init__.py +4 -0
- catocli/parsers/raw/__init__.py +3 -1
- {catocli-2.1.2.dist-info → catocli-2.1.4.dist-info}/METADATA +1 -1
- {catocli-2.1.2.dist-info → catocli-2.1.4.dist-info}/RECORD +98 -66
- models/mutation.accountManagement.disableAccount.json +545 -0
- models/mutation.policy.antiMalwareFileHash.addRule.json +2068 -0
- models/mutation.policy.antiMalwareFileHash.addSection.json +1350 -0
- models/mutation.policy.antiMalwareFileHash.createPolicyRevision.json +1822 -0
- models/mutation.policy.antiMalwareFileHash.discardPolicyRevision.json +1758 -0
- models/mutation.policy.antiMalwareFileHash.moveRule.json +1552 -0
- models/mutation.policy.antiMalwareFileHash.moveSection.json +1251 -0
- models/mutation.policy.antiMalwareFileHash.publishPolicyRevision.json +1813 -0
- models/mutation.policy.antiMalwareFileHash.removeRule.json +1204 -0
- models/mutation.policy.antiMalwareFileHash.removeSection.json +954 -0
- models/mutation.policy.antiMalwareFileHash.updatePolicy.json +1834 -0
- models/mutation.policy.antiMalwareFileHash.updateRule.json +1757 -0
- models/mutation.policy.antiMalwareFileHash.updateSection.json +1105 -0
- models/mutation.site.updateSiteGeneralDetails.json +3 -3
- models/mutation.sites.updateSiteGeneralDetails.json +3 -3
- models/query.devices.json +249 -2
- models/query.hardware.json +224 -0
- models/query.policy.antiMalwareFileHash.policy.json +1583 -0
- models/query.site.siteGeneralDetails.json +899 -0
- schema/catolib.py +52 -14
- {catocli-2.1.2.dist-info → catocli-2.1.4.dist-info}/WHEEL +0 -0
- {catocli-2.1.2.dist-info → catocli-2.1.4.dist-info}/entry_points.txt +0 -0
- {catocli-2.1.2.dist-info → catocli-2.1.4.dist-info}/licenses/LICENSE +0 -0
- {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("../
|
|
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
|
-
|
|
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
|
-
|
|
1471
|
+
# Main execution function with threading support
|
|
1434
1472
|
options = initParser()
|
|
1435
1473
|
|
|
1436
1474
|
# Load the introspection schema
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|