diff --git a/test/integration/assigned-ca-trust.test.ts b/test/integration/assigned-ca-trust.test.ts index 8a8b215..f5bccc4 100644 --- a/test/integration/assigned-ca-trust.test.ts +++ b/test/integration/assigned-ca-trust.test.ts @@ -118,6 +118,23 @@ async function register(module: string): Promise { await mesh(`module add /${module}.json`); } +/** + * Put the mesh's composed user list where this machine's bus reads it, and make it re-read. + * + * **What genesis has to do by hand, and only genesis** (novox/hq 04-ISSUES/146). Every account on + * the bus reaches it in the declaration of the machine that runs it — which requires that machine + * to be an enrolled node, and at genesis it is not. So until the bus is a module, the composition + * is placed by whoever is raising the machine: the control plane says what it composed, and this + * writes it beside the bus's configuration. Twice, because two accounts come into existence at + * different moments — the enrolment when the token is issued, and the node's own when it enrols. + */ +async function composeTheBusUsers(): Promise { + await must( + `docker exec mesh-controller /mesh-controller broker accounts > /var/lib/mesh-bus-conf/accounts.conf && ` + + `docker kill -s HUP mesh-broker`, + ); +} + /** Dial the authority the way anything on this machine would: verifying, with nothing handed to it. */ async function verifying(): Promise<{ out: string; ok: boolean }> { return on(`curl --silent --show-error --max-time 10 ${AUTHORITY}`); @@ -155,11 +172,20 @@ before(async () => { await mesh(`node add ${MACHINE}`); const token = tokenFrom(await mesh(`token issue --node ${MACHINE}`)); + // The account that token is the password of exists in the mesh's records now; this is what puts + // it on the bus, because nothing else can until this machine is a node. + await composeTheBusUsers(); await must(`${HOST_PATH} enrol --token ${quote(token)}`); + // And again for the credential enrolment just minted, which the machine's own link connects with. + await composeTheBusUsers(); await must(`nohup ${HOST_PATH} run > /var/log/mesh-host.log 2>&1 & sleep 3`); }, { timeout: 1_800_000 }); after(async () => { + if (process.env["MESH_LAB_KEEP"]) { + console.log(`MESH_LAB_KEEP set — leaving ${instanceId} standing`); + return; + } if (instanceId) await destroy(instanceId); await destroyAll(`${SCENARIO}-`); }, { timeout: 600_000 }); @@ -167,9 +193,20 @@ after(async () => { test("the mesh's authority is verified on a machine holding ca-trust, and not on one that is not", { skip, timeout: 1_800_000, }, async () => { - // The authority first, on its own. Nothing about trust yet. + // The private network first. The authority certifies itself for the address it holds there + // (`${machine:at}`), which a machine with no overlay has not got — so this is what the bed needs + // it for, and nothing else. + await mesh(`overlay place ${MACHINE} --hub --endpoint 192.0.2.10:51820 --site lab`); + // The control plane ships this one — its resources are computed per node, so there is no + // manifest to register. + await mesh(`assign ${MACHINE} networking`); + await mesh(`push ${MACHINE}`); + await settled(); + + // The authority next, on its own. Nothing about trust yet. await register("step-ca"); - await mesh(`module issue step-ca --node ${MACHINE}`); + // No `module issue`: that delivers a bus account, and the authority declares none — its own + // secret is the password it initialises itself with, which the mesh mints at assignment. await mesh(`assign ${MACHINE} step-ca`); await mesh(`push ${MACHINE}`); await settled();