influxdb: place its directories, hand secrets over as files, name its UI #152

Open
mesh-admin wants to merge 2 commits from feat/influxdb-for-ace into main
Contributor

The manifest named /services/influxdb and /var/lib/influxdb-module — one
machine's paths — and passed the admin password and token through the
environment. ace is moving its 2022 instance onto the mesh, so the module
has to be what it is on any machine.

  • data, config and state are placed directories; the data keeps 1000:1000,
    the image's influxdb user, which is who owns ace's data today.
  • the init secrets reach the image through its own
    DOCKER_INFLUXDB_INIT_{PASSWORD,ADMIN_TOKEN}_FILE; the vault's files are
    mounted read-only. secrets-in-environment is gone.
  • the sidecar reads its token from the same file (MESH_INFLUXDB_TOKEN_FILE,
    added to client.ts) and reaches the server at its assigned machine port
    (${port:8086}) instead of assuming 8086. The unused config-dir mount,
    which held the CLI's copy of the admin token, is dropped.
  • the api endpoint contributes a route: the web UI is how people use it,
    and reach is the assignment's to say.

Verified: catalogue tests pass with MESH_CATALOGUE pointed at this tree.
The pinned 2.9.1 image, run on a scratch copy of ace's 2.4.0 data, opens
it, runs its metadata migrations (backing up the pre-upgrade bolt/sqlite)
and hashes the two stored tokens; /health passes. A fresh setup through
the _FILE variables, with dummy secrets as root-owned 0600 files, accepts
the token (200 on /api/v2/buckets) and the password (204 on /signin).
client.ts typechecks strict and reads the token file, tolerating the
endpoints key in its config.

The manifest named /services/influxdb and /var/lib/influxdb-module — one machine's paths — and passed the admin password and token through the environment. ace is moving its 2022 instance onto the mesh, so the module has to be what it is on any machine. - data, config and state are placed directories; the data keeps 1000:1000, the image's influxdb user, which is who owns ace's data today. - the init secrets reach the image through its own DOCKER_INFLUXDB_INIT_{PASSWORD,ADMIN_TOKEN}_FILE; the vault's files are mounted read-only. secrets-in-environment is gone. - the sidecar reads its token from the same file (MESH_INFLUXDB_TOKEN_FILE, added to client.ts) and reaches the server at its assigned machine port (${port:8086}) instead of assuming 8086. The unused config-dir mount, which held the CLI's copy of the admin token, is dropped. - the api endpoint contributes a route: the web UI is how people use it, and reach is the assignment's to say. Verified: catalogue tests pass with MESH_CATALOGUE pointed at this tree. The pinned 2.9.1 image, run on a scratch copy of ace's 2.4.0 data, opens it, runs its metadata migrations (backing up the pre-upgrade bolt/sqlite) and hashes the two stored tokens; /health passes. A fresh setup through the _FILE variables, with dummy secrets as root-owned 0600 files, accepts the token (200 on /api/v2/buckets) and the password (204 on /signin). client.ts typechecks strict and reads the token file, tolerating the endpoints key in its config.
mesh-admin added 1 commit 2026-09-29 22:12:31 +00:00
The manifest named /services/influxdb and /var/lib/influxdb-module — one
machine's paths — and passed the admin password and token through the
environment. ace is moving its 2022 instance onto the mesh, so the module
has to be what it is on any machine.

- data, config and state are placed directories; the data keeps 1000:1000,
  the image's influxdb user, which is who owns ace's data today.
- the init secrets reach the image through its own
  DOCKER_INFLUXDB_INIT_{PASSWORD,ADMIN_TOKEN}_FILE; the vault's files are
  mounted read-only. secrets-in-environment is gone.
- the sidecar reads its token from the same file (MESH_INFLUXDB_TOKEN_FILE,
  added to client.ts) and reaches the server at its assigned machine port
  (${port:8086}) instead of assuming 8086. The unused config-dir mount,
  which held the CLI's copy of the admin token, is dropped.
- the api endpoint contributes a route: the web UI is how people use it,
  and reach is the assignment's to say.

Verified: catalogue tests pass with MESH_CATALOGUE pointed at this tree.
The pinned 2.9.1 image, run on a scratch copy of ace's 2.4.0 data, opens
it, runs its metadata migrations (backing up the pre-upgrade bolt/sqlite)
and hashes the two stored tokens; /health passes. A fresh setup through
the _FILE variables, with dummy secrets as root-owned 0600 files, accepts
the token (200 on /api/v2/buckets) and the password (204 on /signin).
client.ts typechecks strict and reads the token file, tolerating the
endpoints key in its config.
jschoubben added 1 commit 2026-09-30 11:02:25 +00:00
grafana's data source and Node-RED's influxdb nodes reached ace's
InfluxDB by a LAN IP or a public name nobody routes, with a credential
somebody made by hand. Now a consumer requires influxdb-api and is told
where it is, which org and default bucket it serves, and signs in with
the password the mesh minted for the pair.

The credential is a v1-compatibility authorization, made per grant by
the new provisioner: InfluxDB 2.x generates API tokens itself and
ignores one the caller sends, so a v2 token could only be accepted by
hand per pair; a v1 authorization takes a caller-chosen password (8-72
characters, the mesh mints 40) and reads/writes every bucket as a
database of its name over InfluxQL and line protocol. A consumer
contributes `access` (read, write, read-write) and, for writing, the
buckets; a missing bucket is made and never deleted. Only
authorizations named mesh_* and marked [mesh] are ever changed or
removed; anything else of that name is refused and left alone.

The org and default bucket are served facts the assignment's settings
set, reaching both the consumers and the provisioner's config.json.
Author
Contributor

New on this branch (323ef9e): influxdb provides influxdb-api

  • Provision: influxdb-api (scope mesh). It serves scheme http, port (8086, which the mesh redirects to the machine port), org and bucket. org and bucket default to mesh/default and are set by the assignment's settings, which reach both the served facts and the provisioner's config.json. On ace that is org: zurag, bucket: zurag.
  • Credential model: provisioned, not accepted. For each grant, the new provisioner (provisioner/index.ts, grants.ts) creates a v1-compatibility authorization. Its username is the consumer's identity (mesh_<node>_<module>) and its password is the pair credential the mesh minted. A v2 API token can't be used: InfluxDB 2.9.1 ignores a token sent to POST /api/v2/authorizations (tested: the chosen token got 401), so a token could only be accepted by hand for each pair. A v1 authorization takes a password the caller chooses (8–72 characters; the mesh mints 40) and reads and writes every bucket as a database of the same name through /query (InfluxQL) and /write. No DBRP mapping is needed because InfluxDB maps each bucket virtually. No secret accept is needed for any consumer.
  • What a consumer contributes: access (read, the default, or write or read-write) and buckets. A reader that names no buckets may read every bucket in the org. A writer has to name its buckets, and system buckets are refused. If a named bucket is missing it is created with infinite retention, and it is never deleted.
  • Safety: only authorizations named mesh_* whose description starts with [mesh] are updated or removed. One with the same name that isn't marked is refused and left exactly as it is. No other token, user or bucket is touched. holds only reads, and ensure writes only what differs: the password is tried first and set only if it fails.
  • Runtime: the provisioner runs in the existing mesh-influxdb sidecar (MESH_TOOL_MODULES). It reads its grants from the placed directory ${dir:grants} through MESH_RECEIVES.

Tests

  • npm test pattern (compiled in the mesh-tools build image, node 22): typecheck and build pass, and 11/11 tests in test/grants.test.ts pass against a fake InfluxDB that mirrors 2.9.1's status codes.
  • MESH_CATALOGUE=<#152+#155 merged> go test ./internal/catalogue/ passes, including the real-catalogue parse (73 manifests).
  • Scratch resolution for ace, not committed: grafana's binding carries at ace.internal, port 8086, org/bucket zurag and as mesh_ace_grafana. The provider gets grants/ace.grafana.secret and a mesh.json with {access: read}. Every ${bound:…} and ${dir:…} fills.
  • End to end with throwaway containers (InfluxDB 2.9.1 at the pinned digest, this Dockerfile's runtime image, a scratch NATS, grafana 13.2.2):
    • The provisioner created mesh_ace_grafana with read access to every bucket, and grafana's own data source health check returned "datasource is working".
    • A rotated pair password was applied in place.
    • An authorization deleted by hand was recreated within about 25 seconds.
    • A writer grant (mesh_ace_nodered, write on zurag) wrote line protocol with a 204 and got a 404 on _monitoring. When it was withdrawn, its authorization was removed and the bucket stayed.
**New on this branch (323ef9e): influxdb provides `influxdb-api`** - **Provision:** `influxdb-api` (scope mesh). It serves `scheme` http, `port` (8086, which the mesh redirects to the machine port), `org` and `bucket`. `org` and `bucket` default to `mesh`/`default` and are set by the assignment's settings, which reach both the served facts and the provisioner's config.json. On ace that is `org: zurag, bucket: zurag`. - **Credential model: provisioned, not accepted.** For each grant, the new provisioner (`provisioner/index.ts`, `grants.ts`) creates a **v1-compatibility authorization**. Its username is the consumer's identity (`mesh_<node>_<module>`) and its password is the pair credential the mesh minted. A v2 API token can't be used: InfluxDB 2.9.1 ignores a `token` sent to `POST /api/v2/authorizations` (tested: the chosen token got 401), so a token could only be accepted by hand for each pair. A v1 authorization takes a password the caller chooses (8–72 characters; the mesh mints 40) and reads and writes every bucket as a database of the same name through `/query` (InfluxQL) and `/write`. No DBRP mapping is needed because InfluxDB maps each bucket virtually. **No `secret accept` is needed for any consumer.** - **What a consumer contributes:** `access` (`read`, the default, or `write` or `read-write`) and `buckets`. A reader that names no buckets may read every bucket in the org. A writer has to name its buckets, and system buckets are refused. If a named bucket is missing it is created with infinite retention, and it is **never deleted**. - **Safety:** only authorizations named `mesh_*` whose description starts with `[mesh]` are updated or removed. One with the same name that isn't marked is refused and left exactly as it is. No other token, user or bucket is touched. `holds` only reads, and `ensure` writes only what differs: the password is tried first and set only if it fails. - **Runtime:** the provisioner runs in the existing `mesh-influxdb` sidecar (`MESH_TOOL_MODULES`). It reads its grants from the placed directory `${dir:grants}` through `MESH_RECEIVES`. **Tests** - `npm test` pattern (compiled in the mesh-tools build image, node 22): typecheck and build pass, and 11/11 tests in `test/grants.test.ts` pass against a fake InfluxDB that mirrors 2.9.1's status codes. - `MESH_CATALOGUE=<#152+#155 merged> go test ./internal/catalogue/` passes, including the real-catalogue parse (73 manifests). - Scratch resolution for ace, not committed: grafana's binding carries `at` ace.internal, `port` 8086, `org`/`bucket` zurag and `as` mesh_ace_grafana. The provider gets `grants/ace.grafana.secret` and a `mesh.json` with `{access: read}`. Every `${bound:…}` and `${dir:…}` fills. - End to end with throwaway containers (InfluxDB 2.9.1 at the pinned digest, this Dockerfile's runtime image, a scratch NATS, grafana 13.2.2): - The provisioner created `mesh_ace_grafana` with read access to every bucket, and grafana's own data source health check returned "datasource is working". - A rotated pair password was applied in place. - An authorization deleted by hand was recreated within about 25 seconds. - A writer grant (`mesh_ace_nodered`, write on `zurag`) wrote line protocol with a 204 and got a 404 on `_monitoring`. When it was withdrawn, its authorization was removed and the bucket stayed.
You are not authorized to merge this pull request.
This pull request can be merged automatically.
This branch is out-of-date with the base branch
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin feat/influxdb-for-ace:feat/influxdb-for-ace
git checkout feat/influxdb-for-ace
Sign in to join this conversation.
No Reviewers
No labels
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: novox/mesh-catalog#152