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
@@ -609,7 +609,7 @@ class VPCFlowAnalyzer(BaseInventory):
|
|
609
609
|
if i != j: # Cross-AZ traffic
|
610
610
|
# REMOVED: Random traffic simulation violates enterprise standards
|
611
611
|
# TODO: Calculate actual cross-AZ traffic from VPC Flow Logs
|
612
|
-
|
612
|
+
|
613
613
|
traffic_bytes = 500000 * time_range_hours # Deterministic baseline
|
614
614
|
az_pair = f"{source_az}-to-{dest_az}"
|
615
615
|
|
runbooks/main.py
CHANGED
@@ -22,45 +22,46 @@ Enterprise Features Preserved:
|
|
22
22
|
- Safety controls and audit trails
|
23
23
|
"""
|
24
24
|
|
25
|
+
import os
|
25
26
|
import sys
|
26
27
|
from datetime import datetime
|
27
28
|
from pathlib import Path
|
28
29
|
from typing import Optional
|
29
|
-
import os
|
30
30
|
|
31
31
|
import click
|
32
32
|
from loguru import logger
|
33
33
|
|
34
34
|
try:
|
35
35
|
from rich.console import Console
|
36
|
-
from rich.table import Table
|
37
36
|
from rich.markup import escape
|
37
|
+
from rich.table import Table
|
38
|
+
|
38
39
|
_HAS_RICH = True
|
39
40
|
except ImportError:
|
40
41
|
_HAS_RICH = False
|
42
|
+
|
41
43
|
# Fallback console implementation
|
42
44
|
class Console:
|
43
45
|
def print(self, *args, **kwargs):
|
44
46
|
output = " ".join(str(arg) for arg in args)
|
45
47
|
print(output)
|
46
48
|
|
49
|
+
|
47
50
|
import boto3
|
48
51
|
|
49
52
|
from runbooks import __version__
|
50
53
|
from runbooks.cli.registry import DRYCommandRegistry
|
51
|
-
from runbooks.common.performance_monitor import get_performance_benchmark
|
52
|
-
|
53
|
-
# Initialize Rich console
|
54
|
-
console = Console()
|
55
|
-
|
56
|
-
# Common decorators and options
|
57
54
|
from runbooks.common.decorators import (
|
58
55
|
common_aws_options,
|
59
|
-
common_output_options,
|
60
56
|
common_filter_options,
|
57
|
+
common_output_options,
|
58
|
+
error_handler,
|
61
59
|
performance_timing,
|
62
|
-
error_handler
|
63
60
|
)
|
61
|
+
from runbooks.common.performance_monitor import get_performance_benchmark
|
62
|
+
|
63
|
+
# Initialize Rich console
|
64
|
+
console = Console()
|
64
65
|
|
65
66
|
|
66
67
|
def display_banner():
|
@@ -81,9 +82,12 @@ def display_banner():
|
|
81
82
|
@click.group()
|
82
83
|
@click.version_option(version=__version__)
|
83
84
|
@click.option("--debug", is_flag=True, help="Enable debug logging")
|
84
|
-
@click.option(
|
85
|
-
|
86
|
-
|
85
|
+
@click.option(
|
86
|
+
"--log-level",
|
87
|
+
type=click.Choice(["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]),
|
88
|
+
default="INFO",
|
89
|
+
help="Set logging level",
|
90
|
+
)
|
87
91
|
@click.option("--json-output", is_flag=True, help="Enable structured JSON output for programmatic use")
|
88
92
|
@common_aws_options
|
89
93
|
@click.option("--config", type=click.Path(), help="Configuration file path")
|
@@ -120,22 +124,28 @@ def main(ctx, debug, log_level, json_output, profile, region, dry_run, config):
|
|
120
124
|
|
121
125
|
# Configure logging
|
122
126
|
if debug:
|
123
|
-
log_level =
|
127
|
+
log_level = "DEBUG"
|
124
128
|
|
125
129
|
logger.remove()
|
126
|
-
logger.add(
|
130
|
+
logger.add(
|
131
|
+
sys.stderr,
|
132
|
+
level=log_level,
|
133
|
+
format="<green>{time}</green> | <level>{level: <8}</level> | <cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> - <level>{message}</level>",
|
134
|
+
)
|
127
135
|
|
128
136
|
# Store global options in context
|
129
|
-
ctx.obj.update(
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
137
|
+
ctx.obj.update(
|
138
|
+
{
|
139
|
+
"debug": debug,
|
140
|
+
"log_level": log_level,
|
141
|
+
"json_output": json_output,
|
142
|
+
"profile": profile,
|
143
|
+
"region": region,
|
144
|
+
"dry_run": dry_run,
|
145
|
+
"config": config,
|
146
|
+
"start_time": datetime.now(),
|
147
|
+
}
|
148
|
+
)
|
139
149
|
|
140
150
|
# Display banner for interactive use
|
141
151
|
if not json_output and ctx.invoked_subcommand is None:
|
@@ -167,18 +177,19 @@ except Exception as e:
|
|
167
177
|
@click.pass_context
|
168
178
|
def version(ctx):
|
169
179
|
"""Display version information and performance metrics."""
|
170
|
-
performance_data = get_performance_benchmark()
|
180
|
+
performance_data = get_performance_benchmark("main")
|
171
181
|
|
172
182
|
version_info = {
|
173
183
|
"version": __version__,
|
174
184
|
"python_version": sys.version.split()[0],
|
175
185
|
"platform": sys.platform,
|
176
186
|
"commands_loaded": len(DRYCommandRegistry.list_commands()),
|
177
|
-
"performance": performance_data
|
187
|
+
"performance": performance_data,
|
178
188
|
}
|
179
189
|
|
180
|
-
if ctx.obj.get(
|
190
|
+
if ctx.obj.get("json_output"):
|
181
191
|
import json
|
192
|
+
|
182
193
|
click.echo(json.dumps(version_info, indent=2))
|
183
194
|
else:
|
184
195
|
console.print(f"[bold]CloudOps Runbooks v{__version__}[/bold]")
|
@@ -187,23 +198,27 @@ def version(ctx):
|
|
187
198
|
console.print(f"Commands: {version_info['commands_loaded']} groups loaded")
|
188
199
|
|
189
200
|
if performance_data:
|
190
|
-
|
201
|
+
avg_time = getattr(performance_data, "avg_execution_time", "N/A")
|
202
|
+
console.print(f"Performance: {avg_time}s avg execution")
|
191
203
|
|
192
204
|
|
193
205
|
@main.command()
|
194
|
-
@click.option(
|
195
|
-
|
206
|
+
@click.option(
|
207
|
+
"--format", "output_format", type=click.Choice(["table", "json", "yaml"]), default="table", help="Output format"
|
208
|
+
)
|
196
209
|
@click.pass_context
|
197
210
|
def list_commands(ctx, output_format):
|
198
211
|
"""List all available commands and their descriptions."""
|
199
212
|
commands = DRYCommandRegistry.register_commands()
|
200
213
|
|
201
|
-
if output_format ==
|
214
|
+
if output_format == "json":
|
202
215
|
import json
|
216
|
+
|
203
217
|
command_data = {name: cmd.get_short_help_str() for name, cmd in commands.items()}
|
204
218
|
click.echo(json.dumps(command_data, indent=2))
|
205
|
-
elif output_format ==
|
219
|
+
elif output_format == "yaml":
|
206
220
|
import yaml
|
221
|
+
|
207
222
|
command_data = {name: cmd.get_short_help_str() for name, cmd in commands.items()}
|
208
223
|
click.echo(yaml.dump(command_data, default_flow_style=False))
|
209
224
|
else:
|
@@ -225,4 +240,4 @@ def cli_entry_point():
|
|
225
240
|
|
226
241
|
|
227
242
|
if __name__ == "__main__":
|
228
|
-
main()
|
243
|
+
main()
|
runbooks/main_final.py
CHANGED
@@ -4,7 +4,7 @@ CloudOps Runbooks - PERFORMANCE OPTIMIZED Enterprise CLI Interface
|
|
4
4
|
## Performance Optimizations Applied:
|
5
5
|
|
6
6
|
1. **Import Chain Fix**: Direct version import avoids heavy finops chain
|
7
|
-
2. **Lazy Loading**: Heavy components loaded only when needed
|
7
|
+
2. **Lazy Loading**: Heavy components loaded only when needed
|
8
8
|
3. **Fast Operations**: --help, --version run in <0.5s
|
9
9
|
4. **Progressive Disclosure**: Basic CLI → Enterprise features on demand
|
10
10
|
|
@@ -29,50 +29,67 @@ __version__ = "1.0.0" # Avoid 'from runbooks import __version__'
|
|
29
29
|
# Fast Rich console loading
|
30
30
|
try:
|
31
31
|
from rich.console import Console
|
32
|
+
|
32
33
|
_HAS_RICH = True
|
33
34
|
except ImportError:
|
34
35
|
_HAS_RICH = False
|
36
|
+
|
35
37
|
class Console:
|
36
38
|
def print(self, *args, **kwargs):
|
37
39
|
print(*args)
|
38
40
|
|
41
|
+
|
39
42
|
console = Console()
|
40
43
|
|
44
|
+
|
41
45
|
# Lazy loading functions for heavy components
|
42
46
|
def lazy_load_finops():
|
43
47
|
"""Lazy load FinOps components only when needed."""
|
44
48
|
from runbooks.finops.dashboard_runner import run_dashboard
|
45
49
|
from runbooks.finops import get_cost_data, get_trend
|
50
|
+
|
46
51
|
return run_dashboard, get_cost_data, get_trend
|
47
52
|
|
53
|
+
|
48
54
|
def lazy_load_inventory():
|
49
55
|
"""Lazy load inventory components only when needed."""
|
50
56
|
from runbooks.inventory.core.collector import InventoryCollector
|
57
|
+
|
51
58
|
return InventoryCollector
|
52
59
|
|
60
|
+
|
53
61
|
def lazy_load_security():
|
54
62
|
"""Lazy load security components only when needed."""
|
55
63
|
from runbooks.security.security_baseline_tester import SecurityBaselineTester
|
64
|
+
|
56
65
|
return SecurityBaselineTester
|
57
66
|
|
67
|
+
|
58
68
|
def lazy_load_cfat():
|
59
69
|
"""Lazy load CFAT components only when needed."""
|
60
70
|
from runbooks.cfat.runner import AssessmentRunner
|
71
|
+
|
61
72
|
return AssessmentRunner
|
62
73
|
|
74
|
+
|
63
75
|
def lazy_load_profile_utils():
|
64
76
|
"""Lazy load profile utilities only when needed."""
|
65
77
|
from runbooks.common.profile_utils import get_profile_for_operation
|
78
|
+
|
66
79
|
return get_profile_for_operation
|
67
80
|
|
81
|
+
|
68
82
|
def lazy_load_aws_session():
|
69
83
|
"""Lazy load AWS session creation."""
|
70
84
|
import boto3
|
85
|
+
|
71
86
|
return boto3.Session()
|
72
87
|
|
88
|
+
|
73
89
|
# Performance monitoring
|
74
90
|
def track_performance(operation_name: str):
|
75
91
|
"""Decorator to track operation performance."""
|
92
|
+
|
76
93
|
def decorator(func):
|
77
94
|
def wrapper(*args, **kwargs):
|
78
95
|
start_time = datetime.now()
|
@@ -86,35 +103,41 @@ def track_performance(operation_name: str):
|
|
86
103
|
duration = (datetime.now() - start_time).total_seconds()
|
87
104
|
console.print(f"❌ {operation_name} failed after {duration:.3f}s: {e}")
|
88
105
|
raise
|
106
|
+
|
89
107
|
return wrapper
|
108
|
+
|
90
109
|
return decorator
|
91
110
|
|
111
|
+
|
92
112
|
# ============================================================================
|
93
113
|
# CLI MAIN ENTRY POINT - OPTIMIZED
|
94
114
|
# ============================================================================
|
95
115
|
|
116
|
+
|
96
117
|
@click.group()
|
97
118
|
@click.version_option(version=__version__, prog_name="runbooks")
|
98
|
-
@click.option(
|
99
|
-
@click.option(
|
119
|
+
@click.option("--debug", is_flag=True, help="Enable debug logging")
|
120
|
+
@click.option("--profile", help="AWS profile to use")
|
100
121
|
@click.pass_context
|
101
122
|
def cli(ctx: click.Context, debug: bool, profile: str):
|
102
123
|
"""
|
103
124
|
CloudOps Runbooks - Enterprise AWS Automation Platform
|
104
|
-
|
125
|
+
|
105
126
|
Performance optimized: <0.5s for basic operations.
|
106
127
|
"""
|
107
128
|
ctx.ensure_object(dict)
|
108
|
-
ctx.obj[
|
109
|
-
ctx.obj[
|
110
|
-
|
129
|
+
ctx.obj["profile"] = profile
|
130
|
+
ctx.obj["debug"] = debug
|
131
|
+
|
111
132
|
if debug:
|
112
133
|
logger.enable("runbooks")
|
113
134
|
|
135
|
+
|
114
136
|
# ============================================================================
|
115
137
|
# FAST BASIC COMMANDS
|
116
138
|
# ============================================================================
|
117
139
|
|
140
|
+
|
118
141
|
@cli.command("version-info")
|
119
142
|
@track_performance("version")
|
120
143
|
def version_info():
|
@@ -122,6 +145,7 @@ def version_info():
|
|
122
145
|
console.print(f"[bold blue]CloudOps Runbooks[/bold blue] v{__version__}")
|
123
146
|
console.print("Enterprise AWS Automation Platform")
|
124
147
|
|
148
|
+
|
125
149
|
@cli.command()
|
126
150
|
@track_performance("status")
|
127
151
|
def status():
|
@@ -130,16 +154,17 @@ def status():
|
|
130
154
|
console.print(f"Version: [green]{__version__}[/green]")
|
131
155
|
console.print("Status: [green]Ready[/green]")
|
132
156
|
|
157
|
+
|
133
158
|
@cli.command()
|
134
159
|
@track_performance("perf")
|
135
160
|
def perf():
|
136
161
|
"""Performance diagnostics and benchmarking."""
|
137
162
|
start_time = datetime.now()
|
138
163
|
console.print("🚀 [bold]Performance Diagnostics[/bold]")
|
139
|
-
|
164
|
+
|
140
165
|
# Test component loading times
|
141
166
|
console.print("\n📊 Component Loading Performance:")
|
142
|
-
|
167
|
+
|
143
168
|
# Test FinOps loading
|
144
169
|
try:
|
145
170
|
load_start = datetime.now()
|
@@ -148,93 +173,95 @@ def perf():
|
|
148
173
|
console.print(f"FinOps Module: [green]{load_time:.3f}s[/green]")
|
149
174
|
except Exception as e:
|
150
175
|
console.print(f"FinOps Module: [red]Error - {e}[/red]")
|
151
|
-
|
176
|
+
|
152
177
|
# Test AWS session
|
153
178
|
try:
|
154
|
-
aws_start = datetime.now()
|
179
|
+
aws_start = datetime.now()
|
155
180
|
lazy_load_aws_session()
|
156
181
|
aws_time = (datetime.now() - aws_start).total_seconds()
|
157
182
|
console.print(f"AWS Session: [green]{aws_time:.3f}s[/green]")
|
158
183
|
except Exception as e:
|
159
184
|
console.print(f"AWS Session: [yellow]No credentials - {e}[/yellow]")
|
160
|
-
|
185
|
+
|
161
186
|
total_time = (datetime.now() - start_time).total_seconds()
|
162
187
|
console.print(f"\n⏱️ [bold]Total Diagnostic Time: {total_time:.3f}s[/bold]")
|
163
188
|
|
189
|
+
|
164
190
|
# ============================================================================
|
165
191
|
# FINOPS COMMANDS - LAZY LOADED
|
166
192
|
# ============================================================================
|
167
193
|
|
194
|
+
|
168
195
|
@cli.group()
|
169
196
|
def finops():
|
170
197
|
"""Financial Operations and Cost Analysis (lazy loaded)"""
|
171
198
|
pass
|
172
199
|
|
200
|
+
|
173
201
|
@finops.command()
|
174
|
-
@click.option(
|
175
|
-
@click.option(
|
176
|
-
@click.option(
|
202
|
+
@click.option("--profile", help="AWS profile to use")
|
203
|
+
@click.option("--export", type=click.Choice(["csv", "json", "html", "pdf"]), help="Export format")
|
204
|
+
@click.option("--output-file", type=click.Path(), help="Output file path")
|
177
205
|
@track_performance("finops_dashboard")
|
178
206
|
def dashboard(profile: str, export: str, output_file: str):
|
179
207
|
"""Run FinOps cost analysis dashboard."""
|
180
208
|
console.print("🚀 Loading FinOps Dashboard...")
|
181
|
-
|
209
|
+
|
182
210
|
# Lazy load components
|
183
211
|
run_dashboard, get_cost_data, get_trend = lazy_load_finops()
|
184
212
|
get_profile_for_operation = lazy_load_profile_utils()
|
185
|
-
|
213
|
+
|
186
214
|
try:
|
187
215
|
# Resolve profile
|
188
216
|
resolved_profile = get_profile_for_operation("billing", profile)
|
189
217
|
console.print(f"Using profile: [blue]{resolved_profile}[/blue]")
|
190
|
-
|
218
|
+
|
191
219
|
# Run dashboard
|
192
|
-
result = run_dashboard(
|
193
|
-
profile=resolved_profile,
|
194
|
-
export_format=export,
|
195
|
-
output_file=output_file
|
196
|
-
)
|
220
|
+
result = run_dashboard(profile=resolved_profile, export_format=export, output_file=output_file)
|
197
221
|
console.print("✅ FinOps analysis completed successfully")
|
198
222
|
return result
|
199
223
|
except Exception as e:
|
200
224
|
console.print(f"❌ FinOps analysis failed: {e}")
|
201
225
|
raise
|
202
226
|
|
227
|
+
|
203
228
|
# ============================================================================
|
204
|
-
# INVENTORY COMMANDS - LAZY LOADED
|
229
|
+
# INVENTORY COMMANDS - LAZY LOADED
|
205
230
|
# ============================================================================
|
206
231
|
|
232
|
+
|
207
233
|
@cli.group()
|
208
234
|
def inventory():
|
209
235
|
"""Resource Discovery and Inventory Management (lazy loaded)"""
|
210
236
|
pass
|
211
237
|
|
238
|
+
|
212
239
|
@inventory.command()
|
213
|
-
@click.option(
|
214
|
-
@click.option(
|
215
|
-
@click.option(
|
240
|
+
@click.option("--profile", help="AWS profile to use")
|
241
|
+
@click.option("--regions", multiple=True, help="AWS regions to scan")
|
242
|
+
@click.option("--services", multiple=True, help="AWS services to include")
|
216
243
|
@track_performance("inventory_collect")
|
217
244
|
def collect(profile: str, regions: tuple, services: tuple):
|
218
245
|
"""Collect comprehensive inventory across AWS accounts."""
|
219
246
|
console.print("🔍 Loading Inventory Collector...")
|
220
|
-
|
247
|
+
|
221
248
|
# Lazy load components
|
222
249
|
InventoryCollector = lazy_load_inventory()
|
223
250
|
get_profile_for_operation = lazy_load_profile_utils()
|
224
251
|
session = lazy_load_aws_session()
|
225
|
-
|
252
|
+
|
226
253
|
try:
|
227
254
|
# Resolve profile
|
228
255
|
resolved_profile = get_profile_for_operation("management", profile)
|
229
256
|
console.print(f"Using profile: [blue]{resolved_profile}[/blue]")
|
230
|
-
|
257
|
+
|
231
258
|
# Create collector
|
232
259
|
collector = InventoryCollector()
|
233
|
-
|
260
|
+
|
234
261
|
result = collector.collect_services(
|
235
262
|
profile=resolved_profile,
|
236
263
|
regions=list(regions) if regions else None,
|
237
|
-
services=list(services) if services else None
|
264
|
+
services=list(services) if services else None,
|
238
265
|
)
|
239
266
|
console.print("✅ Inventory collection completed")
|
240
267
|
return result
|
@@ -242,117 +269,121 @@ def collect(profile: str, regions: tuple, services: tuple):
|
|
242
269
|
console.print(f"❌ Inventory collection failed: {e}")
|
243
270
|
raise
|
244
271
|
|
272
|
+
|
245
273
|
# ============================================================================
|
246
274
|
# SECURITY COMMANDS - LAZY LOADED
|
247
275
|
# ============================================================================
|
248
276
|
|
277
|
+
|
249
278
|
@cli.group()
|
250
279
|
def security():
|
251
280
|
"""Security Assessment and Compliance (lazy loaded)"""
|
252
281
|
pass
|
253
282
|
|
283
|
+
|
254
284
|
@security.command()
|
255
|
-
@click.option(
|
256
|
-
@click.option(
|
285
|
+
@click.option("--profile", help="AWS profile to use")
|
286
|
+
@click.option("--frameworks", multiple=True, help="Compliance frameworks")
|
257
287
|
@track_performance("security_assess")
|
258
288
|
def assess(profile: str, frameworks: tuple):
|
259
289
|
"""Run security baseline assessment."""
|
260
290
|
console.print("🔒 Loading Security Assessment...")
|
261
|
-
|
291
|
+
|
262
292
|
# Lazy load components
|
263
293
|
SecurityBaselineTester = lazy_load_security()
|
264
294
|
get_profile_for_operation = lazy_load_profile_utils()
|
265
|
-
|
295
|
+
|
266
296
|
try:
|
267
297
|
# Resolve profile
|
268
298
|
resolved_profile = get_profile_for_operation("management", profile)
|
269
299
|
console.print(f"Using profile: [blue]{resolved_profile}[/blue]")
|
270
|
-
|
300
|
+
|
271
301
|
# Create tester
|
272
302
|
tester = SecurityBaselineTester()
|
273
|
-
|
274
|
-
result = tester.run_assessment(
|
275
|
-
profile=resolved_profile,
|
276
|
-
frameworks=list(frameworks) if frameworks else None
|
277
|
-
)
|
303
|
+
|
304
|
+
result = tester.run_assessment(profile=resolved_profile, frameworks=list(frameworks) if frameworks else None)
|
278
305
|
console.print("✅ Security assessment completed")
|
279
306
|
return result
|
280
307
|
except Exception as e:
|
281
308
|
console.print(f"❌ Security assessment failed: {e}")
|
282
309
|
raise
|
283
310
|
|
311
|
+
|
284
312
|
# ============================================================================
|
285
313
|
# CFAT COMMANDS - LAZY LOADED
|
286
314
|
# ============================================================================
|
287
315
|
|
316
|
+
|
288
317
|
@cli.group()
|
289
318
|
def cfat():
|
290
319
|
"""Cloud Foundations Assessment Tool (lazy loaded)"""
|
291
320
|
pass
|
292
321
|
|
322
|
+
|
293
323
|
@cfat.command()
|
294
|
-
@click.option(
|
295
|
-
@click.option(
|
324
|
+
@click.option("--profile", help="AWS profile to use")
|
325
|
+
@click.option("--output-file", type=click.Path(), help="Report output file")
|
296
326
|
@track_performance("cfat_assess")
|
297
327
|
def assess(profile: str, output_file: str):
|
298
328
|
"""Run Cloud Foundations Assessment."""
|
299
329
|
console.print("🏛️ Loading CFAT Assessment...")
|
300
|
-
|
330
|
+
|
301
331
|
# Lazy load components
|
302
332
|
AssessmentRunner = lazy_load_cfat()
|
303
333
|
get_profile_for_operation = lazy_load_profile_utils()
|
304
|
-
|
334
|
+
|
305
335
|
try:
|
306
336
|
# Resolve profile
|
307
337
|
resolved_profile = get_profile_for_operation("management", profile)
|
308
338
|
console.print(f"Using profile: [blue]{resolved_profile}[/blue]")
|
309
|
-
|
339
|
+
|
310
340
|
# Create runner
|
311
341
|
runner = AssessmentRunner()
|
312
|
-
|
313
|
-
result = runner.run_assessment(
|
314
|
-
profile=resolved_profile,
|
315
|
-
output_file=output_file
|
316
|
-
)
|
342
|
+
|
343
|
+
result = runner.run_assessment(profile=resolved_profile, output_file=output_file)
|
317
344
|
console.print("✅ CFAT assessment completed")
|
318
345
|
return result
|
319
346
|
except Exception as e:
|
320
347
|
console.print(f"❌ CFAT assessment failed: {e}")
|
321
348
|
raise
|
322
349
|
|
350
|
+
|
323
351
|
# ============================================================================
|
324
352
|
# OPERATE COMMANDS - LAZY LOADED
|
325
353
|
# ============================================================================
|
326
354
|
|
355
|
+
|
327
356
|
@cli.group()
|
328
357
|
def operate():
|
329
358
|
"""AWS Resource Operations and Automation (lazy loaded)"""
|
330
359
|
pass
|
331
360
|
|
361
|
+
|
332
362
|
@operate.command()
|
333
|
-
@click.option(
|
334
|
-
@click.option(
|
363
|
+
@click.option("--profile", help="AWS profile to use")
|
364
|
+
@click.option("--dry-run", is_flag=True, default=True, help="Dry run mode")
|
335
365
|
@track_performance("operate_list")
|
336
366
|
def list(profile: str, dry_run: bool):
|
337
367
|
"""List AWS resources (placeholder for full operate functionality)."""
|
338
368
|
console.print("⚡ Loading AWS Operations...")
|
339
|
-
|
369
|
+
|
340
370
|
get_profile_for_operation = lazy_load_profile_utils()
|
341
371
|
session = lazy_load_aws_session()
|
342
|
-
|
372
|
+
|
343
373
|
try:
|
344
374
|
resolved_profile = get_profile_for_operation("operational", profile)
|
345
375
|
console.print(f"Using profile: [blue]{resolved_profile}[/blue]")
|
346
|
-
|
376
|
+
|
347
377
|
if dry_run:
|
348
378
|
console.print("🔒 [yellow]Running in dry-run mode[/yellow]")
|
349
|
-
|
379
|
+
|
350
380
|
# Would load operate components here
|
351
381
|
console.print("✅ Operations module ready")
|
352
|
-
|
382
|
+
|
353
383
|
except Exception as e:
|
354
384
|
console.print(f"❌ Operations failed: {e}")
|
355
385
|
raise
|
356
386
|
|
387
|
+
|
357
388
|
if __name__ == "__main__":
|
358
|
-
cli()
|
389
|
+
cli()
|