Skip to content

test(e2e): drive every write path against a real esxi node - #206

Merged
Bugs5382 merged 1 commit into
mainfrom
feat/38-esxi-full-loop
Oct 15, 2026
Merged

Bugs5382 merged 1 commit into
mainfrom
feat/38-esxi-full-loop

Conversation

@Bugs5382

Copy link
Copy Markdown
Contributor

What and why

Adds test/e2e/esxi (task e2e:esxi): a scripted run that exercises every write path the Fleet
Manager's public API exposes, live, against real CryptOS nodes a lab gate run (or the cryptos-lab
tooling) already installed, checking each result on the node itself rather than trusting the
manager's own view of it.

It stands up a throwaway Fleet Manager against a throwaway Postgres container (the operator-CA and
operator-credential write paths only wire up with a database, not the in-memory store), bootstraps
it with its own throwaway operator CA generated in memory for the run, links it to the given nodes,
and drives: profile create/apply/update/requestable/delete, a protocol toggle, certificate issue and
revoke, a config-push round trip, image status (stage/activate/rollback when a signed release image
is supplied), SCEP challenge mint/list/revoke, re-key (opt-in, destructive), escrow export/import,
node enrolment link and reject, the full operator-credential lifecycle, and decommission.

It reuses internal/nodeclient and internal/config rather than inventing new node-dialing or
config code, matching the manager's own shape for node credentials.

Refs #38

Scope not covered yet

  • OS image stage/activate/rollback need a signed CryptOS release image and its detached release
    signature; without E2E_IMAGE_URL/E2E_IMAGE_SIGNATURE_PATH this run only proves
    GetNodeImageStatus.
  • Driving an actual SCEP device enrolment through a minted challenge
    (ApproveNodeScepEnrollment/RejectNodeScepEnrollment) needs a real RFC 8894 SCEP client talking
    to the node; this run proves challenge minting, listing and revocation only. I'll file a follow-up
    issue for both.
  • The live run against real nodes still waits on cryptos-appliance#53 (its gate-gateway fix is
    blocked behind an unmerged dependency); this PR only adds the harness.

Verification

  • Lint clean
  • Tests pass
  • Build succeeds
  • Documentation updated (if behavior or API changed)

How this was verified

  • task fmt, task vet, go build ./..., golangci-lint run ./... (0 issues) and task test
    (whole repo) all pass.
  • task license (golic dry run): 0/282 files need a header change.
  • A real smoke run, not just unit tests: docker run postgres:18-alpine, then task e2e:esxi
    against one node entry whose endpoint is unreachable (no real CryptOS node is reachable from
    here). The manager started for real, printed and consumed its bootstrap token, registered this
    script's operator CA, submitted and recorded the first admin certificate, and ran every step in
    order; the steps needing a live node failed with the manager's own node-unreachable codes (1100,
    1900), exactly as expected, and operator-credentials/request-record-revoke-cancel passed in
    full against the real running manager.
  • That same smoke run caught two real bugs in this PR's own certificate generation, before I wrote
    this description: the throwaway operator CA needs over 30 days of validity to register (the
    manager refuses under 30 with 1605 EXPIRING), and every signed operator credential needs an
    explicit basicConstraints CA:FALSE, not merely absent (1610 BASIC_CONSTRAINTS). Both are
    fixed, and credentials_test.go now runs every generated certificate through the manager's own
    internal/operatorca.ValidateAnchor and CheckOperatorCert as the oracle, so a regression here
    fails in task test, not only in a live run.
  • Docs (docs/e2e-esxi.md): every command block in it was run in the clean environment above
    (fresh Postgres container, fresh work directory) before marking this ready.

Before merging: add a closing comment summarizing what was actually done in this PR
(not just the checked boxes).

Adds test/e2e/esxi (task e2e:esxi): a scripted run that stands up a
throwaway Fleet Manager against a throwaway Postgres container, bootstraps
it with its own throwaway operator CA, links it to nodes a lab gate run
already installed, and drives profile, protocol, certificate, config-push,
image-status, SCEP-challenge, re-key, escrow, enrolment, operator-credential
and decommission write paths, checking each result on the node itself.

Reuses internal/nodeclient and internal/config rather than inventing new
node-dialing or config code, and generates its own ECDSA P-384 operator CA
in memory for the run since the manager's operator CA is always external.

A smoke run against a real throwaway manager and Postgres container (no
real CryptOS node reachable from here) found two certificate bugs the real
oracle (internal/operatorca.ValidateAnchor and CheckOperatorCert) now guards
against in the test suite: the throwaway operator CA needs over 30 days of
validity to register, and every signed credential needs an explicit
basicConstraints CA:FALSE, not merely absent.

The live run against real nodes still waits on cryptos-appliance#53
(blocked on an unmerged dependency); this change only adds the harness and
proves it with a reachable-but-fake node.

Refs #38

Signed-off-by: Bugs5382 <12115015+Bugs5382@users.noreply.github.com>
@Bugs5382
Bugs5382 marked this pull request as ready for review October 15, 2026 20:11
@github-actions github-actions Bot added the skip-changelog Excluded from release notes (chore/ci/test/style). label Oct 15, 2026
@Bugs5382

Copy link
Copy Markdown
Contributor Author

Filed the follow-up for the two scope gaps: #207.

@Bugs5382
Bugs5382 merged commit 25f7d3a into main Oct 15, 2026
18 checks passed
@Bugs5382
Bugs5382 deleted the feat/38-esxi-full-loop branch October 15, 2026 23:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

skip-changelog Excluded from release notes (chore/ci/test/style).

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant