runbooks 1.1.9__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.
- runbooks/__init__.py +1 -1
- runbooks/__init___optimized.py +2 -1
- runbooks/_platform/__init__.py +1 -1
- runbooks/cfat/cli.py +4 -3
- runbooks/cfat/cloud_foundations_assessment.py +1 -2
- runbooks/cfat/tests/test_cli.py +4 -1
- runbooks/cli/commands/finops.py +68 -19
- runbooks/cli/commands/inventory.py +796 -7
- runbooks/cli/commands/operate.py +65 -4
- runbooks/cloudops/cost_optimizer.py +1 -3
- runbooks/common/cli_decorators.py +6 -4
- runbooks/common/config_loader.py +787 -0
- runbooks/common/config_schema.py +280 -0
- runbooks/common/dry_run_framework.py +14 -2
- runbooks/common/mcp_integration.py +238 -0
- runbooks/finops/ebs_cost_optimizer.py +7 -4
- runbooks/finops/elastic_ip_optimizer.py +7 -4
- runbooks/finops/infrastructure/__init__.py +3 -2
- runbooks/finops/infrastructure/commands.py +7 -4
- runbooks/finops/infrastructure/load_balancer_optimizer.py +7 -4
- runbooks/finops/infrastructure/vpc_endpoint_optimizer.py +7 -4
- runbooks/finops/nat_gateway_optimizer.py +7 -4
- runbooks/finops/tests/run_tests.py +1 -1
- runbooks/inventory/ArgumentsClass.py +2 -1
- runbooks/inventory/README.md +111 -12
- runbooks/inventory/Tests/test_Inventory_Modules.py +27 -10
- runbooks/inventory/Tests/test_cfn_describe_stacks.py +18 -7
- runbooks/inventory/Tests/test_ec2_describe_instances.py +30 -15
- runbooks/inventory/Tests/test_lambda_list_functions.py +17 -3
- runbooks/inventory/Tests/test_org_list_accounts.py +17 -4
- runbooks/inventory/account_class.py +0 -1
- runbooks/inventory/all_my_instances_wrapper.py +4 -8
- runbooks/inventory/aws_organization.png +0 -0
- runbooks/inventory/check_cloudtrail_compliance.py +4 -4
- runbooks/inventory/check_controltower_readiness.py +50 -47
- runbooks/inventory/check_landingzone_readiness.py +35 -31
- runbooks/inventory/cloud_foundations_integration.py +8 -3
- runbooks/inventory/core/collector.py +201 -1
- runbooks/inventory/discovery.md +2 -1
- runbooks/inventory/{draw_org_structure.py → draw_org.py} +55 -9
- runbooks/inventory/drift_detection_cli.py +8 -68
- runbooks/inventory/find_cfn_drift_detection.py +14 -4
- runbooks/inventory/find_cfn_orphaned_stacks.py +7 -5
- runbooks/inventory/find_cfn_stackset_drift.py +5 -5
- runbooks/inventory/find_ec2_security_groups.py +6 -3
- runbooks/inventory/find_landingzone_versions.py +5 -5
- runbooks/inventory/find_vpc_flow_logs.py +5 -5
- runbooks/inventory/inventory.sh +20 -7
- runbooks/inventory/inventory_mcp_cli.py +4 -0
- runbooks/inventory/inventory_modules.py +9 -7
- runbooks/inventory/list_cfn_stacks.py +18 -8
- runbooks/inventory/list_cfn_stackset_operation_results.py +2 -2
- runbooks/inventory/list_cfn_stackset_operations.py +32 -20
- runbooks/inventory/list_cfn_stacksets.py +7 -4
- runbooks/inventory/list_config_recorders_delivery_channels.py +4 -4
- runbooks/inventory/list_ds_directories.py +3 -3
- runbooks/inventory/list_ec2_availability_zones.py +7 -3
- runbooks/inventory/list_ec2_ebs_volumes.py +3 -3
- runbooks/inventory/list_ec2_instances.py +1 -1
- runbooks/inventory/list_ecs_clusters_and_tasks.py +8 -4
- runbooks/inventory/list_elbs_load_balancers.py +7 -3
- runbooks/inventory/list_enis_network_interfaces.py +3 -3
- runbooks/inventory/list_guardduty_detectors.py +9 -5
- runbooks/inventory/list_iam_policies.py +7 -3
- runbooks/inventory/list_iam_roles.py +3 -3
- runbooks/inventory/list_iam_saml_providers.py +8 -4
- runbooks/inventory/list_lambda_functions.py +8 -4
- runbooks/inventory/list_org_accounts.py +306 -276
- runbooks/inventory/list_org_accounts_users.py +45 -9
- runbooks/inventory/list_rds_db_instances.py +4 -4
- runbooks/inventory/list_route53_hosted_zones.py +3 -3
- runbooks/inventory/list_servicecatalog_provisioned_products.py +5 -5
- runbooks/inventory/list_sns_topics.py +4 -4
- runbooks/inventory/list_ssm_parameters.py +6 -3
- runbooks/inventory/list_vpc_subnets.py +8 -4
- runbooks/inventory/list_vpcs.py +15 -4
- runbooks/inventory/mcp_vpc_validator.py +6 -0
- runbooks/inventory/organizations_discovery.py +17 -3
- runbooks/inventory/organizations_utils.py +553 -0
- runbooks/inventory/output_formatters.py +422 -0
- runbooks/inventory/recover_cfn_stack_ids.py +5 -5
- runbooks/inventory/run_on_multi_accounts.py +3 -3
- runbooks/inventory/tag_coverage.py +481 -0
- runbooks/inventory/validation_utils.py +358 -0
- runbooks/inventory/verify_ec2_security_groups.py +18 -5
- runbooks/inventory/vpc_architecture_validator.py +7 -1
- runbooks/inventory/vpc_dependency_analyzer.py +6 -0
- runbooks/main_final.py +2 -2
- runbooks/main_ultra_minimal.py +2 -2
- runbooks/mcp/integration.py +6 -4
- runbooks/remediation/acm_remediation.py +2 -2
- runbooks/remediation/cloudtrail_remediation.py +2 -2
- runbooks/remediation/cognito_remediation.py +2 -2
- runbooks/remediation/dynamodb_remediation.py +2 -2
- runbooks/remediation/ec2_remediation.py +2 -2
- runbooks/remediation/kms_remediation.py +2 -2
- runbooks/remediation/lambda_remediation.py +2 -2
- runbooks/remediation/rds_remediation.py +2 -2
- runbooks/remediation/s3_remediation.py +1 -1
- runbooks/vpc/cloudtrail_audit_integration.py +1 -1
- {runbooks-1.1.9.dist-info → runbooks-1.1.10.dist-info}/METADATA +74 -4
- {runbooks-1.1.9.dist-info → runbooks-1.1.10.dist-info}/RECORD +106 -100
- runbooks/__init__.py.backup +0 -134
- {runbooks-1.1.9.dist-info → runbooks-1.1.10.dist-info}/WHEEL +0 -0
- {runbooks-1.1.9.dist-info → runbooks-1.1.10.dist-info}/entry_points.txt +0 -0
- {runbooks-1.1.9.dist-info → runbooks-1.1.10.dist-info}/licenses/LICENSE +0 -0
- {runbooks-1.1.9.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.
|
64
|
+
__version__ = "1.1.10"
|
65
65
|
|
66
66
|
# Fallback for legacy importlib.metadata usage during transition
|
67
67
|
try:
|
runbooks/__init___optimized.py
CHANGED
@@ -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
|
-
|
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:
|
runbooks/_platform/__init__.py
CHANGED
@@ -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
|
-
|
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
|
58
|
+
# Import and register the assess command from modular commands
|
60
59
|
# This reuses the enhanced assess command with all its features
|
61
|
-
|
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()
|
runbooks/cfat/tests/test_cli.py
CHANGED
@@ -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
|
-
|
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
|
runbooks/cli/commands/finops.py
CHANGED
@@ -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
|
-
|
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-
|
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
|
-
|
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-
|
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-
|
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-
|
193
|
+
runbooks finops dashboard --all-profile MANAGEMENT_PROFILE --export-format pdf
|
174
194
|
"""
|
175
|
-
# Handle multi-account Landing Zone analysis
|
176
|
-
if
|
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",
|
183
|
-
console.print("[cyan]🏢
|
184
|
-
|
185
|
-
|
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 =
|
236
|
+
args.profile = all_profile # Use management profile for AWS Organizations access
|
190
237
|
args.timeframe = timeframe
|
191
238
|
args.services = services
|
192
|
-
|
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 =
|
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]💡
|
254
|
-
resolved_profile =
|
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
|
|