catocli 2.0.2__py3-none-any.whl → 2.0.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of catocli might be problematic. Click here for more details.
- catocli/Utils/clidriver.py +4 -1
- catocli/__init__.py +1 -1
- catocli/parsers/custom/__init__.py +4 -3
- catocli/parsers/custom/customLib.py +239 -1
- catocli/parsers/custom/export_rules/export_rules.py +1 -1
- catocli/parsers/custom/export_sites/export_sites.py +186 -54
- catocli/parsers/custom/import_rules_to_tf/__init__.py +1 -1
- catocli/parsers/custom/import_rules_to_tf/import_rules_to_tf.py +1 -137
- catocli/parsers/custom/import_sites_to_tf/__init__.py +45 -0
- catocli/parsers/custom/import_sites_to_tf/import_sites_to_tf.py +891 -0
- catocli/parsers/mutation_accountManagement/__init__.py +6 -6
- catocli/parsers/mutation_admin/__init__.py +6 -6
- catocli/parsers/mutation_container/__init__.py +2 -2
- catocli/parsers/mutation_hardware/__init__.py +2 -2
- catocli/parsers/mutation_policy/__init__.py +192 -192
- catocli/parsers/mutation_sandbox/__init__.py +4 -4
- catocli/parsers/mutation_site/__init__.py +56 -56
- catocli/parsers/mutation_sites/__init__.py +56 -56
- catocli/parsers/mutation_xdr/__init__.py +6 -6
- catocli/parsers/parserApiClient.py +36 -11
- catocli/parsers/query_accountBySubdomain/__init__.py +2 -2
- catocli/parsers/query_accountManagement/__init__.py +2 -2
- catocli/parsers/query_accountMetrics/__init__.py +2 -2
- catocli/parsers/query_accountRoles/__init__.py +2 -2
- catocli/parsers/query_accountSnapshot/__init__.py +2 -2
- catocli/parsers/query_admin/__init__.py +2 -2
- catocli/parsers/query_admins/__init__.py +2 -2
- catocli/parsers/query_appStats/__init__.py +2 -2
- catocli/parsers/query_appStatsTimeSeries/__init__.py +2 -2
- catocli/parsers/query_auditFeed/__init__.py +2 -2
- catocli/parsers/query_catalogs/__init__.py +2 -2
- catocli/parsers/query_container/__init__.py +2 -2
- catocli/parsers/query_devices/__init__.py +2 -2
- catocli/parsers/query_entityLookup/__init__.py +2 -2
- catocli/parsers/query_events/__init__.py +2 -2
- catocli/parsers/query_eventsFeed/__init__.py +2 -2
- catocli/parsers/query_eventsTimeSeries/__init__.py +2 -2
- catocli/parsers/query_hardware/__init__.py +2 -2
- catocli/parsers/query_hardwareManagement/__init__.py +2 -2
- catocli/parsers/query_licensing/__init__.py +2 -2
- catocli/parsers/query_policy/__init__.py +2 -2
- catocli/parsers/query_sandbox/__init__.py +2 -2
- catocli/parsers/query_site/__init__.py +2 -2
- catocli/parsers/query_siteLocation/__init__.py +2 -2
- catocli/parsers/query_subDomains/__init__.py +2 -2
- catocli/parsers/query_xdr/__init__.py +4 -4
- catocli/parsers/raw/README.md +4 -0
- catocli/parsers/raw/__init__.py +3 -2
- {catocli-2.0.2.dist-info → catocli-2.0.3.dist-info}/METADATA +1 -1
- {catocli-2.0.2.dist-info → catocli-2.0.3.dist-info}/RECORD +55 -53
- schema/catolib.py +14 -9
- {catocli-2.0.2.dist-info → catocli-2.0.3.dist-info}/LICENSE +0 -0
- {catocli-2.0.2.dist-info → catocli-2.0.3.dist-info}/WHEEL +0 -0
- {catocli-2.0.2.dist-info → catocli-2.0.3.dist-info}/entry_points.txt +0 -0
- {catocli-2.0.2.dist-info → catocli-2.0.3.dist-info}/top_level.txt +0 -0
|
@@ -13,6 +13,7 @@ import re
|
|
|
13
13
|
import time
|
|
14
14
|
import glob
|
|
15
15
|
from pathlib import Path
|
|
16
|
+
from ..customLib import validate_terraform_environment
|
|
16
17
|
|
|
17
18
|
|
|
18
19
|
def load_json_data(json_file):
|
|
@@ -191,143 +192,6 @@ def import_rules(rules, module_name, verbose=False,
|
|
|
191
192
|
return successful_imports, failed_imports
|
|
192
193
|
|
|
193
194
|
|
|
194
|
-
def check_terraform_binary():
|
|
195
|
-
"""Check if terraform binary is available"""
|
|
196
|
-
try:
|
|
197
|
-
result = subprocess.run(['terraform', '--version'], capture_output=True, text=True)
|
|
198
|
-
if result.returncode == 0:
|
|
199
|
-
return True, result.stdout.strip().split('\n')[0]
|
|
200
|
-
else:
|
|
201
|
-
return False, "Terraform binary not found or not working"
|
|
202
|
-
except FileNotFoundError:
|
|
203
|
-
return False, "Terraform binary not found in PATH"
|
|
204
|
-
except Exception as e:
|
|
205
|
-
return False, f"Error checking terraform binary: {e}"
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
def check_terraform_config_files():
|
|
209
|
-
"""Check if Terraform configuration files exist in current directory"""
|
|
210
|
-
tf_files = glob.glob('*.tf') + glob.glob('*.tf.json')
|
|
211
|
-
if tf_files:
|
|
212
|
-
return True, tf_files
|
|
213
|
-
else:
|
|
214
|
-
return False, []
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
def check_terraform_init():
|
|
218
|
-
"""Check if Terraform has been initialized"""
|
|
219
|
-
terraform_dir = Path('.terraform')
|
|
220
|
-
if terraform_dir.exists() and terraform_dir.is_dir():
|
|
221
|
-
# Check for providers
|
|
222
|
-
providers_dir = terraform_dir / 'providers'
|
|
223
|
-
if providers_dir.exists():
|
|
224
|
-
return True, "Terraform is initialized"
|
|
225
|
-
else:
|
|
226
|
-
return False, "Terraform directory exists but no providers found"
|
|
227
|
-
else:
|
|
228
|
-
return False, "Terraform not initialized (.terraform directory not found)"
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
def check_module_exists(module_name):
|
|
232
|
-
"""Check if the specified module exists in Terraform configuration"""
|
|
233
|
-
try:
|
|
234
|
-
# Remove 'module.' prefix if present
|
|
235
|
-
clean_module_name = module_name.replace('module.', '')
|
|
236
|
-
|
|
237
|
-
# Method 1: Check .tf files directly for module definitions
|
|
238
|
-
tf_files = glob.glob('*.tf') + glob.glob('*.tf.json')
|
|
239
|
-
for tf_file in tf_files:
|
|
240
|
-
try:
|
|
241
|
-
with open(tf_file, 'r') as f:
|
|
242
|
-
content = f.read()
|
|
243
|
-
# Look for module "module_name" blocks
|
|
244
|
-
if f'module "{clean_module_name}"' in content or f"module '{clean_module_name}'" in content:
|
|
245
|
-
return True, f"Module '{clean_module_name}' found in {tf_file}"
|
|
246
|
-
except Exception as e:
|
|
247
|
-
print(f"Warning: Could not read {tf_file}: {e}")
|
|
248
|
-
continue
|
|
249
|
-
|
|
250
|
-
# Method 2: Try terraform show -json as fallback
|
|
251
|
-
try:
|
|
252
|
-
result = subprocess.run(
|
|
253
|
-
['terraform', 'show', '-json'],
|
|
254
|
-
capture_output=True,
|
|
255
|
-
text=True,
|
|
256
|
-
cwd=Path.cwd()
|
|
257
|
-
)
|
|
258
|
-
|
|
259
|
-
if result.returncode == 0:
|
|
260
|
-
state_data = json.loads(result.stdout)
|
|
261
|
-
|
|
262
|
-
# Check if module exists in configuration
|
|
263
|
-
if 'configuration' in state_data and state_data['configuration']:
|
|
264
|
-
modules = state_data.get('configuration', {}).get('root_module', {}).get('module_calls', {})
|
|
265
|
-
if clean_module_name in modules:
|
|
266
|
-
return True, f"Module '{clean_module_name}' found in Terraform state"
|
|
267
|
-
|
|
268
|
-
# Also check in planned_values for modules
|
|
269
|
-
if 'planned_values' in state_data and state_data['planned_values']:
|
|
270
|
-
modules = state_data.get('planned_values', {}).get('root_module', {}).get('child_modules', [])
|
|
271
|
-
for module in modules:
|
|
272
|
-
module_addr = module.get('address', '')
|
|
273
|
-
if clean_module_name in module_addr:
|
|
274
|
-
return True, f"Module '{clean_module_name}' found in planned values"
|
|
275
|
-
except (subprocess.SubprocessError, json.JSONDecodeError) as e:
|
|
276
|
-
print(f"Warning: Could not check terraform state: {e}")
|
|
277
|
-
|
|
278
|
-
return False, f"Module '{clean_module_name}' not found in Terraform configuration files"
|
|
279
|
-
|
|
280
|
-
except Exception as e:
|
|
281
|
-
return False, f"Error checking module existence: {e}"
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
def validate_terraform_environment(module_name, verbose=False):
|
|
285
|
-
"""Validate the complete Terraform environment"""
|
|
286
|
-
print("\n Validating Terraform environment...")
|
|
287
|
-
|
|
288
|
-
# 1. Check terraform binary
|
|
289
|
-
print("\n Checking Terraform binary...")
|
|
290
|
-
has_terraform, terraform_msg = check_terraform_binary()
|
|
291
|
-
if not has_terraform:
|
|
292
|
-
raise Exception(f" Terraform not available: {terraform_msg}")
|
|
293
|
-
if verbose:
|
|
294
|
-
print(f" {terraform_msg}")
|
|
295
|
-
else:
|
|
296
|
-
print(" Terraform binary found")
|
|
297
|
-
|
|
298
|
-
# 2. Check for configuration files
|
|
299
|
-
print("\n Checking Terraform configuration files...")
|
|
300
|
-
has_config, config_files = check_terraform_config_files()
|
|
301
|
-
if not has_config:
|
|
302
|
-
raise Exception(" No Terraform configuration files (.tf or .tf.json) found in current directory")
|
|
303
|
-
if verbose:
|
|
304
|
-
print(f" Found {len(config_files)} configuration files: {', '.join(config_files)}")
|
|
305
|
-
else:
|
|
306
|
-
print(f" Found {len(config_files)} Terraform configuration files")
|
|
307
|
-
|
|
308
|
-
# 3. Check if terraform is initialized
|
|
309
|
-
print("\n Checking Terraform initialization...")
|
|
310
|
-
is_initialized, init_msg = check_terraform_init()
|
|
311
|
-
if not is_initialized:
|
|
312
|
-
raise Exception(f" {init_msg}. Run 'terraform init' first.")
|
|
313
|
-
if verbose:
|
|
314
|
-
print(f" {init_msg}")
|
|
315
|
-
else:
|
|
316
|
-
print(" Terraform is initialized")
|
|
317
|
-
|
|
318
|
-
# 4. Check if the specified module exists
|
|
319
|
-
print(f"\n Checking if module '{module_name}' exists...")
|
|
320
|
-
module_exists, module_msg = check_module_exists(module_name)
|
|
321
|
-
if not module_exists:
|
|
322
|
-
raise Exception(f" {module_msg}. Please add the module to your Terraform configuration first.")
|
|
323
|
-
if verbose:
|
|
324
|
-
print(f" {module_msg}")
|
|
325
|
-
else:
|
|
326
|
-
print(f" Module '{module_name}' found")
|
|
327
|
-
|
|
328
|
-
print("\n All Terraform environment checks passed!")
|
|
329
|
-
|
|
330
|
-
|
|
331
195
|
def import_if_rules_to_tf(args, configuration):
|
|
332
196
|
"""Main function to orchestrate the import process"""
|
|
333
197
|
try:
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import catocli.parsers.custom.import_sites_to_tf.import_sites_to_tf as import_sites_to_tf
|
|
2
|
+
|
|
3
|
+
def site_import_parse(subparsers, import_parser):
|
|
4
|
+
"""Add socket sites import command to existing import parser"""
|
|
5
|
+
|
|
6
|
+
if import_parser is None:
|
|
7
|
+
raise ValueError("Import parser not found. Make sure rule_import_parse is called before site_import_parse.")
|
|
8
|
+
|
|
9
|
+
# Get the existing subparsers from the import parser
|
|
10
|
+
import_subparsers = None
|
|
11
|
+
for action in import_parser._subparsers._group_actions:
|
|
12
|
+
if hasattr(action, 'choices'):
|
|
13
|
+
import_subparsers = action
|
|
14
|
+
break
|
|
15
|
+
|
|
16
|
+
if import_subparsers is None:
|
|
17
|
+
raise ValueError("Import subparsers not found in existing import parser.")
|
|
18
|
+
|
|
19
|
+
# Add socket_sites_to_tf command
|
|
20
|
+
socket_sites_parser = import_subparsers.add_parser(
|
|
21
|
+
'socket_sites_to_tf',
|
|
22
|
+
help='Import socket sites to Terraform state',
|
|
23
|
+
usage='catocli import socket_sites_to_tf <json_file> --module-name <module_name> [options]\n\nexample: catocli import socket_sites_to_tf config_data/socket_sites_11484.json --module-name module.sites'
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
socket_sites_parser.add_argument('json_file', help='Path to the JSON file containing socket sites data')
|
|
27
|
+
socket_sites_parser.add_argument('--module-name', required=True,
|
|
28
|
+
help='Terraform module name to import resources into')
|
|
29
|
+
socket_sites_parser.add_argument('-accountID', help='Account ID (required by CLI framework but not used for import)', required=False)
|
|
30
|
+
socket_sites_parser.add_argument('--batch-size', type=int, default=10,
|
|
31
|
+
help='Number of imports per batch (default: 10)')
|
|
32
|
+
socket_sites_parser.add_argument('--delay', type=int, default=2,
|
|
33
|
+
help='Delay between batches in seconds (default: 2)')
|
|
34
|
+
socket_sites_parser.add_argument('--sites-only', action='store_true',
|
|
35
|
+
help='Import only sites, skip interfaces and network ranges')
|
|
36
|
+
socket_sites_parser.add_argument('--interfaces-only', action='store_true',
|
|
37
|
+
help='Import only WAN interfaces, skip sites and network ranges')
|
|
38
|
+
socket_sites_parser.add_argument('--network-ranges-only', action='store_true',
|
|
39
|
+
help='Import only network ranges, skip sites and interfaces')
|
|
40
|
+
socket_sites_parser.add_argument('-v', '--verbose', action='store_true', help='Verbose output')
|
|
41
|
+
socket_sites_parser.add_argument('--auto-approve', action='store_true', help='Skip confirmation prompt and proceed automatically')
|
|
42
|
+
|
|
43
|
+
socket_sites_parser.set_defaults(func=import_sites_to_tf.import_socket_sites_to_tf)
|
|
44
|
+
|
|
45
|
+
return import_parser
|