Skip to content

feat: add nvd commands for the NVD API 2.0 compatible endpoints - #346

Merged
alex-vulncheck merged 1 commit into
mainfrom
nvd-compat-commands
Oct 13, 2026
Merged

alex-vulncheck merged 1 commit into
mainfrom
nvd-compat-commands

Conversation

@alex-vulncheck

Copy link
Copy Markdown
Collaborator

What

Adds vulncheck nvd, with one subcommand per NVD API 2.0 compatible endpoint:

Command Endpoint
nvd cves GET /rest/json/cves/2.0
nvd cvehistory GET /rest/json/cvehistory/2.0
nvd cpes GET /rest/json/cpes/2.0
nvd cpematch GET /rest/json/cpematch/2.0
nvd source GET /rest/json/source/2.0

The commands mirror the API and add nothing to it.

  • Flags: one per query parameter, named as the parameter in kebab-case (--cve-id is cveId, --last-mod-start-date is lastModStartDate).
  • Values: sent unchanged. The API validates them and answers a bad one with a 400 naming the parameter.
  • Requests: each command makes exactly one. Page the way the API does: --cursor "" for the first page, then each response's nextCursor, or --start-index (the only paging on source). There is deliberately no --all.

Output

Output follows the existing model, as index list does:

  • stdout: the endpoint's records (vulnerabilities, cveChanges, products, matchStrings or sources), or the whole NVD response with --full. Both are passed through as the server sent them.
  • Status lines ("1 of 837 results", "Next page: --cursor …"): stdout in text mode, stderr under --json, so --json stdout is only the payload.
  • Errors: the standard error envelope and exit codes. MetaError now also decodes the NVD endpoints' {"message", "status"} body; before this, the reason was dropped and the error came out empty.

Testing

  • TestParametersAreTheAPIs pins each command's flags to its endpoint's parameters, so the CLI neither drops one the API takes nor offers one it doesn't.
  • Other command tests run against a fake API. They cover:
    • unset flags not being sent, and an empty --cursor being sent;
    • stdout and stderr in each output mode, and --full;
    • stable --json output;
    • source having no --cursor;
    • a 400 becoming a bad_request error with the API's message.
  • SDK tests for GetNvd, including query reset between calls, and an NVD case added to the MetaError shape test.
  • Tested live on prod: lookups, --full, a two-page cursor walk, a multi-word --event-name, cpes, cpematch and source. An over-long date range returned bad_request with the API's reason and exit 2. commands --json lists nvd.
  • go test ./... passes and golangci-lint is clean.

One subcommand per endpoint (cves, cvehistory, cpes, cpematch, source) and one
flag per query parameter, named as the parameter in kebab-case. Values are
sent unchanged and validated by the API, and each command makes one request:
page with --cursor ("" for the first page, then each nextCursor) or
--start-index, as the API does.

Output follows the existing model. The endpoint's records go to stdout, or the
whole NVD response with --full, passed through as the server sent them. Status
lines go to stdout in text mode and stderr under --json. A refused request
becomes the standard error envelope with the API's reason: MetaError now also
decodes the NVD endpoints' {"message", "status"} body, which it previously
reduced to an empty error.
@alex-vulncheck alex-vulncheck self-assigned this Oct 13, 2026
@alex-vulncheck
alex-vulncheck merged commit d56fb25 into main Oct 13, 2026
12 checks passed
@alex-vulncheck
alex-vulncheck deleted the nvd-compat-commands branch October 13, 2026 13:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants