runbooks 1.1.7__py3-none-any.whl → 1.1.10__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 (113) hide show
  1. runbooks/__init__.py +1 -1
  2. runbooks/__init___optimized.py +2 -1
  3. runbooks/_platform/__init__.py +1 -1
  4. runbooks/cfat/cli.py +4 -3
  5. runbooks/cfat/cloud_foundations_assessment.py +1 -2
  6. runbooks/cfat/tests/test_cli.py +4 -1
  7. runbooks/cli/commands/finops.py +68 -19
  8. runbooks/cli/commands/inventory.py +838 -14
  9. runbooks/cli/commands/operate.py +65 -4
  10. runbooks/cli/commands/vpc.py +1 -1
  11. runbooks/cloudops/cost_optimizer.py +1 -3
  12. runbooks/common/cli_decorators.py +6 -4
  13. runbooks/common/config_loader.py +787 -0
  14. runbooks/common/config_schema.py +280 -0
  15. runbooks/common/dry_run_framework.py +14 -2
  16. runbooks/common/mcp_integration.py +238 -0
  17. runbooks/finops/ebs_cost_optimizer.py +7 -4
  18. runbooks/finops/elastic_ip_optimizer.py +7 -4
  19. runbooks/finops/infrastructure/__init__.py +3 -2
  20. runbooks/finops/infrastructure/commands.py +7 -4
  21. runbooks/finops/infrastructure/load_balancer_optimizer.py +7 -4
  22. runbooks/finops/infrastructure/vpc_endpoint_optimizer.py +7 -4
  23. runbooks/finops/nat_gateway_optimizer.py +7 -4
  24. runbooks/finops/tests/run_tests.py +1 -1
  25. runbooks/inventory/ArgumentsClass.py +2 -1
  26. runbooks/inventory/CLAUDE.md +41 -0
  27. runbooks/inventory/README.md +210 -2
  28. runbooks/inventory/Tests/test_Inventory_Modules.py +27 -10
  29. runbooks/inventory/Tests/test_cfn_describe_stacks.py +18 -7
  30. runbooks/inventory/Tests/test_ec2_describe_instances.py +30 -15
  31. runbooks/inventory/Tests/test_lambda_list_functions.py +17 -3
  32. runbooks/inventory/Tests/test_org_list_accounts.py +17 -4
  33. runbooks/inventory/account_class.py +0 -1
  34. runbooks/inventory/all_my_instances_wrapper.py +4 -8
  35. runbooks/inventory/aws_organization.png +0 -0
  36. runbooks/inventory/check_cloudtrail_compliance.py +4 -4
  37. runbooks/inventory/check_controltower_readiness.py +50 -47
  38. runbooks/inventory/check_landingzone_readiness.py +35 -31
  39. runbooks/inventory/cloud_foundations_integration.py +8 -3
  40. runbooks/inventory/collectors/aws_compute.py +59 -11
  41. runbooks/inventory/collectors/aws_management.py +39 -5
  42. runbooks/inventory/core/collector.py +1655 -159
  43. runbooks/inventory/core/concurrent_paginator.py +511 -0
  44. runbooks/inventory/discovery.md +15 -6
  45. runbooks/inventory/{draw_org_structure.py → draw_org.py} +55 -9
  46. runbooks/inventory/drift_detection_cli.py +8 -68
  47. runbooks/inventory/find_cfn_drift_detection.py +14 -4
  48. runbooks/inventory/find_cfn_orphaned_stacks.py +7 -5
  49. runbooks/inventory/find_cfn_stackset_drift.py +5 -5
  50. runbooks/inventory/find_ec2_security_groups.py +6 -3
  51. runbooks/inventory/find_landingzone_versions.py +5 -5
  52. runbooks/inventory/find_vpc_flow_logs.py +5 -5
  53. runbooks/inventory/inventory.sh +20 -7
  54. runbooks/inventory/inventory_mcp_cli.py +4 -0
  55. runbooks/inventory/inventory_modules.py +9 -7
  56. runbooks/inventory/list_cfn_stacks.py +18 -8
  57. runbooks/inventory/list_cfn_stackset_operation_results.py +2 -2
  58. runbooks/inventory/list_cfn_stackset_operations.py +32 -20
  59. runbooks/inventory/list_cfn_stacksets.py +7 -4
  60. runbooks/inventory/list_config_recorders_delivery_channels.py +4 -4
  61. runbooks/inventory/list_ds_directories.py +3 -3
  62. runbooks/inventory/list_ec2_availability_zones.py +7 -3
  63. runbooks/inventory/list_ec2_ebs_volumes.py +3 -3
  64. runbooks/inventory/list_ec2_instances.py +1 -1
  65. runbooks/inventory/list_ecs_clusters_and_tasks.py +8 -4
  66. runbooks/inventory/list_elbs_load_balancers.py +7 -3
  67. runbooks/inventory/list_enis_network_interfaces.py +3 -3
  68. runbooks/inventory/list_guardduty_detectors.py +9 -5
  69. runbooks/inventory/list_iam_policies.py +7 -3
  70. runbooks/inventory/list_iam_roles.py +3 -3
  71. runbooks/inventory/list_iam_saml_providers.py +8 -4
  72. runbooks/inventory/list_lambda_functions.py +8 -4
  73. runbooks/inventory/list_org_accounts.py +306 -276
  74. runbooks/inventory/list_org_accounts_users.py +45 -9
  75. runbooks/inventory/list_rds_db_instances.py +4 -4
  76. runbooks/inventory/list_route53_hosted_zones.py +3 -3
  77. runbooks/inventory/list_servicecatalog_provisioned_products.py +5 -5
  78. runbooks/inventory/list_sns_topics.py +4 -4
  79. runbooks/inventory/list_ssm_parameters.py +6 -3
  80. runbooks/inventory/list_vpc_subnets.py +8 -4
  81. runbooks/inventory/list_vpcs.py +15 -4
  82. runbooks/inventory/mcp_inventory_validator.py +771 -134
  83. runbooks/inventory/mcp_vpc_validator.py +6 -0
  84. runbooks/inventory/organizations_discovery.py +17 -3
  85. runbooks/inventory/organizations_utils.py +553 -0
  86. runbooks/inventory/output_formatters.py +422 -0
  87. runbooks/inventory/recover_cfn_stack_ids.py +5 -5
  88. runbooks/inventory/run_on_multi_accounts.py +3 -3
  89. runbooks/inventory/tag_coverage.py +481 -0
  90. runbooks/inventory/validation_utils.py +358 -0
  91. runbooks/inventory/verify_ec2_security_groups.py +18 -5
  92. runbooks/inventory/vpc_architecture_validator.py +7 -1
  93. runbooks/inventory/vpc_dependency_analyzer.py +6 -0
  94. runbooks/main_final.py +2 -2
  95. runbooks/main_ultra_minimal.py +2 -2
  96. runbooks/mcp/integration.py +6 -4
  97. runbooks/remediation/acm_remediation.py +2 -2
  98. runbooks/remediation/cloudtrail_remediation.py +2 -2
  99. runbooks/remediation/cognito_remediation.py +2 -2
  100. runbooks/remediation/dynamodb_remediation.py +2 -2
  101. runbooks/remediation/ec2_remediation.py +2 -2
  102. runbooks/remediation/kms_remediation.py +2 -2
  103. runbooks/remediation/lambda_remediation.py +2 -2
  104. runbooks/remediation/rds_remediation.py +2 -2
  105. runbooks/remediation/s3_remediation.py +1 -1
  106. runbooks/vpc/cloudtrail_audit_integration.py +1 -1
  107. {runbooks-1.1.7.dist-info → runbooks-1.1.10.dist-info}/METADATA +74 -4
  108. {runbooks-1.1.7.dist-info → runbooks-1.1.10.dist-info}/RECORD +112 -105
  109. runbooks/__init__.py.backup +0 -134
  110. {runbooks-1.1.7.dist-info → runbooks-1.1.10.dist-info}/WHEEL +0 -0
  111. {runbooks-1.1.7.dist-info → runbooks-1.1.10.dist-info}/entry_points.txt +0 -0
  112. {runbooks-1.1.7.dist-info → runbooks-1.1.10.dist-info}/licenses/LICENSE +0 -0
  113. {runbooks-1.1.7.dist-info → runbooks-1.1.10.dist-info}/top_level.txt +0 -0
runbooks/__init__.py CHANGED
@@ -61,7 +61,7 @@ s3_ops = S3Operations()
61
61
 
62
62
  # Centralized Version Management - Single Source of Truth
63
63
  # All modules MUST import __version__ from this location
64
- __version__ = "1.1.7"
64
+ __version__ = "1.1.10"
65
65
 
66
66
  # Fallback for legacy importlib.metadata usage during transition
67
67
  try:
@@ -10,7 +10,8 @@ This should reduce startup time from 5.6s to <0.5s for basic operations.
10
10
  """
11
11
 
12
12
  # Centralized Version Management - Single Source of Truth
13
- __version__ = "1.0.0"
13
+ # This file is optimized variant - must sync with main __init__.py
14
+ __version__ = "1.1.9"
14
15
 
15
16
  # Fallback for legacy importlib.metadata usage during transition
16
17
  try:
@@ -6,7 +6,7 @@ and the FinOps notebook interfaces, enabling business-friendly access
6
6
  to technical cost optimization capabilities.
7
7
  """
8
8
 
9
- __version__ = "1.0.0"
9
+ from runbooks import __version__
10
10
 
11
11
  from .core.runbooks_wrapper import RunbooksWrapper
12
12
  from .finops.unit_economics import UnitEconomicsCalculator
runbooks/cfat/cli.py CHANGED
@@ -14,7 +14,6 @@ import click
14
14
  from loguru import logger
15
15
 
16
16
  from runbooks.cfat import __version__ as cfat_version
17
- from runbooks.main import assess as main_assess
18
17
 
19
18
 
20
19
  @click.group(invoke_without_command=True)
@@ -56,9 +55,11 @@ def main(ctx, debug, profile, region):
56
55
  click.echo(ctx.get_help())
57
56
 
58
57
 
59
- # Import and register the assess command from main CLI
58
+ # Import and register the assess command from modular commands
60
59
  # This reuses the enhanced assess command with all its features
61
- main.add_command(main_assess, name="assess")
60
+ from runbooks.cli.commands.cfat import create_cfat_group
61
+ cfat_group = create_cfat_group()
62
+ main.add_command(cfat_group.commands['assess'], name="assess")
62
63
 
63
64
 
64
65
  @main.command()
@@ -41,8 +41,7 @@ from runbooks.common.rich_utils import (
41
41
  create_panel,
42
42
  )
43
43
  from runbooks.common.profile_utils import get_profile_for_operation
44
-
45
- __version__ = "1.0.0"
44
+ from runbooks import __version__
46
45
 
47
46
 
48
47
  @dataclass
@@ -14,7 +14,10 @@ import pytest
14
14
  from click.testing import CliRunner
15
15
 
16
16
  from runbooks.cfat.tests import create_sample_assessment_report
17
- from runbooks.main import assess, cfat, main
17
+ # Updated import for slim main.py architecture (DRYCommandRegistry pattern)
18
+ # Old: from runbooks.main import assess, cfat, main
19
+ # New: Import main CLI entry point only - commands are dynamically registered
20
+ from runbooks.main import main
18
21
 
19
22
 
20
23
  @pytest.mark.cli
@@ -96,13 +96,33 @@ def create_finops_group():
96
96
  "accounts": accounts
97
97
  })
98
98
 
99
+ # Auto-execute dashboard when no subcommand provided (eliminates "only logs" pattern)
99
100
  if ctx.invoked_subcommand is None:
100
- click.echo(ctx.get_help())
101
+ # Invoke dashboard with default parameters
102
+ ctx.invoke(dashboard,
103
+ profile=profile,
104
+ all_profiles=all_profiles,
105
+ timeframe='monthly',
106
+ services=None,
107
+ accounts=None,
108
+ validate=False,
109
+ validate_mcp=False,
110
+ mcp_validate=False,
111
+ csv=False,
112
+ markdown=False,
113
+ pdf=False,
114
+ json=False,
115
+ export_format=None,
116
+ unblended=False,
117
+ amortized=False,
118
+ dual_metrics=False,
119
+ dry_run=dry_run)
101
120
 
102
121
  @finops.command()
103
122
  @click.option("--profile", help="AWS profile to use for authentication")
104
123
  @click.option(
105
- "--all-profiles", help="Enable multi-account Landing Zone analysis using specified management profile"
124
+ "--all-profile", type=str, default=None,
125
+ help="Management profile for Organizations API auto-discovery (MANAGEMENT_PROFILE, BILLING_PROFILE, or CENTRALISED_OPS_PROFILE)"
106
126
  )
107
127
  @click.option(
108
128
  "--timeframe",
@@ -132,7 +152,7 @@ def create_finops_group():
132
152
  def dashboard(
133
153
  ctx,
134
154
  profile,
135
- all_profiles,
155
+ all_profile,
136
156
  timeframe,
137
157
  services,
138
158
  accounts,
@@ -163,33 +183,61 @@ def create_finops_group():
163
183
  # Single account analysis
164
184
  runbooks finops dashboard --profile BILLING_PROFILE --timeframe monthly --validate
165
185
 
166
- # Multi-account Landing Zone analysis
167
- runbooks finops dashboard --all-profiles MANAGEMENT_PROFILE --mcp-validate
186
+ # Multi-account Landing Zone analysis (Organizations auto-discovery)
187
+ runbooks finops dashboard --all-profile MANAGEMENT_PROFILE --mcp-validate
168
188
 
169
- # Service-specific analysis across all accounts
170
- runbooks finops dashboard --all-profiles MANAGEMENT_PROFILE --services ec2,s3
189
+ # Service-specific analysis across all organization accounts
190
+ runbooks finops dashboard --all-profile MANAGEMENT_PROFILE --services ec2,s3
171
191
 
172
192
  # Export multi-account analysis
173
- runbooks finops dashboard --all-profiles MANAGEMENT_PROFILE --export-format pdf
193
+ runbooks finops dashboard --all-profile MANAGEMENT_PROFILE --export-format pdf
174
194
  """
175
- # Handle multi-account Landing Zone analysis
176
- if all_profiles:
195
+ # Handle multi-account Landing Zone analysis with Organizations API discovery
196
+ if all_profile:
177
197
  try:
178
198
  from runbooks.finops.dashboard_runner import MultiAccountDashboard, DashboardRouter
179
199
  from runbooks.common.rich_utils import print_header, print_success, print_error, print_info
200
+ from runbooks.inventory.inventory_modules import get_org_accounts_from_profiles, get_profiles
180
201
  import argparse
181
202
 
182
- print_header("Multi-Account Landing Zone Dashboard", all_profiles)
183
- console.print("[cyan]🏢 Activating enterprise multi-account consolidated billing analysis[/cyan]")
184
- console.print(f"[dim]Management Profile: {all_profiles}[/dim]")
185
- console.print(f"[dim]Analysis Scope: Organization-wide with Landing Zone support[/dim]\n")
203
+ print_header("Multi-Account Landing Zone Dashboard", all_profile)
204
+ console.print("[cyan]🏢 Discovering AWS Organization accounts via Organizations API...[/cyan]")
205
+
206
+ # CORRECTED: Use management profile TEXT parameter for Organizations API access
207
+ try:
208
+ # Use management profile specified by user (MANAGEMENT_PROFILE, BILLING_PROFILE, or CENTRALISED_OPS_PROFILE)
209
+ mgmt_profile_list = get_profiles(fprofiles=[all_profile])
210
+ console.print(f"[dim]Querying Organizations API with profile: {all_profile}[/dim]")
211
+
212
+ org_accounts = get_org_accounts_from_profiles(mgmt_profile_list)
213
+
214
+ # Extract account IDs from discovered organization accounts
215
+ discovered_account_ids = []
216
+ for acct in org_accounts:
217
+ if acct.get("Success") and acct.get("RootAcct") and acct.get("aws_acct"):
218
+ # Root account found - extract all child accounts
219
+ for child in acct["aws_acct"].ChildAccounts:
220
+ discovered_account_ids.append(child["AccountId"])
221
+
222
+ if discovered_account_ids:
223
+ console.print(f"[green]✅ Discovered {len(discovered_account_ids)} organization accounts[/green]")
224
+ console.print(f"[dim]Analysis Scope: Organization-wide with Landing Zone support[/dim]\n")
225
+ else:
226
+ console.print(f"[yellow]⚠️ No organization accounts discovered - using single account mode[/yellow]")
227
+ console.print(f"[dim]Tip: Ensure {profile} has AWS Organizations permissions[/dim]\n")
228
+
229
+ except Exception as org_error:
230
+ console.print(f"[yellow]⚠️ Organizations discovery failed: {str(org_error)}[/yellow]")
231
+ console.print(f"[dim]Falling back to single account mode[/dim]\n")
232
+ discovered_account_ids = [] # Empty list for fallback
186
233
 
187
234
  # Create mock args object for multi-dashboard compatibility
188
235
  args = argparse.Namespace()
189
- args.profile = all_profiles
236
+ args.profile = all_profile # Use management profile for AWS Organizations access
190
237
  args.timeframe = timeframe
191
238
  args.services = services
192
- args.accounts = accounts
239
+ # PHASE 2 ENHANCEMENT: Use Organizations-discovered accounts if available
240
+ args.accounts = tuple(discovered_account_ids) if discovered_account_ids else accounts
193
241
  args.validate = validate or mcp_validate
194
242
  # CRITICAL FIX: Handle multiple export format flags
195
243
  export_formats = []
@@ -223,6 +271,7 @@ def create_finops_group():
223
271
  args.top_accounts = 50 # Show many accounts for enterprise view
224
272
  args.services_per_account = 3
225
273
  args.time_range = None
274
+ args.audit = False # Not audit mode
226
275
  args.tag = None
227
276
  args.regions = None
228
277
 
@@ -247,11 +296,11 @@ def create_finops_group():
247
296
  console.print(f"[red]❌ Multi-account dashboard not available: {e}[/red]")
248
297
  console.print("[yellow]💡 Falling back to single-account mode with specified profile[/yellow]")
249
298
  # Fallback to single account with the specified profile
250
- resolved_profile = all_profiles
299
+ resolved_profile = all_profile
251
300
  except Exception as e:
252
301
  console.print(f"[red]❌ Multi-account analysis failed: {e}[/red]")
253
- console.print("[yellow]💡 Falling back to single-account mode[/yellow]")
254
- resolved_profile = all_profiles
302
+ console.print("[yellow]💡 Fallingback to single-account mode[/yellow]")
303
+ resolved_profile = all_profile
255
304
  else:
256
305
  resolved_profile = profile or ctx.obj.get("profile", "default")
257
306