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
@@ -38,21 +38,13 @@ from .universal_account_discovery import UniversalAccountDiscovery
38
38
 
39
39
 
40
40
  @click.group()
41
- @click.option(
42
- "--profile",
43
- default=None,
44
- help="AWS profile to use (overrides environment variables)"
45
- )
46
- @click.option(
47
- "--output-dir",
48
- default="./artifacts/remediation",
49
- help="Output directory for remediation reports"
50
- )
41
+ @click.option("--profile", default=None, help="AWS profile to use (overrides environment variables)")
42
+ @click.option("--output-dir", default="./artifacts/remediation", help="Output directory for remediation reports")
51
43
  @click.pass_context
52
44
  def remediation(ctx, profile: Optional[str], output_dir: str):
53
45
  """
54
46
  Enterprise Security Remediation with Dynamic Account Discovery.
55
-
47
+
56
48
  Supports configuration via:
57
49
  - Environment variables (REMEDIATION_TARGET_ACCOUNTS)
58
50
  - Configuration files (REMEDIATION_ACCOUNT_CONFIG)
@@ -62,7 +54,7 @@ def remediation(ctx, profile: Optional[str], output_dir: str):
62
54
  ctx.ensure_object(dict)
63
55
  ctx.obj["profile"] = profile
64
56
  ctx.obj["output_dir"] = output_dir
65
-
57
+
66
58
  # Validate profile if specified
67
59
  if profile:
68
60
  resolved_profile = get_profile_for_operation("management", profile)
@@ -75,55 +67,28 @@ def remediation(ctx, profile: Optional[str], output_dir: str):
75
67
  @click.option(
76
68
  "--operations",
77
69
  multiple=True,
78
- type=click.Choice([
79
- "block_public_access",
80
- "enforce_ssl",
81
- "enable_encryption"
82
- ]),
70
+ type=click.Choice(["block_public_access", "enforce_ssl", "enable_encryption"]),
83
71
  default=["block_public_access"],
84
- help="S3 security operations to execute"
85
- )
86
- @click.option(
87
- "--accounts",
88
- help="Comma-separated account IDs (overrides discovery)"
89
- )
90
- @click.option(
91
- "--all",
92
- "all_accounts",
93
- is_flag=True,
94
- help="Execute on all discovered accounts via Organizations API"
95
- )
96
- @click.option(
97
- "--dry-run",
98
- is_flag=True,
99
- default=True,
100
- help="Perform dry run without making changes (default: true)"
101
- )
102
- @click.option(
103
- "--parallel",
104
- is_flag=True,
105
- default=True,
106
- help="Execute operations in parallel (default: true)"
107
- )
108
- @click.option(
109
- "--max-workers",
110
- type=int,
111
- default=5,
112
- help="Maximum parallel workers"
72
+ help="S3 security operations to execute",
113
73
  )
74
+ @click.option("--accounts", help="Comma-separated account IDs (overrides discovery)")
75
+ @click.option("--all", "all_accounts", is_flag=True, help="Execute on all discovered accounts via Organizations API")
76
+ @click.option("--dry-run", is_flag=True, default=True, help="Perform dry run without making changes (default: true)")
77
+ @click.option("--parallel", is_flag=True, default=True, help="Execute operations in parallel (default: true)")
78
+ @click.option("--max-workers", type=int, default=5, help="Maximum parallel workers")
114
79
  @click.pass_context
115
80
  def s3_security(
116
- ctx,
117
- operations: List[str],
118
- accounts: Optional[str],
119
- all_accounts: bool,
120
- dry_run: bool,
121
- parallel: bool,
122
- max_workers: int
81
+ ctx,
82
+ operations: List[str],
83
+ accounts: Optional[str],
84
+ all_accounts: bool,
85
+ dry_run: bool,
86
+ parallel: bool,
87
+ max_workers: int,
123
88
  ):
124
89
  """
125
90
  Execute S3 security remediation across multiple accounts.
126
-
91
+
127
92
  Environment Variables Supported:
128
93
  - REMEDIATION_TARGET_ACCOUNTS: Comma-separated account IDs
129
94
  - REMEDIATION_ACCOUNT_CONFIG: Path to accounts configuration file
@@ -131,7 +96,7 @@ def s3_security(
131
96
  """
132
97
  profile = ctx.obj["profile"]
133
98
  output_dir = ctx.obj["output_dir"]
134
-
99
+
135
100
  try:
136
101
  # Display operation header
137
102
  operation_status = "DRY RUN" if dry_run else "LIVE EXECUTION"
@@ -145,7 +110,7 @@ def s3_security(
145
110
  border_style="cyan" if dry_run else "red",
146
111
  )
147
112
  )
148
-
113
+
149
114
  # Safety warning for live operations
150
115
  if not dry_run:
151
116
  console.print(
@@ -154,32 +119,32 @@ def s3_security(
154
119
  "This will make actual changes to AWS resources.\n"
155
120
  "Ensure you have proper permissions and backups.",
156
121
  border_style="red",
157
- title="Security Warning"
122
+ title="Security Warning",
158
123
  )
159
124
  )
160
-
125
+
161
126
  if not click.confirm("Continue with live execution?"):
162
127
  print_warning("Operation cancelled by user")
163
128
  return
164
-
129
+
165
130
  # Determine target accounts
166
131
  target_accounts = []
167
-
132
+
168
133
  if accounts:
169
134
  # Use specified accounts
170
135
  account_ids = [acc.strip() for acc in accounts.split(",")]
171
136
  target_accounts = [
172
- type('AWSAccount', (), {'account_id': acc_id, 'environment': f'specified-{i}'})()
137
+ type("AWSAccount", (), {"account_id": acc_id, "environment": f"specified-{i}"})()
173
138
  for i, acc_id in enumerate(account_ids)
174
139
  ]
175
140
  print_info(f"Using specified accounts: {len(target_accounts)} accounts")
176
-
141
+
177
142
  elif all_accounts:
178
143
  # Discover all accounts via Organizations API
179
144
  print_info("Discovering accounts via Organizations API...")
180
145
  target_accounts = discover_organization_accounts(profile=profile)
181
146
  print_info(f"Discovered {len(target_accounts)} accounts")
182
-
147
+
183
148
  else:
184
149
  # Use environment configuration
185
150
  env_accounts = get_accounts_from_environment()
@@ -191,80 +156,70 @@ def s3_security(
191
156
  print_info("No environment configuration found, discovering via Organizations API...")
192
157
  target_accounts = discover_organization_accounts(profile=profile)
193
158
  print_info(f"Discovered {len(target_accounts)} accounts")
194
-
159
+
195
160
  if not target_accounts:
196
161
  print_error("No target accounts found for remediation")
197
162
  raise click.Abort()
198
-
163
+
199
164
  # Initialize multi-account remediator
200
165
  sso_start_url = os.getenv("ACCESS_PORTAL_URL")
201
166
  if not sso_start_url:
202
167
  print_warning("ACCESS_PORTAL_URL not set - SSO functionality may be limited")
203
-
168
+
204
169
  remediator = MultiAccountRemediator(
205
- sso_start_url=sso_start_url,
206
- parallel_execution=parallel,
207
- max_workers=max_workers
170
+ sso_start_url=sso_start_url, parallel_execution=parallel, max_workers=max_workers
208
171
  )
209
-
172
+
210
173
  # Execute bulk S3 security operations
211
174
  print_info(f"Executing S3 security operations on {len(target_accounts)} accounts...")
212
-
213
- results = remediator.bulk_s3_security(
214
- accounts=target_accounts,
215
- operations=list(operations),
216
- dry_run=dry_run
217
- )
218
-
175
+
176
+ results = remediator.bulk_s3_security(accounts=target_accounts, operations=list(operations), dry_run=dry_run)
177
+
219
178
  # Display results summary
220
179
  successful_results = [r for r in results if r.success]
221
180
  failed_results = [r for r in results if r.failed]
222
-
181
+
223
182
  print_success(
224
- f"S3 security remediation completed: "
225
- f"{len(successful_results)} successful, {len(failed_results)} failed"
183
+ f"S3 security remediation completed: {len(successful_results)} successful, {len(failed_results)} failed"
226
184
  )
227
-
185
+
228
186
  if failed_results:
229
187
  print_warning(f"Failed operations: {len(failed_results)}")
230
188
  for result in failed_results[:5]: # Show first 5 failures
231
189
  print_error(f" Account {result.context.account.account_id}: {result.error_message}")
232
-
190
+
233
191
  # Generate compliance report
234
192
  compliance_report = remediator.generate_compliance_report(results)
235
- print_info(f"Compliance report generated: {compliance_report['total_operations']} operations across {compliance_report['total_accounts']} accounts")
236
-
193
+ print_info(
194
+ f"Compliance report generated: {compliance_report['total_operations']} operations across {compliance_report['total_accounts']} accounts"
195
+ )
196
+
237
197
  # Display configuration sources used
238
198
  _display_configuration_sources()
239
-
199
+
240
200
  except Exception as e:
241
201
  print_error(f"S3 security remediation failed: {str(e)}")
242
202
  raise click.Abort()
243
203
 
244
204
 
245
205
  @remediation.command("list-accounts")
246
- @click.option(
247
- "--show-environment",
248
- is_flag=True,
249
- help="Show environment classification for each account"
250
- )
206
+ @click.option("--show-environment", is_flag=True, help="Show environment classification for each account")
251
207
  @click.pass_context
252
208
  def list_accounts(ctx, show_environment: bool):
253
209
  """
254
210
  List available accounts for remediation operations.
255
211
  """
256
212
  profile = ctx.obj["profile"]
257
-
213
+
258
214
  try:
259
215
  console.print(
260
216
  create_panel(
261
- "[bold cyan]Account Discovery[/bold cyan]\n\n"
262
- "[dim]Discovering accounts from all sources...[/dim]",
217
+ "[bold cyan]Account Discovery[/bold cyan]\n\n[dim]Discovering accounts from all sources...[/dim]",
263
218
  title="📋 Account Listing",
264
219
  border_style="blue",
265
220
  )
266
221
  )
267
-
222
+
268
223
  # Try environment configuration first
269
224
  env_accounts = get_accounts_from_environment()
270
225
  if env_accounts:
@@ -272,32 +227,32 @@ def list_accounts(ctx, show_environment: bool):
272
227
  for account in env_accounts:
273
228
  env_indicator = f" ({account.environment})" if show_environment else ""
274
229
  console.print(f" ✅ {account.account_id}{env_indicator}")
275
-
230
+
276
231
  # Discover from Organizations API
277
232
  try:
278
233
  org_accounts = discover_organization_accounts(profile=profile)
279
234
  console.print(f"\n[bold]Accounts from Organizations API Discovery:[/bold]")
280
235
  for account in org_accounts:
281
236
  env_indicator = f" ({account.environment})" if show_environment else ""
282
- name_part = f" - {account.name}" if hasattr(account, 'name') and account.name else ""
237
+ name_part = f" - {account.name}" if hasattr(account, "name") and account.name else ""
283
238
  console.print(f" 🌐 {account.account_id}{env_indicator}{name_part}")
284
239
  except Exception as e:
285
240
  print_warning(f"Organizations API discovery failed: {str(e)}")
286
-
241
+
287
242
  # Display configuration information
288
243
  console.print("\n[bold]Configuration Sources:[/bold]")
289
-
244
+
290
245
  if os.getenv("REMEDIATION_TARGET_ACCOUNTS"):
291
246
  console.print(" ✅ REMEDIATION_TARGET_ACCOUNTS environment variable")
292
-
247
+
293
248
  if os.getenv("REMEDIATION_ACCOUNT_CONFIG"):
294
249
  config_path = os.getenv("REMEDIATION_ACCOUNT_CONFIG")
295
250
  status = "✅" if os.path.exists(config_path) else "⚠️ "
296
251
  console.print(f" {status} REMEDIATION_ACCOUNT_CONFIG: {config_path}")
297
-
252
+
298
253
  if not env_accounts:
299
254
  console.print(" ℹ️ No environment configuration - using Organizations API discovery")
300
-
255
+
301
256
  except Exception as e:
302
257
  print_error(f"Account listing failed: {str(e)}")
303
258
  raise click.Abort()
@@ -309,16 +264,11 @@ def config_info(ctx):
309
264
  """
310
265
  Display current remediation configuration and environment setup.
311
266
  """
312
- console.print(
313
- Panel.fit(
314
- "[bold cyan]Remediation Configuration Information[/bold cyan]",
315
- border_style="cyan"
316
- )
317
- )
318
-
267
+ console.print(Panel.fit("[bold cyan]Remediation Configuration Information[/bold cyan]", border_style="cyan"))
268
+
319
269
  # Display environment variables
320
270
  print_info("Environment Configuration:")
321
-
271
+
322
272
  env_vars = {
323
273
  "Account Configuration": {
324
274
  "REMEDIATION_TARGET_ACCOUNTS": os.getenv("REMEDIATION_TARGET_ACCOUNTS", "Not set"),
@@ -330,35 +280,33 @@ def config_info(ctx):
330
280
  "Profile Configuration": {
331
281
  "MANAGEMENT_PROFILE": os.getenv("MANAGEMENT_PROFILE", "Not set"),
332
282
  "CENTRALISED_OPS_PROFILE": os.getenv("CENTRALISED_OPS_PROFILE", "Not set"),
333
- }
283
+ },
334
284
  }
335
-
285
+
336
286
  for category, variables in env_vars.items():
337
287
  console.print(f"\n[bold]{category}:[/bold]")
338
288
  for var_name, var_value in variables.items():
339
289
  status = "✅" if var_value != "Not set" else "❌"
340
290
  console.print(f" {status} {var_name}: {var_value}")
341
-
291
+
342
292
  # Display example configuration files
343
293
  console.print("\n[bold]Example Configuration Files:[/bold]")
344
- config_examples = [
345
- "src/runbooks/remediation/config/accounts_example.json"
346
- ]
347
-
294
+ config_examples = ["src/runbooks/remediation/config/accounts_example.json"]
295
+
348
296
  for config_file in config_examples:
349
297
  if os.path.exists(config_file):
350
298
  console.print(f" ✅ {config_file}")
351
299
  else:
352
300
  console.print(f" 📝 {config_file} (example)")
353
-
301
+
354
302
  # Usage examples
355
303
  console.print("\n[bold]Usage Examples:[/bold]")
356
304
  examples = [
357
305
  "# Set target accounts via environment variable",
358
- "export REMEDIATION_TARGET_ACCOUNTS=\"111122223333,444455556666\"",
306
+ 'export REMEDIATION_TARGET_ACCOUNTS="111122223333,444455556666"',
359
307
  "",
360
308
  "# Use configuration file",
361
- "export REMEDIATION_ACCOUNT_CONFIG=\"/path/to/accounts.json\"",
309
+ 'export REMEDIATION_ACCOUNT_CONFIG="/path/to/accounts.json"',
362
310
  "",
363
311
  "# Execute S3 security remediation",
364
312
  "runbooks remediation s3-security --operations block_public_access --dry-run",
@@ -366,7 +314,7 @@ def config_info(ctx):
366
314
  "# Execute on all discovered accounts",
367
315
  "runbooks remediation s3-security --all --operations block_public_access,enforce_ssl",
368
316
  ]
369
-
317
+
370
318
  for example in examples:
371
319
  if example.startswith("#") or example == "":
372
320
  console.print(f"[dim]{example}[/dim]")
@@ -377,68 +325,66 @@ def config_info(ctx):
377
325
  def _display_configuration_sources():
378
326
  """Display information about configuration sources used."""
379
327
  console.print("\n[bold]Configuration Sources:[/bold]")
380
-
328
+
381
329
  # Check environment variables
382
330
  if os.getenv("REMEDIATION_TARGET_ACCOUNTS"):
383
331
  console.print(" ✅ Using REMEDIATION_TARGET_ACCOUNTS environment variable")
384
-
332
+
385
333
  if os.getenv("REMEDIATION_ACCOUNT_CONFIG"):
386
334
  config_path = os.getenv("REMEDIATION_ACCOUNT_CONFIG")
387
335
  if os.path.exists(config_path):
388
336
  console.print(f" ✅ Using accounts config file: {config_path}")
389
337
  else:
390
338
  console.print(f" ⚠️ Accounts config file not found: {config_path}")
391
-
339
+
392
340
  if os.getenv("ACCESS_PORTAL_URL"):
393
341
  console.print(" ✅ AWS SSO configured via ACCESS_PORTAL_URL")
394
342
  else:
395
343
  console.print(" ⚠️ ACCESS_PORTAL_URL not set - SSO functionality limited")
396
-
397
- if not any([
398
- os.getenv("REMEDIATION_TARGET_ACCOUNTS"),
399
- os.getenv("REMEDIATION_ACCOUNT_CONFIG")
400
- ]):
344
+
345
+ if not any([os.getenv("REMEDIATION_TARGET_ACCOUNTS"), os.getenv("REMEDIATION_ACCOUNT_CONFIG")]):
401
346
  console.print(" ℹ️ Using default configuration (Organizations API discovery)")
402
347
 
403
348
 
404
349
  @remediation.command("generate-config")
405
350
  @click.option(
406
- "--output-dir",
407
- default="./artifacts/remediation/config",
408
- help="Output directory for configuration templates"
351
+ "--output-dir", default="./artifacts/remediation/config", help="Output directory for configuration templates"
409
352
  )
410
353
  @click.pass_context
411
354
  def generate_config_templates(ctx, output_dir: str):
412
355
  """
413
356
  Generate universal configuration templates for remediation operations.
414
-
357
+
415
358
  Creates templates for:
416
359
  - Account discovery configuration
417
360
  - Environment variable examples
418
361
  - Complete setup documentation
419
-
362
+
420
363
  All templates support universal AWS compatibility with no hardcoded values.
421
364
  """
422
365
  print_info(f"Generating universal remediation configuration templates in {output_dir}...")
423
-
366
+
424
367
  try:
425
368
  # Create output directory
426
369
  from pathlib import Path
370
+
427
371
  output_path = Path(output_dir)
428
372
  output_path.mkdir(parents=True, exist_ok=True)
429
-
373
+
430
374
  # Use the security config generator (it covers remediation too)
431
375
  from runbooks.security.config_template_generator import SecurityConfigTemplateGenerator
376
+
432
377
  generator = SecurityConfigTemplateGenerator(output_dir)
433
-
378
+
434
379
  # Generate account discovery template
435
380
  account_config = generator.generate_account_config_template()
436
381
  account_path = output_path / "account_config.json"
437
382
  import json
438
- with open(account_path, 'w') as f:
383
+
384
+ with open(account_path, "w") as f:
439
385
  json.dump(account_config, f, indent=2)
440
386
  print_success(f"Generated account configuration: {account_path}")
441
-
387
+
442
388
  # Generate environment variables for remediation
443
389
  env_template = """# Universal Remediation Configuration
444
390
  # ===================================
@@ -480,12 +426,12 @@ runbooks remediation ec2-security --operations terminate_unused_instances --dry-
480
426
  # Generate account discovery template
481
427
  runbooks remediation generate-config --output-dir ./config
482
428
  """
483
-
429
+
484
430
  env_path = output_path / "environment_variables.sh"
485
- with open(env_path, 'w') as f:
431
+ with open(env_path, "w") as f:
486
432
  f.write(env_template)
487
433
  print_success(f"Generated environment variables template: {env_path}")
488
-
434
+
489
435
  # Generate setup documentation specific to remediation
490
436
  setup_docs = """# Universal Remediation Module Setup Guide
491
437
  ========================================
@@ -688,23 +634,23 @@ runbooks remediation s3-security --operations block_public_access --dry-run --ac
688
634
 
689
635
  This configuration system provides universal compatibility with any AWS environment while maintaining safety and control.
690
636
  """
691
-
637
+
692
638
  docs_path = output_path / "REMEDIATION_SETUP_GUIDE.md"
693
- with open(docs_path, 'w') as f:
639
+ with open(docs_path, "w") as f:
694
640
  f.write(setup_docs)
695
641
  print_success(f"Generated setup documentation: {docs_path}")
696
-
642
+
697
643
  print_success("Remediation configuration templates generated successfully!")
698
644
  console.print("\n[bold yellow]Next steps:[/bold yellow]")
699
645
  console.print("1. Review and customize the generated configuration files")
700
646
  console.print("2. Set REMEDIATION_ACCOUNT_CONFIG or REMEDIATION_TARGET_ACCOUNTS")
701
647
  console.print("3. Test with: runbooks remediation s3-security --operations block_public_access --dry-run")
702
648
  console.print("4. Execute: runbooks remediation s3-security --operations block_public_access")
703
-
649
+
704
650
  except Exception as e:
705
651
  print_error(f"Failed to generate configuration templates: {e}")
706
652
  raise click.Abort()
707
653
 
708
654
 
709
655
  if __name__ == "__main__":
710
- remediation()
656
+ remediation()