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.
- runbooks/__init__.py +31 -2
- runbooks/__init___optimized.py +18 -4
- runbooks/_platform/__init__.py +1 -5
- runbooks/_platform/core/runbooks_wrapper.py +141 -138
- runbooks/aws2/accuracy_validator.py +812 -0
- runbooks/base.py +7 -0
- runbooks/cfat/assessment/compliance.py +1 -1
- runbooks/cfat/assessment/runner.py +1 -0
- runbooks/cfat/cloud_foundations_assessment.py +227 -239
- runbooks/cli/__init__.py +1 -1
- runbooks/cli/commands/cfat.py +64 -23
- runbooks/cli/commands/finops.py +1005 -54
- runbooks/cli/commands/inventory.py +138 -35
- runbooks/cli/commands/operate.py +9 -36
- runbooks/cli/commands/security.py +42 -18
- runbooks/cli/commands/validation.py +432 -18
- runbooks/cli/commands/vpc.py +81 -17
- runbooks/cli/registry.py +22 -10
- runbooks/cloudops/__init__.py +20 -27
- runbooks/cloudops/base.py +96 -107
- runbooks/cloudops/cost_optimizer.py +544 -542
- runbooks/cloudops/infrastructure_optimizer.py +5 -4
- runbooks/cloudops/interfaces.py +224 -225
- runbooks/cloudops/lifecycle_manager.py +5 -4
- runbooks/cloudops/mcp_cost_validation.py +252 -235
- runbooks/cloudops/models.py +78 -53
- runbooks/cloudops/monitoring_automation.py +5 -4
- runbooks/cloudops/notebook_framework.py +177 -213
- runbooks/cloudops/security_enforcer.py +125 -159
- runbooks/common/accuracy_validator.py +11 -0
- runbooks/common/aws_pricing.py +349 -326
- runbooks/common/aws_pricing_api.py +211 -212
- runbooks/common/aws_profile_manager.py +40 -36
- runbooks/common/aws_utils.py +74 -79
- runbooks/common/business_logic.py +126 -104
- runbooks/common/cli_decorators.py +36 -60
- runbooks/common/comprehensive_cost_explorer_integration.py +455 -463
- runbooks/common/cross_account_manager.py +197 -204
- runbooks/common/date_utils.py +27 -39
- runbooks/common/decorators.py +29 -19
- runbooks/common/dry_run_examples.py +173 -208
- runbooks/common/dry_run_framework.py +157 -155
- runbooks/common/enhanced_exception_handler.py +15 -4
- runbooks/common/enhanced_logging_example.py +50 -64
- runbooks/common/enhanced_logging_integration_example.py +65 -37
- runbooks/common/env_utils.py +16 -16
- runbooks/common/error_handling.py +40 -38
- runbooks/common/lazy_loader.py +41 -23
- runbooks/common/logging_integration_helper.py +79 -86
- runbooks/common/mcp_cost_explorer_integration.py +476 -493
- runbooks/common/mcp_integration.py +63 -74
- runbooks/common/memory_optimization.py +140 -118
- runbooks/common/module_cli_base.py +37 -58
- runbooks/common/organizations_client.py +175 -193
- runbooks/common/patterns.py +23 -25
- runbooks/common/performance_monitoring.py +67 -71
- runbooks/common/performance_optimization_engine.py +283 -274
- runbooks/common/profile_utils.py +111 -37
- runbooks/common/rich_utils.py +201 -141
- runbooks/common/sre_performance_suite.py +177 -186
- runbooks/enterprise/__init__.py +1 -1
- runbooks/enterprise/logging.py +144 -106
- runbooks/enterprise/security.py +187 -204
- runbooks/enterprise/validation.py +43 -56
- runbooks/finops/__init__.py +26 -30
- runbooks/finops/account_resolver.py +1 -1
- runbooks/finops/advanced_optimization_engine.py +980 -0
- runbooks/finops/automation_core.py +268 -231
- runbooks/finops/business_case_config.py +184 -179
- runbooks/finops/cli.py +660 -139
- runbooks/finops/commvault_ec2_analysis.py +157 -164
- runbooks/finops/compute_cost_optimizer.py +336 -320
- runbooks/finops/config.py +20 -20
- runbooks/finops/cost_optimizer.py +484 -618
- runbooks/finops/cost_processor.py +332 -214
- runbooks/finops/dashboard_runner.py +1006 -172
- runbooks/finops/ebs_cost_optimizer.py +991 -657
- runbooks/finops/elastic_ip_optimizer.py +317 -257
- runbooks/finops/enhanced_mcp_integration.py +340 -0
- runbooks/finops/enhanced_progress.py +32 -29
- runbooks/finops/enhanced_trend_visualization.py +3 -2
- runbooks/finops/enterprise_wrappers.py +223 -285
- runbooks/finops/executive_export.py +203 -160
- runbooks/finops/helpers.py +130 -288
- runbooks/finops/iam_guidance.py +1 -1
- runbooks/finops/infrastructure/__init__.py +80 -0
- runbooks/finops/infrastructure/commands.py +506 -0
- runbooks/finops/infrastructure/load_balancer_optimizer.py +866 -0
- runbooks/finops/infrastructure/vpc_endpoint_optimizer.py +832 -0
- runbooks/finops/markdown_exporter.py +337 -174
- runbooks/finops/mcp_validator.py +1952 -0
- runbooks/finops/nat_gateway_optimizer.py +1512 -481
- runbooks/finops/network_cost_optimizer.py +657 -587
- runbooks/finops/notebook_utils.py +226 -188
- runbooks/finops/optimization_engine.py +1136 -0
- runbooks/finops/optimizer.py +19 -23
- runbooks/finops/rds_snapshot_optimizer.py +367 -411
- runbooks/finops/reservation_optimizer.py +427 -363
- runbooks/finops/scenario_cli_integration.py +64 -65
- runbooks/finops/scenarios.py +1277 -438
- runbooks/finops/schemas.py +218 -182
- runbooks/finops/snapshot_manager.py +2289 -0
- runbooks/finops/types.py +3 -3
- runbooks/finops/validation_framework.py +259 -265
- runbooks/finops/vpc_cleanup_exporter.py +189 -144
- runbooks/finops/vpc_cleanup_optimizer.py +591 -573
- runbooks/finops/workspaces_analyzer.py +171 -182
- runbooks/integration/__init__.py +89 -0
- runbooks/integration/mcp_integration.py +1920 -0
- runbooks/inventory/CLAUDE.md +816 -0
- runbooks/inventory/__init__.py +2 -2
- runbooks/inventory/cloud_foundations_integration.py +144 -149
- runbooks/inventory/collectors/aws_comprehensive.py +1 -1
- runbooks/inventory/collectors/aws_networking.py +109 -99
- runbooks/inventory/collectors/base.py +4 -0
- runbooks/inventory/core/collector.py +495 -313
- runbooks/inventory/drift_detection_cli.py +69 -96
- runbooks/inventory/inventory_mcp_cli.py +48 -46
- runbooks/inventory/list_rds_snapshots_aggregator.py +192 -208
- runbooks/inventory/mcp_inventory_validator.py +549 -465
- runbooks/inventory/mcp_vpc_validator.py +359 -442
- runbooks/inventory/organizations_discovery.py +55 -51
- runbooks/inventory/rich_inventory_display.py +33 -32
- runbooks/inventory/unified_validation_engine.py +278 -251
- runbooks/inventory/vpc_analyzer.py +732 -695
- runbooks/inventory/vpc_architecture_validator.py +293 -348
- runbooks/inventory/vpc_dependency_analyzer.py +382 -378
- runbooks/inventory/vpc_flow_analyzer.py +1 -1
- runbooks/main.py +49 -34
- runbooks/main_final.py +91 -60
- runbooks/main_minimal.py +22 -10
- runbooks/main_optimized.py +131 -100
- runbooks/main_ultra_minimal.py +7 -2
- runbooks/mcp/__init__.py +36 -0
- runbooks/mcp/integration.py +679 -0
- runbooks/monitoring/performance_monitor.py +9 -4
- runbooks/operate/dynamodb_operations.py +3 -1
- runbooks/operate/ec2_operations.py +145 -137
- runbooks/operate/iam_operations.py +146 -152
- runbooks/operate/networking_cost_heatmap.py +29 -8
- runbooks/operate/rds_operations.py +223 -254
- runbooks/operate/s3_operations.py +107 -118
- runbooks/operate/vpc_operations.py +646 -616
- runbooks/remediation/base.py +1 -1
- runbooks/remediation/commons.py +10 -7
- runbooks/remediation/commvault_ec2_analysis.py +70 -66
- runbooks/remediation/ec2_unattached_ebs_volumes.py +1 -0
- runbooks/remediation/multi_account.py +24 -21
- runbooks/remediation/rds_snapshot_list.py +86 -60
- runbooks/remediation/remediation_cli.py +92 -146
- runbooks/remediation/universal_account_discovery.py +83 -79
- runbooks/remediation/workspaces_list.py +46 -41
- runbooks/security/__init__.py +19 -0
- runbooks/security/assessment_runner.py +1150 -0
- runbooks/security/baseline_checker.py +812 -0
- runbooks/security/cloudops_automation_security_validator.py +509 -535
- runbooks/security/compliance_automation_engine.py +17 -17
- runbooks/security/config/__init__.py +2 -2
- runbooks/security/config/compliance_config.py +50 -50
- runbooks/security/config_template_generator.py +63 -76
- runbooks/security/enterprise_security_framework.py +1 -1
- runbooks/security/executive_security_dashboard.py +519 -508
- runbooks/security/multi_account_security_controls.py +959 -1210
- runbooks/security/real_time_security_monitor.py +422 -444
- runbooks/security/security_baseline_tester.py +1 -1
- runbooks/security/security_cli.py +143 -112
- runbooks/security/test_2way_validation.py +439 -0
- runbooks/security/two_way_validation_framework.py +852 -0
- runbooks/sre/production_monitoring_framework.py +167 -177
- runbooks/tdd/__init__.py +15 -0
- runbooks/tdd/cli.py +1071 -0
- runbooks/utils/__init__.py +14 -17
- runbooks/utils/logger.py +7 -2
- runbooks/utils/version_validator.py +50 -47
- runbooks/validation/__init__.py +6 -6
- runbooks/validation/cli.py +9 -3
- runbooks/validation/comprehensive_2way_validator.py +745 -704
- runbooks/validation/mcp_validator.py +906 -228
- runbooks/validation/terraform_citations_validator.py +104 -115
- runbooks/validation/terraform_drift_detector.py +447 -451
- runbooks/vpc/README.md +617 -0
- runbooks/vpc/__init__.py +8 -1
- runbooks/vpc/analyzer.py +577 -0
- runbooks/vpc/cleanup_wrapper.py +476 -413
- runbooks/vpc/cli_cloudtrail_commands.py +339 -0
- runbooks/vpc/cli_mcp_validation_commands.py +480 -0
- runbooks/vpc/cloudtrail_audit_integration.py +717 -0
- runbooks/vpc/config.py +92 -97
- runbooks/vpc/cost_engine.py +411 -148
- runbooks/vpc/cost_explorer_integration.py +553 -0
- runbooks/vpc/cross_account_session.py +101 -106
- runbooks/vpc/enhanced_mcp_validation.py +917 -0
- runbooks/vpc/eni_gate_validator.py +961 -0
- runbooks/vpc/heatmap_engine.py +185 -160
- runbooks/vpc/mcp_no_eni_validator.py +680 -639
- runbooks/vpc/nat_gateway_optimizer.py +358 -0
- runbooks/vpc/networking_wrapper.py +15 -8
- runbooks/vpc/pdca_remediation_planner.py +528 -0
- runbooks/vpc/performance_optimized_analyzer.py +219 -231
- runbooks/vpc/runbooks_adapter.py +1167 -241
- runbooks/vpc/tdd_red_phase_stubs.py +601 -0
- runbooks/vpc/test_data_loader.py +358 -0
- runbooks/vpc/tests/conftest.py +314 -4
- runbooks/vpc/tests/test_cleanup_framework.py +1022 -0
- runbooks/vpc/tests/test_cost_engine.py +0 -2
- runbooks/vpc/topology_generator.py +326 -0
- runbooks/vpc/unified_scenarios.py +1297 -1124
- runbooks/vpc/vpc_cleanup_integration.py +1943 -1115
- runbooks-1.1.5.dist-info/METADATA +328 -0
- {runbooks-1.1.4.dist-info → runbooks-1.1.5.dist-info}/RECORD +214 -193
- runbooks/finops/README.md +0 -414
- runbooks/finops/accuracy_cross_validator.py +0 -647
- runbooks/finops/business_cases.py +0 -950
- runbooks/finops/dashboard_router.py +0 -922
- runbooks/finops/ebs_optimizer.py +0 -973
- runbooks/finops/embedded_mcp_validator.py +0 -1629
- runbooks/finops/enhanced_dashboard_runner.py +0 -527
- runbooks/finops/finops_dashboard.py +0 -584
- runbooks/finops/finops_scenarios.py +0 -1218
- runbooks/finops/legacy_migration.py +0 -730
- runbooks/finops/multi_dashboard.py +0 -1519
- runbooks/finops/single_dashboard.py +0 -1113
- runbooks/finops/unlimited_scenarios.py +0 -393
- runbooks-1.1.4.dist-info/METADATA +0 -800
- {runbooks-1.1.4.dist-info → runbooks-1.1.5.dist-info}/WHEEL +0 -0
- {runbooks-1.1.4.dist-info → runbooks-1.1.5.dist-info}/entry_points.txt +0 -0
- {runbooks-1.1.4.dist-info → runbooks-1.1.5.dist-info}/licenses/LICENSE +0 -0
- {runbooks-1.1.4.dist-info → runbooks-1.1.5.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
|
-
|
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(
|
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
|
-
|
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(
|
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,
|
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
|
-
|
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
|
-
|
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
|
-
|
306
|
+
'export REMEDIATION_TARGET_ACCOUNTS="111122223333,444455556666"',
|
359
307
|
"",
|
360
308
|
"# Use configuration file",
|
361
|
-
|
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
|
-
|
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,
|
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,
|
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()
|