cloudburn 0.3.1 → 0.4.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 +10 -0
- package/dist/cli.js +55 -11
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -14,6 +14,16 @@ npm install -g cloudburn
|
|
|
14
14
|
cloudburn
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
+
Static scans auto-detect Terraform and CloudFormation from the file or
|
|
18
|
+
directory path you pass to `cloudburn scan`.
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
cloudburn scan ./main.tf
|
|
22
|
+
cloudburn scan ./template.yaml
|
|
23
|
+
cloudburn scan ./iac
|
|
24
|
+
cloudburn scan --live
|
|
25
|
+
```
|
|
26
|
+
|
|
17
27
|
`cloudburn scan --format json` emits the lean canonical grouped result:
|
|
18
28
|
|
|
19
29
|
```json
|
package/dist/cli.js
CHANGED
|
@@ -58,6 +58,35 @@ import { InvalidArgumentError } from "commander";
|
|
|
58
58
|
// src/exit-codes.ts
|
|
59
59
|
var EXIT_CODE_OK = 0;
|
|
60
60
|
var EXIT_CODE_POLICY_VIOLATION = 1;
|
|
61
|
+
var EXIT_CODE_RUNTIME_ERROR = 2;
|
|
62
|
+
|
|
63
|
+
// src/formatters/error.ts
|
|
64
|
+
var formatError = (err) => {
|
|
65
|
+
const envelope = { error: categorize(err) };
|
|
66
|
+
return JSON.stringify(envelope, null, 2);
|
|
67
|
+
};
|
|
68
|
+
var categorize = (err) => {
|
|
69
|
+
if (!(err instanceof Error)) {
|
|
70
|
+
return { code: "RUNTIME_ERROR", message: "An unexpected error occurred." };
|
|
71
|
+
}
|
|
72
|
+
if (err.name === "CredentialsProviderError" || err.name === "ExpiredTokenException") {
|
|
73
|
+
return {
|
|
74
|
+
code: "CREDENTIALS_ERROR",
|
|
75
|
+
message: "AWS credentials not found or expired. Run 'aws sts get-caller-identity' to verify your session."
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
if (err.name.includes("AccessDenied")) {
|
|
79
|
+
return {
|
|
80
|
+
code: "ACCESS_DENIED",
|
|
81
|
+
message: "Insufficient AWS permissions. Check your IAM role or policy."
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
if (err.code === "ENOENT") {
|
|
85
|
+
const path = err.path ?? "unknown";
|
|
86
|
+
return { code: "PATH_NOT_FOUND", message: `Path not found: ${path}` };
|
|
87
|
+
}
|
|
88
|
+
return { code: "RUNTIME_ERROR", message: err.message || "An unexpected error occurred." };
|
|
89
|
+
};
|
|
61
90
|
|
|
62
91
|
// src/formatters/json.ts
|
|
63
92
|
var formatJson = (result) => JSON.stringify(result, null, 2);
|
|
@@ -148,25 +177,40 @@ var formatters = {
|
|
|
148
177
|
table: formatTable
|
|
149
178
|
};
|
|
150
179
|
var registerScanCommand = (program) => {
|
|
151
|
-
program.command("scan
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
180
|
+
program.command("scan").description("Run an autodetected static IaC scan, or a live AWS scan with --live").argument("[path]", "Terraform file, CloudFormation template, or directory to scan").option("--live", "Run live AWS scan").option("--format <format>", "Output format: table|json|sarif", parseScanFormat, "table").option("--exit-code", "Exit with code 1 when findings exist").addHelpText(
|
|
181
|
+
"after",
|
|
182
|
+
`
|
|
183
|
+
Examples:
|
|
184
|
+
cloudburn scan ./main.tf
|
|
185
|
+
cloudburn scan ./template.yaml
|
|
186
|
+
cloudburn scan ./iac
|
|
187
|
+
cloudburn scan --live
|
|
188
|
+
`
|
|
189
|
+
).action(async (path, options) => {
|
|
190
|
+
try {
|
|
191
|
+
const scanner = new CloudBurnScanner();
|
|
192
|
+
const result = options.live ? await scanner.scanLive() : await scanner.scanStatic(path ?? process.cwd());
|
|
193
|
+
const format = formatters[options.format ?? "table"];
|
|
194
|
+
const output = format(result);
|
|
195
|
+
process.stdout.write(`${output}
|
|
157
196
|
`);
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
197
|
+
if (options.exitCode && countScanResultFindings(result) > 0) {
|
|
198
|
+
process.exitCode = EXIT_CODE_POLICY_VIOLATION;
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
process.exitCode = EXIT_CODE_OK;
|
|
202
|
+
} catch (err) {
|
|
203
|
+
process.stderr.write(`${formatError(err)}
|
|
204
|
+
`);
|
|
205
|
+
process.exitCode = EXIT_CODE_RUNTIME_ERROR;
|
|
161
206
|
}
|
|
162
|
-
process.exitCode = EXIT_CODE_OK;
|
|
163
207
|
});
|
|
164
208
|
};
|
|
165
209
|
|
|
166
210
|
// src/cli.ts
|
|
167
211
|
var createProgram = () => {
|
|
168
212
|
const program = new Command();
|
|
169
|
-
program.name("cloudburn").description("Know what you spend. Fix what you waste.").version("0.
|
|
213
|
+
program.name("cloudburn").description("Know what you spend. Fix what you waste.").version("0.4.0");
|
|
170
214
|
registerScanCommand(program);
|
|
171
215
|
registerInitCommand(program);
|
|
172
216
|
registerRulesListCommand(program);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cloudburn",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Cloudburn CLI for cloud cost optimization",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
],
|
|
12
12
|
"dependencies": {
|
|
13
13
|
"commander": "^13.1.0",
|
|
14
|
-
"@cloudburn/sdk": "0.6.
|
|
14
|
+
"@cloudburn/sdk": "0.6.1"
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
17
17
|
"@biomejs/biome": "^2.4.6",
|