jaque import is a compiler. Point it at a config tree and it gives back CUE and a report, with no dozen screens to babysit. It exists because a Nagios use chain and CUE's unification are different enough semantics that no line-by-line transliteration would be trustworthy: the importer resolves Nagios's own inheritance rules first, then re-derives CUE structure from the result.

Status: round-trip correctness is property-tested against generated configs; the importer has never been run against a real third-party Nagios config, because the project has no such corpus yet. Treat its output as a strong first draft, still short of a finished migration; see section 5.

1. Running it

jaque import -from nagios -o jaque.cue /etc/nagios/

The positional argument is a directory (jaque looks for nagios.cfg inside it, per Nagios's own convention) or a single file. -from accepts nagios and nautobot; the second is described in Nautobot import. -o writes the CUE to a file; without it, CUE goes to stdout and the report to stderr, on separate streams so piping to a file never mixes them. -timezone names the IANA zone the Nagios process ran in, default Local, written once as the config's top-level timezone; see section 4.

2. The pipeline

nagios.cfg
  -> include resolution   (cfg_file=, cfg_dir=, resource.cfg for $USERn$)
  -> parse                (define blocks -> AST, every node keeps file:line)
  -> inheritance resolution (use/name/register -> effective objects)
  -> semantic mapping      (effective objects -> jaque's internal IR)
  -> structure recovery    (shared values factored back into CUE templates)
  -> emit                  (CUE AST via cue/ast + cue/format) + report

Nagios's use chains are ordered multiple inheritance with additive values (+value) and unset (null): semantics that do not map 1:1 onto CUE's unification, so the importer never translates a template directly. It flattens every object using Nagios's own resolution rules first (the correctness anchor, and the most heavily golden-tested part of the pipeline), then factors shared values back out into CUE templates for a readable emit. When that recovery is ambiguous, it emits flat rather than guess, and says so in the report.

3. The migration report

Every source object gets one line: mapped, approximated (translated, but something changed: the report says what), or unsupported (dropped, with file:line). The header carries the trust-anchor number:

objects: N emitted of M in source (P% survived)

That number is the metric that matters: how much of the source tree actually made it across, independent of whether the command exited without errors. The report favors accuracy over a favorable-looking summary: an object silently dropped and called mapped anyway is worse than one marked unsupported.

4. What is mapped versus approximated versus unsupported

Category Examples
Mapped, 1:1 Hosts, services, most check_command translations, parents, timeperiods, including date exceptions and exclude, check_period, escalation_period and contact periods (the service one when the two differ), contacts onto jaque's four contact types, hostgroup-based services (kept as a group-level definition, never exploded into per-host copies), hostdependency and servicedependency onto the dependencies block, with notification_failure_criteria mapped onto fails_on and inherits_parent/dependency_period carried across (see Dependencies section 7), event_handler and event_handler_enabled onto the handlers block, with enable_event_handlers, global_host_event_handler, global_service_event_handler and event_handler_timeout carried across (see Event handlers section 7).
Approximated notification_options combinations that do not map cleanly onto jaque's notification kinds: the report names what changed. Nagios evaluated timeperiods in the process's own zone; the import writes the -timezone value (default Local) as the config's top-level timezone and reports it once.
Not supported today event_handler_period (Icinga 1's; Nagios has no such directive), obsess_over_*, most escalation directives, execution_failure_criteria on a dependency (there is no execution-side gate to land it on), and any object mixing active and passive checks, excluded on purpose. jaque's schema models a check as one type; an object trying to be both active and passive at once has nowhere well-defined to go, so it is reported rather than guessed at.

5. How far it is verified

Round-trip correctness (emit -> re-parse -> compare) is property-tested against generated configs. What is not yet done: verification against a real-world corpus at the scale that would let this page claim a concrete coverage percentage across "typical" Nagios estates. Treat the emitted CUE as a strong first draft: validate it with jaque -config jaque.cue before you trust it, and read the unsupported lines before deciding the import is complete.

6. Icinga 2: not yet

The importer pipeline is built to host more than one frontend, but only Nagios is implemented today. An Icinga 2 frontend is not built.

7. Security considerations

The importer parses a config tree offline, once, at import time. It is not a network-facing surface. The tree itself is still untrusted input if it came from somewhere other than the estate you already run: read the migration report and validate the emitted CUE before loading it into a jaque you care about.