catocli 3.0.30__py3-none-any.whl → 3.0.31__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 +10 -10
- catocli/__init__.py +1 -1
- catocli/parsers/custom/export_rules/__init__.py +27 -2
- catocli/parsers/custom/export_rules/export_rules.py +100 -1
- catocli/parsers/custom/import_rules_to_tf/__init__.py +24 -0
- catocli/parsers/custom/import_rules_to_tf/import_rules_to_tf.py +178 -0
- catocli/parsers/query_appStatsTimeSeries/README.md +0 -1
- catocli/parsers/query_devices/README.md +35 -1
- {catocli-3.0.30.dist-info → catocli-3.0.31.dist-info}/METADATA +1 -1
- {catocli-3.0.30.dist-info → catocli-3.0.31.dist-info}/RECORD +18 -18
- models/mutation.xdr.analystFeedback.json +419 -0
- models/query.devices.json +2178 -604
- models/query.xdr.stories.json +419 -0
- models/query.xdr.story.json +419 -0
- {catocli-3.0.30.dist-info → catocli-3.0.31.dist-info}/WHEEL +0 -0
- {catocli-3.0.30.dist-info → catocli-3.0.31.dist-info}/entry_points.txt +0 -0
- {catocli-3.0.30.dist-info → catocli-3.0.31.dist-info}/licenses/LICENSE +0 -0
- {catocli-3.0.30.dist-info → catocli-3.0.31.dist-info}/top_level.txt +0 -0
catocli/Utils/clidriver.py
CHANGED
|
@@ -47,22 +47,22 @@ from ..parsers.query_enterpriseDirectory import query_enterpriseDirectory_parse
|
|
|
47
47
|
from ..parsers.query_devices import query_devices_parse
|
|
48
48
|
from ..parsers.query_accountSnapshot import query_accountSnapshot_parse
|
|
49
49
|
from ..parsers.query_catalogs import query_catalogs_parse
|
|
50
|
-
from ..parsers.query_xdr import query_xdr_parse
|
|
51
50
|
from ..parsers.query_site import query_site_parse
|
|
52
|
-
from ..parsers.
|
|
53
|
-
from ..parsers.query_container import query_container_parse
|
|
51
|
+
from ..parsers.query_xdr import query_xdr_parse
|
|
54
52
|
from ..parsers.query_policy import query_policy_parse
|
|
53
|
+
from ..parsers.query_container import query_container_parse
|
|
54
|
+
from ..parsers.query_groups import query_groups_parse
|
|
55
|
+
from ..parsers.mutation_sites import mutation_sites_parse
|
|
55
56
|
from ..parsers.mutation_xdr import mutation_xdr_parse
|
|
56
57
|
from ..parsers.mutation_site import mutation_site_parse
|
|
57
|
-
from ..parsers.mutation_sites import mutation_sites_parse
|
|
58
58
|
from ..parsers.mutation_policy import mutation_policy_parse
|
|
59
59
|
from ..parsers.mutation_container import mutation_container_parse
|
|
60
|
-
from ..parsers.mutation_admin import mutation_admin_parse
|
|
61
60
|
from ..parsers.mutation_accountManagement import mutation_accountManagement_parse
|
|
62
61
|
from ..parsers.mutation_sandbox import mutation_sandbox_parse
|
|
63
62
|
from ..parsers.mutation_licensing import mutation_licensing_parse
|
|
64
63
|
from ..parsers.mutation_hardware import mutation_hardware_parse
|
|
65
64
|
from ..parsers.mutation_groups import mutation_groups_parse
|
|
65
|
+
from ..parsers.mutation_admin import mutation_admin_parse
|
|
66
66
|
from ..parsers.mutation_enterpriseDirectory import mutation_enterpriseDirectory_parse
|
|
67
67
|
|
|
68
68
|
def show_version_info(args, configuration=None):
|
|
@@ -182,22 +182,22 @@ query_enterpriseDirectory_parser = query_enterpriseDirectory_parse(query_subpars
|
|
|
182
182
|
query_devices_parser = query_devices_parse(query_subparsers)
|
|
183
183
|
query_accountSnapshot_parser = query_accountSnapshot_parse(query_subparsers)
|
|
184
184
|
query_catalogs_parser = query_catalogs_parse(query_subparsers)
|
|
185
|
-
query_xdr_parser = query_xdr_parse(query_subparsers)
|
|
186
185
|
query_site_parser = query_site_parse(query_subparsers)
|
|
187
|
-
|
|
188
|
-
query_container_parser = query_container_parse(query_subparsers)
|
|
186
|
+
query_xdr_parser = query_xdr_parse(query_subparsers)
|
|
189
187
|
query_policy_parser = query_policy_parse(query_subparsers)
|
|
188
|
+
query_container_parser = query_container_parse(query_subparsers)
|
|
189
|
+
query_groups_parser = query_groups_parse(query_subparsers)
|
|
190
|
+
mutation_sites_parser = mutation_sites_parse(mutation_subparsers)
|
|
190
191
|
mutation_xdr_parser = mutation_xdr_parse(mutation_subparsers)
|
|
191
192
|
mutation_site_parser = mutation_site_parse(mutation_subparsers)
|
|
192
|
-
mutation_sites_parser = mutation_sites_parse(mutation_subparsers)
|
|
193
193
|
mutation_policy_parser = mutation_policy_parse(mutation_subparsers)
|
|
194
194
|
mutation_container_parser = mutation_container_parse(mutation_subparsers)
|
|
195
|
-
mutation_admin_parser = mutation_admin_parse(mutation_subparsers)
|
|
196
195
|
mutation_accountManagement_parser = mutation_accountManagement_parse(mutation_subparsers)
|
|
197
196
|
mutation_sandbox_parser = mutation_sandbox_parse(mutation_subparsers)
|
|
198
197
|
mutation_licensing_parser = mutation_licensing_parse(mutation_subparsers)
|
|
199
198
|
mutation_hardware_parser = mutation_hardware_parse(mutation_subparsers)
|
|
200
199
|
mutation_groups_parser = mutation_groups_parse(mutation_subparsers)
|
|
200
|
+
mutation_admin_parser = mutation_admin_parse(mutation_subparsers)
|
|
201
201
|
mutation_enterpriseDirectory_parser = mutation_enterpriseDirectory_parse(mutation_subparsers)
|
|
202
202
|
|
|
203
203
|
|
catocli/__init__.py
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
__version__ = "3.0.
|
|
1
|
+
__version__ = "3.0.31"
|
|
2
2
|
__cato_host__ = "https://api.catonetworks.com/api/v1/graphql2"
|
|
@@ -56,7 +56,6 @@ Examples:
|
|
|
56
56
|
|
|
57
57
|
if_rules_parser.add_argument('-accountID', help='Account ID to export rules from (uses CATO_ACCOUNT_ID environment variable if not specified)', required=False)
|
|
58
58
|
if_rules_parser.add_argument('-v', '--verbose', action='store_true', help='Verbose output')
|
|
59
|
-
|
|
60
59
|
if_rules_parser.set_defaults(func=export_rules.export_if_rules_to_json)
|
|
61
60
|
|
|
62
61
|
# Add wf_rules command
|
|
@@ -83,7 +82,33 @@ Examples:
|
|
|
83
82
|
|
|
84
83
|
wf_rules_parser.add_argument('-accountID', help='Account ID to export rules from (uses CATO_ACCOUNT_ID environment variable if not specified)', required=False)
|
|
85
84
|
wf_rules_parser.add_argument('-v', '--verbose', action='store_true', help='Verbose output')
|
|
86
|
-
|
|
87
85
|
wf_rules_parser.set_defaults(func=export_rules.export_wf_rules_to_json)
|
|
86
|
+
|
|
87
|
+
# Add tls_rules command
|
|
88
|
+
tls_rules_parser = export_subparsers.add_parser(
|
|
89
|
+
'tls_rules',
|
|
90
|
+
help='Export TLS Inspection rules to JSON format',
|
|
91
|
+
usage='catocli export tls_rules [-accountID <account_id>] [options]',
|
|
92
|
+
description='''Export TLS Inspection rules to JSON format for backup, analysis, or migration purposes.
|
|
93
|
+
|
|
94
|
+
Examples:
|
|
95
|
+
# Basic export (uses CATO_ACCOUNT_ID environment variable)
|
|
96
|
+
catocli export tls_rules
|
|
97
|
+
|
|
98
|
+
# Export with specific account ID
|
|
99
|
+
catocli export tls_rules -accountID 12345
|
|
100
|
+
|
|
101
|
+
# Export with verbose output to see detailed progress
|
|
102
|
+
catocli export tls_rules -v
|
|
103
|
+
|
|
104
|
+
# Export for specific account with full logging
|
|
105
|
+
catocli export tls_rules -accountID 12345 -v''',
|
|
106
|
+
formatter_class=__import__('argparse').RawDescriptionHelpFormatter
|
|
107
|
+
)
|
|
88
108
|
|
|
109
|
+
tls_rules_parser.add_argument('-accountID', help='Account ID to export rules from (uses CATO_ACCOUNT_ID environment variable if not specified)', required=False)
|
|
110
|
+
tls_rules_parser.add_argument('-v', '--verbose', action='store_true', help='Verbose output')
|
|
111
|
+
tls_rules_parser.set_defaults(func=export_rules.export_tls_rules_to_json)
|
|
112
|
+
|
|
113
|
+
|
|
89
114
|
return export_parser
|
|
@@ -141,7 +141,6 @@ def export_if_rules_to_json(args, configuration):
|
|
|
141
141
|
print(f"ERROR: {str(e)}")
|
|
142
142
|
return [{"success": False, "error": str(e)}]
|
|
143
143
|
|
|
144
|
-
|
|
145
144
|
def export_wf_rules_to_json(args, configuration):
|
|
146
145
|
"""
|
|
147
146
|
Export WAN Firewall rules to JSON format
|
|
@@ -242,3 +241,103 @@ def export_wf_rules_to_json(args, configuration):
|
|
|
242
241
|
except Exception as e:
|
|
243
242
|
print(f"ERROR: {str(e)}")
|
|
244
243
|
return [{"success": False, "error": str(e)}]
|
|
244
|
+
|
|
245
|
+
def export_tls_rules_to_json(args, configuration):
|
|
246
|
+
"""
|
|
247
|
+
Export TLS Inspection rules to JSON format
|
|
248
|
+
Adapted from scripts/export_tls_rules_to_json.py
|
|
249
|
+
"""
|
|
250
|
+
try:
|
|
251
|
+
account_id = getAccountID(args, configuration)
|
|
252
|
+
|
|
253
|
+
policy_query = {
|
|
254
|
+
"query": "query policy ( $accountId:ID! ) { policy ( accountId:$accountId ) { tlsInspect { policy { enabled rules { audit { updatedTime updatedBy } rule { id name description index section { id name } enabled source { user { id name } floatingSubnet { id name } globalIpRange { id name } group { id name } host { id name } subnet ipRangeTlsInspectSource: ipRange { from to } networkInterface { id name } site { id name } systemGroup { id name } usersGroup { id name } ip siteNetworkSubnet { id name } } platform country { id name } devicePostureProfile { id name } connectionOrigin application { application { id name } appCategory { id name } country { id name } customApp { id name } customCategory { id name } customServiceIp { name ip ipRange { from to } } domain fqdn subnet ip ipRangeTlsInspectApplication: ipRange { from to } globalIpRange { id name } customService { port portRange { from to } protocol } remoteAsn service { id name } tlsInspectCategory } action untrustedCertificateAction } properties } sections { audit { updatedTime updatedBy } section { id name } properties } audit { publishedTime publishedBy } revision { id name description changes createdTime updatedTime } additionalAttributes { defaultRuleAction defaultRuleUntrustedCertificateAction } } } } }",
|
|
255
|
+
"variables": {
|
|
256
|
+
"accountId": account_id
|
|
257
|
+
},
|
|
258
|
+
"operationName": "policy"
|
|
259
|
+
}
|
|
260
|
+
all_tls_rules = makeCall(args, configuration, policy_query)
|
|
261
|
+
|
|
262
|
+
if not all_tls_rules or 'data' not in all_tls_rules:
|
|
263
|
+
raise ValueError("Failed to retrieve data from API")
|
|
264
|
+
|
|
265
|
+
# Processing data to strip id attributes
|
|
266
|
+
processed_data = strip_ids_recursive(all_tls_rules)
|
|
267
|
+
|
|
268
|
+
# Filter out rules with properties[0]=="SYSTEM"
|
|
269
|
+
filtered_rules = []
|
|
270
|
+
for rule_data in processed_data['data']['policy']['tlsInspect']['policy']['rules']:
|
|
271
|
+
rule_properties = rule_data.get('properties', [])
|
|
272
|
+
# Skip rules where the first property is "SYSTEM"
|
|
273
|
+
if rule_properties and rule_properties[0] == "SYSTEM":
|
|
274
|
+
if hasattr(args, 'verbose') and args.verbose:
|
|
275
|
+
print(f"Excluding SYSTEM rule: {rule_data['rule']['name']}")
|
|
276
|
+
else:
|
|
277
|
+
filtered_rules.append(rule_data)
|
|
278
|
+
|
|
279
|
+
processed_data['data']['policy']['tlsInspect']['policy']['rules'] = filtered_rules
|
|
280
|
+
|
|
281
|
+
# Add index_in_section to each rule
|
|
282
|
+
# Handle empty section names by assigning a default section name
|
|
283
|
+
section_counters = {}
|
|
284
|
+
for rule_data in processed_data['data']['policy']['tlsInspect']['policy']['rules']:
|
|
285
|
+
section_name = rule_data['rule']['section']['name']
|
|
286
|
+
# If section name is empty, use "Default Section" as the section name
|
|
287
|
+
if not section_name or section_name.strip() == "":
|
|
288
|
+
section_name = "Default Section"
|
|
289
|
+
rule_data['rule']['section']['name'] = section_name
|
|
290
|
+
|
|
291
|
+
if section_name not in section_counters:
|
|
292
|
+
section_counters[section_name] = 0
|
|
293
|
+
section_counters[section_name] += 1
|
|
294
|
+
rule_data['rule']['index_in_section'] = section_counters[section_name]
|
|
295
|
+
|
|
296
|
+
# Create rules_in_sections array
|
|
297
|
+
rules_in_sections = []
|
|
298
|
+
for rule_data in processed_data['data']['policy']['tlsInspect']['policy']['rules']:
|
|
299
|
+
rule_info = rule_data['rule']
|
|
300
|
+
rules_in_sections.append({
|
|
301
|
+
"index_in_section": rule_info['index_in_section'],
|
|
302
|
+
"section_name": rule_info['section']['name'],
|
|
303
|
+
"rule_name": rule_info['name']
|
|
304
|
+
})
|
|
305
|
+
rule_info.pop("index_in_section", None)
|
|
306
|
+
rule_info.pop("index", None)
|
|
307
|
+
# rule_info["enabled"] = True
|
|
308
|
+
|
|
309
|
+
# Add rules_in_sections to the policy structure
|
|
310
|
+
processed_data['data']['policy']['tlsInspect']['policy']['rules_in_sections'] = rules_in_sections
|
|
311
|
+
|
|
312
|
+
# Reformat sections array to have index, section_id and section_name structure
|
|
313
|
+
# Exclude the first section from export
|
|
314
|
+
sections_with_ids = all_tls_rules['data']['policy']['tlsInspect']['policy']['sections']
|
|
315
|
+
processed_sections = []
|
|
316
|
+
for index, section_data in enumerate(sections_with_ids):
|
|
317
|
+
processed_sections.append({
|
|
318
|
+
"section_index": index+1,
|
|
319
|
+
"section_name": section_data['section']['name'],
|
|
320
|
+
"section_id": section_data['section']['id']
|
|
321
|
+
})
|
|
322
|
+
|
|
323
|
+
# Replace the original sections array with the reformatted one
|
|
324
|
+
processed_data['data']['policy']['tlsInspect']['policy']['sections'] = processed_sections
|
|
325
|
+
|
|
326
|
+
# Handle timestamp in filename if requested
|
|
327
|
+
filename_template = "all_tls_rules_and_sections_{account_id}.json"
|
|
328
|
+
if hasattr(args, 'append_timestamp') and args.append_timestamp:
|
|
329
|
+
timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
|
|
330
|
+
filename_template = "all_tls_rules_and_sections_{account_id}_" + timestamp + ".json"
|
|
331
|
+
|
|
332
|
+
output_file = writeDataToFile(
|
|
333
|
+
data=processed_data,
|
|
334
|
+
args=args,
|
|
335
|
+
account_id=account_id,
|
|
336
|
+
default_filename_template=filename_template,
|
|
337
|
+
default_directory="config_data"
|
|
338
|
+
)
|
|
339
|
+
|
|
340
|
+
return [{"success": True, "output_file": output_file, "account_id": account_id}]
|
|
341
|
+
except Exception as e:
|
|
342
|
+
print(f"ERROR: {str(e)}")
|
|
343
|
+
return [{"success": False, "error": str(e)}]
|
|
@@ -75,4 +75,28 @@ Common Examples:
|
|
|
75
75
|
|
|
76
76
|
wf_rules_parser.set_defaults(func=import_rules_to_tf.import_wf_rules_to_tf)
|
|
77
77
|
|
|
78
|
+
# Add tls_rules_to_tf command
|
|
79
|
+
tls_rules_parser = import_subparsers.add_parser(
|
|
80
|
+
'tls_rules_to_tf',
|
|
81
|
+
help='Import TLS Inspectiom rules to Terraform state',
|
|
82
|
+
usage='catocli import tls_rules_to_tf <json_file> --module-name <module_name> [options]\n\nexample: catocli import tls_rules_to_tf config_data/all_tls_rules_and_sections.json --module-name module.tls_rules'
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
tls_rules_parser.add_argument('json_file', help='Path to the JSON file containing TLS rules and sections')
|
|
86
|
+
tls_rules_parser.add_argument('--module-name', required=True,
|
|
87
|
+
help='Terraform module name to import resources into')
|
|
88
|
+
tls_rules_parser.add_argument('-accountID', help='Account ID (required by CLI framework but not used for import)', required=False)
|
|
89
|
+
tls_rules_parser.add_argument('--batch-size', type=int, default=10,
|
|
90
|
+
help='Number of imports per batch (default: 10)')
|
|
91
|
+
tls_rules_parser.add_argument('--delay', type=int, default=2,
|
|
92
|
+
help='Delay between batches in seconds (default: 2)')
|
|
93
|
+
tls_rules_parser.add_argument('--rules-only', action='store_true',
|
|
94
|
+
help='Import only rules, skip sections')
|
|
95
|
+
tls_rules_parser.add_argument('--sections-only', action='store_true',
|
|
96
|
+
help='Import only sections, skip rules')
|
|
97
|
+
tls_rules_parser.add_argument('-v', '--verbose', action='store_true', help='Verbose output')
|
|
98
|
+
tls_rules_parser.add_argument('--auto-approve', action='store_true', help='Skip confirmation prompt and proceed automatically')
|
|
99
|
+
|
|
100
|
+
tls_rules_parser.set_defaults(func=import_rules_to_tf.import_tls_rules_to_tf)
|
|
101
|
+
|
|
78
102
|
return import_parser
|
|
@@ -460,3 +460,181 @@ def import_wf_rules_to_tf(args, configuration):
|
|
|
460
460
|
except Exception as e:
|
|
461
461
|
print(f"ERROR: {str(e)}")
|
|
462
462
|
return [{"success": False, "error": str(e)}]
|
|
463
|
+
|
|
464
|
+
|
|
465
|
+
def load_tls_json_data(json_file):
|
|
466
|
+
"""Load TLS Inspection data from JSON file"""
|
|
467
|
+
try:
|
|
468
|
+
with open(json_file, 'r') as f:
|
|
469
|
+
data = json.load(f)
|
|
470
|
+
return data['data']['policy']['tlsInspect']['policy']
|
|
471
|
+
except FileNotFoundError:
|
|
472
|
+
print(f"Error: JSON file '{json_file}' not found")
|
|
473
|
+
sys.exit(1)
|
|
474
|
+
except json.JSONDecodeError as e:
|
|
475
|
+
print(f"Error: Invalid JSON in '{json_file}': {e}")
|
|
476
|
+
sys.exit(1)
|
|
477
|
+
except KeyError as e:
|
|
478
|
+
print(f"Error: Expected JSON structure not found in '{json_file}': {e}")
|
|
479
|
+
sys.exit(1)
|
|
480
|
+
|
|
481
|
+
|
|
482
|
+
def import_tls_sections(sections, module_name, verbose=False,
|
|
483
|
+
resource_type="cato_tls_section", resource_name="sections"):
|
|
484
|
+
"""Import all TLS Inspection sections"""
|
|
485
|
+
print("\nStarting TLS Inspection section imports...")
|
|
486
|
+
total_sections = len(sections)
|
|
487
|
+
successful_imports = 0
|
|
488
|
+
failed_imports = 0
|
|
489
|
+
|
|
490
|
+
for i, section in enumerate(sections):
|
|
491
|
+
section_id = section['section_id']
|
|
492
|
+
section_name = section['section_name']
|
|
493
|
+
section_index = section['section_index']
|
|
494
|
+
# Add module. prefix if not present
|
|
495
|
+
if not module_name.startswith('module.'):
|
|
496
|
+
module_name = f'module.{module_name}'
|
|
497
|
+
resource_address = f'{module_name}.{resource_type}.{resource_name}["{section_name}"]'
|
|
498
|
+
print(f"\n[{i+1}/{total_sections}] Section: {section_name} (index: {section_index})")
|
|
499
|
+
|
|
500
|
+
# For sections, we use the section name as the ID since that's how Cato identifies them
|
|
501
|
+
success, stdout, stderr = run_terraform_import(resource_address, section_id, verbose=verbose)
|
|
502
|
+
|
|
503
|
+
if success:
|
|
504
|
+
successful_imports += 1
|
|
505
|
+
else:
|
|
506
|
+
failed_imports += 1
|
|
507
|
+
|
|
508
|
+
print(f"\nTLS Inspection Section Import Summary: {successful_imports} successful, {failed_imports} failed")
|
|
509
|
+
return successful_imports, failed_imports
|
|
510
|
+
|
|
511
|
+
|
|
512
|
+
def import_tls_rules(rules, module_name, verbose=False,
|
|
513
|
+
resource_type="cato_tls_rule", resource_name="rules",
|
|
514
|
+
batch_size=10, delay_between_batches=2, auto_approve=False):
|
|
515
|
+
"""Import all TLS Inspection rules in batches"""
|
|
516
|
+
print("\nStarting TLS Inspection rule imports...")
|
|
517
|
+
successful_imports = 0
|
|
518
|
+
failed_imports = 0
|
|
519
|
+
total_rules = len(rules)
|
|
520
|
+
|
|
521
|
+
for i, rule in enumerate(rules):
|
|
522
|
+
rule_id = rule['id']
|
|
523
|
+
rule_name = rule['name']
|
|
524
|
+
rule_index = find_rule_index(rules, rule_name)
|
|
525
|
+
terraform_key = sanitize_name_for_terraform(rule_name)
|
|
526
|
+
|
|
527
|
+
# Add module. prefix if not present
|
|
528
|
+
if not module_name.startswith('module.'):
|
|
529
|
+
module_name = f'module.{module_name}'
|
|
530
|
+
|
|
531
|
+
# Use array index syntax instead of rule ID
|
|
532
|
+
resource_address = f'{module_name}.{resource_type}.{resource_name}["{str(rule_name)}"]'
|
|
533
|
+
print(f"\n[{i+1}/{total_rules}] Rule: {rule_name} (index: {rule_index})")
|
|
534
|
+
|
|
535
|
+
success, stdout, stderr = run_terraform_import(resource_address, rule_id, verbose=verbose)
|
|
536
|
+
|
|
537
|
+
if success:
|
|
538
|
+
successful_imports += 1
|
|
539
|
+
else:
|
|
540
|
+
failed_imports += 1
|
|
541
|
+
|
|
542
|
+
# Ask user if they want to continue on failure (unless auto-approved)
|
|
543
|
+
if failed_imports <= 3 and not auto_approve: # Only prompt for first few failures
|
|
544
|
+
response = input(f"\nContinue with remaining imports? (y/n): ").lower()
|
|
545
|
+
if response == 'n':
|
|
546
|
+
print("Import process stopped by user.")
|
|
547
|
+
break
|
|
548
|
+
|
|
549
|
+
# Delay between batches
|
|
550
|
+
if (i + 1) % batch_size == 0 and i < total_rules - 1:
|
|
551
|
+
print(f"\n Batch complete. Waiting {delay_between_batches}s before next batch...")
|
|
552
|
+
time.sleep(delay_between_batches)
|
|
553
|
+
|
|
554
|
+
print(f"\nTLS Inspection Rule Import Summary: {successful_imports} successful, {failed_imports} failed")
|
|
555
|
+
return successful_imports, failed_imports
|
|
556
|
+
|
|
557
|
+
|
|
558
|
+
def import_tls_rules_to_tf(args, configuration):
|
|
559
|
+
"""Main function to orchestrate the TLS Inspection import process"""
|
|
560
|
+
try:
|
|
561
|
+
print(" Terraform Import Tool - Cato TLS Inspection Rules & Sections")
|
|
562
|
+
print("=" * 60)
|
|
563
|
+
|
|
564
|
+
# Load data
|
|
565
|
+
print(f" Loading data from {args.json_file}...")
|
|
566
|
+
policy_data = load_tls_json_data(args.json_file)
|
|
567
|
+
|
|
568
|
+
# Extract rules and sections
|
|
569
|
+
rules, sections = extract_rules_and_sections(policy_data)
|
|
570
|
+
|
|
571
|
+
if hasattr(args, 'verbose') and args.verbose:
|
|
572
|
+
print(f"section_ids: {json.dumps(policy_data.get('section_ids', {}), indent=2)}")
|
|
573
|
+
|
|
574
|
+
print(f" Found {len(rules)} rules")
|
|
575
|
+
print(f" Found {len(sections)} sections")
|
|
576
|
+
|
|
577
|
+
if not rules and not sections:
|
|
578
|
+
print(" No rules or sections found. Exiting.")
|
|
579
|
+
return [{"success": False, "error": "No rules or sections found"}]
|
|
580
|
+
|
|
581
|
+
# Validate Terraform environment before proceeding
|
|
582
|
+
validate_terraform_environment(args.module_name, verbose=args.verbose)
|
|
583
|
+
|
|
584
|
+
# Ask for confirmation (unless auto-approved)
|
|
585
|
+
if not args.rules_only and not args.sections_only:
|
|
586
|
+
print(f"\n Ready to import {len(sections)} sections and {len(rules)} rules.")
|
|
587
|
+
elif args.rules_only:
|
|
588
|
+
print(f"\n Ready to import {len(rules)} rules only.")
|
|
589
|
+
elif args.sections_only:
|
|
590
|
+
print(f"\n Ready to import {len(sections)} sections only.")
|
|
591
|
+
|
|
592
|
+
if hasattr(args, 'auto_approve') and args.auto_approve:
|
|
593
|
+
print("\nAuto-approve enabled, proceeding with import...")
|
|
594
|
+
else:
|
|
595
|
+
confirm = input(f"\nProceed with import? (y/n): ").lower()
|
|
596
|
+
if confirm != 'y':
|
|
597
|
+
print("Import cancelled.")
|
|
598
|
+
return [{"success": False, "error": "Import cancelled by user"}]
|
|
599
|
+
|
|
600
|
+
total_successful = 0
|
|
601
|
+
total_failed = 0
|
|
602
|
+
|
|
603
|
+
# Import sections first (if not skipped)
|
|
604
|
+
if not args.rules_only and sections:
|
|
605
|
+
successful, failed = import_tls_sections(sections, module_name=args.module_name, verbose=args.verbose)
|
|
606
|
+
total_successful += successful
|
|
607
|
+
total_failed += failed
|
|
608
|
+
|
|
609
|
+
# Import rules (if not skipped)
|
|
610
|
+
if not args.sections_only and rules:
|
|
611
|
+
successful, failed = import_tls_rules(rules, module_name=args.module_name,
|
|
612
|
+
verbose=args.verbose, batch_size=args.batch_size,
|
|
613
|
+
delay_between_batches=args.delay,
|
|
614
|
+
auto_approve=getattr(args, 'auto_approve', False))
|
|
615
|
+
total_successful += successful
|
|
616
|
+
total_failed += failed
|
|
617
|
+
|
|
618
|
+
# Final summary
|
|
619
|
+
print("\n" + "=" * 60)
|
|
620
|
+
print(" FINAL IMPORT SUMMARY")
|
|
621
|
+
print("=" * 60)
|
|
622
|
+
print(f" Total successful imports: {total_successful}")
|
|
623
|
+
print(f" Total failed imports: {total_failed}")
|
|
624
|
+
print(f" Overall success rate: {(total_successful / (total_successful + total_failed) * 100):.1f}%" if (total_successful + total_failed) > 0 else "N/A")
|
|
625
|
+
print("\n Import process completed!")
|
|
626
|
+
|
|
627
|
+
return [{
|
|
628
|
+
"success": True,
|
|
629
|
+
"total_successful": total_successful,
|
|
630
|
+
"total_failed": total_failed,
|
|
631
|
+
"module_name": args.module_name
|
|
632
|
+
}]
|
|
633
|
+
|
|
634
|
+
except KeyboardInterrupt:
|
|
635
|
+
print("\nImport process cancelled by user (Ctrl+C).")
|
|
636
|
+
print("Partial imports may have been completed.")
|
|
637
|
+
return [{"success": False, "error": "Import cancelled by user"}]
|
|
638
|
+
except Exception as e:
|
|
639
|
+
print(f"ERROR: {str(e)}")
|
|
640
|
+
return [{"success": False, "error": str(e)}]
|
|
@@ -11,7 +11,7 @@ catocli query devices <json>
|
|
|
11
11
|
|
|
12
12
|
catocli query devices "$(cat < query.devices.json)"
|
|
13
13
|
|
|
14
|
-
catocli query devices '{"deviceAttributeCatalogInput":{"pagingInput":{"from":1,"limit":1},"sortOrderInput":{"direction":"ASC","priority":1},"stringFilterInput":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]}},"deviceCsvExportInput":{"deviceV2FilterInput":{"category":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]},"confidence":{"eq":"LOW","in":"LOW","neq":"LOW","nin":"LOW"},"firstSeen":{"between":["example1","example2"],"eq":"example_value","gt":"example_value","gte":"example_value","in":["example1","example2"],"lt":"example_value","lte":"example_value","neq":"example_value","nin":["example1","example2"]},"hw":{"manufacturer":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]},"model":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]},"type":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]}},"id":{"eq":"id","in":["id1","id2"],"neq":"id","nin":["id1","id2"]},"ipAddress":{"between":["example1","example2"],"eq":"example_value","in":["example1","example2"],"neq":"example_value","nin":["example1","example2"],"nwithin":"example_value","within":"example_value"},"isManaged":{"eq":true,"neq":true},"lastSeen":{"between":["example1","example2"],"eq":"example_value","gt":"example_value","gte":"example_value","in":["example1","example2"],"lt":"example_value","lte":"example_value","neq":"example_value","nin":["example1","example2"]},"name":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]},"network":{"networkName":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]},"subnet":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]}},"nic":{"macAddress":{"eq":"example_value","in":["example1","example2"],"neq":"example_value","nin":["example1","example2"]},"vendor":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]}},"os":{"product":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]},"vendor":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]},"version":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]}},"riskScore":{"between":[1,2],"eq":1,"gt":1,"gte":1,"in":[1,2],"lt":1,"lte":1,"neq":1,"nin":[1,2]},"site":{"eq":{"by":"ID","input":"string"},"in":{"by":"ID","input":"string"},"neq":{"by":"ID","input":"string"},"nin":{"by":"ID","input":"string"}},"user":{"eq":{"by":"ID","input":"string"},"in":{"by":"ID","input":"string"},"neq":{"by":"ID","input":"string"},"nin":{"by":"ID","input":"string"}}}},"deviceV2Input":{"deviceSortInput":{"category":{"direction":"ASC","priority":1},"confidence":{"direction":"ASC","priority":1},"firstSeen":{"direction":"ASC","priority":1},"hw":{"manufacturer":{"direction":"ASC","priority":1},"model":{"direction":"ASC","priority":1},"type":{"direction":"ASC","priority":1}},"id":{"direction":"ASC","priority":1},"ip":{"direction":"ASC","priority":1},"lastSeen":{"direction":"ASC","priority":1},"name":{"direction":"ASC","priority":1},"network":{"networkName":{"direction":"ASC","priority":1},"subnet":{"direction":"ASC","priority":1}},"nic":{"macAddress":{"direction":"ASC","priority":1},"vendor":{"direction":"ASC","priority":1}},"os":{"product":{"direction":"ASC","priority":1},"vendor":{"direction":"ASC","priority":1},"version":{"direction":"ASC","priority":1}},"riskScore":{"direction":"ASC","priority":1},"site":{"id":{"direction":"ASC","priority":1},"name":{"direction":"ASC","priority":1}},"user":{"id":{"direction":"ASC","priority":1},"name":{"direction":"ASC","priority":1}}},"deviceV2FilterInput":{"category":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]},"confidence":{"eq":"LOW","in":"LOW","neq":"LOW","nin":"LOW"},"firstSeen":{"between":["example1","example2"],"eq":"example_value","gt":"example_value","gte":"example_value","in":["example1","example2"],"lt":"example_value","lte":"example_value","neq":"example_value","nin":["example1","example2"]},"hw":{"manufacturer":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]},"model":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]},"type":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]}},"id":{"eq":"id","in":["id1","id2"],"neq":"id","nin":["id1","id2"]},"ipAddress":{"between":["example1","example2"],"eq":"example_value","in":["example1","example2"],"neq":"example_value","nin":["example1","example2"],"nwithin":"example_value","within":"example_value"},"isManaged":{"eq":true,"neq":true},"lastSeen":{"between":["example1","example2"],"eq":"example_value","gt":"example_value","gte":"example_value","in":["example1","example2"],"lt":"example_value","lte":"example_value","neq":"example_value","nin":["example1","example2"]},"name":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]},"network":{"networkName":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]},"subnet":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]}},"nic":{"macAddress":{"eq":"example_value","in":["example1","example2"],"neq":"example_value","nin":["example1","example2"]},"vendor":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]}},"os":{"product":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]},"vendor":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]},"version":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]}},"riskScore":{"between":[1,2],"eq":1,"gt":1,"gte":1,"in":[1,2],"lt":1,"lte":1,"neq":1,"nin":[1,2]},"site":{"eq":{"by":"ID","input":"string"},"in":{"by":"ID","input":"string"},"neq":{"by":"ID","input":"string"},"nin":{"by":"ID","input":"string"}},"user":{"eq":{"by":"ID","input":"string"},"in":{"by":"ID","input":"string"},"neq":{"by":"ID","input":"string"},"nin":{"by":"ID","input":"string"}}},"pagingInput":{"from":1,"limit":1}},"jobId":"id","sortOrderInput":{"direction":"ASC","priority":1}}'
|
|
14
|
+
catocli query devices '{"deviceAttributeCatalogInput":{"pagingInput":{"from":1,"limit":1},"sortOrderInput":{"direction":"ASC","priority":1},"stringFilterInput":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]}},"deviceCsvExportInput":{"deviceV2FilterInput":{"category":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]},"complianceState":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]},"confidence":{"eq":"LOW","in":"LOW","neq":"LOW","nin":"LOW"},"firstSeen":{"between":["example1","example2"],"eq":"example_value","gt":"example_value","gte":"example_value","in":["example1","example2"],"lt":"example_value","lte":"example_value","neq":"example_value","nin":["example1","example2"]},"hw":{"manufacturer":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]},"model":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]},"type":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]}},"id":{"eq":"id","in":["id1","id2"],"neq":"id","nin":["id1","id2"]},"ipAddress":{"between":["example1","example2"],"eq":"example_value","in":["example1","example2"],"neq":"example_value","nin":["example1","example2"],"nwithin":"example_value","within":"example_value"},"isManaged":{"eq":true,"neq":true},"lastSeen":{"between":["example1","example2"],"eq":"example_value","gt":"example_value","gte":"example_value","in":["example1","example2"],"lt":"example_value","lte":"example_value","neq":"example_value","nin":["example1","example2"]},"name":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]},"network":{"networkName":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]},"subnet":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]}},"nic":{"macAddress":{"eq":"example_value","in":["example1","example2"],"neq":"example_value","nin":["example1","example2"]},"vendor":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]}},"originTypes":{"hasAll":"Unknown","in":"Unknown","nin":"Unknown"},"os":{"product":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]},"vendor":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]},"version":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]}},"riskScore":{"between":[1,2],"eq":1,"gt":1,"gte":1,"in":[1,2],"lt":1,"lte":1,"neq":1,"nin":[1,2]},"site":{"eq":{"by":"ID","input":"string"},"in":{"by":"ID","input":"string"},"neq":{"by":"ID","input":"string"},"nin":{"by":"ID","input":"string"}},"user":{"eq":{"by":"ID","input":"string"},"in":{"by":"ID","input":"string"},"neq":{"by":"ID","input":"string"},"nin":{"by":"ID","input":"string"}}}},"deviceV2Input":{"deviceSortInput":{"category":{"direction":"ASC","priority":1},"confidence":{"direction":"ASC","priority":1},"firstSeen":{"direction":"ASC","priority":1},"hw":{"manufacturer":{"direction":"ASC","priority":1},"model":{"direction":"ASC","priority":1},"type":{"direction":"ASC","priority":1}},"id":{"direction":"ASC","priority":1},"ip":{"direction":"ASC","priority":1},"lastSeen":{"direction":"ASC","priority":1},"name":{"direction":"ASC","priority":1},"network":{"networkName":{"direction":"ASC","priority":1},"subnet":{"direction":"ASC","priority":1}},"nic":{"macAddress":{"direction":"ASC","priority":1},"vendor":{"direction":"ASC","priority":1}},"os":{"product":{"direction":"ASC","priority":1},"vendor":{"direction":"ASC","priority":1},"version":{"direction":"ASC","priority":1}},"riskScore":{"direction":"ASC","priority":1},"site":{"id":{"direction":"ASC","priority":1},"name":{"direction":"ASC","priority":1}},"user":{"id":{"direction":"ASC","priority":1},"name":{"direction":"ASC","priority":1}}},"deviceV2FilterInput":{"category":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]},"complianceState":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]},"confidence":{"eq":"LOW","in":"LOW","neq":"LOW","nin":"LOW"},"firstSeen":{"between":["example1","example2"],"eq":"example_value","gt":"example_value","gte":"example_value","in":["example1","example2"],"lt":"example_value","lte":"example_value","neq":"example_value","nin":["example1","example2"]},"hw":{"manufacturer":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]},"model":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]},"type":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]}},"id":{"eq":"id","in":["id1","id2"],"neq":"id","nin":["id1","id2"]},"ipAddress":{"between":["example1","example2"],"eq":"example_value","in":["example1","example2"],"neq":"example_value","nin":["example1","example2"],"nwithin":"example_value","within":"example_value"},"isManaged":{"eq":true,"neq":true},"lastSeen":{"between":["example1","example2"],"eq":"example_value","gt":"example_value","gte":"example_value","in":["example1","example2"],"lt":"example_value","lte":"example_value","neq":"example_value","nin":["example1","example2"]},"name":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]},"network":{"networkName":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]},"subnet":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]}},"nic":{"macAddress":{"eq":"example_value","in":["example1","example2"],"neq":"example_value","nin":["example1","example2"]},"vendor":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]}},"originTypes":{"hasAll":"Unknown","in":"Unknown","nin":"Unknown"},"os":{"product":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]},"vendor":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]},"version":{"eq":"string","in":["string1","string2"],"neq":"string","nin":["string1","string2"]}},"riskScore":{"between":[1,2],"eq":1,"gt":1,"gte":1,"in":[1,2],"lt":1,"lte":1,"neq":1,"nin":[1,2]},"site":{"eq":{"by":"ID","input":"string"},"in":{"by":"ID","input":"string"},"neq":{"by":"ID","input":"string"},"nin":{"by":"ID","input":"string"}},"user":{"eq":{"by":"ID","input":"string"},"in":{"by":"ID","input":"string"},"neq":{"by":"ID","input":"string"},"nin":{"by":"ID","input":"string"}}},"pagingInput":{"from":1,"limit":1}},"jobId":"id","sortOrderInput":{"direction":"ASC","priority":1}}'
|
|
15
15
|
|
|
16
16
|
catocli query devices '{
|
|
17
17
|
"deviceAttributeCatalogInput": {
|
|
@@ -50,6 +50,18 @@ catocli query devices '{
|
|
|
50
50
|
"string2"
|
|
51
51
|
]
|
|
52
52
|
},
|
|
53
|
+
"complianceState": {
|
|
54
|
+
"eq": "string",
|
|
55
|
+
"in": [
|
|
56
|
+
"string1",
|
|
57
|
+
"string2"
|
|
58
|
+
],
|
|
59
|
+
"neq": "string",
|
|
60
|
+
"nin": [
|
|
61
|
+
"string1",
|
|
62
|
+
"string2"
|
|
63
|
+
]
|
|
64
|
+
},
|
|
53
65
|
"confidence": {
|
|
54
66
|
"eq": "LOW",
|
|
55
67
|
"in": "LOW",
|
|
@@ -232,6 +244,11 @@ catocli query devices '{
|
|
|
232
244
|
]
|
|
233
245
|
}
|
|
234
246
|
},
|
|
247
|
+
"originTypes": {
|
|
248
|
+
"hasAll": "Unknown",
|
|
249
|
+
"in": "Unknown",
|
|
250
|
+
"nin": "Unknown"
|
|
251
|
+
},
|
|
235
252
|
"os": {
|
|
236
253
|
"product": {
|
|
237
254
|
"eq": "string",
|
|
@@ -444,6 +461,18 @@ catocli query devices '{
|
|
|
444
461
|
"string2"
|
|
445
462
|
]
|
|
446
463
|
},
|
|
464
|
+
"complianceState": {
|
|
465
|
+
"eq": "string",
|
|
466
|
+
"in": [
|
|
467
|
+
"string1",
|
|
468
|
+
"string2"
|
|
469
|
+
],
|
|
470
|
+
"neq": "string",
|
|
471
|
+
"nin": [
|
|
472
|
+
"string1",
|
|
473
|
+
"string2"
|
|
474
|
+
]
|
|
475
|
+
},
|
|
447
476
|
"confidence": {
|
|
448
477
|
"eq": "LOW",
|
|
449
478
|
"in": "LOW",
|
|
@@ -626,6 +655,11 @@ catocli query devices '{
|
|
|
626
655
|
]
|
|
627
656
|
}
|
|
628
657
|
},
|
|
658
|
+
"originTypes": {
|
|
659
|
+
"hasAll": "Unknown",
|
|
660
|
+
"in": "Unknown",
|
|
661
|
+
"nin": "Unknown"
|
|
662
|
+
},
|
|
629
663
|
"os": {
|
|
630
664
|
"product": {
|
|
631
665
|
"eq": "string",
|