timonel 3.1.1 → 3.1.2
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.
- package/CHANGELOG.md +7 -0
- package/README.md +323 -695
- package/dist/cli.js +275 -15
- package/dist/index.d.ts +5 -1
- package/dist/index.js +12 -0
- package/dist/lib/helm.d.ts +471 -0
- package/dist/lib/helm.js +483 -0
- package/dist/lib/helmChartWriter.d.ts +157 -0
- package/dist/lib/helmChartWriter.js +171 -1
- package/dist/lib/policy/configurationLoader.d.ts +132 -0
- package/dist/lib/policy/configurationLoader.js +132 -0
- package/dist/lib/policy/errorContextGenerator.d.ts +89 -0
- package/dist/lib/policy/errorContextGenerator.js +99 -2
- package/dist/lib/policy/errors.d.ts +35 -0
- package/dist/lib/policy/errors.js +36 -0
- package/dist/lib/policy/index.d.ts +9 -0
- package/dist/lib/policy/index.js +16 -0
- package/dist/lib/policy/parallelExecutor.d.ts +90 -0
- package/dist/lib/policy/parallelExecutor.js +86 -3
- package/dist/lib/policy/pluginLoader.d.ts +92 -0
- package/dist/lib/policy/pluginLoader.js +92 -1
- package/dist/lib/policy/pluginRegistry.d.ts +54 -0
- package/dist/lib/policy/pluginRegistry.js +56 -0
- package/dist/lib/policy/policyEngine.d.ts +137 -0
- package/dist/lib/policy/policyEngine.js +191 -5
- package/dist/lib/policy/resultAggregator.d.ts +46 -0
- package/dist/lib/policy/resultAggregator.js +69 -1
- package/dist/lib/policy/resultFormatter.d.ts +88 -0
- package/dist/lib/policy/resultFormatter.js +101 -0
- package/dist/lib/policy/types.d.ts +136 -0
- package/dist/lib/policy/types.js +8 -0
- package/dist/lib/policy/validationCache.d.ts +146 -0
- package/dist/lib/policy/validationCache.js +142 -6
- package/dist/lib/resources/baseResourceProvider.d.ts +45 -0
- package/dist/lib/resources/baseResourceProvider.js +48 -1
- package/dist/lib/resources/cloud/aws/awsResources.d.ts +192 -0
- package/dist/lib/resources/cloud/aws/awsResources.js +163 -1
- package/dist/lib/resources/cloud/aws/karpenterResources.d.ts +131 -0
- package/dist/lib/resources/cloud/aws/karpenterResources.js +77 -0
- package/dist/lib/rutter.d.ts +381 -3
- package/dist/lib/rutter.js +439 -28
- package/dist/lib/security.d.ts +123 -0
- package/dist/lib/security.js +162 -4
- package/dist/lib/templates/flexible-subchart.d.ts +52 -0
- package/dist/lib/templates/flexible-subchart.js +70 -0
- package/dist/lib/templates/umbrella-chart.d.ts +27 -0
- package/dist/lib/templates/umbrella-chart.js +89 -0
- package/dist/lib/types.d.ts +26 -0
- package/dist/lib/umbrella.d.ts +23 -0
- package/dist/lib/umbrella.js +23 -0
- package/dist/lib/umbrellaRutter.d.ts +75 -0
- package/dist/lib/umbrellaRutter.js +82 -2
- package/dist/lib/utils/envVarsLoader.d.ts +49 -0
- package/dist/lib/utils/envVarsLoader.js +53 -0
- package/dist/lib/utils/helmConstructSerializer.d.ts +17 -0
- package/dist/lib/utils/helmConstructSerializer.js +22 -0
- package/dist/lib/utils/helmControlStructures.d.ts +194 -0
- package/dist/lib/utils/helmControlStructures.js +180 -0
- package/dist/lib/utils/helmHelpers/envHelpers.d.ts +13 -0
- package/dist/lib/utils/helmHelpers/envHelpers.js +13 -0
- package/dist/lib/utils/helmHelpers/gitopsHelpers.d.ts +13 -0
- package/dist/lib/utils/helmHelpers/gitopsHelpers.js +13 -0
- package/dist/lib/utils/helmHelpers/index.d.ts +74 -0
- package/dist/lib/utils/helmHelpers/index.js +85 -1
- package/dist/lib/utils/helmHelpers/observabilityHelpers.d.ts +13 -0
- package/dist/lib/utils/helmHelpers/observabilityHelpers.js +13 -0
- package/dist/lib/utils/helmHelpers/types.d.ts +23 -0
- package/dist/lib/utils/helmHelpers/types.js +4 -0
- package/dist/lib/utils/helmHelpers/validationHelpers.d.ts +13 -0
- package/dist/lib/utils/helmHelpers/validationHelpers.js +13 -0
- package/dist/lib/utils/helmHelpers.d.ts +62 -0
- package/dist/lib/utils/helmHelpers.js +77 -0
- package/dist/lib/utils/helmYamlSerializer.d.ts +77 -0
- package/dist/lib/utils/helmYamlSerializer.js +398 -21
- package/dist/lib/utils/logger.d.ts +153 -0
- package/dist/lib/utils/logger.js +170 -2
- package/dist/lib/utils/valuesRef.d.ts +181 -50
- package/dist/lib/utils/valuesRef.js +168 -170
- package/dist/lib/validation/inputValidator.d.ts +45 -0
- package/dist/lib/validation/inputValidator.js +67 -2
- package/dist/types/index.d.ts +34 -0
- package/dist/types/index.js +3 -0
- package/package.json +31 -38
|
@@ -1,39 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Policy Engine Error Types
|
|
3
|
+
*
|
|
4
|
+
* This module defines custom error types for the Timonel Policy Engine system.
|
|
5
|
+
* These errors provide structured error handling and debugging capabilities.
|
|
6
|
+
*
|
|
7
|
+
* @since 3.0.0
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Base error class for all policy engine related errors
|
|
11
|
+
*/
|
|
1
12
|
export declare class PolicyEngineError extends Error {
|
|
2
13
|
readonly code?: string | undefined;
|
|
3
14
|
readonly context?: Record<string, unknown> | undefined;
|
|
4
15
|
constructor(message: string, code?: string | undefined, context?: Record<string, unknown> | undefined);
|
|
5
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* Error thrown when a plugin fails during execution
|
|
19
|
+
*/
|
|
6
20
|
export declare class PluginError extends PolicyEngineError {
|
|
7
21
|
readonly pluginName: string;
|
|
8
22
|
constructor(message: string, pluginName: string, context?: Record<string, unknown>);
|
|
9
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Error thrown when plugin validation times out
|
|
26
|
+
*/
|
|
10
27
|
export declare class ValidationTimeoutError extends PolicyEngineError {
|
|
11
28
|
constructor(pluginName: string, timeout: number);
|
|
12
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* Error thrown when plugin registration fails
|
|
32
|
+
*/
|
|
13
33
|
export declare class PluginRegistrationError extends PolicyEngineError {
|
|
14
34
|
readonly pluginName?: string | undefined;
|
|
15
35
|
constructor(message: string, pluginName?: string | undefined, context?: Record<string, unknown>);
|
|
16
36
|
}
|
|
37
|
+
/**
|
|
38
|
+
* Error thrown when plugin configuration is invalid
|
|
39
|
+
*/
|
|
17
40
|
export declare class PluginConfigurationError extends PolicyEngineError {
|
|
18
41
|
readonly pluginName: string;
|
|
19
42
|
readonly configPath?: string | undefined;
|
|
20
43
|
constructor(message: string, pluginName: string, configPath?: string | undefined, context?: Record<string, unknown>);
|
|
21
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* Error thrown when validation orchestration fails
|
|
47
|
+
*/
|
|
22
48
|
export declare class ValidationOrchestrationError extends PolicyEngineError {
|
|
23
49
|
readonly failedPlugins?: string[] | undefined;
|
|
24
50
|
constructor(message: string, failedPlugins?: string[] | undefined, context?: Record<string, unknown>);
|
|
25
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* Error thrown when plugin execution fails after all retry attempts
|
|
54
|
+
*/
|
|
26
55
|
export declare class PluginRetryExhaustedError extends PolicyEngineError {
|
|
27
56
|
readonly pluginName: string;
|
|
28
57
|
readonly attempts: number;
|
|
29
58
|
readonly lastError: Error;
|
|
30
59
|
constructor(message: string, pluginName: string, attempts: number, lastError: Error, context?: Record<string, unknown>);
|
|
31
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* Error thrown when graceful degradation is triggered
|
|
63
|
+
*/
|
|
32
64
|
export declare class GracefulDegradationError extends PolicyEngineError {
|
|
33
65
|
readonly degradedPlugins: string[];
|
|
34
66
|
readonly originalErrors: Error[];
|
|
35
67
|
constructor(message: string, degradedPlugins: string[], originalErrors: Error[], context?: Record<string, unknown>);
|
|
36
68
|
}
|
|
69
|
+
/**
|
|
70
|
+
* Error thrown when input validation fails
|
|
71
|
+
*/
|
|
37
72
|
export declare class PolicyValidationError extends PolicyEngineError {
|
|
38
73
|
readonly field?: string | undefined;
|
|
39
74
|
constructor(message: string, field?: string | undefined, context?: Record<string, unknown>);
|
|
@@ -1,14 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Policy Engine Error Types
|
|
3
|
+
*
|
|
4
|
+
* This module defines custom error types for the Timonel Policy Engine system.
|
|
5
|
+
* These errors provide structured error handling and debugging capabilities.
|
|
6
|
+
*
|
|
7
|
+
* @since 3.0.0
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Base error class for all policy engine related errors
|
|
11
|
+
*/
|
|
1
12
|
export class PolicyEngineError extends Error {
|
|
2
13
|
constructor(message, code, context) {
|
|
3
14
|
super(message);
|
|
4
15
|
this.code = code;
|
|
5
16
|
this.context = context;
|
|
6
17
|
this.name = 'PolicyEngineError';
|
|
18
|
+
// Maintain proper stack trace for where our error was thrown (only available on V8)
|
|
7
19
|
if (Error.captureStackTrace) {
|
|
8
20
|
Error.captureStackTrace(this, PolicyEngineError);
|
|
9
21
|
}
|
|
10
22
|
}
|
|
11
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Error thrown when a plugin fails during execution
|
|
26
|
+
*/
|
|
12
27
|
export class PluginError extends PolicyEngineError {
|
|
13
28
|
constructor(message, pluginName, context) {
|
|
14
29
|
super(message, 'PLUGIN_ERROR', { ...context, pluginName });
|
|
@@ -19,6 +34,9 @@ export class PluginError extends PolicyEngineError {
|
|
|
19
34
|
}
|
|
20
35
|
}
|
|
21
36
|
}
|
|
37
|
+
/**
|
|
38
|
+
* Error thrown when plugin validation times out
|
|
39
|
+
*/
|
|
22
40
|
export class ValidationTimeoutError extends PolicyEngineError {
|
|
23
41
|
constructor(pluginName, timeout) {
|
|
24
42
|
super(`Plugin '${pluginName}' timed out after ${timeout}ms`, 'VALIDATION_TIMEOUT', {
|
|
@@ -31,6 +49,9 @@ export class ValidationTimeoutError extends PolicyEngineError {
|
|
|
31
49
|
}
|
|
32
50
|
}
|
|
33
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* Error thrown when plugin registration fails
|
|
54
|
+
*/
|
|
34
55
|
export class PluginRegistrationError extends PolicyEngineError {
|
|
35
56
|
constructor(message, pluginName, context) {
|
|
36
57
|
super(message, 'PLUGIN_REGISTRATION_ERROR', { ...context, pluginName });
|
|
@@ -41,6 +62,9 @@ export class PluginRegistrationError extends PolicyEngineError {
|
|
|
41
62
|
}
|
|
42
63
|
}
|
|
43
64
|
}
|
|
65
|
+
/**
|
|
66
|
+
* Error thrown when plugin configuration is invalid
|
|
67
|
+
*/
|
|
44
68
|
export class PluginConfigurationError extends PolicyEngineError {
|
|
45
69
|
constructor(message, pluginName, configPath, context) {
|
|
46
70
|
super(message, 'PLUGIN_CONFIGURATION_ERROR', { ...context, pluginName, configPath });
|
|
@@ -52,6 +76,9 @@ export class PluginConfigurationError extends PolicyEngineError {
|
|
|
52
76
|
}
|
|
53
77
|
}
|
|
54
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* Error thrown when validation orchestration fails
|
|
81
|
+
*/
|
|
55
82
|
export class ValidationOrchestrationError extends PolicyEngineError {
|
|
56
83
|
constructor(message, failedPlugins, context) {
|
|
57
84
|
super(message, 'VALIDATION_ORCHESTRATION_ERROR', { ...context, failedPlugins });
|
|
@@ -62,6 +89,9 @@ export class ValidationOrchestrationError extends PolicyEngineError {
|
|
|
62
89
|
}
|
|
63
90
|
}
|
|
64
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* Error thrown when plugin execution fails after all retry attempts
|
|
94
|
+
*/
|
|
65
95
|
export class PluginRetryExhaustedError extends PolicyEngineError {
|
|
66
96
|
constructor(message, pluginName, attempts, lastError, context) {
|
|
67
97
|
super(message, 'PLUGIN_RETRY_EXHAUSTED', {
|
|
@@ -79,6 +109,9 @@ export class PluginRetryExhaustedError extends PolicyEngineError {
|
|
|
79
109
|
}
|
|
80
110
|
}
|
|
81
111
|
}
|
|
112
|
+
/**
|
|
113
|
+
* Error thrown when graceful degradation is triggered
|
|
114
|
+
*/
|
|
82
115
|
export class GracefulDegradationError extends PolicyEngineError {
|
|
83
116
|
constructor(message, degradedPlugins, originalErrors, context) {
|
|
84
117
|
super(message, 'GRACEFUL_DEGRADATION', {
|
|
@@ -94,6 +127,9 @@ export class GracefulDegradationError extends PolicyEngineError {
|
|
|
94
127
|
}
|
|
95
128
|
}
|
|
96
129
|
}
|
|
130
|
+
/**
|
|
131
|
+
* Error thrown when input validation fails
|
|
132
|
+
*/
|
|
97
133
|
export class PolicyValidationError extends PolicyEngineError {
|
|
98
134
|
constructor(message, field, context) {
|
|
99
135
|
super(message, 'POLICY_VALIDATION_ERROR', {
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Policy Engine Module
|
|
3
|
+
*
|
|
4
|
+
* This module provides a lightweight, extensible policy validation system for Timonel.
|
|
5
|
+
* It enables validation of Kubernetes manifests through external plugins following
|
|
6
|
+
* industry best practices for plugin architecture and extensibility.
|
|
7
|
+
*
|
|
8
|
+
* @since 3.0.0
|
|
9
|
+
*/
|
|
1
10
|
export { PolicyEngine } from './policyEngine.js';
|
|
2
11
|
export { PluginRegistry } from './pluginRegistry.js';
|
|
3
12
|
export { ConfigurationLoader } from './configurationLoader.js';
|
package/dist/lib/policy/index.js
CHANGED
|
@@ -1,10 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Policy Engine Module
|
|
3
|
+
*
|
|
4
|
+
* This module provides a lightweight, extensible policy validation system for Timonel.
|
|
5
|
+
* It enables validation of Kubernetes manifests through external plugins following
|
|
6
|
+
* industry best practices for plugin architecture and extensibility.
|
|
7
|
+
*
|
|
8
|
+
* @since 3.0.0
|
|
9
|
+
*/
|
|
10
|
+
// Core engine
|
|
1
11
|
export { PolicyEngine } from './policyEngine.js';
|
|
2
12
|
export { PluginRegistry } from './pluginRegistry.js';
|
|
3
13
|
export { ConfigurationLoader } from './configurationLoader.js';
|
|
4
14
|
export { PluginLoader } from './pluginLoader.js';
|
|
15
|
+
// Validation cache
|
|
5
16
|
export { ValidationCache, generateManifestHash, generatePluginHash, } from './validationCache.js';
|
|
17
|
+
// Parallel execution
|
|
6
18
|
export { ParallelExecutor, calculateOptimalConcurrency, } from './parallelExecutor.js';
|
|
19
|
+
// Result aggregation utilities
|
|
7
20
|
export { aggregateResults, generateResultSummary, filterViolationsBySeverity, groupViolationsByPlugin, sortViolationsBySeverity, createEmptyResult, mergeViolationContexts, } from './resultAggregator.js';
|
|
21
|
+
// Result formatters
|
|
8
22
|
export { DefaultResultFormatter, JsonResultFormatter, CompactResultFormatter, GitHubActionsResultFormatter, SarifResultFormatter, createFormatter, getAvailableFormatters, } from './resultFormatter.js';
|
|
23
|
+
// Error context generation
|
|
9
24
|
export { ErrorContextGenerator } from './errorContextGenerator.js';
|
|
25
|
+
// Error types
|
|
10
26
|
export { PolicyEngineError, PluginError, ValidationTimeoutError, PluginRegistrationError, PluginConfigurationError, ValidationOrchestrationError, PluginRetryExhaustedError, GracefulDegradationError, } from './errors.js';
|
|
@@ -1,56 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parallel Execution Manager for Policy Plugins
|
|
3
|
+
*
|
|
4
|
+
* This module provides sophisticated parallel execution capabilities for policy plugins,
|
|
5
|
+
* including resource management, concurrency control, and performance optimization.
|
|
6
|
+
*
|
|
7
|
+
* @since 3.0.0
|
|
8
|
+
*/
|
|
1
9
|
import type { PolicyPlugin, PolicyViolation, ValidationContext } from './types.js';
|
|
10
|
+
/**
|
|
11
|
+
* Parallel execution configuration
|
|
12
|
+
*/
|
|
2
13
|
export interface ParallelExecutionOptions {
|
|
14
|
+
/** Maximum number of concurrent plugin executions */
|
|
3
15
|
maxConcurrency?: number;
|
|
16
|
+
/** Whether to use worker threads for CPU-intensive plugins */
|
|
4
17
|
useWorkerThreads?: boolean;
|
|
18
|
+
/** Timeout for individual plugin execution */
|
|
5
19
|
pluginTimeout?: number;
|
|
20
|
+
/** Whether to fail fast on first error */
|
|
6
21
|
failFast?: boolean;
|
|
22
|
+
/** Resource limits for plugin execution */
|
|
7
23
|
resourceLimits?: {
|
|
24
|
+
/** Maximum memory usage per plugin in MB */
|
|
8
25
|
maxMemoryMB?: number;
|
|
26
|
+
/** Maximum CPU time per plugin in milliseconds */
|
|
9
27
|
maxCpuTimeMs?: number;
|
|
10
28
|
};
|
|
29
|
+
/** Plugin execution priority configuration */
|
|
11
30
|
priorityConfig?: {
|
|
31
|
+
/** High priority plugins (executed first) */
|
|
12
32
|
highPriority?: string[];
|
|
33
|
+
/** Low priority plugins (executed last) */
|
|
13
34
|
lowPriority?: string[];
|
|
14
35
|
};
|
|
15
36
|
}
|
|
37
|
+
/**
|
|
38
|
+
* Plugin execution result
|
|
39
|
+
*/
|
|
16
40
|
export interface PluginExecutionResult {
|
|
41
|
+
/** Plugin that was executed */
|
|
17
42
|
plugin: PolicyPlugin;
|
|
43
|
+
/** Violations found by the plugin */
|
|
18
44
|
violations: PolicyViolation[];
|
|
45
|
+
/** Execution time in milliseconds */
|
|
19
46
|
executionTime: number;
|
|
47
|
+
/** Error if execution failed */
|
|
20
48
|
error?: Error;
|
|
49
|
+
/** Resource usage statistics */
|
|
21
50
|
resourceUsage?: {
|
|
22
51
|
memoryUsageMB: number;
|
|
23
52
|
cpuTimeMs: number;
|
|
24
53
|
};
|
|
25
54
|
}
|
|
55
|
+
/**
|
|
56
|
+
* Parallel execution statistics
|
|
57
|
+
*/
|
|
26
58
|
export interface ParallelExecutionStats {
|
|
59
|
+
/** Total execution time */
|
|
27
60
|
totalExecutionTime: number;
|
|
61
|
+
/** Average plugin execution time */
|
|
28
62
|
averagePluginTime: number;
|
|
63
|
+
/** Maximum plugin execution time */
|
|
29
64
|
maxPluginTime: number;
|
|
65
|
+
/** Number of plugins executed in parallel */
|
|
30
66
|
parallelPluginCount: number;
|
|
67
|
+
/** Concurrency utilization (0-1) */
|
|
31
68
|
concurrencyUtilization: number;
|
|
69
|
+
/** Resource usage statistics */
|
|
32
70
|
resourceUsage: {
|
|
33
71
|
totalMemoryMB: number;
|
|
34
72
|
totalCpuTimeMs: number;
|
|
35
73
|
peakConcurrentPlugins: number;
|
|
36
74
|
};
|
|
37
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* Parallel execution manager for policy plugins
|
|
78
|
+
*/
|
|
38
79
|
export declare class ParallelExecutor {
|
|
39
80
|
private readonly options;
|
|
40
81
|
private readonly logger;
|
|
41
82
|
private activeExecutions;
|
|
42
83
|
private executionQueue;
|
|
43
84
|
constructor(options?: ParallelExecutionOptions);
|
|
85
|
+
/**
|
|
86
|
+
* Executes plugins in parallel with resource management
|
|
87
|
+
* @param plugins - Array of plugins to execute
|
|
88
|
+
* @param manifests - Manifests to validate
|
|
89
|
+
* @param validationContext - Validation context
|
|
90
|
+
* @returns Promise resolving to execution results
|
|
91
|
+
*/
|
|
44
92
|
executePlugins(plugins: PolicyPlugin[], manifests: unknown[], validationContext: ValidationContext): Promise<{
|
|
45
93
|
results: PluginExecutionResult[];
|
|
46
94
|
stats: ParallelExecutionStats;
|
|
47
95
|
}>;
|
|
96
|
+
/**
|
|
97
|
+
* Executes a single plugin with resource monitoring
|
|
98
|
+
* @param plugin - Plugin to execute
|
|
99
|
+
* @param manifests - Manifests to validate
|
|
100
|
+
* @param validationContext - Validation context
|
|
101
|
+
* @returns Promise resolving to execution result
|
|
102
|
+
* @private
|
|
103
|
+
*/
|
|
48
104
|
private executePlugin;
|
|
105
|
+
/**
|
|
106
|
+
* Executes plugin with timeout handling
|
|
107
|
+
* @param plugin - Plugin to execute
|
|
108
|
+
* @param manifests - Manifests to validate
|
|
109
|
+
* @param validationContext - Validation context
|
|
110
|
+
* @param timeout - Timeout in milliseconds
|
|
111
|
+
* @returns Promise resolving to violations
|
|
112
|
+
* @private
|
|
113
|
+
*/
|
|
49
114
|
private executeWithTimeout;
|
|
115
|
+
/**
|
|
116
|
+
* Executes tasks with concurrency control
|
|
117
|
+
* @param tasks - Array of execution tasks
|
|
118
|
+
* @returns Promise resolving to results
|
|
119
|
+
* @private
|
|
120
|
+
*/
|
|
50
121
|
private executeConcurrently;
|
|
122
|
+
/**
|
|
123
|
+
* Sorts plugins by priority configuration
|
|
124
|
+
* @param plugins - Array of plugins to sort
|
|
125
|
+
* @returns Sorted array of plugins
|
|
126
|
+
* @private
|
|
127
|
+
*/
|
|
51
128
|
private sortPluginsByPriority;
|
|
129
|
+
/**
|
|
130
|
+
* Calculates execution statistics
|
|
131
|
+
* @param results - Array of execution results
|
|
132
|
+
* @param totalExecutionTime - Total execution time
|
|
133
|
+
* @returns Execution statistics
|
|
134
|
+
* @private
|
|
135
|
+
*/
|
|
52
136
|
private calculateStats;
|
|
53
137
|
}
|
|
138
|
+
/**
|
|
139
|
+
* Utility function to determine optimal concurrency based on system resources
|
|
140
|
+
* @param pluginCount - Number of plugins to execute
|
|
141
|
+
* @param systemInfo - Optional system information
|
|
142
|
+
* @returns Recommended concurrency level
|
|
143
|
+
*/
|
|
54
144
|
export declare function calculateOptimalConcurrency(pluginCount: number, systemInfo?: {
|
|
55
145
|
cpuCount?: number;
|
|
56
146
|
availableMemoryMB?: number;
|
|
@@ -1,13 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parallel Execution Manager for Policy Plugins
|
|
3
|
+
*
|
|
4
|
+
* This module provides sophisticated parallel execution capabilities for policy plugins,
|
|
5
|
+
* including resource management, concurrency control, and performance optimization.
|
|
6
|
+
*
|
|
7
|
+
* @since 3.0.0
|
|
8
|
+
*/
|
|
1
9
|
import { cpus, totalmem } from 'os';
|
|
2
10
|
import { createLogger } from '../utils/logger.js';
|
|
3
11
|
import { ValidationTimeoutError } from './errors.js';
|
|
12
|
+
/**
|
|
13
|
+
* Constants for error messages
|
|
14
|
+
*/
|
|
4
15
|
const UNKNOWN_ERROR_MESSAGE = 'Unknown error';
|
|
16
|
+
/**
|
|
17
|
+
* Default parallel execution options
|
|
18
|
+
*/
|
|
5
19
|
const DEFAULT_PARALLEL_OPTIONS = {
|
|
6
20
|
maxConcurrency: Math.max(2, Math.min(8, cpus().length)),
|
|
7
|
-
useWorkerThreads: false,
|
|
21
|
+
useWorkerThreads: false, // Disabled by default for simplicity
|
|
8
22
|
pluginTimeout: 5000,
|
|
9
23
|
failFast: false,
|
|
10
24
|
};
|
|
25
|
+
/**
|
|
26
|
+
* Parallel execution manager for policy plugins
|
|
27
|
+
*/
|
|
11
28
|
export class ParallelExecutor {
|
|
12
29
|
constructor(options = {}) {
|
|
13
30
|
this.activeExecutions = 0;
|
|
@@ -21,6 +38,13 @@ export class ParallelExecutor {
|
|
|
21
38
|
operation: 'parallel_executor_init',
|
|
22
39
|
});
|
|
23
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* Executes plugins in parallel with resource management
|
|
43
|
+
* @param plugins - Array of plugins to execute
|
|
44
|
+
* @param manifests - Manifests to validate
|
|
45
|
+
* @param validationContext - Validation context
|
|
46
|
+
* @returns Promise resolving to execution results
|
|
47
|
+
*/
|
|
24
48
|
async executePlugins(plugins, manifests, validationContext) {
|
|
25
49
|
const startTime = Date.now();
|
|
26
50
|
this.logger.info('Starting parallel plugin execution', {
|
|
@@ -29,8 +53,11 @@ export class ParallelExecutor {
|
|
|
29
53
|
manifestCount: manifests.length,
|
|
30
54
|
operation: 'parallel_execution_start',
|
|
31
55
|
});
|
|
56
|
+
// Sort plugins by priority
|
|
32
57
|
const sortedPlugins = this.sortPluginsByPriority(plugins);
|
|
58
|
+
// Create execution tasks
|
|
33
59
|
const executionTasks = sortedPlugins.map((plugin) => () => this.executePlugin(plugin, manifests, validationContext));
|
|
60
|
+
// Execute with concurrency control
|
|
34
61
|
const results = await this.executeConcurrently(executionTasks);
|
|
35
62
|
const totalExecutionTime = Date.now() - startTime;
|
|
36
63
|
const stats = this.calculateStats(results, totalExecutionTime);
|
|
@@ -43,6 +70,14 @@ export class ParallelExecutor {
|
|
|
43
70
|
});
|
|
44
71
|
return { results, stats };
|
|
45
72
|
}
|
|
73
|
+
/**
|
|
74
|
+
* Executes a single plugin with resource monitoring
|
|
75
|
+
* @param plugin - Plugin to execute
|
|
76
|
+
* @param manifests - Manifests to validate
|
|
77
|
+
* @param validationContext - Validation context
|
|
78
|
+
* @returns Promise resolving to execution result
|
|
79
|
+
* @private
|
|
80
|
+
*/
|
|
46
81
|
async executePlugin(plugin, manifests, validationContext) {
|
|
47
82
|
const startTime = Date.now();
|
|
48
83
|
const startMemory = process.memoryUsage().heapUsed;
|
|
@@ -52,6 +87,7 @@ export class ParallelExecutor {
|
|
|
52
87
|
operation: 'plugin_execution_start',
|
|
53
88
|
});
|
|
54
89
|
try {
|
|
90
|
+
// Execute plugin with timeout
|
|
55
91
|
const violations = await this.executeWithTimeout(plugin, manifests, validationContext, this.options.pluginTimeout);
|
|
56
92
|
const executionTime = Date.now() - startTime;
|
|
57
93
|
const endMemory = process.memoryUsage().heapUsed;
|
|
@@ -62,7 +98,7 @@ export class ParallelExecutor {
|
|
|
62
98
|
executionTime,
|
|
63
99
|
resourceUsage: {
|
|
64
100
|
memoryUsageMB,
|
|
65
|
-
cpuTimeMs: executionTime,
|
|
101
|
+
cpuTimeMs: executionTime, // Approximation
|
|
66
102
|
},
|
|
67
103
|
};
|
|
68
104
|
this.logger.debug('Plugin execution completed successfully', {
|
|
@@ -97,6 +133,15 @@ export class ParallelExecutor {
|
|
|
97
133
|
};
|
|
98
134
|
}
|
|
99
135
|
}
|
|
136
|
+
/**
|
|
137
|
+
* Executes plugin with timeout handling
|
|
138
|
+
* @param plugin - Plugin to execute
|
|
139
|
+
* @param manifests - Manifests to validate
|
|
140
|
+
* @param validationContext - Validation context
|
|
141
|
+
* @param timeout - Timeout in milliseconds
|
|
142
|
+
* @returns Promise resolving to violations
|
|
143
|
+
* @private
|
|
144
|
+
*/
|
|
100
145
|
async executeWithTimeout(plugin, manifests, validationContext, timeout) {
|
|
101
146
|
const timeoutPromise = new Promise((_, reject) => {
|
|
102
147
|
globalThis.setTimeout(() => {
|
|
@@ -106,6 +151,12 @@ export class ParallelExecutor {
|
|
|
106
151
|
const validationPromise = plugin.validate(manifests, validationContext);
|
|
107
152
|
return Promise.race([validationPromise, timeoutPromise]);
|
|
108
153
|
}
|
|
154
|
+
/**
|
|
155
|
+
* Executes tasks with concurrency control
|
|
156
|
+
* @param tasks - Array of execution tasks
|
|
157
|
+
* @returns Promise resolving to results
|
|
158
|
+
* @private
|
|
159
|
+
*/
|
|
109
160
|
async executeConcurrently(tasks) {
|
|
110
161
|
const results = [];
|
|
111
162
|
const executing = [];
|
|
@@ -116,6 +167,7 @@ export class ParallelExecutor {
|
|
|
116
167
|
return;
|
|
117
168
|
}
|
|
118
169
|
const currentTaskIndex = taskIndex++;
|
|
170
|
+
// eslint-disable-next-line security/detect-object-injection
|
|
119
171
|
const task = tasks[currentTaskIndex];
|
|
120
172
|
if (!task) {
|
|
121
173
|
return;
|
|
@@ -124,7 +176,9 @@ export class ParallelExecutor {
|
|
|
124
176
|
peakConcurrency = Math.max(peakConcurrency, this.activeExecutions);
|
|
125
177
|
try {
|
|
126
178
|
const result = await task();
|
|
179
|
+
// eslint-disable-next-line security/detect-object-injection
|
|
127
180
|
results[currentTaskIndex] = result;
|
|
181
|
+
// Check for fail-fast condition
|
|
128
182
|
if (this.options.failFast && result.error) {
|
|
129
183
|
this.logger.debug('Fail-fast triggered, stopping execution', {
|
|
130
184
|
pluginName: result.plugin.name,
|
|
@@ -135,6 +189,7 @@ export class ParallelExecutor {
|
|
|
135
189
|
}
|
|
136
190
|
}
|
|
137
191
|
catch (error) {
|
|
192
|
+
// This shouldn't happen as executePlugin catches all errors
|
|
138
193
|
this.logger.error('Unexpected error in parallel execution', {
|
|
139
194
|
taskIndex: currentTaskIndex,
|
|
140
195
|
error: error instanceof Error ? error.message : UNKNOWN_ERROR_MESSAGE,
|
|
@@ -144,14 +199,18 @@ export class ParallelExecutor {
|
|
|
144
199
|
finally {
|
|
145
200
|
this.activeExecutions--;
|
|
146
201
|
}
|
|
202
|
+
// Continue with next task if available and not in fail-fast mode
|
|
203
|
+
// eslint-disable-next-line security/detect-object-injection
|
|
147
204
|
if (!this.options.failFast || !results[currentTaskIndex]?.error) {
|
|
148
205
|
await executeNext();
|
|
149
206
|
}
|
|
150
207
|
};
|
|
208
|
+
// Start initial batch of concurrent executions
|
|
151
209
|
const maxConcurrency = this.options.maxConcurrency;
|
|
152
210
|
for (let i = 0; i < Math.min(maxConcurrency, tasks.length); i++) {
|
|
153
211
|
executing.push(executeNext());
|
|
154
212
|
}
|
|
213
|
+
// Wait for all executions to complete
|
|
155
214
|
await Promise.all(executing);
|
|
156
215
|
this.logger.debug('Concurrent execution completed', {
|
|
157
216
|
totalTasks: tasks.length,
|
|
@@ -159,8 +218,14 @@ export class ParallelExecutor {
|
|
|
159
218
|
peakConcurrency,
|
|
160
219
|
operation: 'concurrent_execution_complete',
|
|
161
220
|
});
|
|
162
|
-
return results.filter((r) => r);
|
|
221
|
+
return results.filter((r) => r); // Filter out undefined results
|
|
163
222
|
}
|
|
223
|
+
/**
|
|
224
|
+
* Sorts plugins by priority configuration
|
|
225
|
+
* @param plugins - Array of plugins to sort
|
|
226
|
+
* @returns Sorted array of plugins
|
|
227
|
+
* @private
|
|
228
|
+
*/
|
|
164
229
|
sortPluginsByPriority(plugins) {
|
|
165
230
|
if (!this.options.priorityConfig) {
|
|
166
231
|
return [...plugins];
|
|
@@ -179,12 +244,20 @@ export class ParallelExecutor {
|
|
|
179
244
|
});
|
|
180
245
|
return sortedPlugins;
|
|
181
246
|
}
|
|
247
|
+
/**
|
|
248
|
+
* Calculates execution statistics
|
|
249
|
+
* @param results - Array of execution results
|
|
250
|
+
* @param totalExecutionTime - Total execution time
|
|
251
|
+
* @returns Execution statistics
|
|
252
|
+
* @private
|
|
253
|
+
*/
|
|
182
254
|
calculateStats(results, totalExecutionTime) {
|
|
183
255
|
const executionTimes = results.map((r) => r.executionTime);
|
|
184
256
|
const averagePluginTime = executionTimes.reduce((sum, time) => sum + time, 0) / results.length;
|
|
185
257
|
const maxPluginTime = Math.max(...executionTimes);
|
|
186
258
|
const totalMemoryMB = results.reduce((sum, r) => sum + (r.resourceUsage?.memoryUsageMB || 0), 0);
|
|
187
259
|
const totalCpuTimeMs = results.reduce((sum, r) => sum + (r.resourceUsage?.cpuTimeMs || 0), 0);
|
|
260
|
+
// Calculate concurrency utilization
|
|
188
261
|
const theoreticalMinTime = Math.max(...executionTimes);
|
|
189
262
|
const concurrencyUtilization = theoreticalMinTime / totalExecutionTime;
|
|
190
263
|
return {
|
|
@@ -201,15 +274,25 @@ export class ParallelExecutor {
|
|
|
201
274
|
};
|
|
202
275
|
}
|
|
203
276
|
}
|
|
277
|
+
/**
|
|
278
|
+
* Utility function to determine optimal concurrency based on system resources
|
|
279
|
+
* @param pluginCount - Number of plugins to execute
|
|
280
|
+
* @param systemInfo - Optional system information
|
|
281
|
+
* @returns Recommended concurrency level
|
|
282
|
+
*/
|
|
204
283
|
export function calculateOptimalConcurrency(pluginCount, systemInfo) {
|
|
205
284
|
const cpuCount = systemInfo?.cpuCount || cpus().length;
|
|
206
285
|
const availableMemoryMB = systemInfo?.availableMemoryMB || totalmem() / (1024 * 1024);
|
|
286
|
+
// Base concurrency on CPU count
|
|
207
287
|
let optimalConcurrency = Math.max(2, Math.min(cpuCount, pluginCount));
|
|
288
|
+
// Adjust for memory constraints (assume 100MB per concurrent plugin)
|
|
208
289
|
const memoryBasedConcurrency = Math.floor(availableMemoryMB / 100);
|
|
209
290
|
optimalConcurrency = Math.min(optimalConcurrency, memoryBasedConcurrency);
|
|
291
|
+
// Reduce concurrency in containerized environments
|
|
210
292
|
if (systemInfo?.isContainerized) {
|
|
211
293
|
optimalConcurrency = Math.max(1, Math.floor(optimalConcurrency * 0.75));
|
|
212
294
|
}
|
|
295
|
+
// Cap at reasonable maximum
|
|
213
296
|
optimalConcurrency = Math.min(optimalConcurrency, 16);
|
|
214
297
|
return optimalConcurrency;
|
|
215
298
|
}
|