A relative link out of this repository resolves nowhere on a forge. Every other reference here names the record in prose.
76 lines
4.1 KiB
Markdown
76 lines
4.1 KiB
Markdown
# Example modules
|
|
|
|
Manifests, not programs. They are here because the contract is easier to read as something that
|
|
works than as a description of something that would.
|
|
|
|
**Third-party software runs *on* the mesh, not *of* it** (novox/hq ADR 0001). dnsmasq is not the
|
|
mesh's, and neither is systemd-resolved — what is the mesh's is the fact only it can know, which
|
|
is which machines exist and where they are. So the mesh writes that to a file and these read it.
|
|
|
|
## Resolving a service named under a machine
|
|
|
|
`postgres.novox.internal`, `plex.ace.internal`. The first label is the service and the rest is the
|
|
node, so **anything under a node's name must resolve to that node** and a proxy there routes by
|
|
the name it was asked for. That routing is a separate concern and stays separate.
|
|
|
|
Two roles, and they are genuinely different things:
|
|
|
|
| | claims | |
|
|
|---|---|---|
|
|
| **serving** | `the-dns-port` | answers the wildcards — `dnsmasq.json` |
|
|
| **asking** | `the-resolver-configuration` | decides what the machine asks — `resolved-split-dns.json`, `resolv-conf.json` |
|
|
|
|
**systemd-resolved cannot serve a wildcard**, so it is only ever an *asking* module: it routes the
|
|
mesh's suffix to something that can. Treating the two roles as one would produce a module that
|
|
cannot work, which is the mistake worth naming.
|
|
|
|
Assign one of each. Two of either is refused by the mesh rather than fought over on the machine:
|
|
|
|
> `resolved-split-dns and resolv-conf both claim "the-resolver-configuration", and only one thing
|
|
> may hold it per node`
|
|
|
|
ADR 0009's table names that resource `/etc/resolv.conf`, which is what it *is*, the way it writes
|
|
*the seat*. A claim is a name in the catalogue's own form, so it is written as one.
|
|
|
|
## Why neither needs to know the machine's address
|
|
|
|
Both would ordinarily need it — a resolver must bind somewhere, and a stub must be pointed
|
|
somewhere — and a static manifest cannot know it.
|
|
|
|
Neither does, because both name things **the mesh itself named**: the private network's interface
|
|
is `mesh0` on every machine, and the address a resolver listens on for the machine's own use is
|
|
`127.0.0.54` on every machine. A name the mesh chose is a name a manifest can use.
|
|
|
|
## Asking for a bucket
|
|
|
|
`object-store.json` provides one, `photos.json` asks for one. Together they are the whole of an
|
|
edge, and they are here as a **pair** because that is the only way to see the halves line up:
|
|
|
|
| the provider says | the consumer says |
|
|
|---|---|
|
|
| `provides: s3-bucket` | `requires: s3-bucket` |
|
|
| `receives` — where to be told who asked | `contributes: {bucket: photos}` — what it wants |
|
|
| `grants` — where their credentials land | `secrets` — where to be given its key |
|
|
| `serves` — port, scheme, region | `binds` — where to be told all that |
|
|
|
|
**The mesh adds the half neither can know**: which machine the provider is on, and where it is on
|
|
the private network. Neither manifest names an address, and that is what lets the same pair work
|
|
on any mesh.
|
|
|
|
**`s3-bucket` names the protocol, not the product** (novox/hq ADR 0027). A
|
|
consumer's code is written against the S3 API, and swapping one store for another does not break
|
|
it — so the coupling is to S3. A database is the other case: an application is written against
|
|
PostgreSQL or against SQL Server, so those provisions name the engine.
|
|
|
|
**What the pair is checked for.** That the names match, that each side says where it wants to be
|
|
told, and that the consumer contributes the key the provisioner actually reads — `bucket`, not
|
|
`name`. Contributing `name` (which is what a database consumer contributes) resolves perfectly and
|
|
then fails on the machine with *asked for a bucket and did not name it*, which is a long way from
|
|
the manifest that caused it.
|
|
|
|
The provisioner that makes the credential true lives in
|
|
[`../objectstore-provisioner`](../objectstore-provisioner), and is proven against a real store in
|
|
the lab — including the assertion a database does not need, that **a consumer cannot reach another
|
|
consumer's bucket**. One store holds every bucket behind one endpoint, so that isolation is a
|
|
policy somebody wrote rather than a boundary the product has.
|