Delete the lab's registry, and bootstrap the anchor through the installer #19
@@ -11,7 +11,7 @@ segments:
|
||||
|
||||
home:
|
||||
kind: private
|
||||
cidr: [192.168.1.0/24]
|
||||
cidr: [10.99.1.0/24]
|
||||
gateway:
|
||||
to: hosting
|
||||
address: [192.0.2.50] # what the world sees the household as
|
||||
@@ -25,7 +25,7 @@ machines:
|
||||
inbound: allow
|
||||
|
||||
home-server: # a dash in the name, on purpose
|
||||
at: { segment: home, address: [192.168.1.135] }
|
||||
at: { segment: home, address: [10.99.1.135] }
|
||||
published:
|
||||
- { port: 8080, on: home }
|
||||
inbound: allow
|
||||
|
||||
@@ -15,7 +15,7 @@ segments:
|
||||
|
||||
home:
|
||||
kind: private
|
||||
cidr: [192.168.1.0/24]
|
||||
cidr: [10.99.1.0/24]
|
||||
gateway:
|
||||
to: hosting
|
||||
address: [192.0.2.50]
|
||||
@@ -53,7 +53,7 @@ machines:
|
||||
inbound: allow
|
||||
|
||||
home-server:
|
||||
at: { segment: home, address: [192.168.1.135] }
|
||||
at: { segment: home, address: [10.99.1.135] }
|
||||
inbound: allow
|
||||
|
||||
thermostat:
|
||||
|
||||
@@ -21,7 +21,7 @@ segments:
|
||||
|
||||
home:
|
||||
kind: private
|
||||
cidr: [192.168.1.0/24, "2001:db8:b:1::/64"]
|
||||
cidr: [10.99.1.0/24, "2001:db8:b:1::/64"]
|
||||
mtu: 1492
|
||||
gateway:
|
||||
to: isp-home
|
||||
@@ -61,17 +61,17 @@ machines:
|
||||
inbound: allow
|
||||
|
||||
home-server:
|
||||
at: { segment: home, address: [192.168.1.135, "2001:db8:b:1::135"] }
|
||||
at: { segment: home, address: [10.99.1.135, "2001:db8:b:1::135"] }
|
||||
published:
|
||||
- { port: 443, on: home }
|
||||
inbound: allow
|
||||
|
||||
workstation:
|
||||
at: { segment: home, address: [192.168.1.250, "2001:db8:b:1::250"] }
|
||||
at: { segment: home, address: [10.99.1.250, "2001:db8:b:1::250"] }
|
||||
inbound: deny
|
||||
|
||||
laptop:
|
||||
at: { segment: home, address: [192.168.1.98, "2001:db8:b:1::98"] }
|
||||
at: { segment: home, address: [10.99.1.98, "2001:db8:b:1::98"] }
|
||||
inbound: deny
|
||||
|
||||
# No `place:` yet. The node host it would place does not exist — this lab is being built to
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
# — the access point — reachable from the outside only through what they dial out to.
|
||||
#
|
||||
# hosting (public, routable) home (private, behind the access point)
|
||||
# novox 192.0.2.20 ── anchor ace 192.168.1.10 home server, media/IoT set
|
||||
# substrate + novox set shanks 192.168.1.20 workstation (light)
|
||||
# overlay hub, ingress g14 192.168.1.30 workstation (light)
|
||||
# novox 192.0.2.20 ── anchor ace 10.99.1.10 home server, media/IoT set
|
||||
# substrate + novox set shanks 10.99.1.20 workstation (light)
|
||||
# overlay hub, ingress g14 10.99.1.30 workstation (light)
|
||||
#
|
||||
# The `home` gateway masquerades v4 outbound and forwards inbound (an ordinary household router).
|
||||
# Home nodes reach novox's public 192.0.2.20 by dialling OUT through it: the substrate broker (5671),
|
||||
@@ -58,7 +58,7 @@ segments:
|
||||
# is exactly the NAT hole a WireGuard keepalive has to hold open.
|
||||
home:
|
||||
kind: private
|
||||
cidr: [192.168.1.0/24]
|
||||
cidr: [10.99.1.0/24]
|
||||
gateway:
|
||||
to: hosting
|
||||
address: [192.0.2.50] # what the world sees the household as
|
||||
@@ -100,7 +100,7 @@ machines:
|
||||
# The home server: the whole ace media/home set — 24 modules, ~50 containers, several heavy
|
||||
# (Plex, Home Assistant, Letta, Baserow, the UniFi JVM, mssql). Behind the gateway.
|
||||
ace:
|
||||
at: { segment: home, address: [192.168.1.10] }
|
||||
at: { segment: home, address: [10.99.1.10] }
|
||||
egress: true
|
||||
inbound: allow
|
||||
memory: 18GiB
|
||||
@@ -140,7 +140,7 @@ machines:
|
||||
# nodes with no overlay endpoint of their own hairpin the hub rather than peering directly, which
|
||||
# is the normal case and is fine.
|
||||
shanks:
|
||||
at: { segment: home, address: [192.168.1.20] }
|
||||
at: { segment: home, address: [10.99.1.20] }
|
||||
egress: true
|
||||
inbound: allow
|
||||
memory: 3GiB
|
||||
@@ -151,7 +151,7 @@ machines:
|
||||
# everywhere" was never a description of anything real.
|
||||
images: [mesh-runtime-portainer:development]
|
||||
g14:
|
||||
at: { segment: home, address: [192.168.1.30] }
|
||||
at: { segment: home, address: [10.99.1.30] }
|
||||
egress: true
|
||||
inbound: allow
|
||||
memory: 3GiB
|
||||
|
||||
@@ -109,7 +109,7 @@ test("segments are ordered public first, then by depth behind them", () => {
|
||||
});
|
||||
|
||||
test("a declared address appears on the machine that holds it", () => {
|
||||
assert.match(xml, /192\.168\.1\.135/);
|
||||
assert.match(xml, /10\.99\.1\.135/);
|
||||
assert.match(xml, /198\.51\.100\.7/);
|
||||
});
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ segments:
|
||||
cidr: [192.0.2.0/24]
|
||||
home:
|
||||
kind: private
|
||||
cidr: [192.168.1.0/24]
|
||||
cidr: [10.99.1.0/24]
|
||||
gateway:
|
||||
to: hosting
|
||||
address: [192.0.2.50]
|
||||
@@ -41,10 +41,10 @@ machines:
|
||||
at: { segment: hosting, address: [192.0.2.20] }
|
||||
egress: true
|
||||
ace:
|
||||
at: { segment: home, address: [192.168.1.10] }
|
||||
at: { segment: home, address: [10.99.1.10] }
|
||||
egress: true
|
||||
sealed:
|
||||
at: { segment: home, address: [192.168.1.99] }
|
||||
at: { segment: home, address: [10.99.1.99] }
|
||||
`;
|
||||
|
||||
test("a machine behind a gateway still reaches the scenario through that gateway", () => {
|
||||
@@ -52,16 +52,16 @@ test("a machine behind a gateway still reaches the scenario through that gateway
|
||||
// handshake has to survive it. An egress machine that stopped using its gateway would be
|
||||
// testing a flat network with extra steps.
|
||||
const routes = scenarioRoutesFor(parseScenario(HOUSEHOLD), "ace");
|
||||
assert.deepEqual(routes, [{ cidr: "192.0.2.0/24", via: "192.168.1.1" }]);
|
||||
assert.deepEqual(routes, [{ cidr: "192.0.2.0/24", via: "10.99.1.1" }]);
|
||||
});
|
||||
|
||||
test("a machine's own segment gets no route — it is already on-link", () => {
|
||||
const routes = scenarioRoutesFor(parseScenario(HOUSEHOLD), "ace");
|
||||
assert.ok(!routes.some((r) => r.cidr === "192.168.1.0/24"), JSON.stringify(routes));
|
||||
assert.ok(!routes.some((r) => r.cidr === "10.99.1.0/24"), JSON.stringify(routes));
|
||||
});
|
||||
|
||||
/**
|
||||
* **The dangerous one.** `home` is 192.168.1.0/24 — a documentation range in spirit, an ordinary
|
||||
* **The dangerous one.** `home` is 10.99.1.0/24 — a documentation range in spirit, an ordinary
|
||||
* private one in fact, and very possibly the network the workstation itself is on.
|
||||
*
|
||||
* With one public segment there is no transit router, so novox has no path to `home` at all. Left
|
||||
@@ -71,7 +71,7 @@ test("a machine's own segment gets no route — it is already on-link", () => {
|
||||
*/
|
||||
test("a range with no path inside the scenario is unreachable, not leaked to the uplink", () => {
|
||||
const routes = scenarioRoutesFor(parseScenario(HOUSEHOLD), "novox");
|
||||
assert.deepEqual(routes, [{ cidr: "192.168.1.0/24", via: null }]);
|
||||
assert.deepEqual(routes, [{ cidr: "10.99.1.0/24", via: null }]);
|
||||
});
|
||||
|
||||
test("a machine without egress is left to its default route, and states nothing", () => {
|
||||
|
||||
@@ -45,7 +45,7 @@ test("ADR 0016 — the lab provides the underlay and NOTHING of the overlay", {
|
||||
|
||||
test("ADR 0016 — the declared address IS what the machine holds", { skip }, async () => {
|
||||
const { stdout } = await exec(instanceId, "home-server", ["ip", "-o", "-4", "addr", "show"]);
|
||||
assert.match(stdout, /192\.168\.1\.135\/24/);
|
||||
assert.match(stdout, /10\.99\.1\.135\/24/);
|
||||
});
|
||||
|
||||
test("design — raise waits for USABLE, not for the call to return", { skip, timeout: 120_000 }, async () => {
|
||||
@@ -75,7 +75,7 @@ test("ADR 0016 — a router is scenery: containers, while machines are virtual m
|
||||
|
||||
test("design — NAT: a private address is not reachable from outside", { skip, timeout: 120_000 }, async () => {
|
||||
const { stdout } = await exec(instanceId, "anchor", [
|
||||
"sh", "-c", "ping -c1 -W2 192.168.1.135 >/dev/null 2>&1 && echo reachable || echo unreachable",
|
||||
"sh", "-c", "ping -c1 -W2 10.99.1.135 >/dev/null 2>&1 && echo reachable || echo unreachable",
|
||||
]);
|
||||
assert.equal(stdout.trim(), "unreachable");
|
||||
});
|
||||
@@ -139,7 +139,7 @@ test("the live diagram reads the hypervisor, and a VM's addresses are not lost",
|
||||
assert.ok(server, "home-server missing from the live picture");
|
||||
assert.equal(server.kind, "machine");
|
||||
assert.ok(
|
||||
server.attachments.some((a) => a.addresses.some((address) => address.startsWith("192.168.1.135"))),
|
||||
server.attachments.some((a) => a.addresses.some((address) => address.startsWith("10.99.1.135"))),
|
||||
`a virtual machine's addresses were not read back: ${JSON.stringify(server.attachments)}`,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* anchor, everything on one public segment) into what production actually is:
|
||||
*
|
||||
* hosting (public) home (private, behind a NAT access point)
|
||||
* novox 192.0.2.20 — the ANCHOR: ace 192.168.1.10 the home server, media/IoT set
|
||||
* substrate (store/broker/ shanks 192.168.1.20 workstation (light: portainer only)
|
||||
* control) + the whole novox g14 192.168.1.30 workstation (light: portainer only)
|
||||
* novox 192.0.2.20 — the ANCHOR: ace 10.99.1.10 the home server, media/IoT set
|
||||
* substrate (store/broker/ shanks 10.99.1.20 workstation (light: portainer only)
|
||||
* control) + the whole novox g14 10.99.1.30 workstation (light: portainer only)
|
||||
* set + overlay hub + ingress
|
||||
*
|
||||
* There is NO separate anchor: novox IS the anchor. The substrate runs on novox, and novox also
|
||||
|
||||
@@ -23,8 +23,8 @@ test("the same address on different segments is NOT a conflict", () => {
|
||||
// Every private network has its own `.1`. Reporting that would make the check useless.
|
||||
assert.deepEqual(
|
||||
duplicateAddresses([
|
||||
{ machine: "gw-a", segment: "home", address: "192.168.1.1/24" },
|
||||
{ machine: "gw-b", segment: "cafe", address: "192.168.1.1/24" },
|
||||
{ machine: "gw-a", segment: "home", address: "10.99.1.1/24" },
|
||||
{ machine: "gw-b", segment: "cafe", address: "10.99.1.1/24" },
|
||||
]),
|
||||
[],
|
||||
);
|
||||
|
||||
+4
-4
@@ -9,9 +9,9 @@ test("segments sharing a gateway declaration share ONE router", () => {
|
||||
const scenario = parseScenario(`scenario: x
|
||||
segments:
|
||||
pub: { kind: public, cidr: [192.0.2.0/24] }
|
||||
home: { kind: private, cidr: [192.168.1.0/24], gateway: { to: pub, address: [192.0.2.5], nat: [v4] } }
|
||||
home: { kind: private, cidr: [10.99.1.0/24], gateway: { to: pub, address: [192.0.2.5], nat: [v4] } }
|
||||
iot: { kind: private, cidr: [192.168.30.0/24], gateway: { to: pub, address: [192.0.2.5], nat: [v4] } }
|
||||
machines: { a: { at: { segment: home, address: [192.168.1.9] } } }`);
|
||||
machines: { a: { at: { segment: home, address: [10.99.1.9] } } }`);
|
||||
const plans = planRouters(scenario, "inst");
|
||||
assert.equal(plans.length, 1, "one gateway declaration, one router");
|
||||
assert.deepEqual(plans[0]?.inside.sort(), ["home", "iot"]);
|
||||
@@ -21,9 +21,9 @@ test("different external addresses mean different routers", () => {
|
||||
const scenario = parseScenario(`scenario: x
|
||||
segments:
|
||||
pub: { kind: public, cidr: [192.0.2.0/24] }
|
||||
home: { kind: private, cidr: [192.168.1.0/24], gateway: { to: pub, address: [192.0.2.5], nat: [v4] } }
|
||||
home: { kind: private, cidr: [10.99.1.0/24], gateway: { to: pub, address: [192.0.2.5], nat: [v4] } }
|
||||
other: { kind: private, cidr: [192.168.30.0/24], gateway: { to: pub, address: [192.0.2.6], nat: [v4] } }
|
||||
machines: { a: { at: { segment: home, address: [192.168.1.9] } } }`);
|
||||
machines: { a: { at: { segment: home, address: [10.99.1.9] } } }`);
|
||||
assert.equal(planRouters(scenario, "inst").length, 2);
|
||||
});
|
||||
|
||||
|
||||
@@ -13,8 +13,8 @@ import { assertSupported, UnsupportedError } from "../src/lifecycle/supported.ts
|
||||
const withGateway = `scenario: x
|
||||
segments:
|
||||
pub: { kind: public, cidr: [192.0.2.0/24] }
|
||||
home: { kind: private, cidr: [192.168.1.0/24], gateway: { to: pub, address: [192.0.2.5], nat: [v4] } }
|
||||
machines: { a: { at: { segment: home, address: [192.168.1.9] } } }`;
|
||||
home: { kind: private, cidr: [10.99.1.0/24], gateway: { to: pub, address: [192.0.2.5], nat: [v4] } }
|
||||
machines: { a: { at: { segment: home, address: [10.99.1.9] } } }`;
|
||||
|
||||
test("a plain scenario is raisable", () => {
|
||||
const scenario = parseScenario(`scenario: x
|
||||
@@ -31,12 +31,12 @@ test("published ports and policy are implemented", () => {
|
||||
const scenario = parseScenario(`scenario: x
|
||||
segments:
|
||||
pub: { kind: public, cidr: [192.0.2.0/24] }
|
||||
home: { kind: private, cidr: [192.168.1.0/24], gateway: { to: pub, address: [192.0.2.5], nat: [v4] } }
|
||||
home: { kind: private, cidr: [10.99.1.0/24], gateway: { to: pub, address: [192.0.2.5], nat: [v4] } }
|
||||
iot: { kind: private, cidr: [192.168.30.0/24], gateway: { to: pub, address: [192.0.2.5], nat: [v4] } }
|
||||
policy: [{ from: iot, to: home, allow: false }]
|
||||
machines:
|
||||
a:
|
||||
at: { segment: home, address: [192.168.1.9] }
|
||||
at: { segment: home, address: [10.99.1.9] }
|
||||
published: [{ port: 443, on: home }]`);
|
||||
assert.doesNotThrow(() => assertSupported(scenario));
|
||||
});
|
||||
|
||||
@@ -27,8 +27,8 @@ test("the shipped scenarios are valid", () => {
|
||||
test("a public segment on a private range is refused — the mesh would silently never form", () => {
|
||||
refuses(
|
||||
`scenario: x
|
||||
segments: { net: { kind: public, cidr: [192.168.1.0/24] } }
|
||||
machines: { a: { at: { segment: net, address: [192.168.1.1] } } }`,
|
||||
segments: { net: { kind: public, cidr: [10.99.1.0/24] } }
|
||||
machines: { a: { at: { segment: net, address: [10.99.1.1] } } }`,
|
||||
/not documentation space/,
|
||||
);
|
||||
});
|
||||
@@ -71,8 +71,8 @@ test("a gateway address must be on the PARENT segment, not the one behind it", (
|
||||
`scenario: x
|
||||
segments:
|
||||
pub: { kind: public, cidr: [192.0.2.0/24] }
|
||||
home: { kind: private, cidr: [192.168.1.0/24], gateway: { to: pub, address: [192.168.1.1], nat: [v4] } }
|
||||
machines: { a: { at: { segment: home, address: [192.168.1.9] } } }`,
|
||||
home: { kind: private, cidr: [10.99.1.0/24], gateway: { to: pub, address: [10.99.1.1], nat: [v4] } }
|
||||
machines: { a: { at: { segment: home, address: [10.99.1.9] } } }`,
|
||||
/is not within 'pub'/,
|
||||
);
|
||||
});
|
||||
@@ -120,7 +120,7 @@ test("publishing on a segment the machine is not attached to is refused", () =>
|
||||
`scenario: x
|
||||
segments:
|
||||
pub: { kind: public, cidr: [192.0.2.0/24] }
|
||||
home: { kind: private, cidr: [192.168.1.0/24], gateway: { to: pub, address: [192.0.2.5], nat: [v4] } }
|
||||
home: { kind: private, cidr: [10.99.1.0/24], gateway: { to: pub, address: [192.0.2.5], nat: [v4] } }
|
||||
machines:
|
||||
a:
|
||||
at: { segment: pub, address: [192.0.2.10] }
|
||||
@@ -176,12 +176,12 @@ test("a multi-homed machine is valid", () => {
|
||||
parseScenario(`scenario: x
|
||||
segments:
|
||||
pub: { kind: public, cidr: [192.0.2.0/24] }
|
||||
home: { kind: private, cidr: [192.168.1.0/24], gateway: { to: pub, address: [192.0.2.5], nat: [v4] } }
|
||||
home: { kind: private, cidr: [10.99.1.0/24], gateway: { to: pub, address: [192.0.2.5], nat: [v4] } }
|
||||
machines:
|
||||
border:
|
||||
at:
|
||||
- { segment: pub, address: [192.0.2.60] }
|
||||
- { segment: home, address: [192.168.1.2] }`),
|
||||
- { segment: home, address: [10.99.1.2] }`),
|
||||
);
|
||||
});
|
||||
|
||||
@@ -206,7 +206,7 @@ segments:
|
||||
cidr: [198.51.100.0/24, "2001:db8:b::/48"]
|
||||
home:
|
||||
kind: private
|
||||
cidr: [192.168.1.0/24]
|
||||
cidr: [10.99.1.0/24]
|
||||
gateway: { to: isp, address: [198.51.100.7, "2001:db8:b::7"], nat: [v4], forwardable: true, mapping_ttl: 120s }
|
||||
devices:
|
||||
kind: private
|
||||
@@ -236,7 +236,7 @@ segments:
|
||||
cidr: [198.51.100.0/24]
|
||||
home:
|
||||
kind: private
|
||||
cidr: [192.168.1.0/24]
|
||||
cidr: [10.99.1.0/24]
|
||||
gateway: { to: isp, address: [198.51.100.7], nat: [v4], forwardable: true }
|
||||
devices:
|
||||
kind: private
|
||||
|
||||
Reference in New Issue
Block a user