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,8 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Result Aggregation Utilities
|
|
3
|
+
*
|
|
4
|
+
* This module provides utilities for aggregating and processing policy validation results.
|
|
5
|
+
* It includes functions for combining results from multiple plugins, generating summaries,
|
|
6
|
+
* and formatting output.
|
|
7
|
+
*
|
|
8
|
+
* @since 3.0.0
|
|
9
|
+
*/
|
|
1
10
|
import type { PolicyResult, PolicyViolation, PolicyWarning, ResultSummary } from './types.js';
|
|
11
|
+
/**
|
|
12
|
+
* Aggregates multiple policy results into a single result
|
|
13
|
+
* @param results - Array of policy results to aggregate
|
|
14
|
+
* @returns Aggregated policy result
|
|
15
|
+
*/
|
|
2
16
|
export declare function aggregateResults(results: PolicyResult[]): PolicyResult;
|
|
17
|
+
/**
|
|
18
|
+
* Generates a summary of validation results
|
|
19
|
+
* @param violations - Array of policy violations
|
|
20
|
+
* @param warnings - Array of policy warnings
|
|
21
|
+
* @param allPlugins - Array of all plugins that were executed (optional)
|
|
22
|
+
* @returns Result summary with statistics
|
|
23
|
+
*/
|
|
3
24
|
export declare function generateResultSummary(violations: PolicyViolation[], warnings: PolicyWarning[], allPlugins?: string[]): ResultSummary;
|
|
25
|
+
/**
|
|
26
|
+
* Filters violations by severity level
|
|
27
|
+
* @param violations - Array of violations to filter
|
|
28
|
+
* @param severity - Severity level to filter by
|
|
29
|
+
* @returns Filtered violations
|
|
30
|
+
*/
|
|
4
31
|
export declare function filterViolationsBySeverity(violations: PolicyViolation[], severity: 'error' | 'warning' | 'info'): PolicyViolation[];
|
|
32
|
+
/**
|
|
33
|
+
* Groups violations by plugin name
|
|
34
|
+
* @param violations - Array of violations to group
|
|
35
|
+
* @returns Violations grouped by plugin name
|
|
36
|
+
*/
|
|
5
37
|
export declare function groupViolationsByPlugin(violations: PolicyViolation[]): Record<string, PolicyViolation[]>;
|
|
38
|
+
/**
|
|
39
|
+
* Sorts violations by severity (error > warning > info)
|
|
40
|
+
* @param violations - Array of violations to sort
|
|
41
|
+
* @returns Sorted violations
|
|
42
|
+
*/
|
|
6
43
|
export declare function sortViolationsBySeverity(violations: PolicyViolation[]): PolicyViolation[];
|
|
44
|
+
/**
|
|
45
|
+
* Creates an empty policy result for cases with no violations
|
|
46
|
+
* @returns Empty policy result
|
|
47
|
+
*/
|
|
7
48
|
export declare function createEmptyResult(): PolicyResult;
|
|
49
|
+
/**
|
|
50
|
+
* Merges violation context objects safely
|
|
51
|
+
* @param contexts - Array of context objects to merge
|
|
52
|
+
* @returns Merged context object
|
|
53
|
+
*/
|
|
8
54
|
export declare function mergeViolationContexts(contexts: Array<Record<string, unknown> | undefined>): Record<string, unknown>;
|
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Result Aggregation Utilities
|
|
3
|
+
*
|
|
4
|
+
* This module provides utilities for aggregating and processing policy validation results.
|
|
5
|
+
* It includes functions for combining results from multiple plugins, generating summaries,
|
|
6
|
+
* and formatting output.
|
|
7
|
+
*
|
|
8
|
+
* @since 3.0.0
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Aggregates multiple policy results into a single result
|
|
12
|
+
* @param results - Array of policy results to aggregate
|
|
13
|
+
* @returns Aggregated policy result
|
|
14
|
+
*/
|
|
1
15
|
export function aggregateResults(results) {
|
|
2
16
|
if (results.length === 0) {
|
|
3
17
|
return createEmptyResult();
|
|
@@ -39,52 +53,87 @@ export function aggregateResults(results) {
|
|
|
39
53
|
};
|
|
40
54
|
return aggregatedResult;
|
|
41
55
|
}
|
|
56
|
+
/**
|
|
57
|
+
* Generates a summary of validation results
|
|
58
|
+
* @param violations - Array of policy violations
|
|
59
|
+
* @param warnings - Array of policy warnings
|
|
60
|
+
* @param allPlugins - Array of all plugins that were executed (optional)
|
|
61
|
+
* @returns Result summary with statistics
|
|
62
|
+
*/
|
|
42
63
|
export function generateResultSummary(violations, warnings, allPlugins) {
|
|
43
64
|
const allViolations = [...violations, ...warnings];
|
|
65
|
+
// Count violations by severity
|
|
44
66
|
const violationsBySeverity = {
|
|
45
67
|
error: violations.filter((v) => v.severity === 'error').length,
|
|
46
68
|
warning: allViolations.filter((v) => v.severity === 'warning').length,
|
|
47
69
|
info: allViolations.filter((v) => v.severity === 'info').length,
|
|
48
70
|
};
|
|
71
|
+
// Count violations by plugin
|
|
49
72
|
const violationsByPlugin = Object.create(null);
|
|
73
|
+
// Initialize all plugins with 0 violations if provided
|
|
50
74
|
if (allPlugins) {
|
|
51
75
|
for (const pluginName of allPlugins) {
|
|
76
|
+
// eslint-disable-next-line security/detect-object-injection
|
|
52
77
|
violationsByPlugin[pluginName] = 0;
|
|
53
78
|
}
|
|
54
79
|
}
|
|
80
|
+
// Count actual violations
|
|
55
81
|
for (const violation of allViolations) {
|
|
56
82
|
const pluginName = violation.plugin;
|
|
83
|
+
// eslint-disable-next-line security/detect-object-injection
|
|
57
84
|
violationsByPlugin[pluginName] = (violationsByPlugin[pluginName] || 0) + 1;
|
|
58
85
|
}
|
|
86
|
+
// Find top violation types (based on message patterns)
|
|
59
87
|
const violationTypeCount = Object.create(null);
|
|
60
88
|
for (const violation of allViolations) {
|
|
89
|
+
// Extract violation type from message (first sentence or first 50 chars)
|
|
61
90
|
const type = extractViolationType(violation.message);
|
|
91
|
+
// eslint-disable-next-line security/detect-object-injection
|
|
62
92
|
violationTypeCount[type] = (violationTypeCount[type] || 0) + 1;
|
|
63
93
|
}
|
|
64
94
|
const topViolationTypes = Object.entries(violationTypeCount)
|
|
65
95
|
.map(([type, count]) => ({ type, count }))
|
|
66
96
|
.sort((a, b) => b.count - a.count)
|
|
67
|
-
.slice(0, 5);
|
|
97
|
+
.slice(0, 5); // Top 5 violation types
|
|
68
98
|
return {
|
|
69
99
|
violationsBySeverity,
|
|
70
100
|
violationsByPlugin,
|
|
71
101
|
topViolationTypes,
|
|
72
102
|
};
|
|
73
103
|
}
|
|
104
|
+
/**
|
|
105
|
+
* Filters violations by severity level
|
|
106
|
+
* @param violations - Array of violations to filter
|
|
107
|
+
* @param severity - Severity level to filter by
|
|
108
|
+
* @returns Filtered violations
|
|
109
|
+
*/
|
|
74
110
|
export function filterViolationsBySeverity(violations, severity) {
|
|
75
111
|
return violations.filter((v) => v.severity === severity);
|
|
76
112
|
}
|
|
113
|
+
/**
|
|
114
|
+
* Groups violations by plugin name
|
|
115
|
+
* @param violations - Array of violations to group
|
|
116
|
+
* @returns Violations grouped by plugin name
|
|
117
|
+
*/
|
|
77
118
|
export function groupViolationsByPlugin(violations) {
|
|
78
119
|
const grouped = Object.create(null);
|
|
79
120
|
for (const violation of violations) {
|
|
80
121
|
const pluginName = violation.plugin;
|
|
122
|
+
// eslint-disable-next-line security/detect-object-injection
|
|
81
123
|
if (!grouped[pluginName]) {
|
|
124
|
+
// eslint-disable-next-line security/detect-object-injection
|
|
82
125
|
grouped[pluginName] = [];
|
|
83
126
|
}
|
|
127
|
+
// eslint-disable-next-line security/detect-object-injection
|
|
84
128
|
grouped[pluginName].push(violation);
|
|
85
129
|
}
|
|
86
130
|
return grouped;
|
|
87
131
|
}
|
|
132
|
+
/**
|
|
133
|
+
* Sorts violations by severity (error > warning > info)
|
|
134
|
+
* @param violations - Array of violations to sort
|
|
135
|
+
* @returns Sorted violations
|
|
136
|
+
*/
|
|
88
137
|
export function sortViolationsBySeverity(violations) {
|
|
89
138
|
const severityOrder = { error: 0, warning: 1, info: 2 };
|
|
90
139
|
return [...violations].sort((a, b) => {
|
|
@@ -93,12 +142,17 @@ export function sortViolationsBySeverity(violations) {
|
|
|
93
142
|
if (orderA !== orderB) {
|
|
94
143
|
return orderA - orderB;
|
|
95
144
|
}
|
|
145
|
+
// If same severity, sort by plugin name, then by message
|
|
96
146
|
if (a.plugin !== b.plugin) {
|
|
97
147
|
return a.plugin.localeCompare(b.plugin);
|
|
98
148
|
}
|
|
99
149
|
return a.message.localeCompare(b.message);
|
|
100
150
|
});
|
|
101
151
|
}
|
|
152
|
+
/**
|
|
153
|
+
* Creates an empty policy result for cases with no violations
|
|
154
|
+
* @returns Empty policy result
|
|
155
|
+
*/
|
|
102
156
|
export function createEmptyResult() {
|
|
103
157
|
const metadata = {
|
|
104
158
|
executionTime: 0,
|
|
@@ -117,19 +171,33 @@ export function createEmptyResult() {
|
|
|
117
171
|
},
|
|
118
172
|
};
|
|
119
173
|
}
|
|
174
|
+
/**
|
|
175
|
+
* Extracts a violation type identifier from a violation message
|
|
176
|
+
* @param message - Violation message
|
|
177
|
+
* @returns Violation type string
|
|
178
|
+
* @private
|
|
179
|
+
*/
|
|
120
180
|
function extractViolationType(message) {
|
|
181
|
+
// Try to extract the first sentence
|
|
121
182
|
const sentences = message.split('.');
|
|
122
183
|
const firstSentence = sentences.length > 0 ? sentences[0] : message;
|
|
123
184
|
if (firstSentence && firstSentence.length <= 50) {
|
|
124
185
|
return firstSentence.trim();
|
|
125
186
|
}
|
|
187
|
+
// If first sentence is too long, take first 50 characters
|
|
126
188
|
return message.substring(0, 50).trim() + '...';
|
|
127
189
|
}
|
|
190
|
+
/**
|
|
191
|
+
* Merges violation context objects safely
|
|
192
|
+
* @param contexts - Array of context objects to merge
|
|
193
|
+
* @returns Merged context object
|
|
194
|
+
*/
|
|
128
195
|
export function mergeViolationContexts(contexts) {
|
|
129
196
|
const merged = Object.create(null);
|
|
130
197
|
for (const context of contexts) {
|
|
131
198
|
if (context && typeof context === 'object') {
|
|
132
199
|
for (const [key, value] of Object.entries(context)) {
|
|
200
|
+
// eslint-disable-next-line security/detect-object-injection
|
|
133
201
|
merged[key] = value;
|
|
134
202
|
}
|
|
135
203
|
}
|
|
@@ -1,25 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Result Formatters
|
|
3
|
+
*
|
|
4
|
+
* This module provides formatters for policy validation results, including
|
|
5
|
+
* default formatters and support for custom formatting.
|
|
6
|
+
*
|
|
7
|
+
* @since 3.0.0
|
|
8
|
+
*/
|
|
1
9
|
import type { PolicyResult, ResultFormatter } from './types.js';
|
|
10
|
+
/**
|
|
11
|
+
* Default result formatter that provides human-readable output
|
|
12
|
+
*/
|
|
2
13
|
export declare class DefaultResultFormatter implements ResultFormatter {
|
|
14
|
+
/**
|
|
15
|
+
* Formats validation results for output
|
|
16
|
+
* @param result - Validation result to format
|
|
17
|
+
* @returns Formatted string representation
|
|
18
|
+
*/
|
|
3
19
|
format(result: PolicyResult): string;
|
|
20
|
+
/**
|
|
21
|
+
* Formats a single violation for display
|
|
22
|
+
* @param violation - Violation to format
|
|
23
|
+
* @returns Formatted violation string
|
|
24
|
+
* @private
|
|
25
|
+
*/
|
|
4
26
|
private formatViolation;
|
|
27
|
+
/**
|
|
28
|
+
* Gets the appropriate icon for a severity level
|
|
29
|
+
* @param severity - Severity level
|
|
30
|
+
* @returns Icon string
|
|
31
|
+
* @private
|
|
32
|
+
*/
|
|
5
33
|
private getSeverityIcon;
|
|
6
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* JSON result formatter that outputs structured JSON
|
|
37
|
+
*/
|
|
7
38
|
export declare class JsonResultFormatter implements ResultFormatter {
|
|
8
39
|
private indent;
|
|
9
40
|
constructor(indent?: number);
|
|
41
|
+
/**
|
|
42
|
+
* Formats validation results as JSON
|
|
43
|
+
* @param result - Validation result to format
|
|
44
|
+
* @returns JSON string representation
|
|
45
|
+
*/
|
|
10
46
|
format(result: PolicyResult): string;
|
|
11
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* Compact result formatter for CI/CD environments
|
|
50
|
+
*/
|
|
12
51
|
export declare class CompactResultFormatter implements ResultFormatter {
|
|
52
|
+
/**
|
|
53
|
+
* Formats validation results in a compact format
|
|
54
|
+
* @param result - Validation result to format
|
|
55
|
+
* @returns Compact string representation
|
|
56
|
+
*/
|
|
13
57
|
format(result: PolicyResult): string;
|
|
14
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* GitHub Actions result formatter that outputs in GitHub Actions format
|
|
61
|
+
*/
|
|
15
62
|
export declare class GitHubActionsResultFormatter implements ResultFormatter {
|
|
63
|
+
/**
|
|
64
|
+
* Formats validation results for GitHub Actions
|
|
65
|
+
* @param result - Validation result to format
|
|
66
|
+
* @returns GitHub Actions formatted string
|
|
67
|
+
*/
|
|
16
68
|
format(result: PolicyResult): string;
|
|
17
69
|
}
|
|
70
|
+
/**
|
|
71
|
+
* SARIF (Static Analysis Results Interchange Format) result formatter
|
|
72
|
+
*/
|
|
18
73
|
export declare class SarifResultFormatter implements ResultFormatter {
|
|
74
|
+
/**
|
|
75
|
+
* Formats validation results as SARIF JSON
|
|
76
|
+
* @param result - Validation result to format
|
|
77
|
+
* @returns SARIF JSON string
|
|
78
|
+
*/
|
|
19
79
|
format(result: PolicyResult): string;
|
|
80
|
+
/**
|
|
81
|
+
* Converts violations to SARIF results format
|
|
82
|
+
* @param violations - Violations to convert
|
|
83
|
+
* @returns SARIF results array
|
|
84
|
+
* @private
|
|
85
|
+
*/
|
|
20
86
|
private convertViolationsToSarifResults;
|
|
87
|
+
/**
|
|
88
|
+
* Generates a rule ID from a violation message
|
|
89
|
+
* @param message - Violation message
|
|
90
|
+
* @returns Rule ID string
|
|
91
|
+
* @private
|
|
92
|
+
*/
|
|
21
93
|
private generateRuleId;
|
|
94
|
+
/**
|
|
95
|
+
* Maps violation severity to SARIF level
|
|
96
|
+
* @param severity - Violation severity
|
|
97
|
+
* @returns SARIF level string
|
|
98
|
+
* @private
|
|
99
|
+
*/
|
|
22
100
|
private mapSeverityToSarifLevel;
|
|
23
101
|
}
|
|
102
|
+
/**
|
|
103
|
+
* Factory function to create formatters by name
|
|
104
|
+
* @param name - Formatter name
|
|
105
|
+
* @param options - Formatter options
|
|
106
|
+
* @returns Result formatter instance
|
|
107
|
+
*/
|
|
24
108
|
export declare function createFormatter(name: string, options?: Record<string, unknown>): ResultFormatter;
|
|
109
|
+
/**
|
|
110
|
+
* Gets a list of available formatter names
|
|
111
|
+
* @returns Array of formatter names
|
|
112
|
+
*/
|
|
25
113
|
export declare function getAvailableFormatters(): string[];
|
|
@@ -1,13 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Result Formatters
|
|
3
|
+
*
|
|
4
|
+
* This module provides formatters for policy validation results, including
|
|
5
|
+
* default formatters and support for custom formatting.
|
|
6
|
+
*
|
|
7
|
+
* @since 3.0.0
|
|
8
|
+
*/
|
|
1
9
|
import { sortViolationsBySeverity } from './resultAggregator.js';
|
|
10
|
+
/**
|
|
11
|
+
* Default result formatter that provides human-readable output
|
|
12
|
+
*/
|
|
2
13
|
export class DefaultResultFormatter {
|
|
14
|
+
/**
|
|
15
|
+
* Formats validation results for output
|
|
16
|
+
* @param result - Validation result to format
|
|
17
|
+
* @returns Formatted string representation
|
|
18
|
+
*/
|
|
3
19
|
format(result) {
|
|
4
20
|
const lines = [];
|
|
21
|
+
// Header
|
|
5
22
|
lines.push('='.repeat(60));
|
|
6
23
|
lines.push('Policy Validation Results');
|
|
7
24
|
lines.push('='.repeat(60));
|
|
25
|
+
// Overall status
|
|
8
26
|
const status = result.valid ? '✅ PASSED' : '❌ FAILED';
|
|
9
27
|
lines.push(`Status: ${status}`);
|
|
10
28
|
lines.push('');
|
|
29
|
+
// Summary statistics
|
|
11
30
|
if (result.summary) {
|
|
12
31
|
lines.push('Summary:');
|
|
13
32
|
lines.push(` Errors: ${result.summary.violationsBySeverity.error}`);
|
|
@@ -15,11 +34,13 @@ export class DefaultResultFormatter {
|
|
|
15
34
|
lines.push(` Info: ${result.summary.violationsBySeverity.info}`);
|
|
16
35
|
lines.push('');
|
|
17
36
|
}
|
|
37
|
+
// Execution metadata
|
|
18
38
|
lines.push('Execution Details:');
|
|
19
39
|
lines.push(` Plugins: ${result.metadata.pluginCount}`);
|
|
20
40
|
lines.push(` Manifests: ${result.metadata.manifestCount}`);
|
|
21
41
|
lines.push(` Duration: ${result.metadata.executionTime}ms`);
|
|
22
42
|
lines.push('');
|
|
43
|
+
// Violations
|
|
23
44
|
if (result.violations.length > 0) {
|
|
24
45
|
lines.push('Violations:');
|
|
25
46
|
lines.push('-'.repeat(40));
|
|
@@ -29,6 +50,7 @@ export class DefaultResultFormatter {
|
|
|
29
50
|
lines.push('');
|
|
30
51
|
}
|
|
31
52
|
}
|
|
53
|
+
// Warnings
|
|
32
54
|
if (result.warnings.length > 0) {
|
|
33
55
|
lines.push('Warnings:');
|
|
34
56
|
lines.push('-'.repeat(40));
|
|
@@ -38,27 +60,43 @@ export class DefaultResultFormatter {
|
|
|
38
60
|
lines.push('');
|
|
39
61
|
}
|
|
40
62
|
}
|
|
63
|
+
// No issues message
|
|
41
64
|
if (result.violations.length === 0 && result.warnings.length === 0) {
|
|
42
65
|
lines.push('✨ No policy violations found!');
|
|
43
66
|
lines.push('');
|
|
44
67
|
}
|
|
45
68
|
return lines.join('\n');
|
|
46
69
|
}
|
|
70
|
+
/**
|
|
71
|
+
* Formats a single violation for display
|
|
72
|
+
* @param violation - Violation to format
|
|
73
|
+
* @returns Formatted violation string
|
|
74
|
+
* @private
|
|
75
|
+
*/
|
|
47
76
|
formatViolation(violation) {
|
|
48
77
|
const lines = [];
|
|
78
|
+
// Severity icon and plugin
|
|
49
79
|
const severityIcon = this.getSeverityIcon(violation.severity);
|
|
50
80
|
lines.push(`${severityIcon} [${violation.plugin}] ${violation.message}`);
|
|
81
|
+
// Resource path and field
|
|
51
82
|
if (violation.resourcePath) {
|
|
52
83
|
lines.push(` Resource: ${violation.resourcePath}`);
|
|
53
84
|
}
|
|
54
85
|
if (violation.field) {
|
|
55
86
|
lines.push(` Field: ${violation.field}`);
|
|
56
87
|
}
|
|
88
|
+
// Suggestion
|
|
57
89
|
if (violation.suggestion) {
|
|
58
90
|
lines.push(` 💡 Suggestion: ${violation.suggestion}`);
|
|
59
91
|
}
|
|
60
92
|
return lines.join('\n');
|
|
61
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* Gets the appropriate icon for a severity level
|
|
96
|
+
* @param severity - Severity level
|
|
97
|
+
* @returns Icon string
|
|
98
|
+
* @private
|
|
99
|
+
*/
|
|
62
100
|
getSeverityIcon(severity) {
|
|
63
101
|
switch (severity) {
|
|
64
102
|
case 'error':
|
|
@@ -72,15 +110,31 @@ export class DefaultResultFormatter {
|
|
|
72
110
|
}
|
|
73
111
|
}
|
|
74
112
|
}
|
|
113
|
+
/**
|
|
114
|
+
* JSON result formatter that outputs structured JSON
|
|
115
|
+
*/
|
|
75
116
|
export class JsonResultFormatter {
|
|
76
117
|
constructor(indent = 2) {
|
|
77
118
|
this.indent = indent;
|
|
78
119
|
}
|
|
120
|
+
/**
|
|
121
|
+
* Formats validation results as JSON
|
|
122
|
+
* @param result - Validation result to format
|
|
123
|
+
* @returns JSON string representation
|
|
124
|
+
*/
|
|
79
125
|
format(result) {
|
|
80
126
|
return JSON.stringify(result, null, this.indent);
|
|
81
127
|
}
|
|
82
128
|
}
|
|
129
|
+
/**
|
|
130
|
+
* Compact result formatter for CI/CD environments
|
|
131
|
+
*/
|
|
83
132
|
export class CompactResultFormatter {
|
|
133
|
+
/**
|
|
134
|
+
* Formats validation results in a compact format
|
|
135
|
+
* @param result - Validation result to format
|
|
136
|
+
* @returns Compact string representation
|
|
137
|
+
*/
|
|
84
138
|
format(result) {
|
|
85
139
|
const status = result.valid ? 'PASS' : 'FAIL';
|
|
86
140
|
const errorCount = result.violations.filter((v) => v.severity === 'error').length;
|
|
@@ -90,6 +144,7 @@ export class CompactResultFormatter {
|
|
|
90
144
|
output += ` (${errorCount} errors, ${warningCount} warnings)`;
|
|
91
145
|
}
|
|
92
146
|
output += ` - ${result.metadata.executionTime}ms`;
|
|
147
|
+
// Add first few violations for context
|
|
93
148
|
if (!result.valid && result.violations.length > 0) {
|
|
94
149
|
output += '\n';
|
|
95
150
|
const firstViolations = result.violations.slice(0, 3);
|
|
@@ -103,11 +158,21 @@ export class CompactResultFormatter {
|
|
|
103
158
|
return output;
|
|
104
159
|
}
|
|
105
160
|
}
|
|
161
|
+
/**
|
|
162
|
+
* GitHub Actions result formatter that outputs in GitHub Actions format
|
|
163
|
+
*/
|
|
106
164
|
export class GitHubActionsResultFormatter {
|
|
165
|
+
/**
|
|
166
|
+
* Formats validation results for GitHub Actions
|
|
167
|
+
* @param result - Validation result to format
|
|
168
|
+
* @returns GitHub Actions formatted string
|
|
169
|
+
*/
|
|
107
170
|
format(result) {
|
|
108
171
|
const lines = [];
|
|
172
|
+
// Output summary
|
|
109
173
|
const status = result.valid ? 'success' : 'failure';
|
|
110
174
|
lines.push(`::notice title=Policy Validation::Status: ${status}`);
|
|
175
|
+
// Output violations as errors/warnings
|
|
111
176
|
for (const violation of result.violations) {
|
|
112
177
|
const level = violation.severity === 'error' ? 'error' : 'warning';
|
|
113
178
|
const file = violation.resourcePath || 'unknown';
|
|
@@ -123,7 +188,15 @@ export class GitHubActionsResultFormatter {
|
|
|
123
188
|
return lines.join('\n');
|
|
124
189
|
}
|
|
125
190
|
}
|
|
191
|
+
/**
|
|
192
|
+
* SARIF (Static Analysis Results Interchange Format) result formatter
|
|
193
|
+
*/
|
|
126
194
|
export class SarifResultFormatter {
|
|
195
|
+
/**
|
|
196
|
+
* Formats validation results as SARIF JSON
|
|
197
|
+
* @param result - Validation result to format
|
|
198
|
+
* @returns SARIF JSON string
|
|
199
|
+
*/
|
|
127
200
|
format(result) {
|
|
128
201
|
const runs = [
|
|
129
202
|
{
|
|
@@ -144,6 +217,12 @@ export class SarifResultFormatter {
|
|
|
144
217
|
};
|
|
145
218
|
return JSON.stringify(sarif, null, 2);
|
|
146
219
|
}
|
|
220
|
+
/**
|
|
221
|
+
* Converts violations to SARIF results format
|
|
222
|
+
* @param violations - Violations to convert
|
|
223
|
+
* @returns SARIF results array
|
|
224
|
+
* @private
|
|
225
|
+
*/
|
|
147
226
|
convertViolationsToSarifResults(violations) {
|
|
148
227
|
return violations.map((violation) => ({
|
|
149
228
|
ruleId: `${violation.plugin}/${this.generateRuleId(violation.message)}`,
|
|
@@ -175,6 +254,12 @@ export class SarifResultFormatter {
|
|
|
175
254
|
},
|
|
176
255
|
}));
|
|
177
256
|
}
|
|
257
|
+
/**
|
|
258
|
+
* Generates a rule ID from a violation message
|
|
259
|
+
* @param message - Violation message
|
|
260
|
+
* @returns Rule ID string
|
|
261
|
+
* @private
|
|
262
|
+
*/
|
|
178
263
|
generateRuleId(message) {
|
|
179
264
|
return message
|
|
180
265
|
.toLowerCase()
|
|
@@ -182,6 +267,12 @@ export class SarifResultFormatter {
|
|
|
182
267
|
.replace(/\s+/g, '-')
|
|
183
268
|
.substring(0, 50);
|
|
184
269
|
}
|
|
270
|
+
/**
|
|
271
|
+
* Maps violation severity to SARIF level
|
|
272
|
+
* @param severity - Violation severity
|
|
273
|
+
* @returns SARIF level string
|
|
274
|
+
* @private
|
|
275
|
+
*/
|
|
185
276
|
mapSeverityToSarifLevel(severity) {
|
|
186
277
|
switch (severity) {
|
|
187
278
|
case 'error':
|
|
@@ -195,6 +286,12 @@ export class SarifResultFormatter {
|
|
|
195
286
|
}
|
|
196
287
|
}
|
|
197
288
|
}
|
|
289
|
+
/**
|
|
290
|
+
* Factory function to create formatters by name
|
|
291
|
+
* @param name - Formatter name
|
|
292
|
+
* @param options - Formatter options
|
|
293
|
+
* @returns Result formatter instance
|
|
294
|
+
*/
|
|
198
295
|
export function createFormatter(name, options) {
|
|
199
296
|
switch (name.toLowerCase()) {
|
|
200
297
|
case 'default':
|
|
@@ -212,6 +309,10 @@ export function createFormatter(name, options) {
|
|
|
212
309
|
throw new Error(`Unknown formatter: ${name}`);
|
|
213
310
|
}
|
|
214
311
|
}
|
|
312
|
+
/**
|
|
313
|
+
* Gets a list of available formatter names
|
|
314
|
+
* @returns Array of formatter names
|
|
315
|
+
*/
|
|
215
316
|
export function getAvailableFormatters() {
|
|
216
317
|
return ['default', 'json', 'compact', 'github-actions', 'sarif'];
|
|
217
318
|
}
|