Skip to main content

Template reference

A template is a YAML file with three sections: tasks, agents (or top-level modules), and transfer. Parsing is strict: an unknown field name is an error, so typos fail fast.

Minimal complete example

tasks:
  - name: disk
    type: local
    local: { command: "df --output=pcent / | tail -1 | tr -d ' %'" }
    variable: disk_pct

agents:
  - name: "myhost"
    group: "Servers"
    interval: 300
    modules:
      - name: "Disk used"
        type: generic_data
        data: "{{ disk_pct }}"
        unit: "%"

transfer:
  mode: tentacle
  tentacle: { address: "pandora.example.com" }

tasks: — ordered list of executions

Tasks run sequentially, in declared order. A task may use variables produced by earlier tasks in any of its string fields (chaining: login → token → authenticated request).

Field Required Description
name yes Unique task identifier (used in logs)
type yes request or local
request if type=request HTTP request spec (below)
local if type=local Command spec (below)
filter no Extraction filter (below). Without it, the trimmed raw output is stored
variable no Name to store the result under. Must match [A-Za-z_][A-Za-z0-9_]*

request: (HTTP)

Field Required Default Description
url yes Target URL. Supports {{ }}
method no GET GET, POST, PUT, DELETE, PATCH, HEAD
headers no Map of header → value. Values support {{ }}
body no Request body. Supports {{ }}
timeout no 30 Seconds
skip_tls_verify no false Accept invalid TLS certificates

A response with status outside 2xx is a task failure. Response bodies are capped at 10 MiB.

local: (command)

Field Required Default Description
command yes Executed with /bin/sh -c. Supports {{ }}. Shell $ is untouched (awk '{print $5}' works as-is)
timeout no 30 Seconds; the process is killed on expiry

A non-zero exit code is a task failure (stderr is included in the log).

filter: — extracting values

Field Required Description
type yes jq or regexp
expression yes The filter expression

Result cardinality (both filter types): 0 matches → variable unset (task failure semantics) · 1 match → scalar · N matches → array.

jq — the task output must be valid JSON. The expression runs with an embedded jq engine (no jq binary needed). Each value the expression emits is one element: .token → scalar, .items[].name → array, .items[] → array of objects.

regexp — Go RE2 syntax (no backtracking, no lookahead) applied to the raw output. Per match:

Pattern shape Each match becomes
No capture group (cpu\d) The full match (string)
One unnamed group ((\d+)%) Capture group 1 (string)
2+ unnamed groups ((a)(b)(c)) Positional array: [[a, b, c], ...]
Named groups ((?P<mount>...)) An object: group name → captured text

Use (?m) for line-anchored multi-line patterns and (?i) for case-insensitive matching. Do not mix named and unnamed groups in the same regexp if you want predictable access; the named form exposes only the named fields.

Type coercion: extracted strings that look numeric become numbers (recursively, including object fields), so arithmetic works on them.

Variables and {{ }} expressions

Any string field of tasks (after the producing task), agents, and modules may embed {{ expression }}. Expressions are evaluated with expr-lang against the variable store.

Expression Result
{{ token }} Variable value
{{ 100 - disk_pct }} Arithmetic
{{ names[0] }} Array indexing
{{ value.mount }} Object field (inside for_each)
{{ names[index] }} Lockstep parallel array (inside for_each)

Referencing an undefined variable is an error → the affected module is skipped (or the run aborts under --strict).

agents: — one block per agent

Required unless you use top-level modules: (see agent_plugin mode). Each agent becomes one <agent_data> XML document.

Field Required Description
name yes Agent name
modules yes List of module blocks (at least one)
alias no Agent alias
parent_agent_name no Parent agent
description no Description
version no Agent version string
os_name, os_version no OS identification
timestamp no Override data timestamp
address no IP/hostname
group no Target group
interval no Seconds (integer)
agent_mode no Agent mode

All string fields support {{ }}.

modules: — module blocks

Module blocks live inside an agent, or at the top level (only with transfer.mode: agent_plugin).

Control fields (executor semantics, not sent to Pandora):

Field Description
for_each Array variable name. The block expands to one module per element; {{ value }} and {{ index }} become available. A scalar variable iterates as a 1-element array. For unnamed capture groups with 2+ groups, each value is an array so you can use {{ value[0] }}. Need several modules per element? Write several blocks with the same for_each
when Raw boolean expr-lang expression (no {{ }}). False → module (or element) skipped. Inside for_each it is evaluated per element and sees value/index. Example: when: 'not (value.mount matches "^/DB")'

Data fields — the two required plus the full set accepted by the dataserver. Values may be numbers or strings in YAML; all support {{ }}:

Field Required Description
name yes Module name
type yes Module type (generic_data, generic_proc, generic_data_string, async_data, ...)
data no Module value
description no Description
unit no Unit label
interval no Module interval
tags no Tags
module_group no Module group
module_parent, module_parent_unlink no Parent module relation
min_warning, max_warning, min_critical, max_critical no Numeric thresholds
min_warning_forced, max_warning_forced, min_critical_forced, max_critical_forced no Forced threshold variants
str_warning, str_critical no String-match thresholds
str_warning_forced, str_critical_forced no Forced string thresholds
warning_inverse, critical_inverse no Invert threshold logic
min, max no Valid data range
post_process no Multiplier applied by the server
disabled no Create disabled
status no Force status
timestamp no Override data timestamp
custom_id no Custom identifier
critical_instructions, warning_instructions, unknown_instructions no Operator instructions
quiet no Quiet mode
min_ff_event, min_ff_event_normal, min_ff_event_warning, min_ff_event_critical no FlipFlop thresholds
module_ff_interval, ff_type, ff_timeout, each_ff no FlipFlop behavior
crontab no Cron-style module scheduling
extra_data no Extra payload
alert_templates no List of alert template names to bind

transfer: — delivery

Field Required Description
mode yes tentacle, local or agent_plugin
tentacle.address for tentacle Pandora server address
tentacle.port no (default 41121) Tentacle port
tentacle.binary no Path to tentacle_client if not in $PATH
tentacle.extra_args no Extra tentacle client arguments (list)
local.directory for local Directory where the .data XML file is written
module_prefix_separator no (default " - ") Separator for multi-agent prefixing in agent_plugin mode
Mode Output Use case
tentacle Full <agent_data> XML sent via tentacle client Remote execution (cron, Discovery)
local Full <agent_data> XML written to a directory Running on the Pandora server itself (point it at the incoming dir), or debugging
agent_plugin Only <module> fragments printed to stdout — the real agent adds the header Running as module_plugin of a software agent

agent_plugin specifics:

  • Top-level modules: without any agents: block is allowed (and only allowed in this mode).
  • With multiple agents defined, each module name is prefixed <agent_name> - <module_name> so modules cannot collide under the one real agent.