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.
Files changed (273) hide show
  1. runbooks/__init__.py +31 -2
  2. runbooks/__init___optimized.py +18 -4
  3. runbooks/_platform/__init__.py +1 -5
  4. runbooks/_platform/core/runbooks_wrapper.py +141 -138
  5. runbooks/aws2/accuracy_validator.py +812 -0
  6. runbooks/base.py +7 -0
  7. runbooks/cfat/assessment/compliance.py +1 -1
  8. runbooks/cfat/assessment/runner.py +1 -0
  9. runbooks/cfat/cloud_foundations_assessment.py +227 -239
  10. runbooks/cli/__init__.py +1 -1
  11. runbooks/cli/commands/cfat.py +64 -23
  12. runbooks/cli/commands/finops.py +1005 -54
  13. runbooks/cli/commands/inventory.py +135 -91
  14. runbooks/cli/commands/operate.py +9 -36
  15. runbooks/cli/commands/security.py +42 -18
  16. runbooks/cli/commands/validation.py +432 -18
  17. runbooks/cli/commands/vpc.py +81 -17
  18. runbooks/cli/registry.py +22 -10
  19. runbooks/cloudops/__init__.py +20 -27
  20. runbooks/cloudops/base.py +96 -107
  21. runbooks/cloudops/cost_optimizer.py +544 -542
  22. runbooks/cloudops/infrastructure_optimizer.py +5 -4
  23. runbooks/cloudops/interfaces.py +224 -225
  24. runbooks/cloudops/lifecycle_manager.py +5 -4
  25. runbooks/cloudops/mcp_cost_validation.py +252 -235
  26. runbooks/cloudops/models.py +78 -53
  27. runbooks/cloudops/monitoring_automation.py +5 -4
  28. runbooks/cloudops/notebook_framework.py +177 -213
  29. runbooks/cloudops/security_enforcer.py +125 -159
  30. runbooks/common/accuracy_validator.py +17 -12
  31. runbooks/common/aws_pricing.py +349 -326
  32. runbooks/common/aws_pricing_api.py +211 -212
  33. runbooks/common/aws_profile_manager.py +40 -36
  34. runbooks/common/aws_utils.py +74 -79
  35. runbooks/common/business_logic.py +126 -104
  36. runbooks/common/cli_decorators.py +36 -60
  37. runbooks/common/comprehensive_cost_explorer_integration.py +455 -463
  38. runbooks/common/cross_account_manager.py +197 -204
  39. runbooks/common/date_utils.py +27 -39
  40. runbooks/common/decorators.py +29 -19
  41. runbooks/common/dry_run_examples.py +173 -208
  42. runbooks/common/dry_run_framework.py +157 -155
  43. runbooks/common/enhanced_exception_handler.py +15 -4
  44. runbooks/common/enhanced_logging_example.py +50 -64
  45. runbooks/common/enhanced_logging_integration_example.py +65 -37
  46. runbooks/common/env_utils.py +16 -16
  47. runbooks/common/error_handling.py +40 -38
  48. runbooks/common/lazy_loader.py +41 -23
  49. runbooks/common/logging_integration_helper.py +79 -86
  50. runbooks/common/mcp_cost_explorer_integration.py +476 -493
  51. runbooks/common/mcp_integration.py +99 -79
  52. runbooks/common/memory_optimization.py +140 -118
  53. runbooks/common/module_cli_base.py +37 -58
  54. runbooks/common/organizations_client.py +175 -193
  55. runbooks/common/patterns.py +23 -25
  56. runbooks/common/performance_monitoring.py +67 -71
  57. runbooks/common/performance_optimization_engine.py +283 -274
  58. runbooks/common/profile_utils.py +111 -37
  59. runbooks/common/rich_utils.py +315 -141
  60. runbooks/common/sre_performance_suite.py +177 -186
  61. runbooks/enterprise/__init__.py +1 -1
  62. runbooks/enterprise/logging.py +144 -106
  63. runbooks/enterprise/security.py +187 -204
  64. runbooks/enterprise/validation.py +43 -56
  65. runbooks/finops/__init__.py +26 -30
  66. runbooks/finops/account_resolver.py +1 -1
  67. runbooks/finops/advanced_optimization_engine.py +980 -0
  68. runbooks/finops/automation_core.py +268 -231
  69. runbooks/finops/business_case_config.py +184 -179
  70. runbooks/finops/cli.py +660 -139
  71. runbooks/finops/commvault_ec2_analysis.py +157 -164
  72. runbooks/finops/compute_cost_optimizer.py +336 -320
  73. runbooks/finops/config.py +20 -20
  74. runbooks/finops/cost_optimizer.py +484 -618
  75. runbooks/finops/cost_processor.py +332 -214
  76. runbooks/finops/dashboard_runner.py +1006 -172
  77. runbooks/finops/ebs_cost_optimizer.py +991 -657
  78. runbooks/finops/elastic_ip_optimizer.py +317 -257
  79. runbooks/finops/enhanced_mcp_integration.py +340 -0
  80. runbooks/finops/enhanced_progress.py +32 -29
  81. runbooks/finops/enhanced_trend_visualization.py +3 -2
  82. runbooks/finops/enterprise_wrappers.py +223 -285
  83. runbooks/finops/executive_export.py +203 -160
  84. runbooks/finops/helpers.py +130 -288
  85. runbooks/finops/iam_guidance.py +1 -1
  86. runbooks/finops/infrastructure/__init__.py +80 -0
  87. runbooks/finops/infrastructure/commands.py +506 -0
  88. runbooks/finops/infrastructure/load_balancer_optimizer.py +866 -0
  89. runbooks/finops/infrastructure/vpc_endpoint_optimizer.py +832 -0
  90. runbooks/finops/markdown_exporter.py +337 -174
  91. runbooks/finops/mcp_validator.py +1952 -0
  92. runbooks/finops/nat_gateway_optimizer.py +1512 -481
  93. runbooks/finops/network_cost_optimizer.py +657 -587
  94. runbooks/finops/notebook_utils.py +226 -188
  95. runbooks/finops/optimization_engine.py +1136 -0
  96. runbooks/finops/optimizer.py +19 -23
  97. runbooks/finops/rds_snapshot_optimizer.py +367 -411
  98. runbooks/finops/reservation_optimizer.py +427 -363
  99. runbooks/finops/scenario_cli_integration.py +64 -65
  100. runbooks/finops/scenarios.py +1277 -438
  101. runbooks/finops/schemas.py +218 -182
  102. runbooks/finops/snapshot_manager.py +2289 -0
  103. runbooks/finops/types.py +3 -3
  104. runbooks/finops/validation_framework.py +259 -265
  105. runbooks/finops/vpc_cleanup_exporter.py +189 -144
  106. runbooks/finops/vpc_cleanup_optimizer.py +591 -573
  107. runbooks/finops/workspaces_analyzer.py +171 -182
  108. runbooks/integration/__init__.py +89 -0
  109. runbooks/integration/mcp_integration.py +1920 -0
  110. runbooks/inventory/CLAUDE.md +816 -0
  111. runbooks/inventory/__init__.py +2 -2
  112. runbooks/inventory/aws_decorators.py +2 -3
  113. runbooks/inventory/check_cloudtrail_compliance.py +2 -4
  114. runbooks/inventory/check_controltower_readiness.py +152 -151
  115. runbooks/inventory/check_landingzone_readiness.py +85 -84
  116. runbooks/inventory/cloud_foundations_integration.py +144 -149
  117. runbooks/inventory/collectors/aws_comprehensive.py +1 -1
  118. runbooks/inventory/collectors/aws_networking.py +109 -99
  119. runbooks/inventory/collectors/base.py +4 -0
  120. runbooks/inventory/core/collector.py +495 -313
  121. runbooks/inventory/core/formatter.py +11 -0
  122. runbooks/inventory/draw_org_structure.py +8 -9
  123. runbooks/inventory/drift_detection_cli.py +69 -96
  124. runbooks/inventory/ec2_vpc_utils.py +2 -2
  125. runbooks/inventory/find_cfn_drift_detection.py +5 -7
  126. runbooks/inventory/find_cfn_orphaned_stacks.py +7 -9
  127. runbooks/inventory/find_cfn_stackset_drift.py +5 -6
  128. runbooks/inventory/find_ec2_security_groups.py +48 -42
  129. runbooks/inventory/find_landingzone_versions.py +4 -6
  130. runbooks/inventory/find_vpc_flow_logs.py +7 -9
  131. runbooks/inventory/inventory_mcp_cli.py +48 -46
  132. runbooks/inventory/inventory_modules.py +103 -91
  133. runbooks/inventory/list_cfn_stacks.py +9 -10
  134. runbooks/inventory/list_cfn_stackset_operation_results.py +1 -3
  135. runbooks/inventory/list_cfn_stackset_operations.py +79 -57
  136. runbooks/inventory/list_cfn_stacksets.py +8 -10
  137. runbooks/inventory/list_config_recorders_delivery_channels.py +49 -39
  138. runbooks/inventory/list_ds_directories.py +65 -53
  139. runbooks/inventory/list_ec2_availability_zones.py +2 -4
  140. runbooks/inventory/list_ec2_ebs_volumes.py +32 -35
  141. runbooks/inventory/list_ec2_instances.py +23 -28
  142. runbooks/inventory/list_ecs_clusters_and_tasks.py +26 -34
  143. runbooks/inventory/list_elbs_load_balancers.py +22 -20
  144. runbooks/inventory/list_enis_network_interfaces.py +26 -33
  145. runbooks/inventory/list_guardduty_detectors.py +2 -4
  146. runbooks/inventory/list_iam_policies.py +2 -4
  147. runbooks/inventory/list_iam_roles.py +5 -7
  148. runbooks/inventory/list_iam_saml_providers.py +4 -6
  149. runbooks/inventory/list_lambda_functions.py +38 -38
  150. runbooks/inventory/list_org_accounts.py +6 -8
  151. runbooks/inventory/list_org_accounts_users.py +55 -44
  152. runbooks/inventory/list_rds_db_instances.py +31 -33
  153. runbooks/inventory/list_rds_snapshots_aggregator.py +192 -208
  154. runbooks/inventory/list_route53_hosted_zones.py +3 -5
  155. runbooks/inventory/list_servicecatalog_provisioned_products.py +37 -41
  156. runbooks/inventory/list_sns_topics.py +2 -4
  157. runbooks/inventory/list_ssm_parameters.py +4 -7
  158. runbooks/inventory/list_vpc_subnets.py +2 -4
  159. runbooks/inventory/list_vpcs.py +7 -10
  160. runbooks/inventory/mcp_inventory_validator.py +554 -468
  161. runbooks/inventory/mcp_vpc_validator.py +359 -442
  162. runbooks/inventory/organizations_discovery.py +63 -55
  163. runbooks/inventory/recover_cfn_stack_ids.py +7 -8
  164. runbooks/inventory/requirements.txt +0 -1
  165. runbooks/inventory/rich_inventory_display.py +35 -34
  166. runbooks/inventory/run_on_multi_accounts.py +3 -5
  167. runbooks/inventory/unified_validation_engine.py +281 -253
  168. runbooks/inventory/verify_ec2_security_groups.py +1 -1
  169. runbooks/inventory/vpc_analyzer.py +735 -697
  170. runbooks/inventory/vpc_architecture_validator.py +293 -348
  171. runbooks/inventory/vpc_dependency_analyzer.py +384 -380
  172. runbooks/inventory/vpc_flow_analyzer.py +1 -1
  173. runbooks/main.py +49 -34
  174. runbooks/main_final.py +91 -60
  175. runbooks/main_minimal.py +22 -10
  176. runbooks/main_optimized.py +131 -100
  177. runbooks/main_ultra_minimal.py +7 -2
  178. runbooks/mcp/__init__.py +36 -0
  179. runbooks/mcp/integration.py +679 -0
  180. runbooks/monitoring/performance_monitor.py +9 -4
  181. runbooks/operate/dynamodb_operations.py +3 -1
  182. runbooks/operate/ec2_operations.py +145 -137
  183. runbooks/operate/iam_operations.py +146 -152
  184. runbooks/operate/networking_cost_heatmap.py +29 -8
  185. runbooks/operate/rds_operations.py +223 -254
  186. runbooks/operate/s3_operations.py +107 -118
  187. runbooks/operate/vpc_operations.py +646 -616
  188. runbooks/remediation/base.py +1 -1
  189. runbooks/remediation/commons.py +10 -7
  190. runbooks/remediation/commvault_ec2_analysis.py +70 -66
  191. runbooks/remediation/ec2_unattached_ebs_volumes.py +1 -0
  192. runbooks/remediation/multi_account.py +24 -21
  193. runbooks/remediation/rds_snapshot_list.py +86 -60
  194. runbooks/remediation/remediation_cli.py +92 -146
  195. runbooks/remediation/universal_account_discovery.py +83 -79
  196. runbooks/remediation/workspaces_list.py +46 -41
  197. runbooks/security/__init__.py +19 -0
  198. runbooks/security/assessment_runner.py +1150 -0
  199. runbooks/security/baseline_checker.py +812 -0
  200. runbooks/security/cloudops_automation_security_validator.py +509 -535
  201. runbooks/security/compliance_automation_engine.py +17 -17
  202. runbooks/security/config/__init__.py +2 -2
  203. runbooks/security/config/compliance_config.py +50 -50
  204. runbooks/security/config_template_generator.py +63 -76
  205. runbooks/security/enterprise_security_framework.py +1 -1
  206. runbooks/security/executive_security_dashboard.py +519 -508
  207. runbooks/security/multi_account_security_controls.py +959 -1210
  208. runbooks/security/real_time_security_monitor.py +422 -444
  209. runbooks/security/security_baseline_tester.py +1 -1
  210. runbooks/security/security_cli.py +143 -112
  211. runbooks/security/test_2way_validation.py +439 -0
  212. runbooks/security/two_way_validation_framework.py +852 -0
  213. runbooks/sre/production_monitoring_framework.py +167 -177
  214. runbooks/tdd/__init__.py +15 -0
  215. runbooks/tdd/cli.py +1071 -0
  216. runbooks/utils/__init__.py +14 -17
  217. runbooks/utils/logger.py +7 -2
  218. runbooks/utils/version_validator.py +50 -47
  219. runbooks/validation/__init__.py +6 -6
  220. runbooks/validation/cli.py +9 -3
  221. runbooks/validation/comprehensive_2way_validator.py +745 -704
  222. runbooks/validation/mcp_validator.py +906 -228
  223. runbooks/validation/terraform_citations_validator.py +104 -115
  224. runbooks/validation/terraform_drift_detector.py +461 -454
  225. runbooks/vpc/README.md +617 -0
  226. runbooks/vpc/__init__.py +8 -1
  227. runbooks/vpc/analyzer.py +577 -0
  228. runbooks/vpc/cleanup_wrapper.py +476 -413
  229. runbooks/vpc/cli_cloudtrail_commands.py +339 -0
  230. runbooks/vpc/cli_mcp_validation_commands.py +480 -0
  231. runbooks/vpc/cloudtrail_audit_integration.py +717 -0
  232. runbooks/vpc/config.py +92 -97
  233. runbooks/vpc/cost_engine.py +411 -148
  234. runbooks/vpc/cost_explorer_integration.py +553 -0
  235. runbooks/vpc/cross_account_session.py +101 -106
  236. runbooks/vpc/enhanced_mcp_validation.py +917 -0
  237. runbooks/vpc/eni_gate_validator.py +961 -0
  238. runbooks/vpc/heatmap_engine.py +185 -160
  239. runbooks/vpc/mcp_no_eni_validator.py +680 -639
  240. runbooks/vpc/nat_gateway_optimizer.py +358 -0
  241. runbooks/vpc/networking_wrapper.py +15 -8
  242. runbooks/vpc/pdca_remediation_planner.py +528 -0
  243. runbooks/vpc/performance_optimized_analyzer.py +219 -231
  244. runbooks/vpc/runbooks_adapter.py +1167 -241
  245. runbooks/vpc/tdd_red_phase_stubs.py +601 -0
  246. runbooks/vpc/test_data_loader.py +358 -0
  247. runbooks/vpc/tests/conftest.py +314 -4
  248. runbooks/vpc/tests/test_cleanup_framework.py +1022 -0
  249. runbooks/vpc/tests/test_cost_engine.py +0 -2
  250. runbooks/vpc/topology_generator.py +326 -0
  251. runbooks/vpc/unified_scenarios.py +1297 -1124
  252. runbooks/vpc/vpc_cleanup_integration.py +1943 -1115
  253. runbooks-1.1.6.dist-info/METADATA +327 -0
  254. runbooks-1.1.6.dist-info/RECORD +489 -0
  255. runbooks/finops/README.md +0 -414
  256. runbooks/finops/accuracy_cross_validator.py +0 -647
  257. runbooks/finops/business_cases.py +0 -950
  258. runbooks/finops/dashboard_router.py +0 -922
  259. runbooks/finops/ebs_optimizer.py +0 -973
  260. runbooks/finops/embedded_mcp_validator.py +0 -1629
  261. runbooks/finops/enhanced_dashboard_runner.py +0 -527
  262. runbooks/finops/finops_dashboard.py +0 -584
  263. runbooks/finops/finops_scenarios.py +0 -1218
  264. runbooks/finops/legacy_migration.py +0 -730
  265. runbooks/finops/multi_dashboard.py +0 -1519
  266. runbooks/finops/single_dashboard.py +0 -1113
  267. runbooks/finops/unlimited_scenarios.py +0 -393
  268. runbooks-1.1.4.dist-info/METADATA +0 -800
  269. runbooks-1.1.4.dist-info/RECORD +0 -468
  270. {runbooks-1.1.4.dist-info → runbooks-1.1.6.dist-info}/WHEEL +0 -0
  271. {runbooks-1.1.4.dist-info → runbooks-1.1.6.dist-info}/entry_points.txt +0 -0
  272. {runbooks-1.1.4.dist-info → runbooks-1.1.6.dist-info}/licenses/LICENSE +0 -0
  273. {runbooks-1.1.4.dist-info → runbooks-1.1.6.dist-info}/top_level.txt +0 -0
@@ -31,8 +31,6 @@ from runbooks.vpc.networking_wrapper import VPCNetworkingWrapper
31
31
 
32
32
  @pytest.fixture(scope="session")
33
33
  def aws_credentials():
34
- # Dynamic test period for consistent test data
35
- test_period = get_test_date_period(30)
36
34
  """Mock AWS credentials for VPC testing."""
37
35
  os.environ["AWS_ACCESS_KEY_ID"] = "testing"
38
36
  os.environ["AWS_SECRET_ACCESS_KEY"] = "testing"
@@ -274,11 +272,15 @@ def performance_benchmarks():
274
272
  @pytest.fixture
275
273
  def mock_cost_explorer_responses():
276
274
  """Mock Cost Explorer API responses for testing."""
275
+ # Dynamic test period calculation
276
+ end_date = datetime.now()
277
+ start_date = end_date - timedelta(days=30)
278
+
277
279
  return {
278
280
  "vpc_costs": {
279
281
  "ResultsByTime": [
280
282
  {
281
- "TimePeriod": {"Start": test_period["Start"], "End": test_period["End"]},
283
+ "TimePeriod": {"Start": start_date.strftime("%Y-%m-%d"), "End": end_date.strftime("%Y-%m-%d")},
282
284
  "Total": {"BlendedCost": {"Amount": "145.67", "Unit": "USD"}},
283
285
  }
284
286
  ]
@@ -286,7 +288,7 @@ def mock_cost_explorer_responses():
286
288
  "nat_gateway_costs": {
287
289
  "ResultsByTime": [
288
290
  {
289
- "TimePeriod": {"Start": test_period["Start"], "End": test_period["End"]},
291
+ "TimePeriod": {"Start": start_date.strftime("%Y-%m-%d"), "End": end_date.strftime("%Y-%m-%d")},
290
292
  "Total": {"BlendedCost": {"Amount": "89.32", "Unit": "USD"}},
291
293
  }
292
294
  ]
@@ -356,3 +358,311 @@ def security_test_validator():
356
358
  return True
357
359
 
358
360
  return _validate_security
361
+
362
+
363
+ # ========================================
364
+ # VPC Cleanup Framework Fixtures
365
+ # ========================================
366
+ # Added to support config-driven VPC cleanup testing
367
+
368
+
369
+ @pytest.fixture
370
+ def cleanup_valid_config():
371
+ """Load AWS-25 reference config for VPC cleanup testing"""
372
+ import yaml
373
+
374
+ config_path = Path(__file__).parent.parent.parent.parent.parent / "examples/vpc-cleanup/aws25-campaign-config.yaml"
375
+ if not config_path.exists():
376
+ # Fallback to minimal valid config if reference not available
377
+ return {
378
+ "campaign_metadata": {
379
+ "campaign_id": "TEST-01",
380
+ "campaign_name": "Test Campaign",
381
+ "execution_date": "2025-10-02",
382
+ "aws_billing_profile": "test-profile",
383
+ "description": "Test campaign description",
384
+ },
385
+ "deleted_vpcs": [
386
+ {
387
+ "vpc_id": "vpc-test123456789abcd",
388
+ "account_id": "123456789012",
389
+ "region": "us-east-1",
390
+ "deletion_date": "2025-09-10",
391
+ "deletion_principal": "test.user@example.com",
392
+ "pre_deletion_baseline_months": 3,
393
+ }
394
+ ],
395
+ "cost_explorer_config": {
396
+ "metrics": ["UnblendedCost"],
397
+ "group_by_dimensions": ["SERVICE", "REGION"],
398
+ "pre_deletion_baseline": {"granularity_monthly": "MONTHLY", "months_before_deletion": 3},
399
+ "pre_deletion_detailed": {"granularity_daily": "DAILY", "days_before_deletion": 10},
400
+ "post_deletion_validation": {"granularity_daily": "DAILY", "days_after_deletion": 30},
401
+ },
402
+ "attribution_rules": {
403
+ "vpc_specific_services": {
404
+ "confidence_level": "HIGH (95%)",
405
+ "attribution_percentage": 100,
406
+ "service_patterns": ["Amazon Virtual Private Cloud"],
407
+ },
408
+ "vpc_related_services": {
409
+ "confidence_level": "MEDIUM (85%)",
410
+ "attribution_percentage": 70,
411
+ "service_patterns": ["Amazon Elastic Compute Cloud - Compute"],
412
+ },
413
+ "other_services": {
414
+ "confidence_level": "LOW (<85%)",
415
+ "attribution_percentage": 30,
416
+ "service_patterns": ["*"],
417
+ },
418
+ },
419
+ "output_config": {
420
+ "csv_output_file": "test_output.csv",
421
+ "csv_columns": ["VPC_ID", "Account_ID", "Deletion_Date", "Monthly_Savings_Realized"],
422
+ "json_results_file": "test_results.json",
423
+ "execution_summary_file": "test_summary.md",
424
+ },
425
+ }
426
+
427
+ with open(config_path) as f:
428
+ return yaml.safe_load(f)
429
+
430
+
431
+ @pytest.fixture
432
+ def cleanup_sample_vpc_deletion():
433
+ """Sample VPC deletion for testing"""
434
+ return {
435
+ "vpc_id": "vpc-test123456789abcd",
436
+ "account_id": "123456789012",
437
+ "region": "us-east-1",
438
+ "deletion_date": "2025-09-10",
439
+ "deletion_principal": "test.user@example.com",
440
+ "pre_deletion_baseline_months": 3,
441
+ }
442
+
443
+
444
+ @pytest.fixture
445
+ def cleanup_sample_vpc_deletions():
446
+ """Sample list of VPC deletions for multi-VPC testing"""
447
+ return [
448
+ {
449
+ "vpc_id": "vpc-test111111111aaaa",
450
+ "account_id": "111111111111",
451
+ "region": "us-east-1",
452
+ "deletion_date": "2025-09-10",
453
+ "deletion_principal": "user1@example.com",
454
+ "pre_deletion_baseline_months": 3,
455
+ },
456
+ {
457
+ "vpc_id": "vpc-test222222222bbbb",
458
+ "account_id": "222222222222",
459
+ "region": "us-west-2",
460
+ "deletion_date": "2025-08-15",
461
+ "deletion_principal": "user2@example.com",
462
+ "pre_deletion_baseline_months": 3,
463
+ },
464
+ {
465
+ "vpc_id": "vpc-test333333333cccc",
466
+ "account_id": "111111111111",
467
+ "region": "eu-west-1",
468
+ "deletion_date": "2025-09-01",
469
+ "deletion_principal": "user3@example.com",
470
+ "pre_deletion_baseline_months": 3,
471
+ },
472
+ ]
473
+
474
+
475
+ @pytest.fixture
476
+ def cleanup_mock_cost_explorer():
477
+ """Mock boto3 Cost Explorer client for cleanup testing"""
478
+ mock_ce_client = MagicMock()
479
+
480
+ def get_cost_side_effect(*args, **kwargs):
481
+ # Return different responses based on time period
482
+ time_period = kwargs.get("TimePeriod", {})
483
+ start_date = time_period.get("Start", "")
484
+
485
+ if start_date.startswith("2025-09"):
486
+ # Post-deletion period
487
+ return {
488
+ "ResultsByTime": [
489
+ {
490
+ "TimePeriod": time_period,
491
+ "Groups": [
492
+ {
493
+ "Keys": ["Amazon Elastic Compute Cloud - Compute", "ap-southeast-2"],
494
+ "Metrics": {"UnblendedCost": {"Amount": "15.00", "Unit": "USD"}},
495
+ }
496
+ ],
497
+ }
498
+ ]
499
+ }
500
+ else:
501
+ # Pre-deletion period
502
+ return {
503
+ "ResultsByTime": [
504
+ {
505
+ "TimePeriod": time_period,
506
+ "Groups": [
507
+ {
508
+ "Keys": ["Amazon Virtual Private Cloud", "ap-southeast-2"],
509
+ "Metrics": {"UnblendedCost": {"Amount": "100.00", "Unit": "USD"}},
510
+ },
511
+ {
512
+ "Keys": ["Amazon Elastic Compute Cloud - Compute", "ap-southeast-2"],
513
+ "Metrics": {"UnblendedCost": {"Amount": "500.00", "Unit": "USD"}},
514
+ },
515
+ ],
516
+ }
517
+ ]
518
+ }
519
+
520
+ mock_ce_client.get_cost_and_usage.side_effect = get_cost_side_effect
521
+ return mock_ce_client
522
+
523
+
524
+ @pytest.fixture
525
+ def cleanup_temp_config_file():
526
+ """Create temporary cleanup config file for testing"""
527
+ import yaml
528
+
529
+ minimal_config = {
530
+ "campaign_metadata": {
531
+ "campaign_id": "TEST-01",
532
+ "campaign_name": "Test Campaign",
533
+ "execution_date": "2025-10-02",
534
+ "aws_billing_profile": "test-profile",
535
+ "description": "Test campaign description",
536
+ },
537
+ "deleted_vpcs": [
538
+ {
539
+ "vpc_id": "vpc-test123456789abcd",
540
+ "account_id": "123456789012",
541
+ "region": "us-east-1",
542
+ "deletion_date": "2025-09-10",
543
+ "deletion_principal": "test.user@example.com",
544
+ "pre_deletion_baseline_months": 3,
545
+ }
546
+ ],
547
+ "cost_explorer_config": {
548
+ "metrics": ["UnblendedCost"],
549
+ "group_by_dimensions": ["SERVICE", "REGION"],
550
+ "pre_deletion_baseline": {"granularity_monthly": "MONTHLY", "months_before_deletion": 3},
551
+ "pre_deletion_detailed": {"granularity_daily": "DAILY", "days_before_deletion": 10},
552
+ "post_deletion_validation": {"granularity_daily": "DAILY", "days_after_deletion": 30},
553
+ },
554
+ "attribution_rules": {
555
+ "vpc_specific_services": {
556
+ "confidence_level": "HIGH (95%)",
557
+ "attribution_percentage": 100,
558
+ "service_patterns": ["Amazon Virtual Private Cloud"],
559
+ },
560
+ "vpc_related_services": {
561
+ "confidence_level": "MEDIUM (85%)",
562
+ "attribution_percentage": 70,
563
+ "service_patterns": ["Amazon Elastic Compute Cloud - Compute"],
564
+ },
565
+ "other_services": {
566
+ "confidence_level": "LOW (<85%)",
567
+ "attribution_percentage": 30,
568
+ "service_patterns": ["*"],
569
+ },
570
+ },
571
+ "output_config": {
572
+ "csv_output_file": "test_output.csv",
573
+ "csv_columns": ["VPC_ID", "Account_ID", "Deletion_Date", "Monthly_Savings_Realized"],
574
+ "json_results_file": "test_results.json",
575
+ "execution_summary_file": "test_summary.md",
576
+ },
577
+ }
578
+
579
+ with tempfile.NamedTemporaryFile(mode="w", suffix=".yaml", delete=False) as f:
580
+ yaml.dump(minimal_config, f)
581
+ temp_path = f.name
582
+
583
+ yield temp_path
584
+
585
+ # Cleanup
586
+ Path(temp_path).unlink(missing_ok=True)
587
+
588
+
589
+ @pytest.fixture
590
+ def cleanup_multi_lz_config():
591
+ """Config for multi-Landing Zone testing with different accounts and regions"""
592
+ return {
593
+ "campaign_metadata": {
594
+ "campaign_id": "MULTI-LZ-01",
595
+ "campaign_name": "Multi-LZ Test Campaign",
596
+ "execution_date": "2025-10-02",
597
+ "aws_billing_profile": "multi-lz-profile",
598
+ "description": "Testing multiple Landing Zones",
599
+ },
600
+ "deleted_vpcs": [
601
+ {
602
+ "vpc_id": "vpc-lz1111111111aaaa",
603
+ "account_id": "111111111111",
604
+ "region": "us-east-1",
605
+ "deletion_date": "2025-09-10",
606
+ "deletion_principal": "lz1.user@example.com",
607
+ "pre_deletion_baseline_months": 3,
608
+ },
609
+ {
610
+ "vpc_id": "vpc-lz2222222222bbbb",
611
+ "account_id": "222222222222",
612
+ "region": "eu-west-1",
613
+ "deletion_date": "2025-08-20",
614
+ "deletion_principal": "lz2.user@example.com",
615
+ "pre_deletion_baseline_months": 3,
616
+ },
617
+ {
618
+ "vpc_id": "vpc-lz3333333333cccc",
619
+ "account_id": "333333333333",
620
+ "region": "ap-southeast-2",
621
+ "deletion_date": "2025-09-05",
622
+ "deletion_principal": "lz3.user@example.com",
623
+ "pre_deletion_baseline_months": 3,
624
+ },
625
+ ],
626
+ "cost_explorer_config": {
627
+ "metrics": ["UnblendedCost"],
628
+ "group_by_dimensions": ["SERVICE", "REGION"],
629
+ "pre_deletion_baseline": {"granularity_monthly": "MONTHLY", "months_before_deletion": 3},
630
+ "pre_deletion_detailed": {"granularity_daily": "DAILY", "days_before_deletion": 10},
631
+ "post_deletion_validation": {"granularity_daily": "DAILY", "days_after_deletion": 30},
632
+ },
633
+ "attribution_rules": {
634
+ "vpc_specific_services": {
635
+ "confidence_level": "HIGH (95%)",
636
+ "attribution_percentage": 100,
637
+ "service_patterns": ["Amazon Virtual Private Cloud", "AWS PrivateLink"],
638
+ },
639
+ "vpc_related_services": {
640
+ "confidence_level": "MEDIUM (85%)",
641
+ "attribution_percentage": 70,
642
+ "service_patterns": ["Amazon Elastic Compute Cloud - Compute", "Elastic Load Balancing"],
643
+ },
644
+ "other_services": {
645
+ "confidence_level": "LOW (<85%)",
646
+ "attribution_percentage": 30,
647
+ "service_patterns": ["*"],
648
+ },
649
+ },
650
+ "output_config": {
651
+ "csv_output_file": "multi_lz_output.csv",
652
+ "csv_columns": [
653
+ "VPC_ID",
654
+ "Account_ID",
655
+ "Deletion_Date",
656
+ "Pre_Deletion_Monthly_Avg",
657
+ "Post_Deletion_Monthly_Avg",
658
+ "Monthly_Savings_Realized",
659
+ "Annual_Savings_Realized",
660
+ "Data_Quality",
661
+ "Confidence_Level",
662
+ "Notes",
663
+ "Service_Analysis",
664
+ ],
665
+ "json_results_file": "multi_lz_results.json",
666
+ "execution_summary_file": "multi_lz_summary.md",
667
+ },
668
+ }