runbooks 1.0.0__py3-none-any.whl → 1.0.1__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/cfat/WEIGHT_CONFIG_README.md +368 -0
- runbooks/cfat/app.ts +27 -19
- runbooks/cfat/assessment/runner.py +6 -5
- runbooks/cfat/tests/test_weight_configuration.ts +449 -0
- runbooks/cfat/weight_config.ts +574 -0
- runbooks/common/__init__.py +26 -9
- runbooks/common/aws_pricing.py +1070 -105
- runbooks/common/date_utils.py +115 -0
- runbooks/common/enhanced_exception_handler.py +10 -7
- runbooks/common/mcp_cost_explorer_integration.py +5 -4
- runbooks/common/profile_utils.py +76 -115
- runbooks/common/rich_utils.py +3 -3
- runbooks/finops/dashboard_runner.py +47 -28
- runbooks/finops/ebs_optimizer.py +56 -9
- runbooks/finops/enhanced_trend_visualization.py +7 -2
- runbooks/finops/finops_dashboard.py +6 -5
- runbooks/finops/iam_guidance.py +6 -1
- runbooks/finops/nat_gateway_optimizer.py +46 -27
- runbooks/finops/tests/test_integration.py +3 -1
- runbooks/finops/vpc_cleanup_optimizer.py +22 -29
- runbooks/inventory/core/collector.py +51 -28
- runbooks/inventory/discovery.md +197 -247
- runbooks/inventory/inventory_modules.py +2 -2
- runbooks/inventory/list_ec2_instances.py +3 -3
- runbooks/inventory/organizations_discovery.py +13 -8
- runbooks/inventory/unified_validation_engine.py +2 -15
- runbooks/main.py +74 -32
- runbooks/operate/base.py +9 -6
- runbooks/operate/deployment_framework.py +5 -4
- runbooks/operate/deployment_validator.py +6 -5
- runbooks/operate/mcp_integration.py +6 -5
- runbooks/operate/networking_cost_heatmap.py +17 -13
- runbooks/operate/vpc_operations.py +52 -12
- runbooks/remediation/base.py +3 -1
- runbooks/remediation/commons.py +5 -5
- runbooks/remediation/commvault_ec2_analysis.py +66 -18
- runbooks/remediation/config/accounts_example.json +31 -0
- runbooks/remediation/multi_account.py +120 -7
- runbooks/remediation/remediation_cli.py +710 -0
- runbooks/remediation/universal_account_discovery.py +377 -0
- runbooks/security/compliance_automation_engine.py +99 -20
- runbooks/security/config/__init__.py +24 -0
- runbooks/security/config/compliance_config.py +255 -0
- runbooks/security/config/compliance_weights_example.json +22 -0
- runbooks/security/config_template_generator.py +500 -0
- runbooks/security/security_cli.py +377 -0
- runbooks/validation/cli.py +8 -7
- runbooks/validation/comprehensive_2way_validator.py +26 -15
- runbooks/validation/mcp_validator.py +62 -8
- runbooks/vpc/config.py +32 -7
- runbooks/vpc/cross_account_session.py +5 -1
- runbooks/vpc/heatmap_engine.py +21 -14
- runbooks/vpc/mcp_no_eni_validator.py +115 -36
- runbooks/vpc/runbooks_adapter.py +33 -12
- runbooks/vpc/tests/conftest.py +4 -2
- runbooks/vpc/tests/test_cost_engine.py +3 -1
- {runbooks-1.0.0.dist-info → runbooks-1.0.1.dist-info}/METADATA +1 -1
- {runbooks-1.0.0.dist-info → runbooks-1.0.1.dist-info}/RECORD +63 -65
- runbooks/finops/runbooks.inventory.organizations_discovery.log +0 -0
- runbooks/finops/runbooks.security.report_generator.log +0 -0
- runbooks/finops/runbooks.security.run_script.log +0 -0
- runbooks/finops/runbooks.security.security_export.log +0 -0
- runbooks/finops/tests/results_test_finops_dashboard.xml +0 -1
- runbooks/inventory/artifacts/scale-optimize-status.txt +0 -12
- runbooks/inventory/runbooks.inventory.organizations_discovery.log +0 -0
- runbooks/inventory/runbooks.security.report_generator.log +0 -0
- runbooks/inventory/runbooks.security.run_script.log +0 -0
- runbooks/inventory/runbooks.security.security_export.log +0 -0
- runbooks/vpc/runbooks.inventory.organizations_discovery.log +0 -0
- runbooks/vpc/runbooks.security.report_generator.log +0 -0
- runbooks/vpc/runbooks.security.run_script.log +0 -0
- runbooks/vpc/runbooks.security.security_export.log +0 -0
- {runbooks-1.0.0.dist-info → runbooks-1.0.1.dist-info}/WHEEL +0 -0
- {runbooks-1.0.0.dist-info → runbooks-1.0.1.dist-info}/entry_points.txt +0 -0
- {runbooks-1.0.0.dist-info → runbooks-1.0.1.dist-info}/licenses/LICENSE +0 -0
- {runbooks-1.0.0.dist-info → runbooks-1.0.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,255 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
"""
|
3
|
+
Universal Compliance Configuration Management
|
4
|
+
============================================
|
5
|
+
|
6
|
+
This module provides enterprise-grade compliance configuration management
|
7
|
+
that eliminates hardcoded values and supports dynamic configuration across
|
8
|
+
all compliance frameworks.
|
9
|
+
|
10
|
+
Features:
|
11
|
+
- Environment variable configuration
|
12
|
+
- Configuration file support
|
13
|
+
- Framework-specific defaults
|
14
|
+
- Universal profile compatibility
|
15
|
+
- No hardcoded compliance weights or thresholds
|
16
|
+
|
17
|
+
Author: DevOps Security Engineer (Claude Code Enterprise Team)
|
18
|
+
Version: 1.0.0 - Universal Compliance Configuration
|
19
|
+
"""
|
20
|
+
|
21
|
+
import json
|
22
|
+
import os
|
23
|
+
from dataclasses import dataclass, field
|
24
|
+
from typing import Dict, Optional
|
25
|
+
|
26
|
+
from runbooks.common.rich_utils import console
|
27
|
+
|
28
|
+
|
29
|
+
@dataclass
|
30
|
+
class ComplianceConfiguration:
|
31
|
+
"""Universal compliance configuration container."""
|
32
|
+
|
33
|
+
control_weights: Dict[str, float] = field(default_factory=dict)
|
34
|
+
framework_thresholds: Dict[str, float] = field(default_factory=dict)
|
35
|
+
assessment_frequencies: Dict[str, str] = field(default_factory=dict)
|
36
|
+
remediation_priorities: Dict[str, int] = field(default_factory=dict)
|
37
|
+
|
38
|
+
|
39
|
+
class UniversalComplianceConfig:
|
40
|
+
"""
|
41
|
+
Universal compliance configuration manager that works with ANY AWS setup.
|
42
|
+
|
43
|
+
Configuration Priority Order:
|
44
|
+
1. Environment variables (highest priority)
|
45
|
+
2. Configuration file (COMPLIANCE_CONFIG_PATH)
|
46
|
+
3. Framework defaults (fallback)
|
47
|
+
|
48
|
+
No hardcoded values - fully configurable for any enterprise environment.
|
49
|
+
"""
|
50
|
+
|
51
|
+
def __init__(self, config_path: Optional[str] = None):
|
52
|
+
"""Initialize universal compliance configuration."""
|
53
|
+
self.config_path = config_path or os.getenv("COMPLIANCE_CONFIG_PATH")
|
54
|
+
self.config = self._load_configuration()
|
55
|
+
|
56
|
+
def _load_configuration(self) -> ComplianceConfiguration:
|
57
|
+
"""Load compliance configuration from all sources."""
|
58
|
+
config = ComplianceConfiguration()
|
59
|
+
|
60
|
+
# Load from configuration file if available
|
61
|
+
if self.config_path and os.path.exists(self.config_path):
|
62
|
+
try:
|
63
|
+
with open(self.config_path, 'r') as f:
|
64
|
+
file_config = json.load(f)
|
65
|
+
|
66
|
+
config.control_weights.update(file_config.get("control_weights", {}))
|
67
|
+
config.framework_thresholds.update(file_config.get("framework_thresholds", {}))
|
68
|
+
config.assessment_frequencies.update(file_config.get("assessment_frequencies", {}))
|
69
|
+
config.remediation_priorities.update(file_config.get("remediation_priorities", {}))
|
70
|
+
|
71
|
+
console.log(f"[green]Loaded compliance configuration from: {self.config_path}[/]")
|
72
|
+
|
73
|
+
except Exception as e:
|
74
|
+
console.log(f"[yellow]Warning: Failed to load compliance config from {self.config_path}: {e}[/]")
|
75
|
+
|
76
|
+
# Override with environment variables (highest priority)
|
77
|
+
self._load_environment_overrides(config)
|
78
|
+
|
79
|
+
return config
|
80
|
+
|
81
|
+
def _load_environment_overrides(self, config: ComplianceConfiguration) -> None:
|
82
|
+
"""Load configuration overrides from environment variables."""
|
83
|
+
|
84
|
+
# Load control weights from environment
|
85
|
+
for env_var in os.environ:
|
86
|
+
if env_var.startswith("COMPLIANCE_WEIGHT_"):
|
87
|
+
control_id = env_var.replace("COMPLIANCE_WEIGHT_", "").replace("_", "-").lower()
|
88
|
+
try:
|
89
|
+
weight = float(os.environ[env_var])
|
90
|
+
config.control_weights[control_id] = weight
|
91
|
+
console.log(f"[dim cyan]Environment override: {control_id} weight = {weight}[/]")
|
92
|
+
except ValueError:
|
93
|
+
console.log(f"[yellow]Warning: Invalid weight in {env_var}: {os.environ[env_var]}[/]")
|
94
|
+
|
95
|
+
# Load framework thresholds from environment
|
96
|
+
for env_var in os.environ:
|
97
|
+
if env_var.startswith("COMPLIANCE_THRESHOLD_"):
|
98
|
+
framework = env_var.replace("COMPLIANCE_THRESHOLD_", "").lower().replace("_", "-")
|
99
|
+
try:
|
100
|
+
threshold = float(os.environ[env_var])
|
101
|
+
config.framework_thresholds[framework] = threshold
|
102
|
+
console.log(f"[dim cyan]Environment override: {framework} threshold = {threshold}[/]")
|
103
|
+
except ValueError:
|
104
|
+
console.log(f"[yellow]Warning: Invalid threshold in {env_var}: {os.environ[env_var]}[/]")
|
105
|
+
|
106
|
+
def get_control_weight(self, control_id: str, framework_default: float = 1.0) -> float:
|
107
|
+
"""
|
108
|
+
Get compliance weight for control with universal fallback.
|
109
|
+
|
110
|
+
Args:
|
111
|
+
control_id: Control identifier (e.g., "SEC-1", "CC6.1")
|
112
|
+
framework_default: Framework-specific default weight
|
113
|
+
|
114
|
+
Returns:
|
115
|
+
float: Compliance weight for the control
|
116
|
+
"""
|
117
|
+
# Normalize control ID for lookup
|
118
|
+
normalized_id = control_id.lower().replace(".", "-")
|
119
|
+
|
120
|
+
# Check configuration sources in priority order
|
121
|
+
if normalized_id in self.config.control_weights:
|
122
|
+
return self.config.control_weights[normalized_id]
|
123
|
+
|
124
|
+
# Use framework default
|
125
|
+
return framework_default
|
126
|
+
|
127
|
+
def get_framework_threshold(self, framework: str, default_threshold: float = 90.0) -> float:
|
128
|
+
"""
|
129
|
+
Get compliance threshold for framework with universal fallback.
|
130
|
+
|
131
|
+
Args:
|
132
|
+
framework: Framework identifier (e.g., "aws-well-architected", "soc2-type-ii")
|
133
|
+
default_threshold: Default threshold if not configured
|
134
|
+
|
135
|
+
Returns:
|
136
|
+
float: Compliance threshold for the framework
|
137
|
+
"""
|
138
|
+
# Normalize framework name for lookup
|
139
|
+
normalized_framework = framework.lower().replace("_", "-")
|
140
|
+
|
141
|
+
# Check configuration sources in priority order
|
142
|
+
if normalized_framework in self.config.framework_thresholds:
|
143
|
+
return self.config.framework_thresholds[normalized_framework]
|
144
|
+
|
145
|
+
# Use default threshold
|
146
|
+
return default_threshold
|
147
|
+
|
148
|
+
def get_assessment_frequency(self, control_id: str, default_frequency: str = "monthly") -> str:
|
149
|
+
"""
|
150
|
+
Get assessment frequency for control with universal fallback.
|
151
|
+
|
152
|
+
Args:
|
153
|
+
control_id: Control identifier
|
154
|
+
default_frequency: Default frequency if not configured
|
155
|
+
|
156
|
+
Returns:
|
157
|
+
str: Assessment frequency for the control
|
158
|
+
"""
|
159
|
+
normalized_id = control_id.lower().replace(".", "-")
|
160
|
+
|
161
|
+
if normalized_id in self.config.assessment_frequencies:
|
162
|
+
return self.config.assessment_frequencies[normalized_id]
|
163
|
+
|
164
|
+
return default_frequency
|
165
|
+
|
166
|
+
def get_remediation_priority(self, control_id: str, default_priority: int = 3) -> int:
|
167
|
+
"""
|
168
|
+
Get remediation priority for control with universal fallback.
|
169
|
+
|
170
|
+
Args:
|
171
|
+
control_id: Control identifier
|
172
|
+
default_priority: Default priority if not configured (1=highest, 5=lowest)
|
173
|
+
|
174
|
+
Returns:
|
175
|
+
int: Remediation priority for the control
|
176
|
+
"""
|
177
|
+
normalized_id = control_id.lower().replace(".", "-")
|
178
|
+
|
179
|
+
if normalized_id in self.config.remediation_priorities:
|
180
|
+
return self.config.remediation_priorities[normalized_id]
|
181
|
+
|
182
|
+
return default_priority
|
183
|
+
|
184
|
+
def export_configuration_template(self, output_path: str) -> None:
|
185
|
+
"""
|
186
|
+
Export a configuration template for enterprise customization.
|
187
|
+
|
188
|
+
Args:
|
189
|
+
output_path: Path to save the configuration template
|
190
|
+
"""
|
191
|
+
template = {
|
192
|
+
"control_weights": {
|
193
|
+
"sec-1": 2.0,
|
194
|
+
"sec-2": 1.5,
|
195
|
+
"cc6-1": 3.0,
|
196
|
+
"cc6-2": 2.5,
|
197
|
+
"pci-1": 2.0,
|
198
|
+
"hipaa-164-312-a-1": 2.5
|
199
|
+
},
|
200
|
+
"framework_thresholds": {
|
201
|
+
"aws-well-architected": 90.0,
|
202
|
+
"soc2-type-ii": 95.0,
|
203
|
+
"pci-dss": 100.0,
|
204
|
+
"hipaa": 95.0,
|
205
|
+
"nist-cybersecurity": 90.0,
|
206
|
+
"iso-27001": 85.0,
|
207
|
+
"cis-benchmarks": 88.0
|
208
|
+
},
|
209
|
+
"assessment_frequencies": {
|
210
|
+
"critical-controls": "weekly",
|
211
|
+
"high-controls": "monthly",
|
212
|
+
"medium-controls": "quarterly",
|
213
|
+
"low-controls": "annually"
|
214
|
+
},
|
215
|
+
"remediation_priorities": {
|
216
|
+
"critical-controls": 1,
|
217
|
+
"high-controls": 2,
|
218
|
+
"medium-controls": 3,
|
219
|
+
"low-controls": 4
|
220
|
+
}
|
221
|
+
}
|
222
|
+
|
223
|
+
try:
|
224
|
+
with open(output_path, 'w') as f:
|
225
|
+
json.dump(template, f, indent=2)
|
226
|
+
console.log(f"[green]Configuration template exported to: {output_path}[/]")
|
227
|
+
except Exception as e:
|
228
|
+
console.log(f"[red]Failed to export configuration template: {e}[/]")
|
229
|
+
|
230
|
+
|
231
|
+
# Global configuration instance
|
232
|
+
_universal_config = None
|
233
|
+
|
234
|
+
|
235
|
+
def get_universal_compliance_config() -> UniversalComplianceConfig:
|
236
|
+
"""Get the global universal compliance configuration instance."""
|
237
|
+
global _universal_config
|
238
|
+
if _universal_config is None:
|
239
|
+
_universal_config = UniversalComplianceConfig()
|
240
|
+
return _universal_config
|
241
|
+
|
242
|
+
|
243
|
+
def reset_compliance_config() -> None:
|
244
|
+
"""Reset the global configuration (useful for testing)."""
|
245
|
+
global _universal_config
|
246
|
+
_universal_config = None
|
247
|
+
|
248
|
+
|
249
|
+
# Export public interface
|
250
|
+
__all__ = [
|
251
|
+
"ComplianceConfiguration",
|
252
|
+
"UniversalComplianceConfig",
|
253
|
+
"get_universal_compliance_config",
|
254
|
+
"reset_compliance_config",
|
255
|
+
]
|
@@ -0,0 +1,22 @@
|
|
1
|
+
{
|
2
|
+
"control_weights": {
|
3
|
+
"SEC-1": 2.5,
|
4
|
+
"SEC-2": 1.8,
|
5
|
+
"CC6.1": 3.2,
|
6
|
+
"CC6.2": 2.8,
|
7
|
+
"PCI-1": 2.5,
|
8
|
+
"HIPAA-164.312(a)(1)": 3.0
|
9
|
+
},
|
10
|
+
"framework_thresholds": {
|
11
|
+
"pci_dss": 100.0,
|
12
|
+
"hipaa": 98.0,
|
13
|
+
"soc2_type_ii": 96.0,
|
14
|
+
"aws_well_architected": 92.0,
|
15
|
+
"iso27001": 91.0,
|
16
|
+
"nist_cybersecurity": 87.0,
|
17
|
+
"cis_benchmarks": 88.0
|
18
|
+
},
|
19
|
+
"description": "Enterprise compliance configuration with dynamic weights and thresholds",
|
20
|
+
"last_updated": "2024-12-19",
|
21
|
+
"version": "1.0"
|
22
|
+
}
|