Adoption bed: an opening the operator's own rule answers is satisfied, and a failed container probe records its evidence
This commit is contained in:
@@ -606,8 +606,19 @@ before(async () => {
|
|||||||
// reaches a published port through the runtime's proxy, on the incoming path, not the forwarded.
|
// reaches a published port through the runtime's proxy, on the incoming path, not the forwarded.
|
||||||
await step("B4", ["A3"], async () => {
|
await step("B4", ["A3"], async () => {
|
||||||
const said: string[] = [];
|
const said: string[] = [];
|
||||||
const fromContainer = await on(CONTROL, `docker run --rm ${ALPINE} nc -z -w 3 ${ANCHOR} ${STORE_PORT}`, 180_000);
|
const fromContainer = await on(CONTROL, `docker run --rm ${ALPINE} nc -zv -w 3 ${ANCHOR} ${STORE_PORT} 2>&1`, 180_000);
|
||||||
assert.ok(fromContainer.ok, `a container on the node cannot reach the store:\n${fromContainer.out}`);
|
if (!fromContainer.ok) {
|
||||||
|
// Evidence, so the cause can be read from this run rather than guessed at the next one.
|
||||||
|
const evidence = await on(CONTROL, [
|
||||||
|
`echo '--- published'; docker ps --format '{{.Names}} {{.Ports}}' | grep -i ${STORE_PORT}`,
|
||||||
|
`echo '--- from the host'; nc -zv -w 3 ${ANCHOR} ${STORE_PORT} 2>&1`,
|
||||||
|
`echo '--- from the host network'; docker run --rm --network host ${ALPINE} nc -zv -w 3 ${ANCHOR} ${STORE_PORT} 2>&1`,
|
||||||
|
`echo '--- iptables FORWARD, DOCKER-USER, isolation'; iptables -S FORWARD; iptables -S DOCKER-USER; iptables -S | grep -i isolation`,
|
||||||
|
`echo '--- the guard'; nft list table inet mesh_guard`,
|
||||||
|
`echo '--- nat for the port'; iptables -t nat -S | grep ${STORE_PORT}`,
|
||||||
|
].join("; "), 120_000);
|
||||||
|
assert.fail(`a container on the node cannot reach the store:\n${fromContainer.out}\n${evidence.out}`);
|
||||||
|
}
|
||||||
said.push(` container -> ${STORE_PORT} reachable from a container on the node itself`);
|
said.push(` container -> ${STORE_PORT} reachable from a container on the node itself`);
|
||||||
return said.join("\n");
|
return said.join("\n");
|
||||||
});
|
});
|
||||||
@@ -753,9 +764,15 @@ before(async () => {
|
|||||||
assert.equal(await must(CONTROL, `cat ${SERVICE_FILE}`), catalogue, `the found file was not replaced with the module's`);
|
assert.equal(await must(CONTROL, `cat ${SERVICE_FILE}`), catalogue, `the found file was not replaced with the module's`);
|
||||||
assert.equal(await must(CONTROL, `cat ${kept}`), await must(CONTROL, `cat ${BEFORE}/file`), `the original was not kept`);
|
assert.equal(await must(CONTROL, `cat ${kept}`), await must(CONTROL, `cat ${BEFORE}/file`), `the original was not kept`);
|
||||||
said.push(` replaced container (spec ${label.slice(0, 12)}…) and ${SERVICE_FILE}; original still at ${kept}`);
|
said.push(` replaced container (spec ${label.slice(0, 12)}…) and ${SERVICE_FILE}; original still at ${kept}`);
|
||||||
|
// Either the mesh opened the port, or the predecessor's own rule already admits it — then the
|
||||||
|
// mesh adds nothing and will remove nothing (ADR 0103), and the operator's rule stays theirs.
|
||||||
const opened = (await openings()).filter((r) => new RegExp(`opening-tcp-${SERVED}-`).test(r));
|
const opened = (await openings()).filter((r) => new RegExp(`opening-tcp-${SERVED}-`).test(r));
|
||||||
assert.ok(opened.length > 0, `no opening for ${SERVED} once ${SERVICE} was taken:\n${(await openings()).join("\n")}`);
|
const operators = (await ufwAdded()).filter((r) => !marked(r) && new RegExp(`\\b${SERVED}\\b`).test(r));
|
||||||
|
assert.ok(opened.length > 0 || operators.length > 0,
|
||||||
|
`no opening for ${SERVED} once ${SERVICE} was taken, and no rule of the operator's admits it:\n${(await ufwAdded()).join("\n")}`);
|
||||||
|
assert.ok(operators.length > 0, `the operator's own rule for ${SERVED} is gone:\n${(await ufwAdded()).join("\n")}`);
|
||||||
said.push(...opened.map((r) => ` opened ${r}`));
|
said.push(...opened.map((r) => ` opened ${r}`));
|
||||||
|
if (opened.length === 0) said.push(` opening ${SERVED} satisfied by the operator's own rule: ${operators.join(" | ")}`);
|
||||||
const page = await until(`the taken ${SERVICE} answers over the private network`, 120, async () => {
|
const page = await until(`the taken ${SERVICE} answers over the private network`, 120, async () => {
|
||||||
const p = await on(JOINER, `curl -s --max-time 3 http://${anchorOnMesh}:${SERVED}/`);
|
const p = await on(JOINER, `curl -s --max-time 3 http://${anchorOnMesh}:${SERVED}/`);
|
||||||
return p.ok && p.out === catalogue ? p.out : null;
|
return p.ok && p.out === catalogue ? p.out : null;
|
||||||
|
|||||||
Reference in New Issue
Block a user