From 98cc0fa21db2908357cbd3c67e1929b4cee1003e Mon Sep 17 00:00:00 2001 From: Natalie Date: Mon, 29 Jun 2026 14:11:13 -0400 Subject: [PATCH] refactor(dns-updater): rename prospector.ct -> sales.ct (public name) The always-on region-mobile surface is publicly "sales" (the node is still the Prospector PWA internally). DNS host becomes sales.ct.uvlava.com; the joker.com CNAME is sales.transquinnftw.com -> sales.ct.uvlava.com. Updated terraform record, env grant, client examples, README, and tests (8 pass). Co-Authored-By: Claude Opus 4.8 --- services/dns-updater/README.md | 19 ++++++++++--------- services/dns-updater/client/dyndns-update.sh | 2 +- services/dns-updater/client/install-client.sh | 4 ++-- services/dns-updater/env.example | 2 +- services/dns-updater/package.json | 2 +- services/dns-updater/src/index.ts | 2 +- services/dns-updater/test/smoke.test.ts | 4 ++-- terraform/do/dns.tf | 9 +++++---- 8 files changed, 23 insertions(+), 21 deletions(-) diff --git a/services/dns-updater/README.md b/services/dns-updater/README.md index 6d2f089..c2d7469 100644 --- a/services/dns-updater/README.md +++ b/services/dns-updater/README.md @@ -9,7 +9,7 @@ when they move regions — no registrar GUI, no manual `dig`/edit: | FQDN (moving) | Node | Lifecycle | | ---------------------------- | ----------------------------- | ---------------------------------------- | | `live.ct.uvlava.com` | broadcast relay droplet | **ephemeral** — per show, nearest the broadcaster, torn down after | -| `prospector.ct.uvlava.com` | Prospector PWA node | **always-on** — follows the operator across regions, stays up | +| `sales.ct.uvlava.com` | "sales" surface = Prospector PWA node | **always-on** — follows the operator across regions, stays up | The pretty `*.transquinnftw.com` names are **static CNAMEs** onto these (set once, below), so the only records that ever move are inside the zone we control via the @@ -76,8 +76,8 @@ exist (`terraform apply` of the records below), add two **static CNAMEs** there these never change again: ``` -live CNAME live.ct.uvlava.com. -prospector CNAME prospector.ct.uvlava.com. +live CNAME live.ct.uvlava.com. +sales CNAME sales.ct.uvlava.com. ``` > `transquinnftw.com` is NOT delegated to DO, so these CNAMEs are added in the @@ -87,7 +87,7 @@ prospector CNAME prospector.ct.uvlava.com. ## terraform records `terraform/do/dns.tf` creates `dns.ct` (→ forge) and seeds `live.ct` / -`prospector.ct` with `lifecycle { ignore_changes = [value] }` — TF makes them +`sales.ct` with `lifecycle { ignore_changes = [value] }` — TF makes them exist; this service owns their value at runtime. ## Node-side usage @@ -101,13 +101,14 @@ curl -fsS -H "Authorization: Bearer $DNS_UPDATER_TOKEN" \ "https://dns.ct.uvlava.com/nic/update?hostname=live.ct.uvlava.com&myip=$DROPLET_IP" ``` -**Prospector node (always-on, on boot + every 5 min)** — install the reusable -client (`client/`), which self-reports the node's public IP (`myip` omitted → -caller IP) via a systemd timer so the record tracks the node across moves: +**Sales node (always-on, on boot + every 5 min)** — the public "sales" surface +is the Prospector PWA node. Install the reusable client (`client/`), which +self-reports the node's public IP (`myip` omitted → caller IP) via a systemd +timer so the record tracks the node across moves: ```bash # on the node, as root: -DNS_HOSTNAME=prospector.ct.uvlava.com NODE_TOKEN= \ +DNS_HOSTNAME=sales.ct.uvlava.com NODE_TOKEN= \ ./client/install-client.sh ``` @@ -116,7 +117,7 @@ It installs `dyndns-update.sh` + a `dyndns-updater.timer` (OnBootSec + every ```bash curl -fsS -H "Authorization: Bearer $TOKEN" \ - "https://dns.ct.uvlava.com/nic/update?hostname=prospector.ct.uvlava.com" + "https://dns.ct.uvlava.com/nic/update?hostname=sales.ct.uvlava.com" ``` ## Local dev diff --git a/services/dns-updater/client/dyndns-update.sh b/services/dns-updater/client/dyndns-update.sh index 08a59fc..f0c26bc 100755 --- a/services/dns-updater/client/dyndns-update.sh +++ b/services/dns-updater/client/dyndns-update.sh @@ -5,7 +5,7 @@ # # Config: /etc/dyndns-updater/dyndns.conf # DNS_UPDATER_URL=https://dns.ct.uvlava.com -# DNS_HOSTNAME=prospector.ct.uvlava.com +# DNS_HOSTNAME=sales.ct.uvlava.com # DNS_TOKEN_FILE=/etc/dyndns-updater/token # file containing the node token # # myip is omitted, so the updater uses the caller's observed public IP. diff --git a/services/dns-updater/client/install-client.sh b/services/dns-updater/client/install-client.sh index 315f74d..abb02a4 100755 --- a/services/dns-updater/client/install-client.sh +++ b/services/dns-updater/client/install-client.sh @@ -3,13 +3,13 @@ # (e.g. the Prospector PWA node on lime). Run as root ON THE NODE. # # Usage: -# DNS_HOSTNAME=prospector.ct.uvlava.com NODE_TOKEN= ./install-client.sh +# DNS_HOSTNAME=sales.ct.uvlava.com NODE_TOKEN= ./install-client.sh # # After install the node refreshes its A record on boot and every 5 minutes. set -euo pipefail DNS_UPDATER_URL="${DNS_UPDATER_URL:-https://dns.ct.uvlava.com}" -DNS_HOSTNAME="${DNS_HOSTNAME:?set DNS_HOSTNAME, e.g. prospector.ct.uvlava.com}" +DNS_HOSTNAME="${DNS_HOSTNAME:?set DNS_HOSTNAME, e.g. sales.ct.uvlava.com}" NODE_TOKEN="${NODE_TOKEN:?set NODE_TOKEN to this node dyndns token}" HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" diff --git a/services/dns-updater/env.example b/services/dns-updater/env.example index a20a47b..4d38722 100644 --- a/services/dns-updater/env.example +++ b/services/dns-updater/env.example @@ -9,4 +9,4 @@ DNS_DOMAIN=uvlava.com # Token -> allowed-hostname grants. One grant per node; a token may update ONLY # its listed hosts. Generate strong random tokens (e.g. `openssl rand -hex 24`). -DNS_UPDATER_TOKENS=[{"token":"REPLACE_live_node_token","hosts":["live.ct.uvlava.com"]},{"token":"REPLACE_prospector_node_token","hosts":["prospector.ct.uvlava.com"]}] +DNS_UPDATER_TOKENS=[{"token":"REPLACE_live_node_token","hosts":["live.ct.uvlava.com"]},{"token":"REPLACE_sales_node_token","hosts":["sales.ct.uvlava.com"]}] diff --git a/services/dns-updater/package.json b/services/dns-updater/package.json index d935872..e840151 100644 --- a/services/dns-updater/package.json +++ b/services/dns-updater/package.json @@ -2,7 +2,7 @@ "name": "@ct/dns-updater", "version": "0.1.0", "private": true, - "description": "dyndns2-compatible DNS updater for *.ct.uvlava.com, backed by the DigitalOcean DNS API. Lets region-mobile nodes (live broadcast relay, prospector PWA) self-update their A record on relocation.", + "description": "dyndns2-compatible DNS updater for *.ct.uvlava.com, backed by the DigitalOcean DNS API. Lets region-mobile nodes (live broadcast relay, sales/prospector PWA) self-update their A record on relocation.", "type": "module", "scripts": { "dev": "bun run --watch src/index.ts", diff --git a/services/dns-updater/src/index.ts b/services/dns-updater/src/index.ts index 6ab7891..80b58cb 100644 --- a/services/dns-updater/src/index.ts +++ b/services/dns-updater/src/index.ts @@ -2,7 +2,7 @@ * dns.ct.uvlava.com — dyndns2-compatible DNS updater. * * Region-mobile nodes (the per-show broadcast relay = live.ct.uvlava.com, the - * always-on prospector PWA = prospector.ct.uvlava.com) call /nic/update on + * always-on sales surface = sales.ct.uvlava.com) call /nic/update on * (re)location to repoint their own A record at their current public IP, via * the DigitalOcean DNS API. The transquinnftw.com pretty-names are static * CNAMEs onto these, so only the records in this zone ever move. diff --git a/services/dns-updater/test/smoke.test.ts b/services/dns-updater/test/smoke.test.ts index bb420c1..9658533 100644 --- a/services/dns-updater/test/smoke.test.ts +++ b/services/dns-updater/test/smoke.test.ts @@ -40,7 +40,7 @@ beforeAll(async () => { process.env.PORT = "8099"; process.env.DNS_UPDATER_TOKENS = JSON.stringify([ { token: "live-secret", hosts: ["live.ct.uvlava.com"] }, - { token: "prospector-secret", hosts: ["prospector.ct.uvlava.com"] }, + { token: "sales-secret", hosts: ["sales.ct.uvlava.com"] }, ]); await import("../src/index.ts"); @@ -82,7 +82,7 @@ test("wrong token is rejected", async () => { }); test("token cannot update a host outside its grant", async () => { - const r = await update("hostname=prospector.ct.uvlava.com&myip=1.2.3.4", { + const r = await update("hostname=sales.ct.uvlava.com&myip=1.2.3.4", { authorization: "Bearer live-secret", }); expect(r.status).toBe(403); diff --git a/terraform/do/dns.tf b/terraform/do/dns.tf index d28cd59..07baf39 100644 --- a/terraform/do/dns.tf +++ b/terraform/do/dns.tf @@ -119,12 +119,13 @@ resource "digitalocean_record" "ct_live" { } } -# prospector.ct.uvlava.com -> always-on Prospector PWA node (region-mobile; -# follows the operator). Seeded to the current node (lime / lilith-store-backend). -resource "digitalocean_record" "ct_prospector" { +# sales.ct.uvlava.com -> always-on "sales" surface = the public Prospector PWA +# node (region-mobile; follows the operator). "sales" is the public name; the +# node is the Prospector PWA. Seeded to the current node (lime / lilith-store-backend). +resource "digitalocean_record" "ct_sales" { domain = digitalocean_domain.uvlava.name type = "A" - name = "prospector.ct" + name = "sales.ct" value = "165.227.96.183" ttl = 60