The ndr connectors command
Four subcommands. Three of them never open a network connection to a foreign
system; the fourth does so only when you ask for it with --live. All of them
run before the main configuration is loaded, so validating a connector file
needs neither the database nor the state store.
ndr connectors listndr connectors validatendr connectors test <instance> --cassette <recording.json>ndr connectors test <instance> --livendr connectors collect <instance> --once --liveRun the live forms as the service user, because a root-run check proves the file modes but not that the service account can read them:
sudo -u nyxtrace env NDR_CONNECTORS_ENABLED=true ndr connectors validatePrints the registered connectors and the configured instances, with their tenant, enabled state, licence state and health.
$ ndr connectors listlist is built with a transport that refuses every request, so it physically
cannot reach out. It tells you what the core knows and what your file declares —
nothing about whether a controller is reachable.
validate
Section titled “validate”Checks connectors.yaml exactly the way startup would, and exits non-zero on
the first problem:
$ ndr connectors validateIt catches: unknown connector ids, unknown fields, duplicate instance names, schema violations including bounds and polling floors, plaintext secrets, missing secret files, and secret files with the wrong owner or mode.
A secret file has exactly two accepted shapes — 0640 root:<service group> or
0600 <service user> — and the group of the secrets directory itself is the
authority for which group counts. Every refusal names the file and the fix. See
UniFi Network.
Run it before every service restart. A connector file that fails validation fails the start, and a service that will not start at 23:00 is a worse evening than a non-zero exit code at 22:55.
Replays a frozen recording against the connector and prints a structured diagnosis:
$ ndr connectors test unifi-home --cassette tests/connectors/unifi/success.jsonThe recording is the unit of testing: it is checked into the repository, it is anonymised, and it exercises the same code path the real connector uses, because the transport is injected. Continuous integration only ever uses this form, and it needs no network.
A recording also declares whether it is synthetic — built from public documentation — or a real capture, and which foreign version it was recorded against. That last field is how you find out that a connector’s assumptions are older than the system it is talking to.
Testing against the real system
Section titled “Testing against the real system”Two ways, and both call the same Test() method.
From the command line, with --live instead of a recording:
sudo -u nyxtrace env NDR_CONNECTORS_ENABLED=true ndr connectors test unifi --livesudo -u nyxtrace env NDR_CONNECTORS_ENABLED=true ndr connectors collect unifi --once --livetest --live proves reachability, authentication, authorisation and the
response shape, and writes nothing. collect --once --live pulls exactly one
batch and prints how many records of which class arrived; it stores nothing and
advances no cursor, so running it never makes the service skip data. Values are
withheld unless --verbose is given, because they can be MAC addresses and
client names. A failure names its class: auth, tls, unreachable,
forbidden, rate_limited, timeout.
--live is deliberately an explicit flag on an explicit invocation. The default
of every subcommand still reaches nothing.
From the interface, with the test connection button next to the connector instance. It calls the same method, which:
- performs no writing request — the conformance suite proves that, rather than the connector claiming it, and a session login counts as authentication rather than a write of domain data;
- returns a structured diagnosis: reachable, authenticated, permissions sufficient, a data sample with a row count, and the detected foreign version.
That one button prevents the most expensive class of integration mistake: the wrong endpoint, the wrong certificate, or an account without the permission it needs — each of which otherwise presents as “it returns nothing” and costs an afternoon.