runbooks 1.1.3__py3-none-any.whl → 1.1.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (247) 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/WEIGHT_CONFIG_README.md +1 -1
  8. runbooks/cfat/assessment/compliance.py +8 -8
  9. runbooks/cfat/assessment/runner.py +1 -0
  10. runbooks/cfat/cloud_foundations_assessment.py +227 -239
  11. runbooks/cfat/models.py +6 -2
  12. runbooks/cfat/tests/__init__.py +6 -1
  13. runbooks/cli/__init__.py +13 -0
  14. runbooks/cli/commands/cfat.py +274 -0
  15. runbooks/cli/commands/finops.py +1164 -0
  16. runbooks/cli/commands/inventory.py +379 -0
  17. runbooks/cli/commands/operate.py +239 -0
  18. runbooks/cli/commands/security.py +248 -0
  19. runbooks/cli/commands/validation.py +825 -0
  20. runbooks/cli/commands/vpc.py +310 -0
  21. runbooks/cli/registry.py +107 -0
  22. runbooks/cloudops/__init__.py +23 -30
  23. runbooks/cloudops/base.py +96 -107
  24. runbooks/cloudops/cost_optimizer.py +549 -547
  25. runbooks/cloudops/infrastructure_optimizer.py +5 -4
  26. runbooks/cloudops/interfaces.py +226 -227
  27. runbooks/cloudops/lifecycle_manager.py +5 -4
  28. runbooks/cloudops/mcp_cost_validation.py +252 -235
  29. runbooks/cloudops/models.py +78 -53
  30. runbooks/cloudops/monitoring_automation.py +5 -4
  31. runbooks/cloudops/notebook_framework.py +179 -215
  32. runbooks/cloudops/security_enforcer.py +125 -159
  33. runbooks/common/accuracy_validator.py +11 -0
  34. runbooks/common/aws_pricing.py +349 -326
  35. runbooks/common/aws_pricing_api.py +211 -212
  36. runbooks/common/aws_profile_manager.py +341 -0
  37. runbooks/common/aws_utils.py +75 -80
  38. runbooks/common/business_logic.py +127 -105
  39. runbooks/common/cli_decorators.py +36 -60
  40. runbooks/common/comprehensive_cost_explorer_integration.py +456 -464
  41. runbooks/common/cross_account_manager.py +198 -205
  42. runbooks/common/date_utils.py +27 -39
  43. runbooks/common/decorators.py +235 -0
  44. runbooks/common/dry_run_examples.py +173 -208
  45. runbooks/common/dry_run_framework.py +157 -155
  46. runbooks/common/enhanced_exception_handler.py +15 -4
  47. runbooks/common/enhanced_logging_example.py +50 -64
  48. runbooks/common/enhanced_logging_integration_example.py +65 -37
  49. runbooks/common/env_utils.py +16 -16
  50. runbooks/common/error_handling.py +40 -38
  51. runbooks/common/lazy_loader.py +41 -23
  52. runbooks/common/logging_integration_helper.py +79 -86
  53. runbooks/common/mcp_cost_explorer_integration.py +478 -495
  54. runbooks/common/mcp_integration.py +63 -74
  55. runbooks/common/memory_optimization.py +140 -118
  56. runbooks/common/module_cli_base.py +37 -58
  57. runbooks/common/organizations_client.py +176 -194
  58. runbooks/common/patterns.py +204 -0
  59. runbooks/common/performance_monitoring.py +67 -71
  60. runbooks/common/performance_optimization_engine.py +283 -274
  61. runbooks/common/profile_utils.py +248 -39
  62. runbooks/common/rich_utils.py +643 -92
  63. runbooks/common/sre_performance_suite.py +177 -186
  64. runbooks/enterprise/__init__.py +1 -1
  65. runbooks/enterprise/logging.py +144 -106
  66. runbooks/enterprise/security.py +187 -204
  67. runbooks/enterprise/validation.py +43 -56
  68. runbooks/finops/__init__.py +29 -33
  69. runbooks/finops/account_resolver.py +1 -1
  70. runbooks/finops/advanced_optimization_engine.py +980 -0
  71. runbooks/finops/automation_core.py +268 -231
  72. runbooks/finops/business_case_config.py +184 -179
  73. runbooks/finops/cli.py +660 -139
  74. runbooks/finops/commvault_ec2_analysis.py +157 -164
  75. runbooks/finops/compute_cost_optimizer.py +336 -320
  76. runbooks/finops/config.py +20 -20
  77. runbooks/finops/cost_optimizer.py +488 -622
  78. runbooks/finops/cost_processor.py +332 -214
  79. runbooks/finops/dashboard_runner.py +1006 -172
  80. runbooks/finops/ebs_cost_optimizer.py +991 -657
  81. runbooks/finops/elastic_ip_optimizer.py +317 -257
  82. runbooks/finops/enhanced_mcp_integration.py +340 -0
  83. runbooks/finops/enhanced_progress.py +40 -37
  84. runbooks/finops/enhanced_trend_visualization.py +3 -2
  85. runbooks/finops/enterprise_wrappers.py +230 -292
  86. runbooks/finops/executive_export.py +203 -160
  87. runbooks/finops/helpers.py +130 -288
  88. runbooks/finops/iam_guidance.py +1 -1
  89. runbooks/finops/infrastructure/__init__.py +80 -0
  90. runbooks/finops/infrastructure/commands.py +506 -0
  91. runbooks/finops/infrastructure/load_balancer_optimizer.py +866 -0
  92. runbooks/finops/infrastructure/vpc_endpoint_optimizer.py +832 -0
  93. runbooks/finops/markdown_exporter.py +338 -175
  94. runbooks/finops/mcp_validator.py +1952 -0
  95. runbooks/finops/nat_gateway_optimizer.py +1513 -482
  96. runbooks/finops/network_cost_optimizer.py +657 -587
  97. runbooks/finops/notebook_utils.py +226 -188
  98. runbooks/finops/optimization_engine.py +1136 -0
  99. runbooks/finops/optimizer.py +25 -29
  100. runbooks/finops/rds_snapshot_optimizer.py +367 -411
  101. runbooks/finops/reservation_optimizer.py +427 -363
  102. runbooks/finops/scenario_cli_integration.py +77 -78
  103. runbooks/finops/scenarios.py +1278 -439
  104. runbooks/finops/schemas.py +218 -182
  105. runbooks/finops/snapshot_manager.py +2289 -0
  106. runbooks/finops/tests/test_finops_dashboard.py +3 -3
  107. runbooks/finops/tests/test_reference_images_validation.py +2 -2
  108. runbooks/finops/tests/test_single_account_features.py +17 -17
  109. runbooks/finops/tests/validate_test_suite.py +1 -1
  110. runbooks/finops/types.py +3 -3
  111. runbooks/finops/validation_framework.py +263 -269
  112. runbooks/finops/vpc_cleanup_exporter.py +191 -146
  113. runbooks/finops/vpc_cleanup_optimizer.py +593 -575
  114. runbooks/finops/workspaces_analyzer.py +171 -182
  115. runbooks/hitl/enhanced_workflow_engine.py +1 -1
  116. runbooks/integration/__init__.py +89 -0
  117. runbooks/integration/mcp_integration.py +1920 -0
  118. runbooks/inventory/CLAUDE.md +816 -0
  119. runbooks/inventory/README.md +3 -3
  120. runbooks/inventory/Tests/common_test_data.py +30 -30
  121. runbooks/inventory/__init__.py +2 -2
  122. runbooks/inventory/cloud_foundations_integration.py +144 -149
  123. runbooks/inventory/collectors/aws_comprehensive.py +28 -11
  124. runbooks/inventory/collectors/aws_networking.py +111 -101
  125. runbooks/inventory/collectors/base.py +4 -0
  126. runbooks/inventory/core/collector.py +495 -313
  127. runbooks/inventory/discovery.md +2 -2
  128. runbooks/inventory/drift_detection_cli.py +69 -96
  129. runbooks/inventory/find_ec2_security_groups.py +1 -1
  130. runbooks/inventory/inventory_mcp_cli.py +48 -46
  131. runbooks/inventory/list_rds_snapshots_aggregator.py +192 -208
  132. runbooks/inventory/mcp_inventory_validator.py +549 -465
  133. runbooks/inventory/mcp_vpc_validator.py +359 -442
  134. runbooks/inventory/organizations_discovery.py +56 -52
  135. runbooks/inventory/rich_inventory_display.py +33 -32
  136. runbooks/inventory/unified_validation_engine.py +278 -251
  137. runbooks/inventory/vpc_analyzer.py +733 -696
  138. runbooks/inventory/vpc_architecture_validator.py +293 -348
  139. runbooks/inventory/vpc_dependency_analyzer.py +382 -378
  140. runbooks/inventory/vpc_flow_analyzer.py +3 -3
  141. runbooks/main.py +152 -9147
  142. runbooks/main_final.py +91 -60
  143. runbooks/main_minimal.py +22 -10
  144. runbooks/main_optimized.py +131 -100
  145. runbooks/main_ultra_minimal.py +7 -2
  146. runbooks/mcp/__init__.py +36 -0
  147. runbooks/mcp/integration.py +679 -0
  148. runbooks/metrics/dora_metrics_engine.py +2 -2
  149. runbooks/monitoring/performance_monitor.py +9 -4
  150. runbooks/operate/dynamodb_operations.py +3 -1
  151. runbooks/operate/ec2_operations.py +145 -137
  152. runbooks/operate/iam_operations.py +146 -152
  153. runbooks/operate/mcp_integration.py +1 -1
  154. runbooks/operate/networking_cost_heatmap.py +33 -10
  155. runbooks/operate/privatelink_operations.py +1 -1
  156. runbooks/operate/rds_operations.py +223 -254
  157. runbooks/operate/s3_operations.py +107 -118
  158. runbooks/operate/vpc_endpoints.py +1 -1
  159. runbooks/operate/vpc_operations.py +648 -618
  160. runbooks/remediation/base.py +1 -1
  161. runbooks/remediation/commons.py +10 -7
  162. runbooks/remediation/commvault_ec2_analysis.py +71 -67
  163. runbooks/remediation/ec2_unattached_ebs_volumes.py +1 -0
  164. runbooks/remediation/multi_account.py +24 -21
  165. runbooks/remediation/rds_snapshot_list.py +91 -65
  166. runbooks/remediation/remediation_cli.py +92 -146
  167. runbooks/remediation/universal_account_discovery.py +83 -79
  168. runbooks/remediation/workspaces_list.py +49 -44
  169. runbooks/security/__init__.py +19 -0
  170. runbooks/security/assessment_runner.py +1150 -0
  171. runbooks/security/baseline_checker.py +812 -0
  172. runbooks/security/cloudops_automation_security_validator.py +509 -535
  173. runbooks/security/compliance_automation_engine.py +17 -17
  174. runbooks/security/config/__init__.py +2 -2
  175. runbooks/security/config/compliance_config.py +50 -50
  176. runbooks/security/config_template_generator.py +63 -76
  177. runbooks/security/enterprise_security_framework.py +1 -1
  178. runbooks/security/executive_security_dashboard.py +519 -508
  179. runbooks/security/integration_test_enterprise_security.py +5 -3
  180. runbooks/security/multi_account_security_controls.py +959 -1210
  181. runbooks/security/real_time_security_monitor.py +422 -444
  182. runbooks/security/run_script.py +1 -1
  183. runbooks/security/security_baseline_tester.py +1 -1
  184. runbooks/security/security_cli.py +143 -112
  185. runbooks/security/test_2way_validation.py +439 -0
  186. runbooks/security/two_way_validation_framework.py +852 -0
  187. runbooks/sre/mcp_reliability_engine.py +6 -6
  188. runbooks/sre/production_monitoring_framework.py +167 -177
  189. runbooks/tdd/__init__.py +15 -0
  190. runbooks/tdd/cli.py +1071 -0
  191. runbooks/utils/__init__.py +14 -17
  192. runbooks/utils/logger.py +7 -2
  193. runbooks/utils/version_validator.py +51 -48
  194. runbooks/validation/__init__.py +6 -6
  195. runbooks/validation/cli.py +9 -3
  196. runbooks/validation/comprehensive_2way_validator.py +754 -708
  197. runbooks/validation/mcp_validator.py +906 -228
  198. runbooks/validation/terraform_citations_validator.py +104 -115
  199. runbooks/validation/terraform_drift_detector.py +447 -451
  200. runbooks/vpc/README.md +617 -0
  201. runbooks/vpc/__init__.py +8 -1
  202. runbooks/vpc/analyzer.py +577 -0
  203. runbooks/vpc/cleanup_wrapper.py +476 -413
  204. runbooks/vpc/cli_cloudtrail_commands.py +339 -0
  205. runbooks/vpc/cli_mcp_validation_commands.py +480 -0
  206. runbooks/vpc/cloudtrail_audit_integration.py +717 -0
  207. runbooks/vpc/config.py +92 -97
  208. runbooks/vpc/cost_engine.py +411 -148
  209. runbooks/vpc/cost_explorer_integration.py +553 -0
  210. runbooks/vpc/cross_account_session.py +101 -106
  211. runbooks/vpc/enhanced_mcp_validation.py +917 -0
  212. runbooks/vpc/eni_gate_validator.py +961 -0
  213. runbooks/vpc/heatmap_engine.py +190 -162
  214. runbooks/vpc/mcp_no_eni_validator.py +681 -640
  215. runbooks/vpc/nat_gateway_optimizer.py +358 -0
  216. runbooks/vpc/networking_wrapper.py +15 -8
  217. runbooks/vpc/pdca_remediation_planner.py +528 -0
  218. runbooks/vpc/performance_optimized_analyzer.py +219 -231
  219. runbooks/vpc/runbooks_adapter.py +1167 -241
  220. runbooks/vpc/tdd_red_phase_stubs.py +601 -0
  221. runbooks/vpc/test_data_loader.py +358 -0
  222. runbooks/vpc/tests/conftest.py +314 -4
  223. runbooks/vpc/tests/test_cleanup_framework.py +1022 -0
  224. runbooks/vpc/tests/test_cost_engine.py +0 -2
  225. runbooks/vpc/topology_generator.py +326 -0
  226. runbooks/vpc/unified_scenarios.py +1302 -1129
  227. runbooks/vpc/vpc_cleanup_integration.py +1943 -1115
  228. runbooks-1.1.5.dist-info/METADATA +328 -0
  229. {runbooks-1.1.3.dist-info → runbooks-1.1.5.dist-info}/RECORD +233 -200
  230. runbooks/finops/README.md +0 -414
  231. runbooks/finops/accuracy_cross_validator.py +0 -647
  232. runbooks/finops/business_cases.py +0 -950
  233. runbooks/finops/dashboard_router.py +0 -922
  234. runbooks/finops/ebs_optimizer.py +0 -956
  235. runbooks/finops/embedded_mcp_validator.py +0 -1629
  236. runbooks/finops/enhanced_dashboard_runner.py +0 -527
  237. runbooks/finops/finops_dashboard.py +0 -584
  238. runbooks/finops/finops_scenarios.py +0 -1218
  239. runbooks/finops/legacy_migration.py +0 -730
  240. runbooks/finops/multi_dashboard.py +0 -1519
  241. runbooks/finops/single_dashboard.py +0 -1113
  242. runbooks/finops/unlimited_scenarios.py +0 -393
  243. runbooks-1.1.3.dist-info/METADATA +0 -799
  244. {runbooks-1.1.3.dist-info → runbooks-1.1.5.dist-info}/WHEEL +0 -0
  245. {runbooks-1.1.3.dist-info → runbooks-1.1.5.dist-info}/entry_points.txt +0 -0
  246. {runbooks-1.1.3.dist-info → runbooks-1.1.5.dist-info}/licenses/LICENSE +0 -0
  247. {runbooks-1.1.3.dist-info → runbooks-1.1.5.dist-info}/top_level.txt +0 -0
@@ -22,94 +22,82 @@ def get_current_year() -> int:
22
22
  def get_current_month_period() -> Dict[str, str]:
23
23
  """
24
24
  Generate current month's start and end dates for AWS API calls.
25
-
25
+
26
26
  Returns:
27
27
  Dict with 'Start' and 'End' keys in YYYY-MM-DD format
28
28
  """
29
29
  now = datetime.now()
30
- start_date = now.replace(day=1).strftime('%Y-%m-%d')
31
-
30
+ start_date = now.replace(day=1).strftime("%Y-%m-%d")
31
+
32
32
  # Get last day of current month
33
33
  if now.month == 12:
34
34
  next_month = now.replace(year=now.year + 1, month=1, day=1)
35
35
  else:
36
36
  next_month = now.replace(month=now.month + 1, day=1)
37
-
38
- end_date = (next_month - timedelta(days=1)).strftime('%Y-%m-%d')
39
-
40
- return {
41
- 'Start': start_date,
42
- 'End': end_date
43
- }
37
+
38
+ end_date = (next_month - timedelta(days=1)).strftime("%Y-%m-%d")
39
+
40
+ return {"Start": start_date, "End": end_date}
44
41
 
45
42
 
46
43
  def get_previous_month_period() -> Dict[str, str]:
47
44
  """
48
45
  Generate previous month's start and end dates for AWS API calls.
49
-
46
+
50
47
  Returns:
51
48
  Dict with 'Start' and 'End' keys in YYYY-MM-DD format
52
49
  """
53
50
  now = datetime.now()
54
-
51
+
55
52
  # Get first day of previous month
56
53
  if now.month == 1:
57
54
  prev_month = now.replace(year=now.year - 1, month=12, day=1)
58
55
  else:
59
56
  prev_month = now.replace(month=now.month - 1, day=1)
60
-
61
- start_date = prev_month.strftime('%Y-%m-%d')
62
-
63
- # Get last day of previous month
64
- end_date = (now.replace(day=1) - timedelta(days=1)).strftime('%Y-%m-%d')
65
-
66
- return {
67
- 'Start': start_date,
68
- 'End': end_date
69
- }
57
+
58
+ start_date = prev_month.strftime("%Y-%m-%d")
59
+
60
+ # Get last day of previous month
61
+ end_date = (now.replace(day=1) - timedelta(days=1)).strftime("%Y-%m-%d")
62
+
63
+ return {"Start": start_date, "End": end_date}
70
64
 
71
65
 
72
66
  def get_test_date_period(days_back: int = 30) -> Dict[str, str]:
73
67
  """
74
68
  Generate test date periods for consistent test data.
75
-
69
+
76
70
  Args:
77
71
  days_back: Number of days back from today for start date
78
-
72
+
79
73
  Returns:
80
74
  Dict with 'Start' and 'End' keys in YYYY-MM-DD format
81
75
  """
82
- end_date = datetime.now().strftime('%Y-%m-%d')
83
- start_date = (datetime.now() - timedelta(days=days_back)).strftime('%Y-%m-%d')
84
-
85
- return {
86
- 'Start': start_date,
87
- 'End': end_date
88
- }
76
+ end_date = datetime.now().strftime("%Y-%m-%d")
77
+ start_date = (datetime.now() - timedelta(days=days_back)).strftime("%Y-%m-%d")
78
+
79
+ return {"Start": start_date, "End": end_date}
89
80
 
90
81
 
91
82
  def get_aws_cli_example_period() -> Tuple[str, str]:
92
83
  """
93
84
  Generate example date period for AWS CLI documentation.
94
85
  Uses yesterday and today to ensure valid time range.
95
-
86
+
96
87
  Returns:
97
88
  Tuple of (start_date, end_date) in YYYY-MM-DD format
98
89
  """
99
90
  today = datetime.now()
100
91
  yesterday = today - timedelta(days=1)
101
-
102
- return (
103
- yesterday.strftime('%Y-%m-%d'),
104
- today.strftime('%Y-%m-%d')
105
- )
92
+
93
+ return (yesterday.strftime("%Y-%m-%d"), today.strftime("%Y-%m-%d"))
106
94
 
107
95
 
108
96
  def get_collection_timestamp() -> str:
109
97
  """
110
98
  Generate collection timestamp for test data.
111
-
99
+
112
100
  Returns:
113
101
  ISO format timestamp string
114
102
  """
115
- return datetime.now().isoformat()
103
+ return datetime.now().isoformat()
@@ -0,0 +1,235 @@
1
+ """
2
+ Common CLI Decorators for Modular Commands
3
+
4
+ KISS Principle: Simple, reusable decorators for consistent CLI patterns
5
+ DRY Principle: No duplicated decorator logic across command modules
6
+
7
+ This module provides consistent decorators used across all modular command
8
+ files, enabling the DRY principle while maintaining enterprise standards.
9
+ """
10
+
11
+ import functools
12
+ import time
13
+ from typing import Any, Callable
14
+
15
+ import click
16
+ from rich.console import Console
17
+
18
+ console = Console()
19
+
20
+
21
+ def common_aws_options(f):
22
+ """
23
+ Common AWS options for all commands.
24
+
25
+ Provides consistent AWS configuration options across all command modules:
26
+ - --profile: AWS profile selection
27
+ - --region: AWS region targeting
28
+ - --dry-run: Safety mode for testing
29
+ """
30
+ f = click.option("--profile", default="default", help="AWS profile to use")(f)
31
+ f = click.option("--region", help="AWS region (overrides profile default)")(f)
32
+ f = click.option("--dry-run", is_flag=True, help="Perform a dry run without making changes")(f)
33
+ return f
34
+
35
+
36
+ def common_output_options(f):
37
+ """
38
+ Common output options for commands that generate reports.
39
+
40
+ Provides consistent output formatting options:
41
+ - --format: Output format selection (table, csv, json, markdown, pdf)
42
+ - --output-file: File output destination
43
+ """
44
+ f = click.option(
45
+ "--format",
46
+ "output_format",
47
+ type=click.Choice(["table", "csv", "json", "markdown", "pdf"]),
48
+ default="table",
49
+ help="Output format",
50
+ )(f)
51
+ f = click.option("--output-file", type=click.Path(), help="Output file path")(f)
52
+ return f
53
+
54
+
55
+ def common_filter_options(f):
56
+ """
57
+ Common filtering options for resource discovery commands.
58
+
59
+ Provides consistent filtering capabilities:
60
+ - --tags: Resource tag filtering
61
+ - --accounts: Account ID filtering
62
+ - --regions: Region filtering
63
+ """
64
+ f = click.option("--tags", multiple=True, help="Filter by tags (key=value format)")(f)
65
+ f = click.option("--accounts", multiple=True, help="Filter by account IDs")(f)
66
+ f = click.option("--regions", multiple=True, help="Filter by regions")(f)
67
+ return f
68
+
69
+
70
+ def performance_timing(f):
71
+ """
72
+ Performance timing decorator for measuring command execution time.
73
+
74
+ Automatically tracks and reports command execution time for performance
75
+ monitoring and optimization analysis.
76
+ """
77
+
78
+ @functools.wraps(f)
79
+ def wrapper(*args, **kwargs):
80
+ start_time = time.time()
81
+ try:
82
+ result = f(*args, **kwargs)
83
+ execution_time = time.time() - start_time
84
+
85
+ # Only show timing in debug mode or for slow operations
86
+ if execution_time > 1.0: # Show for operations > 1 second
87
+ console.print(f"[dim]⏱️ Completed in {execution_time:.2f}s[/dim]")
88
+
89
+ return result
90
+ except Exception as e:
91
+ execution_time = time.time() - start_time
92
+ console.print(f"[red]❌ Failed after {execution_time:.2f}s: {e}[/red]")
93
+ raise
94
+
95
+ return wrapper
96
+
97
+
98
+ def error_handler(f):
99
+ """
100
+ Common error handling decorator for consistent error reporting.
101
+
102
+ Provides enterprise-grade error handling with:
103
+ - Rich formatting for better UX
104
+ - Consistent error message structure
105
+ - Debug information when enabled
106
+ """
107
+
108
+ @functools.wraps(f)
109
+ def wrapper(*args, **kwargs):
110
+ try:
111
+ return f(*args, **kwargs)
112
+ except click.ClickException:
113
+ # Re-raise Click exceptions as-is
114
+ raise
115
+ except ImportError as e:
116
+ console.print(f"[red]❌ Module not available: {e}[/red]")
117
+ console.print(f"[yellow]💡 This functionality may require additional dependencies[/yellow]")
118
+ raise click.ClickException("Required module not available")
119
+ except Exception as e:
120
+ console.print(f"[red]❌ Unexpected error: {e}[/red]")
121
+ console.print(f"[yellow]💡 Run with --debug for detailed error information[/yellow]")
122
+ raise click.ClickException(str(e))
123
+
124
+ return wrapper
125
+
126
+
127
+ def require_aws_profile(f):
128
+ """
129
+ Decorator to ensure AWS profile is properly configured.
130
+
131
+ Validates that the AWS profile exists and is accessible before
132
+ executing commands that require AWS API access.
133
+ """
134
+
135
+ @functools.wraps(f)
136
+ def wrapper(*args, **kwargs):
137
+ # Get profile from context or kwargs
138
+ ctx = click.get_current_context()
139
+ profile = ctx.obj.get("profile", "default")
140
+
141
+ try:
142
+ import boto3
143
+
144
+ # Test profile access
145
+ session = boto3.Session(profile_name=profile)
146
+ session.get_credentials()
147
+
148
+ return f(*args, **kwargs)
149
+ except Exception as e:
150
+ console.print(f"[red]❌ AWS profile '{profile}' not accessible: {e}[/red]")
151
+ console.print(f"[yellow]💡 Run 'aws configure list-profiles' to see available profiles[/yellow]")
152
+ raise click.ClickException(f"AWS profile '{profile}' not accessible")
153
+
154
+ return wrapper
155
+
156
+
157
+ def enterprise_audit_trail(f):
158
+ """
159
+ Enterprise audit trail decorator for compliance and governance.
160
+
161
+ Automatically logs command execution for audit purposes with:
162
+ - Command name and parameters
163
+ - User context and timestamp
164
+ - Execution results and duration
165
+ """
166
+
167
+ @functools.wraps(f)
168
+ def wrapper(*args, **kwargs):
169
+ ctx = click.get_current_context()
170
+
171
+ # Log command execution start
172
+ audit_data = {
173
+ "command": ctx.command.name,
174
+ "profile": ctx.obj.get("profile", "default"),
175
+ "region": ctx.obj.get("region", "default"),
176
+ "dry_run": ctx.obj.get("dry_run", False),
177
+ "timestamp": time.time(),
178
+ }
179
+
180
+ try:
181
+ result = f(*args, **kwargs)
182
+ audit_data["status"] = "success"
183
+ audit_data["duration"] = time.time() - audit_data["timestamp"]
184
+
185
+ # Log successful execution
186
+ if ctx.obj.get("debug"):
187
+ console.print(f"[dim]📋 Audit: {audit_data}[/dim]")
188
+
189
+ return result
190
+ except Exception as e:
191
+ audit_data["status"] = "error"
192
+ audit_data["error"] = str(e)
193
+ audit_data["duration"] = time.time() - audit_data["timestamp"]
194
+
195
+ # Log failed execution
196
+ if ctx.obj.get("debug"):
197
+ console.print(f"[dim]📋 Audit: {audit_data}[/dim]")
198
+
199
+ raise
200
+
201
+ return wrapper
202
+
203
+
204
+ def rich_progress(description: str = "Processing"):
205
+ """
206
+ Rich progress indicator decorator for long-running operations.
207
+
208
+ Args:
209
+ description: Description text for the progress indicator
210
+
211
+ Automatically shows a progress spinner for operations that take time,
212
+ improving user experience for long-running commands.
213
+ """
214
+
215
+ def decorator(f):
216
+ @functools.wraps(f)
217
+ def wrapper(*args, **kwargs):
218
+ from rich.progress import Progress, SpinnerColumn, TextColumn
219
+
220
+ with Progress(
221
+ SpinnerColumn(), TextColumn("[progress.description]{task.description}"), console=console
222
+ ) as progress:
223
+ task = progress.add_task(description, total=None)
224
+
225
+ try:
226
+ result = f(*args, **kwargs)
227
+ progress.update(task, description=f"✅ {description} completed")
228
+ return result
229
+ except Exception as e:
230
+ progress.update(task, description=f"❌ {description} failed")
231
+ raise
232
+
233
+ return wrapper
234
+
235
+ return decorator