Skip to content

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.

Terminal window
ndr connectors list
ndr connectors validate
ndr connectors test <instance> --cassette <recording.json>
ndr connectors test <instance> --live
ndr connectors collect <instance> --once --live

Run 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:

Terminal window
sudo -u nyxtrace env NDR_CONNECTORS_ENABLED=true ndr connectors validate

Prints the registered connectors and the configured instances, with their tenant, enabled state, licence state and health.

Terminal window
$ ndr connectors list

list 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.

Checks connectors.yaml exactly the way startup would, and exits non-zero on the first problem:

Terminal window
$ ndr connectors validate

It 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:

Terminal window
$ ndr connectors test unifi-home --cassette tests/connectors/unifi/success.json

The 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.

Two ways, and both call the same Test() method.

From the command line, with --live instead of a recording:

Terminal window
sudo -u nyxtrace env NDR_CONNECTORS_ENABLED=true ndr connectors test unifi --live
sudo -u nyxtrace env NDR_CONNECTORS_ENABLED=true ndr connectors collect unifi --once --live

test --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.