/** * Reusable positive vantage assertions (ISS-0117). * * Module e2e suites call these after deploying a service to assert the positive network * facts the right consumer should see — TLS works from the internet, the name resolves to * a public address, an internal device reaches the service via the firewall natIp. The * negative/isolation gates (a system that SHOULDN'T reach another) are intentionally not * here — they wait on real firewall isolation (ISS-0118). * * Topology prerequisite: inject the observers the assertion needs, e.g. * network().dmz({ caddy: '10.226.10.10' }).observe('internalDevice', 'publicInternet') */ import { createObserverTransport } from './observer'; import type { NetworkHandle } from './types'; import { VantageProbe } from './vantage'; export interface FrontedServiceExpectation { /** The public hostname the service is fronted at. */ fqdn: string; /** * The firewall natIp, when the topology deploys a firewall. Enables the internalDevice * reachability check (an internal device reaches the service via the controlled DNAT). * Omit for topologies without a firewall (e.g. direct-internet). */ natIp?: string; /** Service port (default 443). */ port?: number; /** Expected HTTPS status (default 200). Override for roots that redirect (e.g. 302). */ expectStatus?: number; /** Optional path appended to the URL for the HTTPS check (e.g. '/-/ping'). */ path?: string; /** Optional expected cert issuer substring (e.g. 'Pebble') — a CA-provenance assertion. */ expectCA?: string; } /** * Assert the positive facts a web-fronted service should present from the right vantages: * - `publicInternet` resolves the FQDN to a public IP (not a private/segmented-zone IP), * - `publicInternet` gets a valid HTTPS response with a real, non-self-signed cert, * - `internalDevice` reaches the service via the firewall natIp (when `natIp` is given). * * Requires the topology to have injected the `publicInternet` (and, for the natIp check, * `internalDevice`) observers. */ export async function assertFrontedServicePositives( net: NetworkHandle, expectation: FrontedServiceExpectation, ): Promise { const probe = new VantageProbe(createObserverTransport(net)); const port = expectation.port ?? 443; const url = `https://${expectation.fqdn}${expectation.path ?? ''}`; // The internet sees the service at a public IP and a valid HTTPS endpoint. await probe.assertResolvesInZone({ from: 'publicInternet', name: expectation.fqdn, zone: 'public', }); await probe.assertHttps({ from: 'publicInternet', url, expectStatus: expectation.expectStatus ?? 200, expectCA: expectation.expectCA, }); // An internal device reaches the service via the controlled natIp DNAT (when firewalled). if (expectation.natIp) { await probe.assertReachable({ from: 'internalDevice', host: expectation.natIp, port }); } } /** Assert several fronted hostnames at once (multi-hostname caddy, etc.). */ export async function assertFrontedHostnames( net: NetworkHandle, fqdns: string[], shared: Omit, ): Promise { for (const fqdn of fqdns) { await assertFrontedServicePositives(net, { ...shared, fqdn }); } }