@sentriflow/cli 0.4.2 → 0.5.1
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/dist/index.js +123 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { createRequire } from 'module';
|
|
3
|
+
const require = createRequire(import.meta.url);
|
|
2
4
|
var __create = Object.create;
|
|
3
5
|
var __defProp = Object.defineProperty;
|
|
4
6
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -12323,7 +12325,7 @@ function generateSarif(results, filePath, rules, options = {}, ipSummary) {
|
|
|
12323
12325
|
tool: {
|
|
12324
12326
|
driver: {
|
|
12325
12327
|
name: "Sentriflow",
|
|
12326
|
-
version: "0.
|
|
12328
|
+
version: "0.5.1",
|
|
12327
12329
|
informationUri: "https://github.com/sentriflow/sentriflow",
|
|
12328
12330
|
rules: sarifRules,
|
|
12329
12331
|
// SEC-007: Include CWE taxonomy when rules reference it
|
|
@@ -12483,7 +12485,7 @@ function generateMultiFileSarif(fileResults, rules, options = {}) {
|
|
|
12483
12485
|
tool: {
|
|
12484
12486
|
driver: {
|
|
12485
12487
|
name: "Sentriflow",
|
|
12486
|
-
version: "0.
|
|
12488
|
+
version: "0.5.1",
|
|
12487
12489
|
informationUri: "https://github.com/sentriflow/sentriflow",
|
|
12488
12490
|
rules: sarifRules,
|
|
12489
12491
|
// SEC-007: Include CWE taxonomy when rules reference it
|
|
@@ -12527,6 +12529,103 @@ function generateMultiFileSarif(fileResults, rules, options = {}) {
|
|
|
12527
12529
|
return JSON.stringify(report, null, 2);
|
|
12528
12530
|
}
|
|
12529
12531
|
|
|
12532
|
+
// src/human.ts
|
|
12533
|
+
var COLORS = {
|
|
12534
|
+
red: "\x1B[31m",
|
|
12535
|
+
yellow: "\x1B[33m",
|
|
12536
|
+
blue: "\x1B[34m",
|
|
12537
|
+
gray: "\x1B[90m",
|
|
12538
|
+
bold: "\x1B[1m",
|
|
12539
|
+
reset: "\x1B[0m"
|
|
12540
|
+
};
|
|
12541
|
+
var SEVERITY_COLORS = {
|
|
12542
|
+
error: COLORS.red,
|
|
12543
|
+
warning: COLORS.yellow,
|
|
12544
|
+
info: COLORS.blue
|
|
12545
|
+
};
|
|
12546
|
+
function countSeverities(results) {
|
|
12547
|
+
const counts = { error: 0, warning: 0, info: 0, total: 0 };
|
|
12548
|
+
for (const r of results) {
|
|
12549
|
+
if (!r.passed) {
|
|
12550
|
+
if (r.level === "error" || r.level === "warning" || r.level === "info") {
|
|
12551
|
+
counts[r.level]++;
|
|
12552
|
+
}
|
|
12553
|
+
counts.total++;
|
|
12554
|
+
}
|
|
12555
|
+
}
|
|
12556
|
+
return counts;
|
|
12557
|
+
}
|
|
12558
|
+
function formatFinding(result, color) {
|
|
12559
|
+
const line = result.loc?.startLine ?? 0;
|
|
12560
|
+
const col = 1;
|
|
12561
|
+
const location = `${line}:${col}`.padEnd(8);
|
|
12562
|
+
const severityColor = color ? SEVERITY_COLORS[result.level] ?? "" : "";
|
|
12563
|
+
const reset = color ? COLORS.reset : "";
|
|
12564
|
+
const severityText = result.level.padEnd(7);
|
|
12565
|
+
const severity = `${severityColor}${severityText}${reset}`;
|
|
12566
|
+
const ruleColor = color ? COLORS.gray : "";
|
|
12567
|
+
const ruleId = `${ruleColor}${result.ruleId}${reset}`;
|
|
12568
|
+
return ` ${location} ${severity} ${result.message} ${ruleId}`;
|
|
12569
|
+
}
|
|
12570
|
+
function formatSummary(counts, color) {
|
|
12571
|
+
if (counts.total === 0) {
|
|
12572
|
+
const check = color ? `${COLORS.bold}\u2714${COLORS.reset}` : "\u2714";
|
|
12573
|
+
return `
|
|
12574
|
+
${check} No problems found
|
|
12575
|
+
`;
|
|
12576
|
+
}
|
|
12577
|
+
const x = color ? `${COLORS.red}\u2716${COLORS.reset}` : "\u2716";
|
|
12578
|
+
const parts = [];
|
|
12579
|
+
if (counts.error > 0) {
|
|
12580
|
+
parts.push(`${counts.error} error${counts.error !== 1 ? "s" : ""}`);
|
|
12581
|
+
}
|
|
12582
|
+
if (counts.warning > 0) {
|
|
12583
|
+
parts.push(`${counts.warning} warning${counts.warning !== 1 ? "s" : ""}`);
|
|
12584
|
+
}
|
|
12585
|
+
if (counts.info > 0) {
|
|
12586
|
+
parts.push(`${counts.info} info`);
|
|
12587
|
+
}
|
|
12588
|
+
const problemText = counts.total === 1 ? "problem" : "problems";
|
|
12589
|
+
return `
|
|
12590
|
+
${x} ${counts.total} ${problemText} (${parts.join(", ")})
|
|
12591
|
+
`;
|
|
12592
|
+
}
|
|
12593
|
+
function formatHuman(results, filePath, options) {
|
|
12594
|
+
const color = options?.color ?? false;
|
|
12595
|
+
const failures = results.filter((r) => !r.passed);
|
|
12596
|
+
const lines = [];
|
|
12597
|
+
const header = color ? `${COLORS.bold}${filePath}${COLORS.reset}` : filePath;
|
|
12598
|
+
lines.push(header);
|
|
12599
|
+
for (const result of failures) {
|
|
12600
|
+
lines.push(formatFinding(result, color));
|
|
12601
|
+
}
|
|
12602
|
+
const counts = countSeverities(results);
|
|
12603
|
+
lines.push(formatSummary(counts, color));
|
|
12604
|
+
return lines.join("\n");
|
|
12605
|
+
}
|
|
12606
|
+
function formatMultiFileHuman(files, options) {
|
|
12607
|
+
const color = options?.color ?? false;
|
|
12608
|
+
const lines = [];
|
|
12609
|
+
const totalCounts = { error: 0, warning: 0, info: 0, total: 0 };
|
|
12610
|
+
for (const { file, results } of files) {
|
|
12611
|
+
const failures = results.filter((r) => !r.passed);
|
|
12612
|
+
if (failures.length === 0) continue;
|
|
12613
|
+
const header = color ? `${COLORS.bold}${file}${COLORS.reset}` : file;
|
|
12614
|
+
lines.push(header);
|
|
12615
|
+
for (const result of failures) {
|
|
12616
|
+
lines.push(formatFinding(result, color));
|
|
12617
|
+
}
|
|
12618
|
+
lines.push("");
|
|
12619
|
+
const counts = countSeverities(results);
|
|
12620
|
+
totalCounts.error += counts.error;
|
|
12621
|
+
totalCounts.warning += counts.warning;
|
|
12622
|
+
totalCounts.info += counts.info;
|
|
12623
|
+
totalCounts.total += counts.total;
|
|
12624
|
+
}
|
|
12625
|
+
lines.push(formatSummary(totalCounts, color));
|
|
12626
|
+
return lines.join("\n");
|
|
12627
|
+
}
|
|
12628
|
+
|
|
12530
12629
|
// ../rules-default/src/common/network-rules.ts
|
|
12531
12630
|
var NoMulticastBroadcastIp = {
|
|
12532
12631
|
id: "NET-IP-001",
|
|
@@ -16510,7 +16609,7 @@ function enrichResultsWithRuleMetadata(results, rules) {
|
|
|
16510
16609
|
});
|
|
16511
16610
|
}
|
|
16512
16611
|
var program = new Command();
|
|
16513
|
-
program.name("sentriflow").description("SentriFlow Network Configuration Validator").version("0.
|
|
16612
|
+
program.name("sentriflow").description("SentriFlow Network Configuration Validator").version("0.5.1").argument("[files...]", "Path(s) to configuration file(s) (supports multiple files)").option("--ast", "Output the AST instead of rule results").option("-f, --format <format>", "Output format (json, human, sarif)", "json").option("-q, --quiet", "Only output failures (suppress passed results)").option("-c, --config <path>", "Path to config file (default: auto-detect)").option("--no-config", "Ignore config file").option("-r, --rules <path>", "Additional rules file to load (legacy)").option(
|
|
16514
16613
|
"--pack <path...>",
|
|
16515
16614
|
"Path(s) to rule pack(s) (.grx2 encrypted or unencrypted JS/TS modules)"
|
|
16516
16615
|
).option(
|
|
@@ -16937,6 +17036,13 @@ Parsing complete: ${allAsts.length} files`);
|
|
|
16937
17036
|
console.log(
|
|
16938
17037
|
generateMultiFileSarif(allFileResults, rules, sarifOptions)
|
|
16939
17038
|
);
|
|
17039
|
+
} else if (options.format === "human") {
|
|
17040
|
+
const isColorEnabled = process.stdout.isTTY && !process.env.NO_COLOR;
|
|
17041
|
+
const humanFiles = allFileResults.map((fr) => ({
|
|
17042
|
+
file: fr.filePath,
|
|
17043
|
+
results: fr.results
|
|
17044
|
+
}));
|
|
17045
|
+
console.log(formatMultiFileHuman(humanFiles, { color: isColorEnabled }));
|
|
16940
17046
|
} else {
|
|
16941
17047
|
const output = {
|
|
16942
17048
|
summary: {
|
|
@@ -17054,6 +17160,9 @@ Scan complete: ${allFileResults.length} files, ${totalFailures} failures, ${tota
|
|
|
17054
17160
|
baseDir: process.cwd()
|
|
17055
17161
|
};
|
|
17056
17162
|
console.log(generateSarif(results2, "<stdin>", stdinRules, sarifOptions, stdinIpSummary));
|
|
17163
|
+
} else if (options.format === "human") {
|
|
17164
|
+
const isColorEnabled = process.stdout.isTTY && !process.env.NO_COLOR;
|
|
17165
|
+
console.log(formatHuman(results2, "<stdin>", { color: isColorEnabled }));
|
|
17057
17166
|
} else {
|
|
17058
17167
|
const output = {
|
|
17059
17168
|
file: "<stdin>",
|
|
@@ -17153,6 +17262,13 @@ Scan complete: ${allFileResults.length} files, ${totalFailures} failures, ${tota
|
|
|
17153
17262
|
console.log(
|
|
17154
17263
|
generateMultiFileSarif(allFileResults, rules, sarifOptions)
|
|
17155
17264
|
);
|
|
17265
|
+
} else if (options.format === "human") {
|
|
17266
|
+
const isColorEnabled = process.stdout.isTTY && !process.env.NO_COLOR;
|
|
17267
|
+
const humanFiles = allFileResults.map((fr) => ({
|
|
17268
|
+
file: fr.filePath,
|
|
17269
|
+
results: fr.results
|
|
17270
|
+
}));
|
|
17271
|
+
console.log(formatMultiFileHuman(humanFiles, { color: isColorEnabled }));
|
|
17156
17272
|
} else {
|
|
17157
17273
|
const output = {
|
|
17158
17274
|
summary: {
|
|
@@ -17271,6 +17387,9 @@ Scan complete: ${allFileResults.length} files, ${totalFailures} failures, ${tota
|
|
|
17271
17387
|
console.log(
|
|
17272
17388
|
generateSarif(results, filePath, singleFileRules, sarifOptions, ipSummary)
|
|
17273
17389
|
);
|
|
17390
|
+
} else if (options.format === "human") {
|
|
17391
|
+
const isColorEnabled = process.stdout.isTTY && !process.env.NO_COLOR;
|
|
17392
|
+
console.log(formatHuman(results, filePath, { color: isColorEnabled }));
|
|
17274
17393
|
} else {
|
|
17275
17394
|
const output = {
|
|
17276
17395
|
vendor: {
|
|
@@ -17305,7 +17424,7 @@ async function loadLicensingExtension() {
|
|
|
17305
17424
|
licensingModulePath
|
|
17306
17425
|
);
|
|
17307
17426
|
if (licensing.registerCommands) {
|
|
17308
|
-
licensing.registerCommands(program, { cliVersion: "0.
|
|
17427
|
+
licensing.registerCommands(program, { cliVersion: "0.5.1" });
|
|
17309
17428
|
}
|
|
17310
17429
|
} catch {
|
|
17311
17430
|
const licensingMessage = `
|