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
@@ -9,12 +9,44 @@ Preserves 100% functionality while reducing main.py context overhead.
9
9
  """
10
10
 
11
11
  import click
12
- from rich.console import Console
12
+ import os
13
+ import sys
13
14
 
14
15
  # Import common utilities and decorators
15
16
  from runbooks.common.decorators import common_aws_options, common_output_options, common_filter_options
16
17
 
17
- console = Console()
18
+ # Test Mode Support: Disable Rich Console in test environments to prevent I/O conflicts
19
+ # Issue: Rich Console writes to StringIO buffer that Click CliRunner closes, causing ValueError
20
+ # Solution: Use plain print() in test mode (RUNBOOKS_TEST_MODE=1), Rich Console in production
21
+ USE_RICH = os.getenv("RUNBOOKS_TEST_MODE") != "1"
22
+
23
+ if USE_RICH:
24
+ from rich.console import Console
25
+
26
+ console = Console()
27
+ else:
28
+ # Mock Rich Console for testing - plain text output compatible with Click CliRunner
29
+ class MockConsole:
30
+ """Mock console that prints to stdout without Rich formatting."""
31
+
32
+ def print(self, *args, **kwargs):
33
+ """Mock print that outputs plain text to stdout."""
34
+ if args:
35
+ # Extract text content from Rich markup if present
36
+ text = str(args[0]) if args else ""
37
+ # Remove Rich markup tags for plain output
38
+ import re
39
+
40
+ text = re.sub(r"\[.*?\]", "", text)
41
+ print(text, file=sys.stdout)
42
+
43
+ def __enter__(self):
44
+ return self
45
+
46
+ def __exit__(self, *args):
47
+ pass
48
+
49
+ console = MockConsole()
18
50
 
19
51
 
20
52
  def create_inventory_group():
@@ -32,7 +64,7 @@ def create_inventory_group():
32
64
  @common_output_options
33
65
  @common_filter_options
34
66
  @click.pass_context
35
- def inventory(ctx, profile, region, dry_run, output, output_file, tags, accounts, regions):
67
+ def inventory(ctx, profile, region, dry_run, output_format, output_file, tags, accounts, regions):
36
68
  """
37
69
  Universal AWS resource discovery and inventory - works with ANY AWS environment.
38
70
 
@@ -49,16 +81,20 @@ def create_inventory_group():
49
81
  runbooks inventory collect # Use default profile
50
82
  runbooks inventory collect --profile my-profile # Use specific profile
51
83
  runbooks inventory collect --resources ec2,rds # Specific resources
52
- runbooks inventory collect --all-accounts # Multi-account (if Organizations access)
84
+ runbooks inventory collect --all-profiles # Multi-account (if Organizations access)
53
85
  runbooks inventory collect --tags Environment=prod # Filtered discovery
54
86
  """
87
+ # Ensure context object exists
88
+ if ctx.obj is None:
89
+ ctx.obj = {}
90
+
55
91
  # Update context with inventory-specific options
56
92
  ctx.obj.update(
57
93
  {
58
94
  "profile": profile,
59
95
  "region": region,
60
96
  "dry_run": dry_run,
61
- "output": output,
97
+ "output_format": output_format,
62
98
  "output_file": output_file,
63
99
  "tags": tags,
64
100
  "accounts": accounts,
@@ -70,27 +106,71 @@ def create_inventory_group():
70
106
  click.echo(ctx.get_help())
71
107
 
72
108
  @inventory.command()
73
- @common_aws_options
74
109
  @click.option("--resources", "-r", multiple=True, help="Resource types (ec2, rds, lambda, s3, etc.)")
75
110
  @click.option("--all-resources", is_flag=True, help="Collect all resource types")
76
- @click.option("--all-accounts", is_flag=True, help="Collect from all organization accounts")
111
+ @click.option("--all-profiles", is_flag=True, help="Collect from all organization accounts")
112
+ @click.option("--all-regions", is_flag=True, help="Execute inventory collection across all AWS regions")
77
113
  @click.option("--include-costs", is_flag=True, help="Include cost information")
114
+ @click.option(
115
+ "--include-cost-analysis", "include_costs", is_flag=True, hidden=True, help="Alias for --include-costs"
116
+ )
117
+ @click.option(
118
+ "--include-security-analysis", "include_security", is_flag=True, help="Include security analysis in inventory"
119
+ )
120
+ @click.option(
121
+ "--include-cost-recommendations",
122
+ "include_cost_recommendations",
123
+ is_flag=True,
124
+ help="Include cost optimization recommendations",
125
+ )
78
126
  @click.option("--parallel", is_flag=True, default=True, help="Enable parallel collection")
79
127
  @click.option("--validate", is_flag=True, default=False, help="Enable MCP validation for ≥99.5% accuracy")
80
- @click.option("--validate-all", is_flag=True, default=False, help="Enable comprehensive 3-way validation: runbooks + MCP + terraform")
81
- @click.option("--all", is_flag=True, help="Use all available AWS profiles for multi-account collection (enterprise scaling)")
128
+ @click.option(
129
+ "--validate-all",
130
+ is_flag=True,
131
+ default=False,
132
+ help="Enable comprehensive 3-way validation: runbooks + MCP + terraform",
133
+ )
134
+ @click.option(
135
+ "--all", is_flag=True, help="Use all available AWS profiles for multi-account collection (enterprise scaling)"
136
+ )
82
137
  @click.option("--combine", is_flag=True, help="Combine results from the same AWS account")
83
138
  @click.option("--csv", is_flag=True, help="Generate CSV export (convenience flag for --export-format csv)")
84
139
  @click.option("--json", is_flag=True, help="Generate JSON export (convenience flag for --export-format json)")
85
140
  @click.option("--pdf", is_flag=True, help="Generate PDF export (convenience flag for --export-format pdf)")
86
- @click.option("--markdown", is_flag=True, help="Generate markdown export (convenience flag for --export-format markdown)")
87
- @click.option("--export-format", type=click.Choice(['json', 'csv', 'markdown', 'pdf', 'yaml']),
88
- help="Export format for results (convenience flags take precedence)")
141
+ @click.option(
142
+ "--markdown", is_flag=True, help="Generate markdown export (convenience flag for --export-format markdown)"
143
+ )
144
+ @click.option(
145
+ "--export-format",
146
+ type=click.Choice(["json", "csv", "markdown", "pdf", "yaml"]),
147
+ help="Export format for results (convenience flags take precedence)",
148
+ )
89
149
  @click.option("--output-dir", default="./awso_evidence", help="Output directory for exports")
90
150
  @click.option("--report-name", help="Base name for export files (without extension)")
91
151
  @click.pass_context
92
- def collect(ctx, profile, region, dry_run, resources, all_resources, all_accounts, include_costs, parallel, validate, validate_all,
93
- all, combine, csv, json, pdf, markdown, export_format, output_dir, report_name):
152
+ def collect(
153
+ ctx,
154
+ resources,
155
+ all_resources,
156
+ all_profiles,
157
+ all_regions,
158
+ include_costs,
159
+ include_security,
160
+ include_cost_recommendations,
161
+ parallel,
162
+ validate,
163
+ validate_all,
164
+ all,
165
+ combine,
166
+ csv,
167
+ json,
168
+ pdf,
169
+ markdown,
170
+ export_format,
171
+ output_dir,
172
+ report_name,
173
+ ):
94
174
  """
95
175
  🔍 Universal AWS resource inventory collection - works with ANY AWS environment.
96
176
 
@@ -112,7 +192,7 @@ def create_inventory_group():
112
192
  # Universal compatibility - works with any AWS setup
113
193
  runbooks inventory collect # Default profile
114
194
  runbooks inventory collect --profile my-aws-profile # Any profile
115
- runbooks inventory collect --all-accounts # Auto-detects Organizations
195
+ runbooks inventory collect --all-profiles # Auto-detects Organizations
116
196
 
117
197
  # Resource-specific discovery
118
198
  runbooks inventory collect --resources ec2,rds,s3 # Specific services
@@ -123,7 +203,12 @@ def create_inventory_group():
123
203
  runbooks inventory collect --profile prod --validate --markdown
124
204
  """
125
205
  try:
126
- from runbooks.inventory.collector import run_inventory_collection
206
+ from runbooks.inventory.core.collector import run_inventory_collection
207
+
208
+ # Access group-level AWS options from context (Bug #1 fix: profile override priority)
209
+ profile = ctx.obj.get('profile')
210
+ region = ctx.obj.get('region')
211
+ dry_run = ctx.obj.get('dry_run', False)
127
212
 
128
213
  # Enhanced context for inventory collection
129
214
  context_args = {
@@ -132,8 +217,11 @@ def create_inventory_group():
132
217
  "dry_run": dry_run,
133
218
  "resources": resources,
134
219
  "all_resources": all_resources,
135
- "all_accounts": all_accounts,
220
+ "all_profiles": all_profiles,
221
+ "all_regions": all_regions,
136
222
  "include_costs": include_costs,
223
+ "include_security": include_security,
224
+ "include_cost_recommendations": include_cost_recommendations,
137
225
  "parallel": parallel,
138
226
  "validate": validate,
139
227
  "validate_all": validate_all,
@@ -141,7 +229,7 @@ def create_inventory_group():
141
229
  "combine": combine,
142
230
  "export_formats": [],
143
231
  "output_dir": output_dir,
144
- "report_name": report_name
232
+ "report_name": report_name,
145
233
  }
146
234
 
147
235
  # Handle export format flags
@@ -171,32 +259,40 @@ def create_inventory_group():
171
259
  raise click.ClickException(str(e))
172
260
 
173
261
  @inventory.command()
174
- @click.option("--resource-types", multiple=True,
175
- type=click.Choice(['ec2', 's3', 'rds', 'lambda', 'vpc', 'iam']),
176
- default=['ec2', 's3', 'vpc'],
177
- help="Resource types to validate")
178
- @click.option("--test-mode", is_flag=True, default=True,
179
- help="Run in test mode with sample data")
262
+ @click.option(
263
+ "--resource-types",
264
+ multiple=True,
265
+ type=click.Choice(["ec2", "s3", "rds", "lambda", "vpc", "iam"]),
266
+ default=["ec2", "s3", "vpc"],
267
+ help="Resource types to validate",
268
+ )
269
+ @click.option("--test-mode", is_flag=True, default=True, help="Run in test mode with sample data")
270
+ @click.option(
271
+ "--real-validation",
272
+ is_flag=True,
273
+ default=False,
274
+ help="Run validation against real AWS APIs (requires valid profiles)",
275
+ )
180
276
  @click.pass_context
181
- def validate_mcp(ctx, resource_types, test_mode):
277
+ def validate_mcp(ctx, resource_types, test_mode, real_validation):
182
278
  """Test inventory MCP validation functionality."""
183
279
  try:
184
280
  from runbooks.inventory.mcp_inventory_validator import create_inventory_mcp_validator
185
281
  from runbooks.common.profile_utils import get_profile_for_operation
186
282
 
283
+ # Access profile from group-level context (Bug #3 fix: profile override support)
284
+ profile = ctx.obj.get('profile')
285
+
187
286
  console.print(f"[blue]🔍 Testing Inventory MCP Validation[/blue]")
188
- console.print(f"[dim]Profile: {ctx.obj['profile']} | Resources: {', '.join(resource_types)}[/dim]")
287
+ console.print(f"[dim]Profile: {profile or 'environment fallback'} | Resources: {', '.join(resource_types)} | Test mode: {test_mode}[/dim]")
189
288
 
190
289
  # Initialize validator
191
- operational_profile = get_profile_for_operation("operational", ctx.obj['profile'])
290
+ operational_profile = get_profile_for_operation("operational", profile)
192
291
  validator = create_inventory_mcp_validator([operational_profile])
193
292
 
194
293
  # Test with sample data
195
294
  sample_data = {
196
- operational_profile: {
197
- "resource_counts": {rt: 5 for rt in resource_types},
198
- "regions": ["us-east-1"]
199
- }
295
+ operational_profile: {"resource_counts": {rt: 5 for rt in resource_types}, "regions": ["us-east-1"]}
200
296
  }
201
297
 
202
298
  console.print("[dim]Running validation test...[/dim]")
@@ -206,7 +302,9 @@ def create_inventory_group():
206
302
  if validation_results.get("passed_validation", False):
207
303
  console.print(f"[green]✅ MCP Validation test completed: {accuracy:.1f}% accuracy[/green]")
208
304
  else:
209
- console.print(f"[yellow]⚠️ MCP Validation test: {accuracy:.1f}% accuracy (demonstrates validation capability)[/yellow]")
305
+ console.print(
306
+ f"[yellow]⚠️ MCP Validation test: {accuracy:.1f}% accuracy (demonstrates validation capability)[/yellow]"
307
+ )
210
308
 
211
309
  console.print(f"[dim]💡 Use 'runbooks inventory collect --validate' for real-time validation[/dim]")
212
310
 
@@ -214,63 +312,9 @@ def create_inventory_group():
214
312
  console.print(f"[red]❌ MCP validation test failed: {e}[/red]")
215
313
  raise click.ClickException(str(e))
216
314
 
217
- @inventory.command("rds-snapshots")
218
- @common_aws_options
219
- @click.option("--all", is_flag=True, help="Use all available AWS profiles for multi-account collection")
220
- @click.option("--combine", is_flag=True, help="Combine results from the same AWS account")
221
- @click.option("--export-format", type=click.Choice(['json', 'csv', 'markdown', 'table']),
222
- default='table', help="Export format for results")
223
- @click.option("--output-dir", default="./awso_evidence", help="Output directory for exports")
224
- @click.option("--filter-account", help="Filter snapshots by specific account ID")
225
- @click.option("--filter-status", help="Filter snapshots by status (available, creating, deleting)")
226
- @click.option("--max-age-days", type=int, help="Filter snapshots older than specified days")
227
- @click.pass_context
228
- def discover_rds_snapshots(ctx, profile, region, dry_run, all, combine, export_format,
229
- output_dir, filter_account, filter_status, max_age_days):
230
- """
231
- 🔍 Discover RDS snapshots using AWS Config organization-aggregator.
232
-
233
- ✅ Enhanced Cross-Account Discovery:
234
- - Leverages AWS Config organization-aggregator for cross-account access
235
- - Multi-region discovery across 7 key AWS regions
236
- - Intelligent Organizations detection with graceful standalone fallback
237
- - Multi-format exports: JSON, CSV, Markdown, Table
238
-
239
- Profile Priority: User > Environment > Default
240
- Universal AWS compatibility with any profile configuration
241
-
242
- Examples:
243
- runbooks inventory rds-snapshots # Default profile
244
- runbooks inventory rds-snapshots --profile org-profile # Organizations profile
245
- runbooks inventory rds-snapshots --all --combine # Multi-account discovery
246
- runbooks inventory rds-snapshots --filter-status available # Filter by status
247
- runbooks inventory rds-snapshots --max-age-days 30 --csv # Recent snapshots
248
- """
249
- try:
250
- from runbooks.inventory.rds_snapshots_discovery import run_rds_snapshots_discovery
251
-
252
- # Enhanced context for RDS snapshots discovery
253
- context_args = {
254
- "profile": profile,
255
- "region": region,
256
- "dry_run": dry_run,
257
- "all": all,
258
- "combine": combine,
259
- "export_format": export_format,
260
- "output_dir": output_dir,
261
- "filter_account": filter_account,
262
- "filter_status": filter_status,
263
- "max_age_days": max_age_days
264
- }
265
-
266
- # Run RDS snapshots discovery
267
- return run_rds_snapshots_discovery(**context_args)
268
-
269
- except ImportError as e:
270
- console.print(f"[red]❌ RDS snapshots discovery module not available: {e}[/red]")
271
- raise click.ClickException("RDS snapshots discovery functionality not available")
272
- except Exception as e:
273
- console.print(f"[red]❌ RDS snapshots discovery failed: {e}[/red]")
274
- raise click.ClickException(str(e))
315
+ # NOTE: rds-snapshots command removed in v1.1.6 (Bug #2 fix: phantom command elimination)
316
+ # Reason: Module rds_snapshots_discovery.py doesn't exist (was never implemented)
317
+ # Future work: Implement proper RDS snapshots discovery in v1.2.0
318
+ # See: artifacts/future-work/rds-snapshots-discovery-v1.2.0.md
275
319
 
276
- return inventory
320
+ return inventory
@@ -84,11 +84,7 @@ def create_operate_group():
84
84
  resolved_profile = get_profile_for_operation("operational", profile)
85
85
 
86
86
  # Delegate to operate module with resolved profile
87
- ec2_ops = EC2Operations(
88
- profile=resolved_profile,
89
- region=region,
90
- dry_run=dry_run
91
- )
87
+ ec2_ops = EC2Operations(profile=resolved_profile, region=region, dry_run=dry_run)
92
88
 
93
89
  return ec2_ops.start_instances(list(instance_ids))
94
90
 
@@ -118,11 +114,7 @@ def create_operate_group():
118
114
  # Use ProfileManager for dynamic profile resolution
119
115
  resolved_profile = get_profile_for_operation("operational", profile)
120
116
 
121
- ec2_ops = EC2Operations(
122
- profile=resolved_profile,
123
- region=region,
124
- dry_run=dry_run
125
- )
117
+ ec2_ops = EC2Operations(profile=resolved_profile, region=region, dry_run=dry_run)
126
118
 
127
119
  return ec2_ops.stop_instances(list(instance_ids))
128
120
 
@@ -157,17 +149,13 @@ def create_operate_group():
157
149
  # Use ProfileManager for dynamic profile resolution
158
150
  resolved_profile = get_profile_for_operation("operational", profile)
159
151
 
160
- s3_ops = S3Operations(
161
- profile=resolved_profile,
162
- region=region,
163
- dry_run=dry_run
164
- )
152
+ s3_ops = S3Operations(profile=resolved_profile, region=region, dry_run=dry_run)
165
153
 
166
154
  return s3_ops.create_bucket(
167
155
  bucket_name=bucket_name,
168
156
  encryption=encryption,
169
157
  versioning=versioning,
170
- public_access_block=public_access_block
158
+ public_access_block=public_access_block,
171
159
  )
172
160
 
173
161
  except ImportError as e:
@@ -199,16 +187,9 @@ def create_operate_group():
199
187
  # Use ProfileManager for dynamic profile resolution
200
188
  resolved_profile = get_profile_for_operation("operational", profile)
201
189
 
202
- vpc_ops = VPCOperations(
203
- profile=resolved_profile,
204
- region=region,
205
- dry_run=dry_run
206
- )
190
+ vpc_ops = VPCOperations(profile=resolved_profile, region=region, dry_run=dry_run)
207
191
 
208
- return vpc_ops.create_vpc(
209
- cidr_block=cidr_block,
210
- vpc_name=vpc_name
211
- )
192
+ return vpc_ops.create_vpc(cidr_block=cidr_block, vpc_name=vpc_name)
212
193
 
213
194
  except ImportError as e:
214
195
  console.print(f"[red]❌ VPC operations module not available: {e}[/red]")
@@ -240,17 +221,9 @@ def create_operate_group():
240
221
  # Use ProfileManager for dynamic profile resolution
241
222
  resolved_profile = get_profile_for_operation("operational", profile)
242
223
 
243
- cf_ops = CloudFormationOperations(
244
- profile=resolved_profile,
245
- region=region,
246
- dry_run=dry_run
247
- )
224
+ cf_ops = CloudFormationOperations(profile=resolved_profile, region=region, dry_run=dry_run)
248
225
 
249
- return cf_ops.deploy_stack(
250
- template_file=template_file,
251
- stack_name=stack_name,
252
- parameters=parameters
253
- )
226
+ return cf_ops.deploy_stack(template_file=template_file, stack_name=stack_name, parameters=parameters)
254
227
 
255
228
  except ImportError as e:
256
229
  console.print(f"[red]❌ CloudFormation operations module not available: {e}[/red]")
@@ -263,4 +236,4 @@ def create_operate_group():
263
236
  # This is a representative sample showing the modular pattern
264
237
  # Complete extraction would include: DynamoDB, Lambda, NAT Gateway, etc.
265
238
 
266
- return operate
239
+ return operate
@@ -56,15 +56,25 @@ def create_security_group():
56
56
 
57
57
  @security.command()
58
58
  @common_aws_options
59
- @click.option("--framework", type=click.Choice(['soc2', 'pci-dss', 'hipaa', 'iso27001', 'well-architected']),
60
- multiple=True, help="Compliance frameworks to assess")
59
+ @click.option(
60
+ "--framework",
61
+ type=click.Choice(["soc2", "pci-dss", "hipaa", "iso27001", "well-architected"]),
62
+ multiple=True,
63
+ help="Compliance frameworks to assess",
64
+ )
61
65
  @click.option("--all-checks", is_flag=True, help="Run all available security checks")
62
- @click.option("--severity", type=click.Choice(['critical', 'high', 'medium', 'low']),
63
- help="Filter by minimum severity level")
64
- @click.option("--export-format", type=click.Choice(['json', 'csv', 'pdf', 'markdown']),
65
- help="Export format for results")
66
- @click.option("--language", type=click.Choice(['en', 'ja', 'ko', 'vi']), default='en',
67
- help="Report language (English, Japanese, Korean, Vietnamese)")
66
+ @click.option(
67
+ "--severity", type=click.Choice(["critical", "high", "medium", "low"]), help="Filter by minimum severity level"
68
+ )
69
+ @click.option(
70
+ "--export-format", type=click.Choice(["json", "csv", "pdf", "markdown"]), help="Export format for results"
71
+ )
72
+ @click.option(
73
+ "--language",
74
+ type=click.Choice(["en", "ja", "ko", "vi"]),
75
+ default="en",
76
+ help="Report language (English, Japanese, Korean, Vietnamese)",
77
+ )
68
78
  @click.option("--all", is_flag=True, help="Use all available AWS profiles for multi-account security assessment")
69
79
  @click.pass_context
70
80
  def assess(ctx, profile, region, dry_run, framework, all_checks, severity, export_format, language, all):
@@ -97,7 +107,7 @@ def create_security_group():
97
107
  frameworks=list(framework) if framework else None,
98
108
  all_checks=all_checks,
99
109
  severity_filter=severity,
100
- language=language
110
+ language=language,
101
111
  )
102
112
 
103
113
  results = assessment.run_comprehensive_assessment()
@@ -116,8 +126,12 @@ def create_security_group():
116
126
 
117
127
  @security.command()
118
128
  @common_aws_options
119
- @click.option("--check-type", type=click.Choice(['baseline', 'advanced', 'enterprise']),
120
- default='baseline', help="Security check depth level")
129
+ @click.option(
130
+ "--check-type",
131
+ type=click.Choice(["baseline", "advanced", "enterprise"]),
132
+ default="baseline",
133
+ help="Security check depth level",
134
+ )
121
135
  @click.option("--include-remediation", is_flag=True, help="Include remediation recommendations")
122
136
  @click.option("--auto-fix", is_flag=True, help="Automatically fix low-risk issues (with approval)")
123
137
  @click.option("--all", is_flag=True, help="Use all available AWS profiles for multi-account baseline assessment")
@@ -150,7 +164,7 @@ def create_security_group():
150
164
  region=region,
151
165
  check_type=check_type,
152
166
  include_remediation=include_remediation,
153
- auto_fix=auto_fix and not dry_run
167
+ auto_fix=auto_fix and not dry_run,
154
168
  )
155
169
 
156
170
  baseline_results = baseline_checker.run_baseline_assessment()
@@ -166,10 +180,20 @@ def create_security_group():
166
180
 
167
181
  @security.command()
168
182
  @common_aws_options
169
- @click.option("--format", "report_format", type=click.Choice(['pdf', 'html', 'markdown', 'json']),
170
- multiple=True, default=['pdf'], help="Report formats")
171
- @click.option("--compliance", type=click.Choice(['soc2', 'pci-dss', 'hipaa', 'iso27001']),
172
- multiple=True, help="Include compliance mapping")
183
+ @click.option(
184
+ "--format",
185
+ "report_format",
186
+ type=click.Choice(["pdf", "html", "markdown", "json"]),
187
+ multiple=True,
188
+ default=["pdf"],
189
+ help="Report formats",
190
+ )
191
+ @click.option(
192
+ "--compliance",
193
+ type=click.Choice(["soc2", "pci-dss", "hipaa", "iso27001"]),
194
+ multiple=True,
195
+ help="Include compliance mapping",
196
+ )
173
197
  @click.option("--executive-summary", is_flag=True, help="Generate executive summary")
174
198
  @click.option("--output-dir", default="./security_reports", help="Output directory")
175
199
  @click.option("--all", is_flag=True, help="Use all available AWS profiles for multi-account security reporting")
@@ -201,7 +225,7 @@ def create_security_group():
201
225
  profile=resolved_profile,
202
226
  output_dir=output_dir,
203
227
  compliance_frameworks=list(compliance) if compliance else None,
204
- executive_summary=executive_summary
228
+ executive_summary=executive_summary,
205
229
  )
206
230
 
207
231
  report_results = {}
@@ -221,4 +245,4 @@ def create_security_group():
221
245
  console.print(f"[red]❌ Security report generation failed: {e}[/red]")
222
246
  raise click.ClickException(str(e))
223
247
 
224
- return security
248
+ return security