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.
Files changed (77) hide show
  1. runbooks/__init__.py +1 -1
  2. runbooks/cfat/WEIGHT_CONFIG_README.md +368 -0
  3. runbooks/cfat/app.ts +27 -19
  4. runbooks/cfat/assessment/runner.py +6 -5
  5. runbooks/cfat/tests/test_weight_configuration.ts +449 -0
  6. runbooks/cfat/weight_config.ts +574 -0
  7. runbooks/common/__init__.py +26 -9
  8. runbooks/common/aws_pricing.py +1070 -105
  9. runbooks/common/date_utils.py +115 -0
  10. runbooks/common/enhanced_exception_handler.py +10 -7
  11. runbooks/common/mcp_cost_explorer_integration.py +5 -4
  12. runbooks/common/profile_utils.py +76 -115
  13. runbooks/common/rich_utils.py +3 -3
  14. runbooks/finops/dashboard_runner.py +47 -28
  15. runbooks/finops/ebs_optimizer.py +56 -9
  16. runbooks/finops/enhanced_trend_visualization.py +7 -2
  17. runbooks/finops/finops_dashboard.py +6 -5
  18. runbooks/finops/iam_guidance.py +6 -1
  19. runbooks/finops/nat_gateway_optimizer.py +46 -27
  20. runbooks/finops/tests/test_integration.py +3 -1
  21. runbooks/finops/vpc_cleanup_optimizer.py +22 -29
  22. runbooks/inventory/core/collector.py +51 -28
  23. runbooks/inventory/discovery.md +197 -247
  24. runbooks/inventory/inventory_modules.py +2 -2
  25. runbooks/inventory/list_ec2_instances.py +3 -3
  26. runbooks/inventory/organizations_discovery.py +13 -8
  27. runbooks/inventory/unified_validation_engine.py +2 -15
  28. runbooks/main.py +74 -32
  29. runbooks/operate/base.py +9 -6
  30. runbooks/operate/deployment_framework.py +5 -4
  31. runbooks/operate/deployment_validator.py +6 -5
  32. runbooks/operate/mcp_integration.py +6 -5
  33. runbooks/operate/networking_cost_heatmap.py +17 -13
  34. runbooks/operate/vpc_operations.py +52 -12
  35. runbooks/remediation/base.py +3 -1
  36. runbooks/remediation/commons.py +5 -5
  37. runbooks/remediation/commvault_ec2_analysis.py +66 -18
  38. runbooks/remediation/config/accounts_example.json +31 -0
  39. runbooks/remediation/multi_account.py +120 -7
  40. runbooks/remediation/remediation_cli.py +710 -0
  41. runbooks/remediation/universal_account_discovery.py +377 -0
  42. runbooks/security/compliance_automation_engine.py +99 -20
  43. runbooks/security/config/__init__.py +24 -0
  44. runbooks/security/config/compliance_config.py +255 -0
  45. runbooks/security/config/compliance_weights_example.json +22 -0
  46. runbooks/security/config_template_generator.py +500 -0
  47. runbooks/security/security_cli.py +377 -0
  48. runbooks/validation/cli.py +8 -7
  49. runbooks/validation/comprehensive_2way_validator.py +26 -15
  50. runbooks/validation/mcp_validator.py +62 -8
  51. runbooks/vpc/config.py +32 -7
  52. runbooks/vpc/cross_account_session.py +5 -1
  53. runbooks/vpc/heatmap_engine.py +21 -14
  54. runbooks/vpc/mcp_no_eni_validator.py +115 -36
  55. runbooks/vpc/runbooks_adapter.py +33 -12
  56. runbooks/vpc/tests/conftest.py +4 -2
  57. runbooks/vpc/tests/test_cost_engine.py +3 -1
  58. {runbooks-1.0.0.dist-info → runbooks-1.0.1.dist-info}/METADATA +1 -1
  59. {runbooks-1.0.0.dist-info → runbooks-1.0.1.dist-info}/RECORD +63 -65
  60. runbooks/finops/runbooks.inventory.organizations_discovery.log +0 -0
  61. runbooks/finops/runbooks.security.report_generator.log +0 -0
  62. runbooks/finops/runbooks.security.run_script.log +0 -0
  63. runbooks/finops/runbooks.security.security_export.log +0 -0
  64. runbooks/finops/tests/results_test_finops_dashboard.xml +0 -1
  65. runbooks/inventory/artifacts/scale-optimize-status.txt +0 -12
  66. runbooks/inventory/runbooks.inventory.organizations_discovery.log +0 -0
  67. runbooks/inventory/runbooks.security.report_generator.log +0 -0
  68. runbooks/inventory/runbooks.security.run_script.log +0 -0
  69. runbooks/inventory/runbooks.security.security_export.log +0 -0
  70. runbooks/vpc/runbooks.inventory.organizations_discovery.log +0 -0
  71. runbooks/vpc/runbooks.security.report_generator.log +0 -0
  72. runbooks/vpc/runbooks.security.run_script.log +0 -0
  73. runbooks/vpc/runbooks.security.security_export.log +0 -0
  74. {runbooks-1.0.0.dist-info → runbooks-1.0.1.dist-info}/WHEEL +0 -0
  75. {runbooks-1.0.0.dist-info → runbooks-1.0.1.dist-info}/entry_points.txt +0 -0
  76. {runbooks-1.0.0.dist-info → runbooks-1.0.1.dist-info}/licenses/LICENSE +0 -0
  77. {runbooks-1.0.0.dist-info → runbooks-1.0.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,449 @@
1
+ /**
2
+ * Comprehensive Test Suite for Dynamic Weight Configuration System
3
+ *
4
+ * QA Testing Specialist - Enterprise Grade Validation Framework
5
+ *
6
+ * Tests for:
7
+ * - Weight configuration loading and validation
8
+ * - Framework-specific weight variations
9
+ * - Environment-based weight adjustments
10
+ * - Custom override functionality
11
+ * - Boundary conditions and error handling
12
+ * - Performance and consistency validation
13
+ */
14
+
15
+ import { describe, test, expect, beforeEach } from '@jest/jest';
16
+ import {
17
+ getWeightConfig,
18
+ validateWeightConfig,
19
+ loadWeightConfigFromEnv,
20
+ ComplianceFramework,
21
+ EnvironmentType,
22
+ OrganizationSize,
23
+ FRAMEWORK_WEIGHTS,
24
+ ENVIRONMENT_MODIFIERS,
25
+ SIZE_MODIFIERS,
26
+ WeightConfig
27
+ } from '../weight_config.js';
28
+
29
+ describe('Dynamic Weight Configuration System', () => {
30
+
31
+ describe('Weight Configuration Loading', () => {
32
+ test('should load default AWS Well-Architected weights', () => {
33
+ const config = getWeightConfig();
34
+
35
+ expect(config.organization_created).toBe(6);
36
+ expect(config.management_account_created).toBe(6);
37
+ expect(config.cloudtrail_created).toBe(6);
38
+ expect(config.iam_users_removed).toBe(4);
39
+ expect(config.ec2_instances_removed).toBe(4);
40
+ });
41
+
42
+ test('should load SOC2 framework weights with enhanced security focus', () => {
43
+ const config = getWeightConfig(ComplianceFramework.SOC2);
44
+
45
+ // SOC2 should have higher security-focused weights
46
+ expect(config.securityhub_org_service_enabled).toBe(6);
47
+ expect(config.iam_access_analyzer_org_service_enabled).toBe(6);
48
+ expect(config.backup_policy_enabled).toBe(6);
49
+ expect(config.guardduty_org_service_enabled).toBe(6);
50
+
51
+ // Management account hygiene should be higher for SOC2
52
+ expect(config.iam_users_removed).toBe(5);
53
+ expect(config.ec2_instances_removed).toBe(5);
54
+ expect(config.vpc_removed).toBe(5);
55
+ });
56
+
57
+ test('should load PCI-DSS framework weights with network isolation focus', () => {
58
+ const config = getWeightConfig(ComplianceFramework.PCI_DSS);
59
+
60
+ // PCI-DSS should emphasize network isolation
61
+ expect(config.iam_users_removed).toBe(6);
62
+ expect(config.ec2_instances_removed).toBe(6);
63
+ expect(config.vpc_removed).toBe(6);
64
+
65
+ // Enhanced security services
66
+ expect(config.securityhub_org_service_enabled).toBe(6);
67
+ expect(config.guardduty_org_service_enabled).toBe(6);
68
+ expect(config.backup_policy_enabled).toBe(6);
69
+ });
70
+
71
+ test('should load HIPAA framework weights with data protection focus', () => {
72
+ const config = getWeightConfig(ComplianceFramework.HIPAA);
73
+
74
+ // HIPAA should emphasize data protection
75
+ expect(config.backup_policy_enabled).toBe(6);
76
+ expect(config.backup_org_service_enabled).toBe(6);
77
+ expect(config.config_org_service_enabled).toBe(6);
78
+
79
+ // Audit and logging
80
+ expect(config.cloudtrail_created).toBe(6);
81
+ expect(config.config_recorder_management).toBe(6);
82
+ expect(config.config_delivery_channel_management).toBe(6);
83
+ });
84
+ });
85
+
86
+ describe('Environment-Based Weight Adjustments', () => {
87
+ test('should apply development environment modifier (20% reduction)', () => {
88
+ const config = getWeightConfig(
89
+ ComplianceFramework.AWS_WELL_ARCHITECTED,
90
+ EnvironmentType.DEVELOPMENT
91
+ );
92
+
93
+ // 6 * 0.8 = 4.8, rounded to 5
94
+ expect(config.organization_created).toBe(5);
95
+ expect(config.management_account_created).toBe(5);
96
+
97
+ // 4 * 0.8 = 3.2, rounded to 3
98
+ expect(config.iam_users_removed).toBe(3);
99
+ });
100
+
101
+ test('should apply staging environment modifier (10% reduction)', () => {
102
+ const config = getWeightConfig(
103
+ ComplianceFramework.AWS_WELL_ARCHITECTED,
104
+ EnvironmentType.STAGING
105
+ );
106
+
107
+ // 6 * 0.9 = 5.4, rounded to 5
108
+ expect(config.organization_created).toBe(5);
109
+
110
+ // 4 * 0.9 = 3.6, rounded to 4
111
+ expect(config.iam_users_removed).toBe(4);
112
+ });
113
+
114
+ test('should apply production environment modifier (no reduction)', () => {
115
+ const config = getWeightConfig(
116
+ ComplianceFramework.AWS_WELL_ARCHITECTED,
117
+ EnvironmentType.PRODUCTION
118
+ );
119
+
120
+ // Full weights for production
121
+ expect(config.organization_created).toBe(6);
122
+ expect(config.iam_users_removed).toBe(4);
123
+ });
124
+
125
+ test('should apply sandbox environment modifier (40% reduction)', () => {
126
+ const config = getWeightConfig(
127
+ ComplianceFramework.AWS_WELL_ARCHITECTED,
128
+ EnvironmentType.SANDBOX
129
+ );
130
+
131
+ // 6 * 0.6 = 3.6, rounded to 4
132
+ expect(config.organization_created).toBe(4);
133
+
134
+ // 4 * 0.6 = 2.4, rounded to 2
135
+ expect(config.iam_users_removed).toBe(2);
136
+ });
137
+ });
138
+
139
+ describe('Organization Size-Based Adjustments', () => {
140
+ test('should adjust weights for large organizations', () => {
141
+ const config = getWeightConfig(
142
+ ComplianceFramework.AWS_WELL_ARCHITECTED,
143
+ EnvironmentType.PRODUCTION,
144
+ OrganizationSize.LARGE
145
+ );
146
+
147
+ // Large orgs should have enhanced governance
148
+ expect(config.scp_enabled).toBe(7); // Base 6 + 1
149
+ expect(config.tag_policy_enabled).toBe(7); // Base 6 + 1
150
+ expect(config.backup_policy_enabled).toBe(6); // Base 5 + 1
151
+ });
152
+
153
+ test('should adjust weights for enterprise organizations', () => {
154
+ const config = getWeightConfig(
155
+ ComplianceFramework.AWS_WELL_ARCHITECTED,
156
+ EnvironmentType.PRODUCTION,
157
+ OrganizationSize.ENTERPRISE
158
+ );
159
+
160
+ // Enterprise requires maximum governance
161
+ expect(config.scp_enabled).toBe(7); // Base 6 + 1
162
+ expect(config.tag_policy_enabled).toBe(7); // Base 6 + 1
163
+ expect(config.backup_policy_enabled).toBe(6); // Base 5 + 1
164
+ expect(config.control_tower_deployed).toBe(7); // Base 6 + 1
165
+ expect(config.security_ou_deployed).toBe(7); // Base 6 + 1
166
+ });
167
+
168
+ test('should adjust weights for small organizations', () => {
169
+ const config = getWeightConfig(
170
+ ComplianceFramework.AWS_WELL_ARCHITECTED,
171
+ EnvironmentType.PRODUCTION,
172
+ OrganizationSize.SMALL
173
+ );
174
+
175
+ // Small orgs might not need all enterprise features
176
+ expect(config.infrastructure_ou_deployed).toBe(4); // Base 5 - 1
177
+ expect(config.workloads_ou_deployed).toBe(4); // Base 5 - 1
178
+ expect(config.backup_policy_enabled).toBe(4); // Base 5 - 1
179
+ });
180
+ });
181
+
182
+ describe('Custom Override Functionality', () => {
183
+ test('should apply custom weight overrides', () => {
184
+ const customOverrides: Partial<WeightConfig> = {
185
+ organization_created: 8,
186
+ cloudtrail_created: 10,
187
+ iam_users_removed: 1
188
+ };
189
+
190
+ const config = getWeightConfig(
191
+ ComplianceFramework.AWS_WELL_ARCHITECTED,
192
+ EnvironmentType.PRODUCTION,
193
+ OrganizationSize.MEDIUM,
194
+ customOverrides
195
+ );
196
+
197
+ // Custom overrides should take precedence
198
+ expect(config.organization_created).toBe(8);
199
+ expect(config.cloudtrail_created).toBe(10);
200
+ expect(config.iam_users_removed).toBe(1);
201
+
202
+ // Non-overridden values should use defaults
203
+ expect(config.management_account_created).toBe(6);
204
+ });
205
+ });
206
+
207
+ describe('Weight Validation', () => {
208
+ test('should validate correct weight configuration', () => {
209
+ const validConfig: WeightConfig = {
210
+ organization_created: 6,
211
+ management_account_created: 6,
212
+ iam_users_removed: 4,
213
+ ec2_instances_removed: 4,
214
+ vpc_removed: 4,
215
+ legacy_cur_setup: 4,
216
+ cloudtrail_created: 6,
217
+ cloudtrail_org_service_enabled: 6,
218
+ cloudtrail_org_trail_deployed: 6,
219
+ config_recorder_management: 6,
220
+ config_delivery_channel_management: 6,
221
+ cloudformation_stacksets_activated: 5,
222
+ guardduty_org_service_enabled: 4,
223
+ ram_org_service_enabled: 4,
224
+ securityhub_org_service_enabled: 4,
225
+ iam_access_analyzer_org_service_enabled: 4,
226
+ config_org_service_enabled: 4,
227
+ cloudformation_org_service_enabled: 5,
228
+ backup_org_service_enabled: 4,
229
+ infrastructure_ou_deployed: 5,
230
+ security_ou_deployed: 6,
231
+ workloads_ou_deployed: 5,
232
+ iam_idc_org_service_enabled: 6,
233
+ iam_idc_configured: 6,
234
+ scp_enabled: 6,
235
+ tag_policy_enabled: 6,
236
+ backup_policy_enabled: 5,
237
+ control_tower_deployed: 6,
238
+ control_tower_latest_version: 5,
239
+ control_tower_not_drifted: 6,
240
+ log_archive_account_deployed: 6,
241
+ audit_account_deployed: 6
242
+ };
243
+
244
+ const result = validateWeightConfig(validConfig);
245
+ expect(result.valid).toBe(true);
246
+ expect(result.errors).toHaveLength(0);
247
+ });
248
+
249
+ test('should detect invalid weight values', () => {
250
+ const invalidConfig: WeightConfig = {
251
+ ...FRAMEWORK_WEIGHTS[ComplianceFramework.AWS_WELL_ARCHITECTED],
252
+ organization_created: 0, // Too low
253
+ management_account_created: 11, // Too high
254
+ iam_users_removed: 3.5 // Not integer
255
+ };
256
+
257
+ const result = validateWeightConfig(invalidConfig);
258
+ expect(result.valid).toBe(false);
259
+ expect(result.errors.length).toBeGreaterThan(0);
260
+
261
+ expect(result.errors).toContain(
262
+ expect.stringContaining('organization_created must be between 1 and 10')
263
+ );
264
+ expect(result.errors).toContain(
265
+ expect.stringContaining('management_account_created must be between 1 and 10')
266
+ );
267
+ expect(result.errors).toContain(
268
+ expect.stringContaining('iam_users_removed must be an integer')
269
+ );
270
+ });
271
+ });
272
+
273
+ describe('Environment Variable Loading', () => {
274
+ beforeEach(() => {
275
+ // Clean up environment variables
276
+ delete process.env.CFAT_COMPLIANCE_FRAMEWORK;
277
+ delete process.env.CFAT_ENVIRONMENT_TYPE;
278
+ delete process.env.CFAT_ORG_SIZE;
279
+ delete process.env.CFAT_WEIGHT_OVERRIDES;
280
+ });
281
+
282
+ test('should load default values when no environment variables set', () => {
283
+ const config = loadWeightConfigFromEnv();
284
+
285
+ expect(config.framework).toBe(ComplianceFramework.AWS_WELL_ARCHITECTED);
286
+ expect(config.environment).toBe(EnvironmentType.PRODUCTION);
287
+ expect(config.orgSize).toBe(OrganizationSize.MEDIUM);
288
+ expect(config.customOverrides).toEqual({});
289
+ });
290
+
291
+ test('should load values from environment variables', () => {
292
+ process.env.CFAT_COMPLIANCE_FRAMEWORK = 'soc2';
293
+ process.env.CFAT_ENVIRONMENT_TYPE = 'staging';
294
+ process.env.CFAT_ORG_SIZE = 'large';
295
+ process.env.CFAT_WEIGHT_OVERRIDES = '{"organization_created": 8}';
296
+
297
+ const config = loadWeightConfigFromEnv();
298
+
299
+ expect(config.framework).toBe(ComplianceFramework.SOC2);
300
+ expect(config.environment).toBe(EnvironmentType.STAGING);
301
+ expect(config.orgSize).toBe(OrganizationSize.LARGE);
302
+ expect(config.customOverrides).toEqual({ organization_created: 8 });
303
+ });
304
+
305
+ test('should handle invalid JSON in weight overrides', () => {
306
+ process.env.CFAT_WEIGHT_OVERRIDES = 'invalid json';
307
+
308
+ const config = loadWeightConfigFromEnv();
309
+
310
+ // Should fall back to empty overrides
311
+ expect(config.customOverrides).toEqual({});
312
+ });
313
+ });
314
+
315
+ describe('Framework Coverage Validation', () => {
316
+ test('should have all required weights for each framework', () => {
317
+ const requiredWeights = [
318
+ 'organization_created',
319
+ 'management_account_created',
320
+ 'cloudtrail_created',
321
+ 'control_tower_deployed',
322
+ 'security_ou_deployed',
323
+ 'log_archive_account_deployed',
324
+ 'audit_account_deployed'
325
+ ];
326
+
327
+ Object.values(ComplianceFramework).forEach(framework => {
328
+ const weights = FRAMEWORK_WEIGHTS[framework];
329
+
330
+ requiredWeights.forEach(weight => {
331
+ expect(weights[weight as keyof WeightConfig]).toBeDefined();
332
+ expect(typeof weights[weight as keyof WeightConfig]).toBe('number');
333
+ expect(weights[weight as keyof WeightConfig]).toBeGreaterThanOrEqual(1);
334
+ expect(weights[weight as keyof WeightConfig]).toBeLessThanOrEqual(10);
335
+ });
336
+ });
337
+ });
338
+ });
339
+
340
+ describe('Performance and Consistency Testing', () => {
341
+ test('should load configuration quickly', () => {
342
+ const startTime = performance.now();
343
+
344
+ for (let i = 0; i < 1000; i++) {
345
+ getWeightConfig();
346
+ }
347
+
348
+ const endTime = performance.now();
349
+ const avgTime = (endTime - startTime) / 1000;
350
+
351
+ // Should average less than 1ms per configuration load
352
+ expect(avgTime).toBeLessThan(1);
353
+ });
354
+
355
+ test('should produce consistent results for same parameters', () => {
356
+ const config1 = getWeightConfig(
357
+ ComplianceFramework.SOC2,
358
+ EnvironmentType.STAGING,
359
+ OrganizationSize.LARGE
360
+ );
361
+
362
+ const config2 = getWeightConfig(
363
+ ComplianceFramework.SOC2,
364
+ EnvironmentType.STAGING,
365
+ OrganizationSize.LARGE
366
+ );
367
+
368
+ expect(config1).toEqual(config2);
369
+ });
370
+ });
371
+
372
+ describe('Boundary Conditions and Error Handling', () => {
373
+ test('should handle minimum weight values correctly', () => {
374
+ const config = getWeightConfig(
375
+ ComplianceFramework.CUSTOM,
376
+ EnvironmentType.SANDBOX,
377
+ OrganizationSize.SMALL,
378
+ { organization_created: 1 }
379
+ );
380
+
381
+ // Should never go below 1
382
+ expect(config.organization_created).toBeGreaterThanOrEqual(1);
383
+ });
384
+
385
+ test('should handle maximum organization size adjustments', () => {
386
+ const config = getWeightConfig(
387
+ ComplianceFramework.AWS_WELL_ARCHITECTED,
388
+ EnvironmentType.PRODUCTION,
389
+ OrganizationSize.ENTERPRISE
390
+ );
391
+
392
+ // Weights should remain reasonable even with maximum adjustments
393
+ Object.values(config).forEach(weight => {
394
+ expect(weight).toBeGreaterThanOrEqual(1);
395
+ expect(weight).toBeLessThanOrEqual(10);
396
+ });
397
+ });
398
+ });
399
+ });
400
+
401
+ /**
402
+ * Integration tests for CFAT app.ts usage
403
+ */
404
+ describe('CFAT App Integration', () => {
405
+ test('should provide weights for all CFAT checks', () => {
406
+ const config = getWeightConfig();
407
+
408
+ // Test that we have all the weights needed by CFAT app
409
+ const cfatRequiredWeights = [
410
+ 'organization_created',
411
+ 'management_account_created',
412
+ 'iam_users_removed',
413
+ 'ec2_instances_removed',
414
+ 'vpc_removed',
415
+ 'legacy_cur_setup',
416
+ 'cloudtrail_created',
417
+ 'cloudtrail_org_service_enabled',
418
+ 'cloudtrail_org_trail_deployed',
419
+ 'config_recorder_management',
420
+ 'config_delivery_channel_management',
421
+ 'cloudformation_stacksets_activated',
422
+ 'guardduty_org_service_enabled',
423
+ 'ram_org_service_enabled',
424
+ 'securityhub_org_service_enabled',
425
+ 'iam_access_analyzer_org_service_enabled',
426
+ 'config_org_service_enabled',
427
+ 'cloudformation_org_service_enabled',
428
+ 'backup_org_service_enabled',
429
+ 'infrastructure_ou_deployed',
430
+ 'security_ou_deployed',
431
+ 'workloads_ou_deployed',
432
+ 'iam_idc_org_service_enabled',
433
+ 'iam_idc_configured',
434
+ 'scp_enabled',
435
+ 'tag_policy_enabled',
436
+ 'backup_policy_enabled',
437
+ 'control_tower_deployed',
438
+ 'control_tower_latest_version',
439
+ 'control_tower_not_drifted',
440
+ 'log_archive_account_deployed',
441
+ 'audit_account_deployed'
442
+ ];
443
+
444
+ cfatRequiredWeights.forEach(weight => {
445
+ expect(config[weight as keyof WeightConfig]).toBeDefined();
446
+ expect(typeof config[weight as keyof WeightConfig]).toBe('number');
447
+ });
448
+ });
449
+ });