Skip to content

Latest commit

 

History

History
126 lines (110 loc) · 8.37 KB

File metadata and controls

126 lines (110 loc) · 8.37 KB

CLI Architecture (packages/cloudburn)

Command Tree

graph TD
  Root["cloudburn"] --> Scan["scan [path]"]
  Root --> Discover["discover"]
  Root --> Config["config"]
  Root --> Rules["rules"]
  Root --> Estimate["estimate"]
  Root --> Completion["completion"]
  Rules --> RulesList["list"]
  Discover --> DiscoverInit["init"]
  Discover --> DiscoverStatus["status"]
  Discover --> DiscoverTypes["supported-resource-types"]
  Completion --> CompletionBash["bash"]
  Completion --> CompletionFish["fish"]
  Completion --> CompletionZsh["zsh"]

  Root -.- RootFlags["--debug\n--format json|table"]
  Scan -.- ScanFlags["--config path\n--enabled-rules ids\n--disabled-rules ids\n--exit-code\n--fail-on severity"]
  Discover -.- DiscoverFlags["--region region\n--cache normal|refresh|off\n--cache-dir path\n--cache-context id\n--config path\n--enabled-rules ids\n--disabled-rules ids\n--exit-code\n--fail-on severity"]
  Estimate -.- EstimateFlags["--server url"]
Loading

Startup

Command registration stays synchronous so help, option validation, and shell completion use the same complete command tree. The SDK defers live AWS imports behind its asynchronous discovery methods. Help, version, and static scans therefore avoid loading AWS clients or credential providers without changing command output or exit codes. Startup benchmarks record fresh-process distributions for both module formats and representative commands.

Formatter Pipeline

graph LR
  Command["Command action"] --> Response["CliResponse"]
  Response --> Dispatch{"resolved format"}
  Dispatch -->|json| JSON["renderResponse(..., 'json')"]
  Dispatch -->|table| Table["renderResponse(..., 'table')"]
  JSON --> Stdout
  Table --> Stdout
Loading

All stdout-producing commands return a typed CliResponse and share the same format resolver.

Format Output
json Pretty JSON for the underlying response payload
table ASCII tables for scans, including resource namespaces when present, record lists, string lists, key/value status output, and rules list

Command Behavior

  • scan [path] is static IaC only. It accepts a Terraform file, CloudFormation template, or directory and calls CloudBurnClient.scanStatic(path, config?, { configPath? }).
  • scan accepts --config, --enabled-rules, --disabled-rules, and --service as one-off overrides on top of the config file defaults.
  • discover runs live AWS discovery and rule evaluation through CloudBurnClient.discover({ target, cache, config?, configPath? }).
  • discover enables per-user evidence persistence by default and accepts --cache normal|refresh|off, --cache-dir, and --cache-context; the SDK owns safe scope resolution, freshness, and storage. See the cache options.
  • Discovery table output summarizes evidence source, completeness, and the oldest observation. JSON preserves the SDK's full evidence provenance.
  • discover accepts --config, --enabled-rules, --disabled-rules, and --service for one-off overrides of discovery config.
  • discover --region <region> overrides the current AWS region resolved from AWS_REGION, AWS_DEFAULT_REGION, aws_region, then the AWS SDK region provider chain.
  • The CLI targets one explicit AWS region per discover run.
  • Multi-region discovery remains an SDK capability through target: { mode: 'regions', regions: [...] } and requires a Resource Explorer aggregator index.
  • discover status reports the current Resource Explorer index state and uses the shared json|table renderer.
  • discover supported-resource-types uses the shared json|table renderer.
  • discover init bootstraps Resource Explorer through the SDK, defaults to the current AWS region, accepts --region <region> as an override, and falls back to local-only setup when cross-region bootstrap is denied.
  • discover init status output includes the resolved setup indexType so users can distinguish local-only setup from aggregator setup.
  • config --init creates .cloudburn.yml in the git root (or current directory when no git root exists), unless a config file already exists there.
  • config --print prints the current discovered config file as raw YAML by default and can render table or JSON when --format is provided.
  • config --print-template prints the starter template without writing a file.
  • rules list, config, and estimate all use the shared formatter system instead of ad hoc string output.
  • completion is a structural parent command. completion bash|fish|zsh prints shell completion scripts for the selected shell.
  • --debug is a global flag that relays SDK and provider execution tracing to stderr without changing normal command output on stdout.
  • discover streams catalog, dataset, and provisional rule progress to stderr when stderr is an interactive terminal and --debug is off. Rule lines show completed/total rules, the rule ID, status, and finding count, explicitly marked provisional. They can arrive before all datasets finish; the final report and exit code remain authoritative. Piped and scripted invocations keep a quiet stderr, and --format json writes one final JSON result to stdout.
  • --format is documented as a global option and defaults to table, except config --print and config --print-template, which preserve raw YAML by default for redirection workflows.
  • scan and discover can also source their default format from .cloudburn.yml; explicit --format still wins.
  • The hidden __complete command exists only as the runtime hook for generated shell scripts.
  • --exit-code counts nested matches across all provider and rule groups.
  • --fail-on high|medium|low counts only active findings at or above the inclusive threshold. Suppressed findings do not count toward either gate.
  • Gate precedence is explicit --fail-on, then explicit --exit-code, then the mode's configured fail-on value.
  • Runtime errors still write a structured JSON envelope to stderr.
  • Root help configuration is shared through src/help.ts. New structural parent commands should register through registerParentCommand(...) so bare parent invocations print scoped help and future commands inherit the same help layout automatically.

Help Examples

cloudburn scan ./main.tf
cloudburn scan ./template.yaml
cloudburn scan ./iac
cloudburn scan ./iac --config .cloudburn.yml
cloudburn scan ./iac --enabled-rules CLDBRN-AWS-EBS-1,CLDBRN-AWS-EC2-1
cloudburn scan ./iac --service ec2,s3
cloudburn scan ./iac --fail-on high
cloudburn discover
cloudburn discover --region eu-central-1
cloudburn discover --cache refresh
cloudburn discover --config .cloudburn.yml --disabled-rules CLDBRN-AWS-S3-1
cloudburn discover --service ec2,s3
cloudburn discover --fail-on medium
cloudburn discover init
cloudburn config --init
cloudburn config --print
cloudburn config --print-template
cloudburn rules
cloudburn rules list
cloudburn rules list --service ec2 --source discovery --severity high
cloudburn completion
cloudburn completion zsh
cloudburn --format json scan ./iac

Exit-Code Contract

Constant Value Meaning
EXIT_CODE_OK 0 No active finding meets the selected gate, or no gate is configured
EXIT_CODE_POLICY_VIOLATION 1 An active finding meets --fail-on, configured fail-on, or the any-finding gate
EXIT_CODE_RUNTIME_ERROR 2 Runtime failures and usage errors (invalid options or arguments)

Usage errors — unknown options or invalid option arguments such as an unknown --service value or a malformed --region — exit with 2, not Commander's default 1. Exit code 1 stays reserved for policy violations so CI pipelines can distinguish "findings exist" from "the command was invoked incorrectly". Help and version output exit with 0.