cloudburn 0.8.5 → 0.9.0
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/README.md +2 -0
- package/dist/cli.js +122 -87
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -64,8 +64,10 @@ cloudburn discover
|
|
|
64
64
|
cloudburn discover --region eu-central-1
|
|
65
65
|
cloudburn discover --region all
|
|
66
66
|
cloudburn discover --config .cloudburn.yml --enabled-rules CLDBRN-AWS-EBS-1
|
|
67
|
+
cloudburn discover --service ec2,s3
|
|
67
68
|
cloudburn discover list-enabled-regions --format text
|
|
68
69
|
cloudburn rules list
|
|
70
|
+
cloudburn rules list --service ec2 --source discovery
|
|
69
71
|
```
|
|
70
72
|
|
|
71
73
|
`cloudburn discover --region all` needs an AWS Resource Explorer aggregator and an unfiltered default view in the aggregator region.
|
package/dist/cli.js
CHANGED
|
@@ -543,7 +543,7 @@ var getScanDiagnostics = (result) => result.diagnostics ?? [];
|
|
|
543
543
|
var DEFAULT_TABLE_WIDTH = 200;
|
|
544
544
|
var MIN_COLUMN_WIDTH = 4;
|
|
545
545
|
var PREFERRED_MIN_COLUMN_WIDTH = 8;
|
|
546
|
-
var supportedOutputFormats = ["
|
|
546
|
+
var supportedOutputFormats = ["json", "table"];
|
|
547
547
|
var scanColumns = [
|
|
548
548
|
{ key: "provider", header: "Provider" },
|
|
549
549
|
{ key: "ruleId", header: "RuleId" },
|
|
@@ -557,7 +557,15 @@ var scanColumns = [
|
|
|
557
557
|
{ key: "column", header: "Column" },
|
|
558
558
|
{ key: "message", header: "Message" }
|
|
559
559
|
];
|
|
560
|
-
var
|
|
560
|
+
var ruleListColumns = [
|
|
561
|
+
{ key: "ruleId", header: "RuleId" },
|
|
562
|
+
{ key: "provider", header: "Provider" },
|
|
563
|
+
{ key: "service", header: "Service" },
|
|
564
|
+
{ key: "supports", header: "Supports" },
|
|
565
|
+
{ key: "name", header: "Name" },
|
|
566
|
+
{ key: "description", header: "Description" }
|
|
567
|
+
];
|
|
568
|
+
var formatOptionDescription = "Options: table: human-readable terminal output.\njson: machine-readable output for automation and downstream systems.";
|
|
561
569
|
var OUTPUT_FORMAT_OPTION_DESCRIPTION = formatOptionDescription;
|
|
562
570
|
var parseOutputFormat = (value) => {
|
|
563
571
|
if (supportedOutputFormats.includes(value)) {
|
|
@@ -576,8 +584,6 @@ var renderResponse = (response, format) => {
|
|
|
576
584
|
switch (format) {
|
|
577
585
|
case "json":
|
|
578
586
|
return renderJson(response);
|
|
579
|
-
case "text":
|
|
580
|
-
return renderText(response);
|
|
581
587
|
case "table":
|
|
582
588
|
return renderTable(response);
|
|
583
589
|
}
|
|
@@ -600,25 +606,6 @@ var renderJson = (response) => {
|
|
|
600
606
|
return JSON.stringify(response.values, null, 2);
|
|
601
607
|
}
|
|
602
608
|
};
|
|
603
|
-
var renderText = (response) => {
|
|
604
|
-
switch (response.kind) {
|
|
605
|
-
case "document":
|
|
606
|
-
return response.content;
|
|
607
|
-
case "discovery-status":
|
|
608
|
-
return `${response.summaryText}
|
|
609
|
-
${renderTextRows(response.rows, response.columns, "No discovery status available.")}`;
|
|
610
|
-
case "record-list":
|
|
611
|
-
return renderTextRows(response.rows, response.columns, response.emptyMessage);
|
|
612
|
-
case "rule-list":
|
|
613
|
-
return renderRuleList(response.rules, response.emptyMessage);
|
|
614
|
-
case "scan-result":
|
|
615
|
-
return renderTextRows(projectScanRows(response.result), scanColumns, "No findings.");
|
|
616
|
-
case "status":
|
|
617
|
-
return response.text;
|
|
618
|
-
case "string-list":
|
|
619
|
-
return response.values.length === 0 ? response.emptyMessage : response.values.join("\n");
|
|
620
|
-
}
|
|
621
|
-
};
|
|
622
609
|
var renderTable = (response) => {
|
|
623
610
|
switch (response.kind) {
|
|
624
611
|
case "document":
|
|
@@ -648,7 +635,7 @@ ${regionsTable}`;
|
|
|
648
635
|
case "record-list":
|
|
649
636
|
return response.rows.length === 0 ? response.emptyMessage : renderAsciiTable(response.rows, response.columns ?? inferColumns(response.rows));
|
|
650
637
|
case "rule-list":
|
|
651
|
-
return
|
|
638
|
+
return renderRuleTable(response.rules, response.emptyMessage);
|
|
652
639
|
case "scan-result": {
|
|
653
640
|
const rows = projectScanRows(response.result);
|
|
654
641
|
return rows.length === 0 ? "No findings." : renderAsciiTable(rows, scanColumns);
|
|
@@ -696,39 +683,27 @@ var projectScanRows = (result) => [
|
|
|
696
683
|
source: diagnostic.source
|
|
697
684
|
}))
|
|
698
685
|
];
|
|
699
|
-
var renderTextRows = (rows, columns, emptyMessage) => {
|
|
700
|
-
if (rows.length === 0) {
|
|
701
|
-
return emptyMessage;
|
|
702
|
-
}
|
|
703
|
-
const resolvedColumns = columns ?? inferColumns(rows);
|
|
704
|
-
return rows.map((row) => resolvedColumns.map((column) => toTextCell(row[column.key])).join(" ")).join("\n");
|
|
705
|
-
};
|
|
706
686
|
var inferColumns = (rows) => {
|
|
707
687
|
const keys = Array.from(new Set(rows.flatMap((row) => Object.keys(row)))).sort(
|
|
708
688
|
(left, right) => left.localeCompare(right)
|
|
709
689
|
);
|
|
710
690
|
return keys.map((key) => ({ key, header: key }));
|
|
711
691
|
};
|
|
712
|
-
var
|
|
692
|
+
var renderRuleTable = (rules, emptyMessage) => {
|
|
713
693
|
if (rules.length === 0) {
|
|
714
694
|
return emptyMessage;
|
|
715
695
|
}
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
}
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
lines.push(` ${rule.service}`);
|
|
728
|
-
}
|
|
729
|
-
lines.push(` ${rule.id}: ${rule.description}`);
|
|
730
|
-
}
|
|
731
|
-
return lines.join("\n");
|
|
696
|
+
return renderAsciiTable(
|
|
697
|
+
rules.map((rule) => ({
|
|
698
|
+
description: rule.description,
|
|
699
|
+
name: rule.name,
|
|
700
|
+
provider: rule.provider,
|
|
701
|
+
ruleId: rule.id,
|
|
702
|
+
service: rule.service,
|
|
703
|
+
supports: rule.supports
|
|
704
|
+
})),
|
|
705
|
+
ruleListColumns
|
|
706
|
+
);
|
|
732
707
|
};
|
|
733
708
|
var toTextCell = (value) => {
|
|
734
709
|
if (value === null || value === void 0) {
|
|
@@ -857,21 +832,38 @@ var renderAsciiTable = (rows, columns) => {
|
|
|
857
832
|
};
|
|
858
833
|
|
|
859
834
|
// src/commands/config-options.ts
|
|
835
|
+
import { builtInRuleMetadata } from "@cloudburn/sdk";
|
|
860
836
|
import { InvalidArgumentError as InvalidArgumentError2 } from "commander";
|
|
837
|
+
var parseCommaSeparatedList = (value, itemLabel) => {
|
|
838
|
+
const items = value.split(",").map((item) => item.trim()).filter((item) => item.length > 0);
|
|
839
|
+
if (items.length === 0) {
|
|
840
|
+
throw new InvalidArgumentError2(`Provide at least one ${itemLabel}.`);
|
|
841
|
+
}
|
|
842
|
+
return items;
|
|
843
|
+
};
|
|
861
844
|
var parseRuleIdList = (value) => {
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
845
|
+
return parseCommaSeparatedList(value, "rule ID");
|
|
846
|
+
};
|
|
847
|
+
var parseServiceList = (value) => parseCommaSeparatedList(value, "service").map((service) => service.toLowerCase());
|
|
848
|
+
var parseSourceList = (value) => parseCommaSeparatedList(value, "source").map((source) => source.toLowerCase());
|
|
849
|
+
var validateServiceList = (mode, services) => {
|
|
850
|
+
if (services === void 0) {
|
|
851
|
+
return void 0;
|
|
865
852
|
}
|
|
866
|
-
|
|
853
|
+
const validServices = new Set(
|
|
854
|
+
builtInRuleMetadata.filter((rule) => rule.supports.includes(mode)).map((rule) => rule.service)
|
|
855
|
+
);
|
|
856
|
+
const invalidService = services.find((service) => !validServices.has(service));
|
|
857
|
+
if (invalidService) {
|
|
858
|
+
throw new InvalidArgumentError2(
|
|
859
|
+
`Unknown service "${invalidService}" for ${mode}. Allowed services: ${Array.from(validServices).sort().join(", ")}.`
|
|
860
|
+
);
|
|
861
|
+
}
|
|
862
|
+
return services;
|
|
867
863
|
};
|
|
868
864
|
|
|
869
865
|
// src/commands/discover.ts
|
|
870
|
-
var
|
|
871
|
-
const aggregatorSummary = status.aggregatorRegion ? ` Aggregator region: ${status.aggregatorRegion}.` : "";
|
|
872
|
-
const warningSummary = status.warning ? ` ${status.warning}` : "";
|
|
873
|
-
return `Coverage: ${status.coverage}. Indexed ${status.indexedRegionCount} of ${status.totalRegionCount} enabled regions.${aggregatorSummary}${warningSummary}`.trim();
|
|
874
|
-
};
|
|
866
|
+
var parseDiscoveryServiceList = (value) => validateServiceList("discovery", parseServiceList(value)) ?? [];
|
|
875
867
|
var describeInitializationMessage = (result) => {
|
|
876
868
|
const baseMessage = result.indexType === "aggregator" ? result.aggregatorAction === "promoted" ? `Promoted the existing local Resource Explorer index in ${result.aggregatorRegion} to the aggregator.` : result.aggregatorAction === "created" ? `Configured ${result.aggregatorRegion} as the Resource Explorer aggregator.` : result.coverage === "full" ? `Resource Explorer aggregator already exists in ${result.aggregatorRegion}.` : `Resource Explorer aggregator already exists in ${result.aggregatorRegion}, but only ${result.observedStatus.indexedRegionCount} of ${result.observedStatus.totalRegionCount} regions are indexed.` : result.status === "EXISTING" ? `Local Resource Explorer setup already exists in ${result.aggregatorRegion}.` : `Local Resource Explorer setup created in ${result.aggregatorRegion}.`;
|
|
877
869
|
const indexSummaryParts = [];
|
|
@@ -945,13 +937,14 @@ var parseDiscoverRegion = (value) => {
|
|
|
945
937
|
};
|
|
946
938
|
var resolveDiscoveryTarget = (region) => region === void 0 ? { mode: "current" } : region === "all" ? { mode: "all" } : { mode: "region", region };
|
|
947
939
|
var toDiscoveryConfigOverride = (options) => {
|
|
948
|
-
if (options.enabledRules === void 0 && options.disabledRules === void 0) {
|
|
940
|
+
if (options.enabledRules === void 0 && options.disabledRules === void 0 && options.service === void 0) {
|
|
949
941
|
return void 0;
|
|
950
942
|
}
|
|
951
943
|
return {
|
|
952
944
|
discovery: {
|
|
953
945
|
disabledRules: options.disabledRules,
|
|
954
|
-
enabledRules: options.enabledRules
|
|
946
|
+
enabledRules: options.enabledRules,
|
|
947
|
+
services: options.service
|
|
955
948
|
}
|
|
956
949
|
};
|
|
957
950
|
};
|
|
@@ -978,14 +971,18 @@ var registerDiscoverCommand = (program) => {
|
|
|
978
971
|
"--disabled-rules <ruleIds>",
|
|
979
972
|
"Comma-separated rule IDs to disable. By default, all rules are enabled; use this to exclude specific rules.",
|
|
980
973
|
parseRuleIdList
|
|
974
|
+
).option(
|
|
975
|
+
"--service <services>",
|
|
976
|
+
"Comma-separated services to include in the discovery rule set.",
|
|
977
|
+
parseDiscoveryServiceList
|
|
981
978
|
).option("--exit-code", "Exit with code 1 when findings exist").action(async (options, command) => {
|
|
982
979
|
await runCommand(async () => {
|
|
983
980
|
const scanner = new CloudBurnClient();
|
|
981
|
+
const configOverride = toDiscoveryConfigOverride(options);
|
|
984
982
|
const loadedConfig = await scanner.loadConfig(options.config);
|
|
985
983
|
const discoveryOptions = {
|
|
986
984
|
target: resolveDiscoveryTarget(options.region)
|
|
987
985
|
};
|
|
988
|
-
const configOverride = toDiscoveryConfigOverride(options);
|
|
989
986
|
if (configOverride !== void 0) {
|
|
990
987
|
discoveryOptions.config = configOverride;
|
|
991
988
|
}
|
|
@@ -1055,8 +1052,7 @@ var registerDiscoverCommand = (program) => {
|
|
|
1055
1052
|
{ key: "notes", header: "Notes" }
|
|
1056
1053
|
],
|
|
1057
1054
|
rows,
|
|
1058
|
-
summary
|
|
1059
|
-
summaryText: describeDiscoverySummary(status)
|
|
1055
|
+
summary
|
|
1060
1056
|
},
|
|
1061
1057
|
format
|
|
1062
1058
|
);
|
|
@@ -1102,8 +1098,7 @@ var registerDiscoverCommand = (program) => {
|
|
|
1102
1098
|
const output = renderResponse(
|
|
1103
1099
|
{
|
|
1104
1100
|
kind: "status",
|
|
1105
|
-
data: buildInitializationStatusData(result, message, format)
|
|
1106
|
-
text: message
|
|
1101
|
+
data: buildInitializationStatusData(result, message, format)
|
|
1107
1102
|
},
|
|
1108
1103
|
format
|
|
1109
1104
|
);
|
|
@@ -1151,8 +1146,7 @@ var registerEstimateCommand = (program) => {
|
|
|
1151
1146
|
message: "No server configured. This command is optional and requires a dashboard URL.",
|
|
1152
1147
|
server: "",
|
|
1153
1148
|
status: "NOT_CONFIGURED"
|
|
1154
|
-
}
|
|
1155
|
-
text: "No server configured. This command is optional and requires a dashboard URL."
|
|
1149
|
+
}
|
|
1156
1150
|
},
|
|
1157
1151
|
format
|
|
1158
1152
|
);
|
|
@@ -1167,8 +1161,7 @@ var registerEstimateCommand = (program) => {
|
|
|
1167
1161
|
message: `Estimate request scaffold ready for server: ${options.server}`,
|
|
1168
1162
|
server: options.server,
|
|
1169
1163
|
status: "READY"
|
|
1170
|
-
}
|
|
1171
|
-
text: `Estimate request scaffold ready for server: ${options.server}`
|
|
1164
|
+
}
|
|
1172
1165
|
},
|
|
1173
1166
|
format
|
|
1174
1167
|
);
|
|
@@ -1184,12 +1177,16 @@ var CONFIG_FILENAMES = [".cloudburn.yml", ".cloudburn.yaml"];
|
|
|
1184
1177
|
var starterConfig = `# Static IaC scan configuration.
|
|
1185
1178
|
# enabled-rules restricts scans to only the listed rule IDs.
|
|
1186
1179
|
# disabled-rules removes specific rule IDs from the active set.
|
|
1180
|
+
# services restricts scans to rules for the listed services.
|
|
1187
1181
|
# format sets the default output format when --format is not passed.
|
|
1188
1182
|
iac:
|
|
1189
1183
|
enabled-rules:
|
|
1190
1184
|
- CLDBRN-AWS-EBS-1
|
|
1191
1185
|
disabled-rules:
|
|
1192
1186
|
- CLDBRN-AWS-EC2-2
|
|
1187
|
+
services:
|
|
1188
|
+
- ebs
|
|
1189
|
+
- ec2
|
|
1193
1190
|
format: table
|
|
1194
1191
|
|
|
1195
1192
|
# Live AWS discovery configuration.
|
|
@@ -1199,16 +1196,29 @@ discovery:
|
|
|
1199
1196
|
- CLDBRN-AWS-EBS-1
|
|
1200
1197
|
disabled-rules:
|
|
1201
1198
|
- CLDBRN-AWS-S3-1
|
|
1199
|
+
services:
|
|
1200
|
+
- ebs
|
|
1201
|
+
- s3
|
|
1202
1202
|
format: json
|
|
1203
1203
|
`;
|
|
1204
|
-
var
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1204
|
+
var resolveExplicitOutputFormat = (command) => {
|
|
1205
|
+
const options = typeof command.optsWithGlobals === "function" ? command.optsWithGlobals() : command.opts();
|
|
1206
|
+
return options.format;
|
|
1207
|
+
};
|
|
1208
|
+
var renderStarterConfig = (command) => {
|
|
1209
|
+
const explicitFormat = resolveExplicitOutputFormat(command);
|
|
1210
|
+
if (explicitFormat === void 0) {
|
|
1211
|
+
return starterConfig;
|
|
1212
|
+
}
|
|
1213
|
+
return renderResponse(
|
|
1214
|
+
{
|
|
1215
|
+
kind: "document",
|
|
1216
|
+
content: starterConfig,
|
|
1217
|
+
contentType: "application/yaml"
|
|
1218
|
+
},
|
|
1219
|
+
explicitFormat
|
|
1220
|
+
);
|
|
1221
|
+
};
|
|
1212
1222
|
var fileExists = async (path) => {
|
|
1213
1223
|
try {
|
|
1214
1224
|
await access(path);
|
|
@@ -1264,8 +1274,7 @@ var registerInitCommand = (program) => {
|
|
|
1264
1274
|
data: {
|
|
1265
1275
|
message: "Created CloudBurn config.",
|
|
1266
1276
|
path: configPath
|
|
1267
|
-
}
|
|
1268
|
-
text: `Created ${configPath}.`
|
|
1277
|
+
}
|
|
1269
1278
|
},
|
|
1270
1279
|
resolveOutputFormat(this)
|
|
1271
1280
|
);
|
|
@@ -1281,17 +1290,41 @@ var registerInitCommand = (program) => {
|
|
|
1281
1290
|
};
|
|
1282
1291
|
|
|
1283
1292
|
// src/commands/rules-list.ts
|
|
1284
|
-
import { builtInRuleMetadata } from "@cloudburn/sdk";
|
|
1293
|
+
import { builtInRuleMetadata as builtInRuleMetadata2 } from "@cloudburn/sdk";
|
|
1294
|
+
import { InvalidArgumentError as InvalidArgumentError4 } from "commander";
|
|
1295
|
+
var VALID_SOURCES = ["discovery", "iac"];
|
|
1296
|
+
var validateSelectedValues = (values, validValues, label) => {
|
|
1297
|
+
const invalidValue = values.find((value) => !validValues.has(value));
|
|
1298
|
+
if (invalidValue !== void 0) {
|
|
1299
|
+
throw new InvalidArgumentError4(
|
|
1300
|
+
`Unknown ${label} "${invalidValue}". Allowed ${label}s: ${Array.from(validValues).sort().join(", ")}.`
|
|
1301
|
+
);
|
|
1302
|
+
}
|
|
1303
|
+
return values;
|
|
1304
|
+
};
|
|
1305
|
+
var parseRulesListServiceList = (value) => validateSelectedValues(parseServiceList(value), new Set(builtInRuleMetadata2.map((rule) => rule.service)), "service");
|
|
1306
|
+
var parseRulesListSourceList = (value) => validateSelectedValues(parseSourceList(value), new Set(VALID_SOURCES), "source");
|
|
1307
|
+
var filterRules = (options) => {
|
|
1308
|
+
return builtInRuleMetadata2.filter((rule) => {
|
|
1309
|
+
if (options.service !== void 0 && !options.service.includes(rule.service)) {
|
|
1310
|
+
return false;
|
|
1311
|
+
}
|
|
1312
|
+
if (options.source !== void 0 && !options.source.some((source) => rule.supports.includes(source))) {
|
|
1313
|
+
return false;
|
|
1314
|
+
}
|
|
1315
|
+
return true;
|
|
1316
|
+
});
|
|
1317
|
+
};
|
|
1285
1318
|
var registerRulesListCommand = (program) => {
|
|
1286
1319
|
const rulesCommand = registerParentCommand(program, "rules", "Inspect built-in CloudBurn rules");
|
|
1287
|
-
rulesCommand.command("list").description("List built-in CloudBurn rules").action(function() {
|
|
1320
|
+
rulesCommand.command("list").description("List built-in CloudBurn rules").option("--service <services>", "Comma-separated services to include.", parseRulesListServiceList).option("--source <sources>", "Comma-separated sources to include (`iac`, `discovery`).", parseRulesListSourceList).action(function(options) {
|
|
1288
1321
|
const output = renderResponse(
|
|
1289
1322
|
{
|
|
1290
1323
|
kind: "rule-list",
|
|
1291
1324
|
emptyMessage: "No built-in rules are available.",
|
|
1292
|
-
rules:
|
|
1325
|
+
rules: filterRules(options)
|
|
1293
1326
|
},
|
|
1294
|
-
resolveOutputFormat(this, void 0, "
|
|
1327
|
+
resolveOutputFormat(this, void 0, "table")
|
|
1295
1328
|
);
|
|
1296
1329
|
process.stdout.write(`${output}
|
|
1297
1330
|
`);
|
|
@@ -1300,14 +1333,16 @@ var registerRulesListCommand = (program) => {
|
|
|
1300
1333
|
|
|
1301
1334
|
// src/commands/scan.ts
|
|
1302
1335
|
import { CloudBurnClient as CloudBurnClient2 } from "@cloudburn/sdk";
|
|
1336
|
+
var parseIaCServiceList = (value) => validateServiceList("iac", parseServiceList(value)) ?? [];
|
|
1303
1337
|
var toScanConfigOverride = (options) => {
|
|
1304
|
-
if (options.enabledRules === void 0 && options.disabledRules === void 0) {
|
|
1338
|
+
if (options.enabledRules === void 0 && options.disabledRules === void 0 && options.service === void 0) {
|
|
1305
1339
|
return void 0;
|
|
1306
1340
|
}
|
|
1307
1341
|
return {
|
|
1308
1342
|
iac: {
|
|
1309
1343
|
disabledRules: options.disabledRules,
|
|
1310
|
-
enabledRules: options.enabledRules
|
|
1344
|
+
enabledRules: options.enabledRules,
|
|
1345
|
+
services: options.service
|
|
1311
1346
|
}
|
|
1312
1347
|
};
|
|
1313
1348
|
};
|
|
@@ -1321,11 +1356,11 @@ var registerScanCommand = (program) => {
|
|
|
1321
1356
|
"--disabled-rules <ruleIds>",
|
|
1322
1357
|
"Comma-separated rule IDs to disable. By default, all rules are enabled; use this to exclude specific rules.",
|
|
1323
1358
|
parseRuleIdList
|
|
1324
|
-
).option("--exit-code", "Exit with code 1 when findings exist").action(async (path, options, command) => {
|
|
1359
|
+
).option("--service <services>", "Comma-separated services to include in the scan rule set.", parseIaCServiceList).option("--exit-code", "Exit with code 1 when findings exist").action(async (path, options, command) => {
|
|
1325
1360
|
try {
|
|
1326
1361
|
const scanner = new CloudBurnClient2();
|
|
1327
|
-
const loadedConfig = await scanner.loadConfig(options.config);
|
|
1328
1362
|
const configOverride = toScanConfigOverride(options);
|
|
1363
|
+
const loadedConfig = await scanner.loadConfig(options.config);
|
|
1329
1364
|
const scanPath = path ?? process.cwd();
|
|
1330
1365
|
const result = configOverride === void 0 && options.config === void 0 ? await scanner.scanStatic(scanPath) : options.config === void 0 ? await scanner.scanStatic(scanPath, configOverride) : await scanner.scanStatic(scanPath, configOverride, { configPath: options.config });
|
|
1331
1366
|
const format = resolveOutputFormat(command, void 0, loadedConfig.iac.format ?? "table");
|
|
@@ -1363,7 +1398,7 @@ var isCliEntrypoint = (moduleUrl, argvEntry = process.argv[1]) => {
|
|
|
1363
1398
|
};
|
|
1364
1399
|
var createProgram = () => {
|
|
1365
1400
|
const program = createCliCommand();
|
|
1366
|
-
program.name("cloudburn").usage("[command]").description("Know what you spend. Fix what you waste.").version("0.
|
|
1401
|
+
program.name("cloudburn").usage("[command]").description("Know what you spend. Fix what you waste.").version("0.9.0").option("--format <format>", OUTPUT_FORMAT_OPTION_DESCRIPTION, parseOutputFormat);
|
|
1367
1402
|
configureCliHelp(program);
|
|
1368
1403
|
registerCompletionCommand(program);
|
|
1369
1404
|
registerDiscoverCommand(program);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cloudburn",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Cloudburn CLI for cloud cost optimization",
|
|
5
5
|
"homepage": "https://cloudburn.io/docs",
|
|
6
6
|
"bugs": {
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
],
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"commander": "^13.1.0",
|
|
23
|
-
"@cloudburn/sdk": "0.
|
|
23
|
+
"@cloudburn/sdk": "0.15.0"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"@biomejs/biome": "^2.4.6",
|