runbooks 1.1.4__py3-none-any.whl → 1.1.6__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.
- runbooks/__init__.py +31 -2
- runbooks/__init___optimized.py +18 -4
- runbooks/_platform/__init__.py +1 -5
- runbooks/_platform/core/runbooks_wrapper.py +141 -138
- runbooks/aws2/accuracy_validator.py +812 -0
- runbooks/base.py +7 -0
- runbooks/cfat/assessment/compliance.py +1 -1
- runbooks/cfat/assessment/runner.py +1 -0
- runbooks/cfat/cloud_foundations_assessment.py +227 -239
- runbooks/cli/__init__.py +1 -1
- runbooks/cli/commands/cfat.py +64 -23
- runbooks/cli/commands/finops.py +1005 -54
- runbooks/cli/commands/inventory.py +135 -91
- runbooks/cli/commands/operate.py +9 -36
- runbooks/cli/commands/security.py +42 -18
- runbooks/cli/commands/validation.py +432 -18
- runbooks/cli/commands/vpc.py +81 -17
- runbooks/cli/registry.py +22 -10
- runbooks/cloudops/__init__.py +20 -27
- runbooks/cloudops/base.py +96 -107
- runbooks/cloudops/cost_optimizer.py +544 -542
- runbooks/cloudops/infrastructure_optimizer.py +5 -4
- runbooks/cloudops/interfaces.py +224 -225
- runbooks/cloudops/lifecycle_manager.py +5 -4
- runbooks/cloudops/mcp_cost_validation.py +252 -235
- runbooks/cloudops/models.py +78 -53
- runbooks/cloudops/monitoring_automation.py +5 -4
- runbooks/cloudops/notebook_framework.py +177 -213
- runbooks/cloudops/security_enforcer.py +125 -159
- runbooks/common/accuracy_validator.py +17 -12
- runbooks/common/aws_pricing.py +349 -326
- runbooks/common/aws_pricing_api.py +211 -212
- runbooks/common/aws_profile_manager.py +40 -36
- runbooks/common/aws_utils.py +74 -79
- runbooks/common/business_logic.py +126 -104
- runbooks/common/cli_decorators.py +36 -60
- runbooks/common/comprehensive_cost_explorer_integration.py +455 -463
- runbooks/common/cross_account_manager.py +197 -204
- runbooks/common/date_utils.py +27 -39
- runbooks/common/decorators.py +29 -19
- runbooks/common/dry_run_examples.py +173 -208
- runbooks/common/dry_run_framework.py +157 -155
- runbooks/common/enhanced_exception_handler.py +15 -4
- runbooks/common/enhanced_logging_example.py +50 -64
- runbooks/common/enhanced_logging_integration_example.py +65 -37
- runbooks/common/env_utils.py +16 -16
- runbooks/common/error_handling.py +40 -38
- runbooks/common/lazy_loader.py +41 -23
- runbooks/common/logging_integration_helper.py +79 -86
- runbooks/common/mcp_cost_explorer_integration.py +476 -493
- runbooks/common/mcp_integration.py +99 -79
- runbooks/common/memory_optimization.py +140 -118
- runbooks/common/module_cli_base.py +37 -58
- runbooks/common/organizations_client.py +175 -193
- runbooks/common/patterns.py +23 -25
- runbooks/common/performance_monitoring.py +67 -71
- runbooks/common/performance_optimization_engine.py +283 -274
- runbooks/common/profile_utils.py +111 -37
- runbooks/common/rich_utils.py +315 -141
- runbooks/common/sre_performance_suite.py +177 -186
- runbooks/enterprise/__init__.py +1 -1
- runbooks/enterprise/logging.py +144 -106
- runbooks/enterprise/security.py +187 -204
- runbooks/enterprise/validation.py +43 -56
- runbooks/finops/__init__.py +26 -30
- runbooks/finops/account_resolver.py +1 -1
- runbooks/finops/advanced_optimization_engine.py +980 -0
- runbooks/finops/automation_core.py +268 -231
- runbooks/finops/business_case_config.py +184 -179
- runbooks/finops/cli.py +660 -139
- runbooks/finops/commvault_ec2_analysis.py +157 -164
- runbooks/finops/compute_cost_optimizer.py +336 -320
- runbooks/finops/config.py +20 -20
- runbooks/finops/cost_optimizer.py +484 -618
- runbooks/finops/cost_processor.py +332 -214
- runbooks/finops/dashboard_runner.py +1006 -172
- runbooks/finops/ebs_cost_optimizer.py +991 -657
- runbooks/finops/elastic_ip_optimizer.py +317 -257
- runbooks/finops/enhanced_mcp_integration.py +340 -0
- runbooks/finops/enhanced_progress.py +32 -29
- runbooks/finops/enhanced_trend_visualization.py +3 -2
- runbooks/finops/enterprise_wrappers.py +223 -285
- runbooks/finops/executive_export.py +203 -160
- runbooks/finops/helpers.py +130 -288
- runbooks/finops/iam_guidance.py +1 -1
- runbooks/finops/infrastructure/__init__.py +80 -0
- runbooks/finops/infrastructure/commands.py +506 -0
- runbooks/finops/infrastructure/load_balancer_optimizer.py +866 -0
- runbooks/finops/infrastructure/vpc_endpoint_optimizer.py +832 -0
- runbooks/finops/markdown_exporter.py +337 -174
- runbooks/finops/mcp_validator.py +1952 -0
- runbooks/finops/nat_gateway_optimizer.py +1512 -481
- runbooks/finops/network_cost_optimizer.py +657 -587
- runbooks/finops/notebook_utils.py +226 -188
- runbooks/finops/optimization_engine.py +1136 -0
- runbooks/finops/optimizer.py +19 -23
- runbooks/finops/rds_snapshot_optimizer.py +367 -411
- runbooks/finops/reservation_optimizer.py +427 -363
- runbooks/finops/scenario_cli_integration.py +64 -65
- runbooks/finops/scenarios.py +1277 -438
- runbooks/finops/schemas.py +218 -182
- runbooks/finops/snapshot_manager.py +2289 -0
- runbooks/finops/types.py +3 -3
- runbooks/finops/validation_framework.py +259 -265
- runbooks/finops/vpc_cleanup_exporter.py +189 -144
- runbooks/finops/vpc_cleanup_optimizer.py +591 -573
- runbooks/finops/workspaces_analyzer.py +171 -182
- runbooks/integration/__init__.py +89 -0
- runbooks/integration/mcp_integration.py +1920 -0
- runbooks/inventory/CLAUDE.md +816 -0
- runbooks/inventory/__init__.py +2 -2
- runbooks/inventory/aws_decorators.py +2 -3
- runbooks/inventory/check_cloudtrail_compliance.py +2 -4
- runbooks/inventory/check_controltower_readiness.py +152 -151
- runbooks/inventory/check_landingzone_readiness.py +85 -84
- runbooks/inventory/cloud_foundations_integration.py +144 -149
- runbooks/inventory/collectors/aws_comprehensive.py +1 -1
- runbooks/inventory/collectors/aws_networking.py +109 -99
- runbooks/inventory/collectors/base.py +4 -0
- runbooks/inventory/core/collector.py +495 -313
- runbooks/inventory/core/formatter.py +11 -0
- runbooks/inventory/draw_org_structure.py +8 -9
- runbooks/inventory/drift_detection_cli.py +69 -96
- runbooks/inventory/ec2_vpc_utils.py +2 -2
- runbooks/inventory/find_cfn_drift_detection.py +5 -7
- runbooks/inventory/find_cfn_orphaned_stacks.py +7 -9
- runbooks/inventory/find_cfn_stackset_drift.py +5 -6
- runbooks/inventory/find_ec2_security_groups.py +48 -42
- runbooks/inventory/find_landingzone_versions.py +4 -6
- runbooks/inventory/find_vpc_flow_logs.py +7 -9
- runbooks/inventory/inventory_mcp_cli.py +48 -46
- runbooks/inventory/inventory_modules.py +103 -91
- runbooks/inventory/list_cfn_stacks.py +9 -10
- runbooks/inventory/list_cfn_stackset_operation_results.py +1 -3
- runbooks/inventory/list_cfn_stackset_operations.py +79 -57
- runbooks/inventory/list_cfn_stacksets.py +8 -10
- runbooks/inventory/list_config_recorders_delivery_channels.py +49 -39
- runbooks/inventory/list_ds_directories.py +65 -53
- runbooks/inventory/list_ec2_availability_zones.py +2 -4
- runbooks/inventory/list_ec2_ebs_volumes.py +32 -35
- runbooks/inventory/list_ec2_instances.py +23 -28
- runbooks/inventory/list_ecs_clusters_and_tasks.py +26 -34
- runbooks/inventory/list_elbs_load_balancers.py +22 -20
- runbooks/inventory/list_enis_network_interfaces.py +26 -33
- runbooks/inventory/list_guardduty_detectors.py +2 -4
- runbooks/inventory/list_iam_policies.py +2 -4
- runbooks/inventory/list_iam_roles.py +5 -7
- runbooks/inventory/list_iam_saml_providers.py +4 -6
- runbooks/inventory/list_lambda_functions.py +38 -38
- runbooks/inventory/list_org_accounts.py +6 -8
- runbooks/inventory/list_org_accounts_users.py +55 -44
- runbooks/inventory/list_rds_db_instances.py +31 -33
- runbooks/inventory/list_rds_snapshots_aggregator.py +192 -208
- runbooks/inventory/list_route53_hosted_zones.py +3 -5
- runbooks/inventory/list_servicecatalog_provisioned_products.py +37 -41
- runbooks/inventory/list_sns_topics.py +2 -4
- runbooks/inventory/list_ssm_parameters.py +4 -7
- runbooks/inventory/list_vpc_subnets.py +2 -4
- runbooks/inventory/list_vpcs.py +7 -10
- runbooks/inventory/mcp_inventory_validator.py +554 -468
- runbooks/inventory/mcp_vpc_validator.py +359 -442
- runbooks/inventory/organizations_discovery.py +63 -55
- runbooks/inventory/recover_cfn_stack_ids.py +7 -8
- runbooks/inventory/requirements.txt +0 -1
- runbooks/inventory/rich_inventory_display.py +35 -34
- runbooks/inventory/run_on_multi_accounts.py +3 -5
- runbooks/inventory/unified_validation_engine.py +281 -253
- runbooks/inventory/verify_ec2_security_groups.py +1 -1
- runbooks/inventory/vpc_analyzer.py +735 -697
- runbooks/inventory/vpc_architecture_validator.py +293 -348
- runbooks/inventory/vpc_dependency_analyzer.py +384 -380
- runbooks/inventory/vpc_flow_analyzer.py +1 -1
- runbooks/main.py +49 -34
- runbooks/main_final.py +91 -60
- runbooks/main_minimal.py +22 -10
- runbooks/main_optimized.py +131 -100
- runbooks/main_ultra_minimal.py +7 -2
- runbooks/mcp/__init__.py +36 -0
- runbooks/mcp/integration.py +679 -0
- runbooks/monitoring/performance_monitor.py +9 -4
- runbooks/operate/dynamodb_operations.py +3 -1
- runbooks/operate/ec2_operations.py +145 -137
- runbooks/operate/iam_operations.py +146 -152
- runbooks/operate/networking_cost_heatmap.py +29 -8
- runbooks/operate/rds_operations.py +223 -254
- runbooks/operate/s3_operations.py +107 -118
- runbooks/operate/vpc_operations.py +646 -616
- runbooks/remediation/base.py +1 -1
- runbooks/remediation/commons.py +10 -7
- runbooks/remediation/commvault_ec2_analysis.py +70 -66
- runbooks/remediation/ec2_unattached_ebs_volumes.py +1 -0
- runbooks/remediation/multi_account.py +24 -21
- runbooks/remediation/rds_snapshot_list.py +86 -60
- runbooks/remediation/remediation_cli.py +92 -146
- runbooks/remediation/universal_account_discovery.py +83 -79
- runbooks/remediation/workspaces_list.py +46 -41
- runbooks/security/__init__.py +19 -0
- runbooks/security/assessment_runner.py +1150 -0
- runbooks/security/baseline_checker.py +812 -0
- runbooks/security/cloudops_automation_security_validator.py +509 -535
- runbooks/security/compliance_automation_engine.py +17 -17
- runbooks/security/config/__init__.py +2 -2
- runbooks/security/config/compliance_config.py +50 -50
- runbooks/security/config_template_generator.py +63 -76
- runbooks/security/enterprise_security_framework.py +1 -1
- runbooks/security/executive_security_dashboard.py +519 -508
- runbooks/security/multi_account_security_controls.py +959 -1210
- runbooks/security/real_time_security_monitor.py +422 -444
- runbooks/security/security_baseline_tester.py +1 -1
- runbooks/security/security_cli.py +143 -112
- runbooks/security/test_2way_validation.py +439 -0
- runbooks/security/two_way_validation_framework.py +852 -0
- runbooks/sre/production_monitoring_framework.py +167 -177
- runbooks/tdd/__init__.py +15 -0
- runbooks/tdd/cli.py +1071 -0
- runbooks/utils/__init__.py +14 -17
- runbooks/utils/logger.py +7 -2
- runbooks/utils/version_validator.py +50 -47
- runbooks/validation/__init__.py +6 -6
- runbooks/validation/cli.py +9 -3
- runbooks/validation/comprehensive_2way_validator.py +745 -704
- runbooks/validation/mcp_validator.py +906 -228
- runbooks/validation/terraform_citations_validator.py +104 -115
- runbooks/validation/terraform_drift_detector.py +461 -454
- runbooks/vpc/README.md +617 -0
- runbooks/vpc/__init__.py +8 -1
- runbooks/vpc/analyzer.py +577 -0
- runbooks/vpc/cleanup_wrapper.py +476 -413
- runbooks/vpc/cli_cloudtrail_commands.py +339 -0
- runbooks/vpc/cli_mcp_validation_commands.py +480 -0
- runbooks/vpc/cloudtrail_audit_integration.py +717 -0
- runbooks/vpc/config.py +92 -97
- runbooks/vpc/cost_engine.py +411 -148
- runbooks/vpc/cost_explorer_integration.py +553 -0
- runbooks/vpc/cross_account_session.py +101 -106
- runbooks/vpc/enhanced_mcp_validation.py +917 -0
- runbooks/vpc/eni_gate_validator.py +961 -0
- runbooks/vpc/heatmap_engine.py +185 -160
- runbooks/vpc/mcp_no_eni_validator.py +680 -639
- runbooks/vpc/nat_gateway_optimizer.py +358 -0
- runbooks/vpc/networking_wrapper.py +15 -8
- runbooks/vpc/pdca_remediation_planner.py +528 -0
- runbooks/vpc/performance_optimized_analyzer.py +219 -231
- runbooks/vpc/runbooks_adapter.py +1167 -241
- runbooks/vpc/tdd_red_phase_stubs.py +601 -0
- runbooks/vpc/test_data_loader.py +358 -0
- runbooks/vpc/tests/conftest.py +314 -4
- runbooks/vpc/tests/test_cleanup_framework.py +1022 -0
- runbooks/vpc/tests/test_cost_engine.py +0 -2
- runbooks/vpc/topology_generator.py +326 -0
- runbooks/vpc/unified_scenarios.py +1297 -1124
- runbooks/vpc/vpc_cleanup_integration.py +1943 -1115
- runbooks-1.1.6.dist-info/METADATA +327 -0
- runbooks-1.1.6.dist-info/RECORD +489 -0
- runbooks/finops/README.md +0 -414
- runbooks/finops/accuracy_cross_validator.py +0 -647
- runbooks/finops/business_cases.py +0 -950
- runbooks/finops/dashboard_router.py +0 -922
- runbooks/finops/ebs_optimizer.py +0 -973
- runbooks/finops/embedded_mcp_validator.py +0 -1629
- runbooks/finops/enhanced_dashboard_runner.py +0 -527
- runbooks/finops/finops_dashboard.py +0 -584
- runbooks/finops/finops_scenarios.py +0 -1218
- runbooks/finops/legacy_migration.py +0 -730
- runbooks/finops/multi_dashboard.py +0 -1519
- runbooks/finops/single_dashboard.py +0 -1113
- runbooks/finops/unlimited_scenarios.py +0 -393
- runbooks-1.1.4.dist-info/METADATA +0 -800
- runbooks-1.1.4.dist-info/RECORD +0 -468
- {runbooks-1.1.4.dist-info → runbooks-1.1.6.dist-info}/WHEEL +0 -0
- {runbooks-1.1.4.dist-info → runbooks-1.1.6.dist-info}/entry_points.txt +0 -0
- {runbooks-1.1.4.dist-info → runbooks-1.1.6.dist-info}/licenses/LICENSE +0 -0
- {runbooks-1.1.4.dist-info → runbooks-1.1.6.dist-info}/top_level.txt +0 -0
@@ -62,18 +62,17 @@ from time import time
|
|
62
62
|
|
63
63
|
from ArgumentsClass import CommonArguments
|
64
64
|
from botocore.exceptions import ClientError
|
65
|
-
from
|
65
|
+
from runbooks.common.rich_utils import console
|
66
66
|
from Inventory_Modules import (
|
67
67
|
display_results,
|
68
68
|
find_references_to_security_groups2,
|
69
69
|
find_security_groups2,
|
70
70
|
get_all_credentials,
|
71
71
|
)
|
72
|
-
|
72
|
+
# Migrated to Rich.Progress - see rich_utils.py for enterprise UX standards
|
73
|
+
# from tqdm.auto import tqdm
|
73
74
|
|
74
|
-
init()
|
75
75
|
__version__ = "2024.09.24"
|
76
|
-
ERASE_LINE = "\x1b[2K"
|
77
76
|
begin_time = time()
|
78
77
|
|
79
78
|
|
@@ -387,7 +386,7 @@ def check_accounts_for_security_groups(
|
|
387
386
|
logging.info(
|
388
387
|
f"{ERASE_LINE}Finished finding security groups in account {c_account_credentials['AccountId']} in region {c_account_credentials['Region']}"
|
389
388
|
)
|
390
|
-
pbar.update()
|
389
|
+
pbar.update(pbar_task, advance=1) # Update Rich progress bar
|
391
390
|
self.queue.task_done()
|
392
391
|
|
393
392
|
###########
|
@@ -406,43 +405,50 @@ def check_accounts_for_security_groups(
|
|
406
405
|
# Initialize thread-safe work queue
|
407
406
|
checkqueue = Queue()
|
408
407
|
|
409
|
-
#
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
408
|
+
# Import Rich display utilities for professional progress tracking
|
409
|
+
from runbooks.common.rich_utils import create_progress_bar
|
410
|
+
|
411
|
+
# Initialize progress tracking for user feedback during long-running analysis
|
412
|
+
with create_progress_bar() as progress:
|
413
|
+
task = progress.add_task(
|
414
|
+
f"[cyan]Finding security groups from {len(fCredentialList)} locations...",
|
415
|
+
total=len(fCredentialList)
|
416
|
+
)
|
417
|
+
|
418
|
+
# Make progress object available to worker threads via global (multi-threaded pattern)
|
419
|
+
global pbar
|
420
|
+
pbar = progress
|
421
|
+
global pbar_task
|
422
|
+
pbar_task = task
|
423
|
+
|
424
|
+
# Start worker thread pool for concurrent security group analysis
|
425
|
+
for x in range(WorkerThreads):
|
426
|
+
worker = FindSecurityGroups(checkqueue)
|
427
|
+
# Daemon threads will terminate when main thread exits
|
428
|
+
# This prevents hanging if an exception occurs in main thread
|
429
|
+
worker.daemon = True
|
430
|
+
worker.start()
|
431
|
+
|
432
|
+
# Queue all credential work items for concurrent processing
|
433
|
+
for credential in fCredentialList:
|
434
|
+
logging.info(f"Connecting to account {credential['AccountId']}")
|
435
|
+
try:
|
436
|
+
# Add credential set and parameters to work queue for worker thread processing
|
437
|
+
checkqueue.put((credential, fFragment, fExact, fDefault))
|
438
|
+
except ClientError as my_Error:
|
439
|
+
# Handle credential validation errors during queue population
|
440
|
+
if "AuthFailure" in str(my_Error):
|
441
|
+
logging.error(
|
442
|
+
f"Authorization Failure accessing account {credential['AccountId']} in '{credential['Region']}' region"
|
443
|
+
)
|
444
|
+
logging.warning(f"It's possible that the region '{credential['Region']}' hasn't been opted-into")
|
445
|
+
# Continue queuing other credentials despite this failure
|
446
|
+
pass
|
415
447
|
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
#
|
420
|
-
# This prevents hanging if an exception occurs in main thread
|
421
|
-
worker.daemon = True
|
422
|
-
worker.start()
|
423
|
-
|
424
|
-
# Queue all credential work items for concurrent processing
|
425
|
-
for credential in fCredentialList:
|
426
|
-
logging.info(f"Connecting to account {credential['AccountId']}")
|
427
|
-
try:
|
428
|
-
# Add credential set and parameters to work queue for worker thread processing
|
429
|
-
checkqueue.put((credential, fFragment, fExact, fDefault))
|
430
|
-
except ClientError as my_Error:
|
431
|
-
# Handle credential validation errors during queue population
|
432
|
-
if "AuthFailure" in str(my_Error):
|
433
|
-
logging.error(
|
434
|
-
f"Authorization Failure accessing account {credential['AccountId']} in '{credential['Region']}' region"
|
435
|
-
)
|
436
|
-
logging.warning(f"It's possible that the region '{credential['Region']}' hasn't been opted-into")
|
437
|
-
# Continue queuing other credentials despite this failure
|
438
|
-
pass
|
439
|
-
|
440
|
-
# Wait for all queued work items to be processed by worker threads
|
441
|
-
# This blocks until all worker threads call task_done()
|
442
|
-
checkqueue.join()
|
443
|
-
|
444
|
-
# Clean up progress bar
|
445
|
-
pbar.close()
|
448
|
+
# Wait for all queued work items to be processed by worker threads
|
449
|
+
# This blocks until all worker threads call task_done()
|
450
|
+
checkqueue.join()
|
451
|
+
# Progress bar auto-closes when exiting context manager
|
446
452
|
|
447
453
|
return AllSecurityGroups
|
448
454
|
|
@@ -659,7 +665,7 @@ if __name__ == "__main__":
|
|
659
665
|
print(f"Data has been saved to {saved_filename}")
|
660
666
|
if pTiming:
|
661
667
|
print(ERASE_LINE)
|
662
|
-
print(f"
|
668
|
+
print(f"[green]This script took {time() - begin_time:.2f} seconds")
|
663
669
|
|
664
670
|
print(
|
665
671
|
f"We found {len(AllSecurityGroups)} {'default ' if pDefault else ''}security group{'' if len(AllSecurityGroups) == 1 else 's'} across {len(AccountList)} accounts and {len(RegionList)} regions"
|
@@ -76,10 +76,9 @@ import boto3
|
|
76
76
|
import Inventory_Modules
|
77
77
|
from ArgumentsClass import CommonArguments
|
78
78
|
from botocore.exceptions import ClientError, CredentialRetrievalError, InvalidConfigError
|
79
|
-
|
79
|
+
# colorama removed - migrated to Rich
|
80
80
|
|
81
81
|
# Initialize colorama for cross-platform colored terminal output
|
82
|
-
init()
|
83
82
|
|
84
83
|
__version__ = "2023.05.31"
|
85
84
|
|
@@ -101,7 +100,6 @@ logging.basicConfig(
|
|
101
100
|
|
102
101
|
##########################
|
103
102
|
# Terminal control and operational configuration constants
|
104
|
-
ERASE_LINE = "\x1b[2K" # ANSI escape sequence for clearing terminal line during progress display
|
105
103
|
SkipProfiles = ["default"] # Profile exclusion list for organizational Landing Zone discovery
|
106
104
|
|
107
105
|
# Configure AWS profile discovery strategy based on user input
|
@@ -129,7 +127,7 @@ ALZProfiles = [] # Initialize Landing Zone profile collection for discovered Ma
|
|
129
127
|
|
130
128
|
for profile in AllProfiles:
|
131
129
|
# Display real-time progress during profile analysis with terminal line clearing
|
132
|
-
print(f"
|
130
|
+
print(f"Checking profile: {profile}", end="\r")
|
133
131
|
|
134
132
|
try:
|
135
133
|
# Analyze current profile to determine if it represents an AWS Landing Zone Management Account
|
@@ -164,7 +162,7 @@ for profile in AllProfiles:
|
|
164
162
|
pass
|
165
163
|
|
166
164
|
# Clear progress display and initialize tabular output formatting for Landing Zone inventory
|
167
|
-
print(
|
165
|
+
console.print()
|
168
166
|
fmt = "%-20s %-13s %-15s %-35s %-21s" # Column formatting for structured Landing Zone data display
|
169
167
|
print(fmt % ("Profile", "Account", "Region", "ALZ Stack Name", "ALZ Version"))
|
170
168
|
print(fmt % ("-------", "-------", "------", "--------------", "-----------"))
|
@@ -194,7 +192,7 @@ for item in ALZProfiles:
|
|
194
192
|
)
|
195
193
|
|
196
194
|
# Display comprehensive operational summary with discovery metrics
|
197
|
-
print(
|
195
|
+
console.print()
|
198
196
|
print(f"Checked {len(AllProfiles)} accounts/ Orgs. Found {len(ALZProfiles)} ALZs")
|
199
197
|
print()
|
200
198
|
print("Thank you for using this script.")
|
@@ -93,13 +93,11 @@ from account_class import aws_acct_access
|
|
93
93
|
from ArgumentsClass import CommonArguments
|
94
94
|
from botocore.config import Config
|
95
95
|
from botocore.exceptions import ClientError
|
96
|
-
from
|
96
|
+
from runbooks.common.rich_utils import console
|
97
97
|
from Inventory_Modules import RemoveCoreAccounts, display_results, get_all_credentials, get_regions3
|
98
98
|
|
99
99
|
# Initialize colorama for cross-platform colored terminal output
|
100
|
-
init()
|
101
100
|
__version__ = "2024.03.10"
|
102
|
-
ERASE_LINE = "\x1b[2K" # ANSI escape sequence for clearing terminal line during progress display
|
103
101
|
begin_time = time() # Script execution timing for performance monitoring
|
104
102
|
sleep_interval = 5 # Default wait interval for CloudWatch Logs query processing
|
105
103
|
|
@@ -305,13 +303,13 @@ def setup_auth_accounts_and_regions(fProfile: str) -> (aws_acct_access, list, li
|
|
305
303
|
|
306
304
|
# Display comprehensive operational context for user confirmation and audit logging
|
307
305
|
print(f"You asked to sum flow log data")
|
308
|
-
print(f"\tin these accounts: {
|
309
|
-
print(f"\tin these regions: {
|
306
|
+
print(f"\tin these accounts: [red]{AccountList}")
|
307
|
+
print(f"\tin these regions: [red]{RegionList}")
|
310
308
|
print(f"\tFrom: {pStartDate} until {pEndDate}")
|
311
309
|
|
312
310
|
# Display account exclusion information for operational transparency
|
313
311
|
if pSkipAccounts is not None:
|
314
|
-
print(f"\tWhile skipping these accounts: {
|
312
|
+
print(f"\tWhile skipping these accounts: [red]{pSkipAccounts}")
|
315
313
|
|
316
314
|
return aws_acct, AccountList, RegionList
|
317
315
|
|
@@ -1040,13 +1038,13 @@ def get_cw_query_results(fquery_requests: list) -> list[dict]:
|
|
1040
1038
|
# Implement timeout protection for long-running queries
|
1041
1039
|
if waited_seconds_total > (SpannedDaysChecked * 5):
|
1042
1040
|
print(
|
1043
|
-
f"
|
1041
|
+
f"Query is still running... Waited {waited_seconds_total} seconds already, we'll have to check manually later. "
|
1044
1042
|
)
|
1045
1043
|
break
|
1046
1044
|
|
1047
1045
|
# Display real-time progress for query execution monitoring
|
1048
1046
|
print(
|
1049
|
-
f"
|
1047
|
+
f"Query for vpc {query['VPCId']} in account {query['AccountId']} in region {query['Region']} is still running... It's been {waited_seconds_total} seconds so far",
|
1050
1048
|
end="\r",
|
1051
1049
|
)
|
1052
1050
|
|
@@ -1181,7 +1179,7 @@ if __name__ == "__main__":
|
|
1181
1179
|
f"Account {credential['AccountId']} was successfully connected via role {credential.get('Role', pAccessRole)} from {aws_acct.acct_number}"
|
1182
1180
|
)
|
1183
1181
|
print(
|
1184
|
-
f"
|
1182
|
+
f"Checking account [blue]{credential['AccountId']} in region [blue]{credential['Region']}...",
|
1185
1183
|
end="\r",
|
1186
1184
|
)
|
1187
1185
|
"""
|
@@ -25,22 +25,28 @@ from .mcp_inventory_validator import create_inventory_mcp_validator
|
|
25
25
|
|
26
26
|
|
27
27
|
@click.command()
|
28
|
-
@click.option(
|
29
|
-
@click.option(
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
28
|
+
@click.option("--profile", help="AWS profile name (takes precedence over environment variables)")
|
29
|
+
@click.option(
|
30
|
+
"--resource-types",
|
31
|
+
multiple=True,
|
32
|
+
type=click.Choice(["ec2", "s3", "rds", "lambda", "vpc", "iam", "cloudformation"]),
|
33
|
+
default=["ec2", "s3", "vpc"],
|
34
|
+
help="Resource types to validate",
|
35
|
+
)
|
36
|
+
@click.option("--test-mode", is_flag=True, default=True, help="Run in test mode with sample data")
|
37
|
+
@click.option(
|
38
|
+
"--real-validation",
|
39
|
+
is_flag=True,
|
40
|
+
default=False,
|
41
|
+
help="Run validation against real AWS APIs (requires valid profiles)",
|
42
|
+
)
|
37
43
|
def validate_inventory_mcp(profile: Optional[str], resource_types: List[str], test_mode: bool, real_validation: bool):
|
38
44
|
"""
|
39
45
|
Test inventory MCP validation functionality.
|
40
|
-
|
46
|
+
|
41
47
|
This command demonstrates inventory MCP validation integration
|
42
48
|
following proven enterprise patterns from FinOps module success.
|
43
|
-
|
49
|
+
|
44
50
|
Examples:
|
45
51
|
runbooks inventory validate-mcp --profile my-profile --resource-types ec2,s3
|
46
52
|
runbooks inventory validate-mcp --test-mode --resource-types ec2,vpc,rds
|
@@ -48,7 +54,9 @@ def validate_inventory_mcp(profile: Optional[str], resource_types: List[str], te
|
|
48
54
|
"""
|
49
55
|
try:
|
50
56
|
console.print(f"[blue]🔍 Inventory MCP Validation Test[/blue]")
|
51
|
-
console.print(
|
57
|
+
console.print(
|
58
|
+
f"[dim]Profile: {profile or 'environment fallback'} | Resources: {', '.join(resource_types)} | Test mode: {test_mode}[/dim]"
|
59
|
+
)
|
52
60
|
|
53
61
|
# Apply profile priority system following proven patterns
|
54
62
|
operational_profile = get_profile_for_operation("operational", profile)
|
@@ -61,7 +69,7 @@ def validate_inventory_mcp(profile: Optional[str], resource_types: List[str], te
|
|
61
69
|
if test_mode and not real_validation:
|
62
70
|
# Test mode: Use sample data to demonstrate validation
|
63
71
|
print_info("Running test mode with sample inventory data")
|
64
|
-
|
72
|
+
|
65
73
|
# Create sample inventory data for testing
|
66
74
|
sample_inventory = {
|
67
75
|
operational_profile: {
|
@@ -72,89 +80,83 @@ def validate_inventory_mcp(profile: Optional[str], resource_types: List[str], te
|
|
72
80
|
"lambda": 12,
|
73
81
|
"vpc": 4,
|
74
82
|
"iam": 25,
|
75
|
-
"cloudformation": 6
|
83
|
+
"cloudformation": 6,
|
76
84
|
},
|
77
|
-
"regions": ["us-east-1", "us-west-2"]
|
85
|
+
"regions": ["us-east-1", "us-west-2"],
|
78
86
|
}
|
79
87
|
}
|
80
|
-
|
88
|
+
|
81
89
|
# Filter to requested resource types
|
82
90
|
filtered_inventory = {
|
83
91
|
operational_profile: {
|
84
92
|
"resource_counts": {
|
85
|
-
rt: sample_inventory[operational_profile]["resource_counts"].get(rt, 0)
|
86
|
-
for rt in resource_types
|
93
|
+
rt: sample_inventory[operational_profile]["resource_counts"].get(rt, 0) for rt in resource_types
|
87
94
|
},
|
88
|
-
"regions": sample_inventory[operational_profile]["regions"]
|
95
|
+
"regions": sample_inventory[operational_profile]["regions"],
|
89
96
|
}
|
90
97
|
}
|
91
|
-
|
92
|
-
print_info(
|
93
|
-
|
98
|
+
|
99
|
+
print_info(
|
100
|
+
f"Testing validation with sample resource counts: {filtered_inventory[operational_profile]['resource_counts']}"
|
101
|
+
)
|
102
|
+
|
94
103
|
# Note: In test mode, this will compare sample data against real AWS APIs
|
95
104
|
# This demonstrates the validation mechanism without requiring mock data
|
96
105
|
validation_results = validator.validate_inventory_data(filtered_inventory)
|
97
|
-
|
106
|
+
|
98
107
|
elif real_validation:
|
99
108
|
# Real validation mode: Requires actual inventory collection
|
100
109
|
print_warning("Real validation mode requires actual inventory collection")
|
101
110
|
print_info("This would typically be called from the main inventory collector")
|
102
|
-
|
111
|
+
|
103
112
|
# For demonstration, we'll validate empty inventory (should show 0 vs actual counts)
|
104
113
|
empty_inventory = {
|
105
|
-
operational_profile: {
|
106
|
-
"resource_counts": {rt: 0 for rt in resource_types},
|
107
|
-
"regions": ["us-east-1"]
|
108
|
-
}
|
114
|
+
operational_profile: {"resource_counts": {rt: 0 for rt in resource_types}, "regions": ["us-east-1"]}
|
109
115
|
}
|
110
|
-
|
116
|
+
|
111
117
|
print_info("Validating empty inventory against real AWS APIs (demonstrates detection capability)")
|
112
118
|
validation_results = validator.validate_inventory_data(empty_inventory)
|
113
|
-
|
119
|
+
|
114
120
|
else:
|
115
121
|
# Resource count validation only
|
116
122
|
print_info("Running resource count validation test")
|
117
|
-
|
118
|
-
sample_counts = {
|
119
|
-
|
120
|
-
"s3": 5,
|
121
|
-
"vpc": 2
|
122
|
-
}
|
123
|
-
|
123
|
+
|
124
|
+
sample_counts = {"ec2": 10, "s3": 5, "vpc": 2}
|
125
|
+
|
124
126
|
# Filter to requested resource types
|
125
127
|
test_counts = {rt: sample_counts.get(rt, 0) for rt in resource_types if rt in sample_counts}
|
126
|
-
|
128
|
+
|
127
129
|
validation_results = validator.validate_resource_counts(test_counts)
|
128
130
|
|
129
131
|
# Display results summary
|
130
132
|
console.print(f"\n[bright_cyan]📊 Validation Test Results Summary[/]")
|
131
|
-
|
133
|
+
|
132
134
|
if isinstance(validation_results, dict):
|
133
135
|
if "total_accuracy" in validation_results:
|
134
136
|
accuracy = validation_results.get("total_accuracy", 0)
|
135
137
|
passed = validation_results.get("passed_validation", False)
|
136
|
-
|
138
|
+
|
137
139
|
if passed:
|
138
140
|
print_success(f"✅ Test validation completed: {accuracy:.1f}% accuracy")
|
139
141
|
else:
|
140
142
|
print_warning(f"⚠️ Test validation: {accuracy:.1f}% accuracy (target: ≥99.5%)")
|
141
|
-
|
143
|
+
|
142
144
|
profiles_validated = validation_results.get("profiles_validated", 0)
|
143
145
|
console.print(f"[dim]Profiles validated: {profiles_validated}[/dim]")
|
144
|
-
|
146
|
+
|
145
147
|
# Show resource summary if available
|
146
148
|
resource_summary = validation_results.get("resource_validation_summary", {})
|
147
149
|
if resource_summary:
|
148
150
|
console.print(f"[dim]Resource types validated: {len(resource_summary)}[/dim]")
|
149
|
-
|
151
|
+
|
150
152
|
elif "validated_count" in validation_results:
|
151
153
|
validated_count = validation_results.get("validated_count", 0)
|
152
154
|
passed_count = validation_results.get("passed_count", 0)
|
153
155
|
print_info(f"Resource count validation: {passed_count}/{validated_count} passed")
|
154
|
-
|
156
|
+
|
155
157
|
else:
|
156
158
|
print_info("Validation completed - see detailed output above")
|
157
|
-
|
159
|
+
|
158
160
|
# Integration guidance
|
159
161
|
console.print(f"\n[bright_cyan]💡 Integration Information[/]")
|
160
162
|
console.print(f"[dim]This MCP validator is automatically integrated into:[/dim]")
|
@@ -168,4 +170,4 @@ def validate_inventory_mcp(profile: Optional[str], resource_types: List[str], te
|
|
168
170
|
|
169
171
|
|
170
172
|
if __name__ == "__main__":
|
171
|
-
validate_inventory_mcp()
|
173
|
+
validate_inventory_mcp()
|