runbooks 1.1.4__py3-none-any.whl → 1.1.5__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 (228) 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 +138 -35
  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 +11 -0
  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 +63 -74
  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 +201 -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/cloud_foundations_integration.py +144 -149
  113. runbooks/inventory/collectors/aws_comprehensive.py +1 -1
  114. runbooks/inventory/collectors/aws_networking.py +109 -99
  115. runbooks/inventory/collectors/base.py +4 -0
  116. runbooks/inventory/core/collector.py +495 -313
  117. runbooks/inventory/drift_detection_cli.py +69 -96
  118. runbooks/inventory/inventory_mcp_cli.py +48 -46
  119. runbooks/inventory/list_rds_snapshots_aggregator.py +192 -208
  120. runbooks/inventory/mcp_inventory_validator.py +549 -465
  121. runbooks/inventory/mcp_vpc_validator.py +359 -442
  122. runbooks/inventory/organizations_discovery.py +55 -51
  123. runbooks/inventory/rich_inventory_display.py +33 -32
  124. runbooks/inventory/unified_validation_engine.py +278 -251
  125. runbooks/inventory/vpc_analyzer.py +732 -695
  126. runbooks/inventory/vpc_architecture_validator.py +293 -348
  127. runbooks/inventory/vpc_dependency_analyzer.py +382 -378
  128. runbooks/inventory/vpc_flow_analyzer.py +1 -1
  129. runbooks/main.py +49 -34
  130. runbooks/main_final.py +91 -60
  131. runbooks/main_minimal.py +22 -10
  132. runbooks/main_optimized.py +131 -100
  133. runbooks/main_ultra_minimal.py +7 -2
  134. runbooks/mcp/__init__.py +36 -0
  135. runbooks/mcp/integration.py +679 -0
  136. runbooks/monitoring/performance_monitor.py +9 -4
  137. runbooks/operate/dynamodb_operations.py +3 -1
  138. runbooks/operate/ec2_operations.py +145 -137
  139. runbooks/operate/iam_operations.py +146 -152
  140. runbooks/operate/networking_cost_heatmap.py +29 -8
  141. runbooks/operate/rds_operations.py +223 -254
  142. runbooks/operate/s3_operations.py +107 -118
  143. runbooks/operate/vpc_operations.py +646 -616
  144. runbooks/remediation/base.py +1 -1
  145. runbooks/remediation/commons.py +10 -7
  146. runbooks/remediation/commvault_ec2_analysis.py +70 -66
  147. runbooks/remediation/ec2_unattached_ebs_volumes.py +1 -0
  148. runbooks/remediation/multi_account.py +24 -21
  149. runbooks/remediation/rds_snapshot_list.py +86 -60
  150. runbooks/remediation/remediation_cli.py +92 -146
  151. runbooks/remediation/universal_account_discovery.py +83 -79
  152. runbooks/remediation/workspaces_list.py +46 -41
  153. runbooks/security/__init__.py +19 -0
  154. runbooks/security/assessment_runner.py +1150 -0
  155. runbooks/security/baseline_checker.py +812 -0
  156. runbooks/security/cloudops_automation_security_validator.py +509 -535
  157. runbooks/security/compliance_automation_engine.py +17 -17
  158. runbooks/security/config/__init__.py +2 -2
  159. runbooks/security/config/compliance_config.py +50 -50
  160. runbooks/security/config_template_generator.py +63 -76
  161. runbooks/security/enterprise_security_framework.py +1 -1
  162. runbooks/security/executive_security_dashboard.py +519 -508
  163. runbooks/security/multi_account_security_controls.py +959 -1210
  164. runbooks/security/real_time_security_monitor.py +422 -444
  165. runbooks/security/security_baseline_tester.py +1 -1
  166. runbooks/security/security_cli.py +143 -112
  167. runbooks/security/test_2way_validation.py +439 -0
  168. runbooks/security/two_way_validation_framework.py +852 -0
  169. runbooks/sre/production_monitoring_framework.py +167 -177
  170. runbooks/tdd/__init__.py +15 -0
  171. runbooks/tdd/cli.py +1071 -0
  172. runbooks/utils/__init__.py +14 -17
  173. runbooks/utils/logger.py +7 -2
  174. runbooks/utils/version_validator.py +50 -47
  175. runbooks/validation/__init__.py +6 -6
  176. runbooks/validation/cli.py +9 -3
  177. runbooks/validation/comprehensive_2way_validator.py +745 -704
  178. runbooks/validation/mcp_validator.py +906 -228
  179. runbooks/validation/terraform_citations_validator.py +104 -115
  180. runbooks/validation/terraform_drift_detector.py +447 -451
  181. runbooks/vpc/README.md +617 -0
  182. runbooks/vpc/__init__.py +8 -1
  183. runbooks/vpc/analyzer.py +577 -0
  184. runbooks/vpc/cleanup_wrapper.py +476 -413
  185. runbooks/vpc/cli_cloudtrail_commands.py +339 -0
  186. runbooks/vpc/cli_mcp_validation_commands.py +480 -0
  187. runbooks/vpc/cloudtrail_audit_integration.py +717 -0
  188. runbooks/vpc/config.py +92 -97
  189. runbooks/vpc/cost_engine.py +411 -148
  190. runbooks/vpc/cost_explorer_integration.py +553 -0
  191. runbooks/vpc/cross_account_session.py +101 -106
  192. runbooks/vpc/enhanced_mcp_validation.py +917 -0
  193. runbooks/vpc/eni_gate_validator.py +961 -0
  194. runbooks/vpc/heatmap_engine.py +185 -160
  195. runbooks/vpc/mcp_no_eni_validator.py +680 -639
  196. runbooks/vpc/nat_gateway_optimizer.py +358 -0
  197. runbooks/vpc/networking_wrapper.py +15 -8
  198. runbooks/vpc/pdca_remediation_planner.py +528 -0
  199. runbooks/vpc/performance_optimized_analyzer.py +219 -231
  200. runbooks/vpc/runbooks_adapter.py +1167 -241
  201. runbooks/vpc/tdd_red_phase_stubs.py +601 -0
  202. runbooks/vpc/test_data_loader.py +358 -0
  203. runbooks/vpc/tests/conftest.py +314 -4
  204. runbooks/vpc/tests/test_cleanup_framework.py +1022 -0
  205. runbooks/vpc/tests/test_cost_engine.py +0 -2
  206. runbooks/vpc/topology_generator.py +326 -0
  207. runbooks/vpc/unified_scenarios.py +1297 -1124
  208. runbooks/vpc/vpc_cleanup_integration.py +1943 -1115
  209. runbooks-1.1.5.dist-info/METADATA +328 -0
  210. {runbooks-1.1.4.dist-info → runbooks-1.1.5.dist-info}/RECORD +214 -193
  211. runbooks/finops/README.md +0 -414
  212. runbooks/finops/accuracy_cross_validator.py +0 -647
  213. runbooks/finops/business_cases.py +0 -950
  214. runbooks/finops/dashboard_router.py +0 -922
  215. runbooks/finops/ebs_optimizer.py +0 -973
  216. runbooks/finops/embedded_mcp_validator.py +0 -1629
  217. runbooks/finops/enhanced_dashboard_runner.py +0 -527
  218. runbooks/finops/finops_dashboard.py +0 -584
  219. runbooks/finops/finops_scenarios.py +0 -1218
  220. runbooks/finops/legacy_migration.py +0 -730
  221. runbooks/finops/multi_dashboard.py +0 -1519
  222. runbooks/finops/single_dashboard.py +0 -1113
  223. runbooks/finops/unlimited_scenarios.py +0 -393
  224. runbooks-1.1.4.dist-info/METADATA +0 -800
  225. {runbooks-1.1.4.dist-info → runbooks-1.1.5.dist-info}/WHEEL +0 -0
  226. {runbooks-1.1.4.dist-info → runbooks-1.1.5.dist-info}/entry_points.txt +0 -0
  227. {runbooks-1.1.4.dist-info → runbooks-1.1.5.dist-info}/licenses/LICENSE +0 -0
  228. {runbooks-1.1.4.dist-info → runbooks-1.1.5.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,
@@ -73,24 +109,72 @@ def create_inventory_group():
73
109
  @common_aws_options
74
110
  @click.option("--resources", "-r", multiple=True, help="Resource types (ec2, rds, lambda, s3, etc.)")
75
111
  @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")
112
+ @click.option("--all-profiles", is_flag=True, help="Collect from all organization accounts")
113
+ @click.option("--all-regions", is_flag=True, help="Execute inventory collection across all AWS regions")
77
114
  @click.option("--include-costs", is_flag=True, help="Include cost information")
115
+ @click.option(
116
+ "--include-cost-analysis", "include_costs", is_flag=True, hidden=True, help="Alias for --include-costs"
117
+ )
118
+ @click.option(
119
+ "--include-security-analysis", "include_security", is_flag=True, help="Include security analysis in inventory"
120
+ )
121
+ @click.option(
122
+ "--include-cost-recommendations",
123
+ "include_cost_recommendations",
124
+ is_flag=True,
125
+ help="Include cost optimization recommendations",
126
+ )
78
127
  @click.option("--parallel", is_flag=True, default=True, help="Enable parallel collection")
79
128
  @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)")
129
+ @click.option(
130
+ "--validate-all",
131
+ is_flag=True,
132
+ default=False,
133
+ help="Enable comprehensive 3-way validation: runbooks + MCP + terraform",
134
+ )
135
+ @click.option(
136
+ "--all", is_flag=True, help="Use all available AWS profiles for multi-account collection (enterprise scaling)"
137
+ )
82
138
  @click.option("--combine", is_flag=True, help="Combine results from the same AWS account")
83
139
  @click.option("--csv", is_flag=True, help="Generate CSV export (convenience flag for --export-format csv)")
84
140
  @click.option("--json", is_flag=True, help="Generate JSON export (convenience flag for --export-format json)")
85
141
  @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)")
142
+ @click.option(
143
+ "--markdown", is_flag=True, help="Generate markdown export (convenience flag for --export-format markdown)"
144
+ )
145
+ @click.option(
146
+ "--export-format",
147
+ type=click.Choice(["json", "csv", "markdown", "pdf", "yaml"]),
148
+ help="Export format for results (convenience flags take precedence)",
149
+ )
89
150
  @click.option("--output-dir", default="./awso_evidence", help="Output directory for exports")
90
151
  @click.option("--report-name", help="Base name for export files (without extension)")
91
152
  @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):
153
+ def collect(
154
+ ctx,
155
+ profile,
156
+ region,
157
+ dry_run,
158
+ resources,
159
+ all_resources,
160
+ all_profiles,
161
+ all_regions,
162
+ include_costs,
163
+ include_security,
164
+ include_cost_recommendations,
165
+ parallel,
166
+ validate,
167
+ validate_all,
168
+ all,
169
+ combine,
170
+ csv,
171
+ json,
172
+ pdf,
173
+ markdown,
174
+ export_format,
175
+ output_dir,
176
+ report_name,
177
+ ):
94
178
  """
95
179
  🔍 Universal AWS resource inventory collection - works with ANY AWS environment.
96
180
 
@@ -112,7 +196,7 @@ def create_inventory_group():
112
196
  # Universal compatibility - works with any AWS setup
113
197
  runbooks inventory collect # Default profile
114
198
  runbooks inventory collect --profile my-aws-profile # Any profile
115
- runbooks inventory collect --all-accounts # Auto-detects Organizations
199
+ runbooks inventory collect --all-profiles # Auto-detects Organizations
116
200
 
117
201
  # Resource-specific discovery
118
202
  runbooks inventory collect --resources ec2,rds,s3 # Specific services
@@ -123,7 +207,7 @@ def create_inventory_group():
123
207
  runbooks inventory collect --profile prod --validate --markdown
124
208
  """
125
209
  try:
126
- from runbooks.inventory.collector import run_inventory_collection
210
+ from runbooks.inventory.core.collector import run_inventory_collection
127
211
 
128
212
  # Enhanced context for inventory collection
129
213
  context_args = {
@@ -132,8 +216,11 @@ def create_inventory_group():
132
216
  "dry_run": dry_run,
133
217
  "resources": resources,
134
218
  "all_resources": all_resources,
135
- "all_accounts": all_accounts,
219
+ "all_profiles": all_profiles,
220
+ "all_regions": all_regions,
136
221
  "include_costs": include_costs,
222
+ "include_security": include_security,
223
+ "include_cost_recommendations": include_cost_recommendations,
137
224
  "parallel": parallel,
138
225
  "validate": validate,
139
226
  "validate_all": validate_all,
@@ -141,7 +228,7 @@ def create_inventory_group():
141
228
  "combine": combine,
142
229
  "export_formats": [],
143
230
  "output_dir": output_dir,
144
- "report_name": report_name
231
+ "report_name": report_name,
145
232
  }
146
233
 
147
234
  # Handle export format flags
@@ -171,12 +258,14 @@ def create_inventory_group():
171
258
  raise click.ClickException(str(e))
172
259
 
173
260
  @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")
261
+ @click.option(
262
+ "--resource-types",
263
+ multiple=True,
264
+ type=click.Choice(["ec2", "s3", "rds", "lambda", "vpc", "iam"]),
265
+ default=["ec2", "s3", "vpc"],
266
+ help="Resource types to validate",
267
+ )
268
+ @click.option("--test-mode", is_flag=True, default=True, help="Run in test mode with sample data")
180
269
  @click.pass_context
181
270
  def validate_mcp(ctx, resource_types, test_mode):
182
271
  """Test inventory MCP validation functionality."""
@@ -188,15 +277,12 @@ def create_inventory_group():
188
277
  console.print(f"[dim]Profile: {ctx.obj['profile']} | Resources: {', '.join(resource_types)}[/dim]")
189
278
 
190
279
  # Initialize validator
191
- operational_profile = get_profile_for_operation("operational", ctx.obj['profile'])
280
+ operational_profile = get_profile_for_operation("operational", ctx.obj["profile"])
192
281
  validator = create_inventory_mcp_validator([operational_profile])
193
282
 
194
283
  # Test with sample data
195
284
  sample_data = {
196
- operational_profile: {
197
- "resource_counts": {rt: 5 for rt in resource_types},
198
- "regions": ["us-east-1"]
199
- }
285
+ operational_profile: {"resource_counts": {rt: 5 for rt in resource_types}, "regions": ["us-east-1"]}
200
286
  }
201
287
 
202
288
  console.print("[dim]Running validation test...[/dim]")
@@ -206,7 +292,9 @@ def create_inventory_group():
206
292
  if validation_results.get("passed_validation", False):
207
293
  console.print(f"[green]✅ MCP Validation test completed: {accuracy:.1f}% accuracy[/green]")
208
294
  else:
209
- console.print(f"[yellow]⚠️ MCP Validation test: {accuracy:.1f}% accuracy (demonstrates validation capability)[/yellow]")
295
+ console.print(
296
+ f"[yellow]⚠️ MCP Validation test: {accuracy:.1f}% accuracy (demonstrates validation capability)[/yellow]"
297
+ )
210
298
 
211
299
  console.print(f"[dim]💡 Use 'runbooks inventory collect --validate' for real-time validation[/dim]")
212
300
 
@@ -218,15 +306,30 @@ def create_inventory_group():
218
306
  @common_aws_options
219
307
  @click.option("--all", is_flag=True, help="Use all available AWS profiles for multi-account collection")
220
308
  @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")
309
+ @click.option(
310
+ "--export-format",
311
+ type=click.Choice(["json", "csv", "markdown", "table"]),
312
+ default="table",
313
+ help="Export format for results",
314
+ )
223
315
  @click.option("--output-dir", default="./awso_evidence", help="Output directory for exports")
224
316
  @click.option("--filter-account", help="Filter snapshots by specific account ID")
225
317
  @click.option("--filter-status", help="Filter snapshots by status (available, creating, deleting)")
226
318
  @click.option("--max-age-days", type=int, help="Filter snapshots older than specified days")
227
319
  @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):
320
+ def discover_rds_snapshots(
321
+ ctx,
322
+ profile,
323
+ region,
324
+ dry_run,
325
+ all,
326
+ combine,
327
+ export_format,
328
+ output_dir,
329
+ filter_account,
330
+ filter_status,
331
+ max_age_days,
332
+ ):
230
333
  """
231
334
  🔍 Discover RDS snapshots using AWS Config organization-aggregator.
232
335
 
@@ -260,7 +363,7 @@ def create_inventory_group():
260
363
  "output_dir": output_dir,
261
364
  "filter_account": filter_account,
262
365
  "filter_status": filter_status,
263
- "max_age_days": max_age_days
366
+ "max_age_days": max_age_days,
264
367
  }
265
368
 
266
369
  # Run RDS snapshots discovery
@@ -273,4 +376,4 @@ def create_inventory_group():
273
376
  console.print(f"[red]❌ RDS snapshots discovery failed: {e}[/red]")
274
377
  raise click.ClickException(str(e))
275
378
 
276
- return inventory
379
+ 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