External commands (passive results, acknowledgements, downtimes) reach
jaque through two doors: the Nagios external command file, unchanged on
the wire, and a ConnectRPC CommandService that speaks JSON, gRPC and
gRPC-Web on the dashboard's port. Both feed one internal command channel,
merged before the engine sees a command, so a client that only knows the
1999 FIFO format and a client that wants a typed batch RPC get identical
semantics. The FIFO exists for compatibility and costs nothing to keep;
the API exists because a translator receiving bursts needs a response
code and an all-or-nothing batch, which a named pipe cannot give.
1. The FIFO
Enable it with -command-file <path> and write lines in Nagios's format:
[<unix_ts>] PROCESS_SERVICE_CHECK_RESULT;<host>;<service>;<code>;<output>
FIFO external commands
lists every verb the FIFO accepts, the full wire format and field-by-field
detail, including what a downtime line must and must not carry: only
fixed=1 and trigger_id=0. Flexible and triggered downtimes are
rejected, not silently downgraded.
2. The API
CommandService exposes six RPCs: ProcessCheckResult,
ProcessCheckResults (batch), AcknowledgeProblem,
RemoveAcknowledgement, ScheduleDowntime and DeleteDowntime. They
are served over ConnectRPC, so a JSON POST from curl, a gRPC client and a
gRPC-Web client all reach the same handler on the same port as the
dashboard, over cleartext HTTP/2 via h2c. Optional bearer auth via
-api-token protects writes only; reads through QueryService are
always open. Command and query
service is the full RPC surface.
2.1 Batch is all-or-nothing
ProcessCheckResults validates every item before enqueueing any: one
malformed result fails the whole call and nothing is queued. Once
validation passes, results enqueue in order and the first send failure
stops the rest. A translator receiving bursts (an SNMP trap pipeline, for
instance) gets one clear failure point rather than a partially applied
batch.
2.2 Enqueued is not applied
A passive result posted through the API lands on the same command channel
as one from the FIFO, tagged origin: passive. An OK response means
enqueued, never applied: the engine resolves it at its own pace, and a
result for an object not declared passive is discarded with a warning
rather than silently accepted. Passive checks
covers what happens to it after that.
3. One channel, either door
Text version
FIFO reader ---+
+---> command channel ---> engine loop
API handler ---+ |
not mine -------+---> owning engine (one hop)
Both the FIFO reader and the API handler feed the same internal command
channel. A command addressed to an object owned by a different engine, in
a multi-engine deployment, is forwarded once to its owner, and a
forwarded command is never forwarded again, which makes the single hop
structural rather than a convention. A client can therefore send to any
engine, or to a -target ui process, without knowing who owns what; see
Cluster and coordination.
4. Security considerations
The FIFO is a file: whoever can write it can acknowledge, silence or
assert the state of any passive object, and there is no authentication
beyond the file's mode. The API listens on the dashboard's port; without
-api-token every write RPC is open to anyone who can reach that port,
and with it the token travels as a bearer header over whatever transport
the operator put in front of jaque, which by default is cleartext. Reads
are open by design. Put the port behind TLS termination and a network
boundary before exposing it beyond the monitoring host; Deployment
security says how.