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 <noreply@anthropic.com>
This commit is contained in:
parent
e89cca3dc9
commit
98cc0fa21d
8 changed files with 23 additions and 21 deletions
|
|
@ -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=<token> \
|
||||
DNS_HOSTNAME=sales.ct.uvlava.com NODE_TOKEN=<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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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=<token> ./install-client.sh
|
||||
# DNS_HOSTNAME=sales.ct.uvlava.com NODE_TOKEN=<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)"
|
||||
|
|
|
|||
|
|
@ -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"]}]
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue