Skip to main content

Requisition

Manage Horizon requisitions, the provision.pl-shape data, declaratively from git. requisition convert brings existing XML in, apply ships edits out, and requisition import / status cover the lifecycle.

YAML​

The composite kind: Requisition document carries both the requisition (nodes, interfaces, services, categories, assets) and its optional spec.foreignSource (scan interval, detectors, policies).

A node may declare a location (its monitoring / Minion location); omit it for the Default location.

apiVersion: provisioning.opennms.org/v1
kind: Requisition
metadata:
name: acme-prod
spec:
# Omit this whole block for "portable" YAML that inherits Horizon's
# default foreign-source.
foreignSource:
scanInterval: 1d
detectors:
- name: ICMP
class: org.opennms.netmgt.provision.detector.icmp.IcmpDetector
nodes:
- foreignId: bbone-sw01
label: bbone-sw01
location: labmonkeys-hq # monitoring (Minion) location
interfaces:
- ip: 192.168.8.8
snmpPrimary: P
services: [ICMP, SNMP]
categories: [Production, Network]

Pinned vs portable foreignSource. Include spec.foreignSource (detectors + policies) and the YAML owns both the requisition and its foreign source. Omit it and the requisition inherits Horizon's default foreign source; if a custom foreign source already existed for that name, apply deletes it (--diff enumerates the displaced detectors/policies). The example below shows the pinned style with every modeled field.

Unmodeled XML is preserved under metadata.x-onmsctl-unmodeled, so a convert then apply then export then re-apply round trip keeps server-side fields onmsctl doesn't model yet. The annotation is stripped before the diff and the wire body, so it never changes the apply outcome.

Apply​

onmsctl apply -f acme-prod.yaml --dry-run --diff # preview the per-node diff
onmsctl apply -f acme-prod.yaml # POST + auto-import

The apply path computes a three-level diff (canonical-bytes / per-node / per-leaf), auto-decides rescanExisting from the scan-relevance of what changed, writes the foreign source and requisition, and triggers the import. apply picks rescanExisting automatically from the diff: changes that affect what provisiond discovers (services, SNMP primary, detectors, location) trigger a rescan; pure metadata (labels, categories, assets) does not. Import completion is asynchronous: block with import --wait or poll requisition status <fs>.

Inspect and delete​

onmsctl requisition list
onmsctl requisition status acme-prod # deployed state
onmsctl requisition import acme-prod # re-import without re-POST
onmsctl requisition import acme-prod --rescan-existing # re-evaluate existing nodes
onmsctl requisition import acme-prod --wait --timeout 5m # block on the async import
onmsctl requisition delete acme-prod --yes # purge pending + deployed

Lifecycle and read verbs: requisition list|status|import|export|delete and the node|interface|service|category|asset list/get reads. requisition delete <fs> requires --yes: it purges both pending and deployed snapshots.

Read-only inspection:

onmsctl requisition node list acme-prod
onmsctl requisition interface list acme-prod <foreign-id>
onmsctl requisition service list acme-prod <foreign-id> <ip>
onmsctl requisition category list acme-prod <foreign-id>

Convert​

# Migrate provision.pl-shape XML (requisitions + matching foreign-sources)
onmsctl requisition convert --from ./reqs/ --foreign-sources-dir ./fs/ --out ./yaml/

Export what's already deployed, the reverse of apply:

onmsctl requisition export acme-prod > acme-prod.yaml # one, to stdout
onmsctl requisition export --out ./yaml/ # all, per-file
onmsctl requisition export acme-prod --include-defaults # inline the default FS

The provision.pl migration is covered in the migration guide.

Example​

examples/requisition-acme-prod.yaml
# yaml-language-server: $schema=https://raw.githubusercontent.com/no42-org/onmsctl/main/schemas/requisition.schema.json
#
# Composite kind: Requisition example covering every modeled field
# (per task 10.4 of the add-provisioning-capability change).
#
# Pair with `onmsctl apply -f examples/requisition-acme-prod.yaml
# --dry-run --diff` to see the structured diff against a live Horizon.
apiVersion: provisioning.opennms.org/v1
kind: Requisition
metadata:
name: acme-prod
spec:
# Pinned-style YAML: the requisition carries its own foreign-source
# definition. Operators who want portable YAML can drop this entire
# block; on apply, Horizon's default foreign-source is inherited
# (see design D1 + the portable-vs-pinned section in the README).
foreignSource:
scanInterval: 1d
detectors:
- name: ICMP
class: org.opennms.netmgt.provision.detector.icmp.IcmpDetector
parameters:
- key: timeout
value: "2000"
- key: retries
value: "1"
- name: SNMP
class: org.opennms.netmgt.provision.detector.snmp.SnmpDetector
parameters:
- key: port
value: "161"
- key: timeout
value: "2000"
policies:
- name: Production tag
class: org.opennms.netmgt.provision.persist.policies.NodeCategorySettingPolicy
parameters:
- key: category
value: Production
- key: matchBehavior
value: ALL_PARAMETERS
nodes:
- foreignId: web01
label: web01.acme.com
# Monitoring (Minion) location that polls this node. Omit or leave
# empty for the Default location. Maps to the requisition node's
# `location` attribute in Horizon.
location: labmonkeys-hq
interfaces:
- ip: 10.0.0.1
snmpPrimary: P
services:
- HTTP
- HTTPS
- SNMP
- ip: 10.0.0.2
snmpPrimary: S
services:
- ICMP
categories:
- Production
- Web
# Asset keys are stored verbatim by Horizon but only the
# canonical column names (`city`, `state`, `serialNumber`,
# `rack`, `country`, …) render in the inventory UI. Stick to
# canonical names unless you're using assets purely as
# operator-private metadata.
assets:
city: NYC
rack: R3
serialNumber: SN-12345
- foreignId: db01
label: db01.acme.com
interfaces:
- ip: 10.0.1.1
snmpPrimary: P
services:
- PostgreSQL
- SNMP
categories:
- Production
- Database
assets:
city: NYC
- foreignId: cache01
label: cache01.acme.com
interfaces:
- ip: 10.0.2.1
snmpPrimary: N
categories:
- Production
- Cache