YAML Processing Examples¶
This guide demonstrates common yq queries for working with opnDossier YAML exports.
The YAML export uses the CommonDevice model -- a platform-agnostic representation with normalized field names. If you are looking for the internal XML schema (OpnSenseDocument), see the Model Reference.
Exporting to YAML¶
# Basic export
opndossier convert config.xml --format yaml -o config.yaml
# Output to stdout
opndossier convert config.xml --format yaml
# Export with sensitive fields redacted
opndossier convert config.xml --format yaml --redact -o config.yaml
Prerequisites¶
Install yq (YAML processor):
# macOS
brew install yq
# Linux (snap)
snap install yq
# Go install
go install github.com/mikefarah/yq/v4@latest
System Information¶
Basic Queries¶
# Get hostname
yq '.system.hostname' config.yaml
# Get domain
yq '.system.domain' config.yaml
# Get system timezone
yq '.system.timezone' config.yaml
Users¶
# List all usernames
yq '.users[].name' config.yaml
# Get user details as YAML
yq '.users[] | {"name": .name, "scope": .scope}' config.yaml
SSH Configuration¶
# Check SSH settings
yq '.system.ssh' config.yaml
# Get SSH group
yq '.system.ssh.group' config.yaml
Network Configuration¶
Interfaces¶
# List interface names
yq '[.interfaces[].name]' config.yaml
# Get specific interface by name
yq '.interfaces[] | select(.name == "wan")' config.yaml
# List all interface IPs
yq '.interfaces[] | select(.ipAddress) | {"name": .name, "ip": .ipAddress}' config.yaml
VLANs¶
Gateways¶
# List gateways
yq '.routing.gateways[]' config.yaml
# Find default gateway
yq '.routing.gateways[] | select(.defaultGw == "1")' config.yaml
Firewall Rules¶
Rule Queries¶
# Count rules
yq '.firewallRules | length' config.yaml
# List rule descriptions
yq '.firewallRules[].description' config.yaml
# Get enabled rules only
yq '.firewallRules[] | select(.disabled | not)' config.yaml
Security Analysis¶
# Find rules with any source
yq '.firewallRules[] | select(.source.address == "any")' config.yaml
# Find SSH rules
yq '.firewallRules[] | select(.destination.port == "22")' config.yaml
Services¶
DHCP¶
# List DHCP interfaces
yq '[.dhcp[].interface]' config.yaml
# Get DHCP range for a specific interface
yq '.dhcp[] | select(.interface == "lan") | .range' config.yaml
# List static mappings
yq '.dhcp[].staticMappings[]' config.yaml
DNS¶
# Check Unbound status
yq '.dns.unbound' config.yaml
# List DNS host overrides
yq '.dns.unbound.hostOverrides[]' config.yaml
VPN Configuration¶
OpenVPN¶
# List OpenVPN servers
yq '.vpn.openVpn.servers[] | {"description": .description, "port": .localPort}' config.yaml
# List OpenVPN clients
yq '.vpn.openVpn.clients[] | {"description": .description, "server": .serverAddress}' config.yaml
WireGuard¶
# List WireGuard servers
yq '.vpn.wireGuard.servers[]' config.yaml
# List WireGuard clients
yq '.vpn.wireGuard.clients[] | {"name": .name, "server": .serverAddress}' config.yaml
Certificates¶
# List certificates
yq '.certificates[] | {"description": .description, "type": .certType}' config.yaml
# List certificate authorities
yq '.cas[].description' config.yaml
Data Transformation¶
Convert to JSON¶
Extract Subset¶
# Extract just firewall config
yq '.firewallRules' config.yaml > firewall.yaml
# Extract network config
yq '{"interfaces": .interfaces, "routing": .routing, "vlans": .vlans}' config.yaml > network.yaml
Modify Values¶
# Note: These examples show the query, not modifying the original file
# Change hostname (display only)
yq '.system.hostname = "new-hostname"' config.yaml
# Add a comment
yq '. head_comment="OPNsense Configuration Export"' config.yaml
Integration Examples¶
Ansible Playbook¶
- name: Process OPNsense Configuration
hosts: localhost
tasks:
- name: Export configuration to YAML
command: opndossier convert config.xml --format yaml
register: config_output
- name: Parse configuration
set_fact:
opnsense_config: '{{ config_output.stdout | from_yaml }}'
- name: Display hostname
debug:
msg: 'Firewall hostname: {{ opnsense_config.system.hostname }}'
- name: List interfaces
debug:
msg: 'Interfaces: {{ opnsense_config.interfaces | map(attribute="name")
| list }}'
Shell Script¶
#!/bin/bash
CONFIG_FILE="config.yaml"
# Export if needed
if [ ! -f "$CONFIG_FILE" ]; then
opndossier convert config.xml --format yaml -o "$CONFIG_FILE"
fi
# Extract information
HOSTNAME=$(yq '.system.hostname' "$CONFIG_FILE")
DOMAIN=$(yq '.system.domain' "$CONFIG_FILE")
RULE_COUNT=$(yq '.firewallRules | length' "$CONFIG_FILE")
echo "Firewall: $HOSTNAME.$DOMAIN"
echo "Total firewall rules: $RULE_COUNT"
# Check for risky rules
echo "Rules with 'any' source:"
yq '.firewallRules[] | select(.source.address == "any") | .description' "$CONFIG_FILE"
Python¶
import yaml
import subprocess
# Export configuration
result = subprocess.run(
["opndossier", "convert", "config.xml", "--format", "yaml"],
capture_output=True,
text=True,
)
# Parse YAML
config = yaml.safe_load(result.stdout)
# Access data
print(f"Hostname: {config['system']['hostname']}")
print(f"Interfaces: {[iface['name'] for iface in config['interfaces']]}")
print(f"Rule count: {len(config['firewallRules'])}")
Comparison and Diff¶
For comparing two OPNsense configurations, use the built-in diff command instead of manual YAML comparison: