opn_api 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +10 -0
- data/LICENSE +25 -0
- data/README.md +979 -0
- data/bin/opn-api +7 -0
- data/lib/opn_api/cli/commands/api.rb +57 -0
- data/lib/opn_api/cli/commands/backup.rb +38 -0
- data/lib/opn_api/cli/commands/base.rb +50 -0
- data/lib/opn_api/cli/commands/device.rb +53 -0
- data/lib/opn_api/cli/commands/plugin.rb +67 -0
- data/lib/opn_api/cli/commands/reconfigure.rb +40 -0
- data/lib/opn_api/cli/commands/resource.rb +248 -0
- data/lib/opn_api/cli/formatter.rb +198 -0
- data/lib/opn_api/cli/main.rb +160 -0
- data/lib/opn_api/client.rb +204 -0
- data/lib/opn_api/config.rb +111 -0
- data/lib/opn_api/errors.rb +45 -0
- data/lib/opn_api/id_resolver.rb +222 -0
- data/lib/opn_api/logger.rb +29 -0
- data/lib/opn_api/normalize.rb +47 -0
- data/lib/opn_api/resource.rb +142 -0
- data/lib/opn_api/resource_registry.rb +377 -0
- data/lib/opn_api/service_reconfigure.rb +293 -0
- data/lib/opn_api/version.rb +5 -0
- data/lib/opn_api.rb +32 -0
- metadata +73 -0
data/README.md
ADDED
|
@@ -0,0 +1,979 @@
|
|
|
1
|
+
# opn_api
|
|
2
|
+
|
|
3
|
+
A Ruby client library and CLI tool for the OPNsense REST API.
|
|
4
|
+
|
|
5
|
+
#### Table of Contents
|
|
6
|
+
|
|
7
|
+
1. [Overview](#overview)
|
|
8
|
+
1. [Supported resources](#supported-resources)
|
|
9
|
+
1. [Install](#install)
|
|
10
|
+
1. [Modes](#modes)
|
|
11
|
+
1. [CLI Usage](#cli-usage)
|
|
12
|
+
1. [Configuration](#configuration)
|
|
13
|
+
1. [Basics](#basics)
|
|
14
|
+
1. [Table output and field filtering](#table-output-and-field-filtering)
|
|
15
|
+
1. [Examples](#examples)
|
|
16
|
+
- [ACME Client](#acme-client)
|
|
17
|
+
- [Backup](#backup)
|
|
18
|
+
- [Cron](#cron)
|
|
19
|
+
- [DHC Relay](#dhc-relay)
|
|
20
|
+
- [Firewall](#firewall)
|
|
21
|
+
- [Gateways](#gateways)
|
|
22
|
+
- [Groups](#groups)
|
|
23
|
+
- [HA Sync](#ha-sync)
|
|
24
|
+
- [HAProxy](#haproxy)
|
|
25
|
+
- [IPsec](#ipsec)
|
|
26
|
+
- [Kea DHCP](#kea-dhcp)
|
|
27
|
+
- [Node Exporter](#node-exporter)
|
|
28
|
+
- [OpenVPN](#openvpn)
|
|
29
|
+
- [Plugins](#plugins)
|
|
30
|
+
- [Routes](#routes)
|
|
31
|
+
- [Service reconfigure](#service-reconfigure-1)
|
|
32
|
+
- [Snapshots](#snapshots)
|
|
33
|
+
- [Syslog](#syslog)
|
|
34
|
+
- [Trust certificates](#trust-certificates)
|
|
35
|
+
- [Tunables](#tunables)
|
|
36
|
+
- [Users](#users)
|
|
37
|
+
- [Zabbix](#zabbix)
|
|
38
|
+
- [Error handling](#error-handling)
|
|
39
|
+
- [Wrapper keys](#wrapper-keys)
|
|
40
|
+
- [Raw API access](#raw-api-access)
|
|
41
|
+
- [Ruby API](#ruby-api)
|
|
42
|
+
1. [Features](#features)
|
|
43
|
+
- [Config loader](#config-loader)
|
|
44
|
+
- [ID resolver](#id-resolver)
|
|
45
|
+
- [Normalize](#normalize)
|
|
46
|
+
- [Resource CRUD](#resource-crud)
|
|
47
|
+
- [Resource registry](#resource-registry)
|
|
48
|
+
- [Service reconfigure](#service-reconfigure)
|
|
49
|
+
1. [Development](#development)
|
|
50
|
+
- [Contributing](#contributing)
|
|
51
|
+
1. [License](#license)
|
|
52
|
+
|
|
53
|
+
## Overview
|
|
54
|
+
|
|
55
|
+
opn_api is a standalone Ruby library and command-line tool for communicating with [OPNsense](https://opnsense.org/) firewalls via their REST API. It is meant as a replacement for [opn-cli](https://github.com/andreas-stuerz/opn-cli). It provides:
|
|
56
|
+
|
|
57
|
+
- An HTTP client with SSL, redirect handling, and API key authentication
|
|
58
|
+
- UUID/name resolution for ModelRelationField and CertificateField references
|
|
59
|
+
- Service reconfigure orchestration with configtest support
|
|
60
|
+
- OPNsense selection-hash normalization
|
|
61
|
+
- A CLI tool for interactive API access
|
|
62
|
+
- A resource registry that abstracts away inconsistent endpoint naming
|
|
63
|
+
|
|
64
|
+
## Supported resources
|
|
65
|
+
|
|
66
|
+
Backups and plugins are managed separately via dedicated commands (`backup`, `plugins`, `install`, `uninstall`).
|
|
67
|
+
|
|
68
|
+
| Resource | Manages |
|
|
69
|
+
|----------|---------|
|
|
70
|
+
| `acmeclient_account` | ACME Client accounts |
|
|
71
|
+
| `acmeclient_action` | ACME Client automation actions |
|
|
72
|
+
| `acmeclient_certificate` | ACME Client certificates |
|
|
73
|
+
| `acmeclient_settings` | ACME Client global settings (singleton) |
|
|
74
|
+
| `acmeclient_validation` | ACME Client validation methods |
|
|
75
|
+
| `cron` | Cron jobs |
|
|
76
|
+
| `dhcrelay` | DHCP Relay instances |
|
|
77
|
+
| `dhcrelay_destination` | DHCP Relay destinations |
|
|
78
|
+
| `firewall_alias` | Firewall aliases |
|
|
79
|
+
| `firewall_category` | Firewall categories |
|
|
80
|
+
| `firewall_group` | Firewall interface groups |
|
|
81
|
+
| `firewall_rule` | Firewall filter rules (new GUI) |
|
|
82
|
+
| `gateway` | Routing gateways |
|
|
83
|
+
| `group` | Local groups |
|
|
84
|
+
| `haproxy_acl` | HAProxy ACLs (conditions) |
|
|
85
|
+
| `haproxy_action` | HAProxy actions (rules) |
|
|
86
|
+
| `haproxy_backend` | HAProxy backend pools |
|
|
87
|
+
| `haproxy_cpu` | HAProxy CPU affinity / thread binding |
|
|
88
|
+
| `haproxy_errorfile` | HAProxy error files |
|
|
89
|
+
| `haproxy_fcgi` | HAProxy FastCGI applications |
|
|
90
|
+
| `haproxy_frontend` | HAProxy frontend listeners |
|
|
91
|
+
| `haproxy_group` | HAProxy user-list groups |
|
|
92
|
+
| `haproxy_healthcheck` | HAProxy health checks |
|
|
93
|
+
| `haproxy_lua` | HAProxy Lua scripts |
|
|
94
|
+
| `haproxy_mailer` | HAProxy mailers |
|
|
95
|
+
| `haproxy_mapfile` | HAProxy map files |
|
|
96
|
+
| `haproxy_resolver` | HAProxy DNS resolvers |
|
|
97
|
+
| `haproxy_server` | HAProxy backend servers |
|
|
98
|
+
| `haproxy_settings` | HAProxy global settings (singleton) |
|
|
99
|
+
| `haproxy_user` | HAProxy user-list users |
|
|
100
|
+
| `hasync` | HA sync / CARP settings (singleton) |
|
|
101
|
+
| `ipsec_child` | IPsec child SAs (Swanctl) |
|
|
102
|
+
| `ipsec_connection` | IPsec connections (Swanctl) |
|
|
103
|
+
| `ipsec_keypair` | IPsec key pairs (Swanctl) |
|
|
104
|
+
| `ipsec_local` | IPsec local authentication (Swanctl) |
|
|
105
|
+
| `ipsec_pool` | IPsec address pools (Swanctl) |
|
|
106
|
+
| `ipsec_presharedkey` | IPsec pre-shared keys (Swanctl) |
|
|
107
|
+
| `ipsec_remote` | IPsec remote authentication (Swanctl) |
|
|
108
|
+
| `ipsec_settings` | IPsec global settings (singleton) |
|
|
109
|
+
| `ipsec_vti` | IPsec VTI entries (Swanctl) |
|
|
110
|
+
| `kea_ctrl_agent` | KEA Control Agent settings (singleton) |
|
|
111
|
+
| `kea_dhcpv4` | KEA DHCPv4 global settings (singleton) |
|
|
112
|
+
| `kea_dhcpv4_peer` | KEA DHCPv4 HA peers |
|
|
113
|
+
| `kea_dhcpv4_reservation` | KEA DHCPv4 reservations |
|
|
114
|
+
| `kea_dhcpv4_subnet` | KEA DHCPv4 subnets |
|
|
115
|
+
| `kea_dhcpv6` | KEA DHCPv6 global settings (singleton) |
|
|
116
|
+
| `kea_dhcpv6_pd_pool` | KEA DHCPv6 prefix delegation pools |
|
|
117
|
+
| `kea_dhcpv6_peer` | KEA DHCPv6 HA peers |
|
|
118
|
+
| `kea_dhcpv6_reservation` | KEA DHCPv6 reservations |
|
|
119
|
+
| `kea_dhcpv6_subnet` | KEA DHCPv6 subnets |
|
|
120
|
+
| `node_exporter` | Prometheus Node Exporter settings (singleton) |
|
|
121
|
+
| `openvpn_cso` | OpenVPN client-specific overrides |
|
|
122
|
+
| `openvpn_instance` | OpenVPN instances |
|
|
123
|
+
| `openvpn_statickey` | OpenVPN static keys |
|
|
124
|
+
| `route` | Static routes |
|
|
125
|
+
| `snapshot` | ZFS snapshots |
|
|
126
|
+
| `syslog` | Syslog remote destinations |
|
|
127
|
+
| `trust_ca` | Trust Certificate Authorities |
|
|
128
|
+
| `trust_cert` | Trust certificates |
|
|
129
|
+
| `trust_crl` | Trust Certificate Revocation Lists |
|
|
130
|
+
| `tunable` | System tunables (sysctl) |
|
|
131
|
+
| `user` | Local users |
|
|
132
|
+
| `zabbix_agent` | Zabbix Agent settings (singleton) |
|
|
133
|
+
| `zabbix_agent_alias` | Zabbix Agent Alias entries |
|
|
134
|
+
| `zabbix_agent_userparameter` | Zabbix Agent UserParameter entries |
|
|
135
|
+
| `zabbix_proxy` | Zabbix Proxy settings (singleton) |
|
|
136
|
+
|
|
137
|
+
## Install
|
|
138
|
+
|
|
139
|
+
```
|
|
140
|
+
gem install opn_api
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Or add to your Gemfile:
|
|
144
|
+
|
|
145
|
+
```ruby
|
|
146
|
+
gem 'opn_api'
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Modes
|
|
150
|
+
|
|
151
|
+
opn_api can be used in 2 modes: CLI mode and Ruby API mode.
|
|
152
|
+
|
|
153
|
+
CLI mode provides the `opn-api` command for interactive use and shell scripts. Ruby API mode allows direct integration into Ruby projects.
|
|
154
|
+
|
|
155
|
+
## CLI Usage
|
|
156
|
+
|
|
157
|
+
```
|
|
158
|
+
$ opn-api --help
|
|
159
|
+
|
|
160
|
+
Usage: opn-api [options] <command> [command-options] [args...]
|
|
161
|
+
|
|
162
|
+
A CLI tool for the OPNsense REST API.
|
|
163
|
+
|
|
164
|
+
Global options:
|
|
165
|
+
-c, --config-dir PATH Config directory for device files
|
|
166
|
+
-d, --device NAME Device name (default: "default")
|
|
167
|
+
-f, --format FORMAT Output format: table, json, yaml (default: table)
|
|
168
|
+
-F, --fields FIELDS Comma-separated field names for table output
|
|
169
|
+
-A, --all-fields Show all fields in table output (default: first 5)
|
|
170
|
+
-E, --show-empty Show empty fields in table output (default: hidden)
|
|
171
|
+
-v, --verbose Enable debug output (includes API error details)
|
|
172
|
+
--version Show version
|
|
173
|
+
-h, --help Show this help
|
|
174
|
+
|
|
175
|
+
Commands:
|
|
176
|
+
backup Download config backup
|
|
177
|
+
create Create resource
|
|
178
|
+
delete Delete resource
|
|
179
|
+
devices List configured devices
|
|
180
|
+
get GET request to API path
|
|
181
|
+
groups List reconfigure groups
|
|
182
|
+
install Install plugin
|
|
183
|
+
plugins List installed plugins
|
|
184
|
+
post POST request to API path
|
|
185
|
+
reconfigure Trigger service reconfigure
|
|
186
|
+
resources List known resource types
|
|
187
|
+
search Search resources
|
|
188
|
+
show Show single resource
|
|
189
|
+
test Test device connectivity
|
|
190
|
+
uninstall Uninstall plugin
|
|
191
|
+
update Update resource
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Resource commands (`search`, `show`, `create`, `update`, `delete`) accept a resource name from the built-in registry. Run `opn-api resources` for a full list. Singleton resources (settings) are auto-detected and work without UUID for `show` and `update`.
|
|
195
|
+
|
|
196
|
+
## Configuration
|
|
197
|
+
|
|
198
|
+
Device credentials are stored in YAML files, one per OPNsense device. The config directory is searched in this order (highest priority last):
|
|
199
|
+
|
|
200
|
+
1. `/etc/opn-api/devices/` (system-wide)
|
|
201
|
+
2. `~/.config/opn-api/devices/` (per-user)
|
|
202
|
+
3. Explicit `config_dir` parameter or `-c` CLI flag
|
|
203
|
+
4. `OPN_API_CONFIG_DIR` environment variable (override)
|
|
204
|
+
|
|
205
|
+
### Device file format
|
|
206
|
+
|
|
207
|
+
Each device is a YAML file named `<device_name>.yaml`:
|
|
208
|
+
|
|
209
|
+
```yaml
|
|
210
|
+
# ~/.config/opn-api/devices/opnsense01.yaml
|
|
211
|
+
url: https://192.168.1.1/api
|
|
212
|
+
api_key: +OPNSENSE_API_KEY
|
|
213
|
+
api_secret: +OPNSENSE_API_SECRET
|
|
214
|
+
ssl_verify: false
|
|
215
|
+
timeout: 60
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
This format is compatible with [puppet-opn](https://github.com/markt-de/puppet-opn) device files, so existing Puppet configurations can be reused by pointing `config_dir` to the Puppet config directory.
|
|
219
|
+
|
|
220
|
+
## Basics
|
|
221
|
+
|
|
222
|
+
```
|
|
223
|
+
# List configured devices
|
|
224
|
+
$ opn-api devices
|
|
225
|
+
|
|
226
|
+
# Test connectivity
|
|
227
|
+
$ opn-api -d opnsense01 test
|
|
228
|
+
|
|
229
|
+
# List known resource types (shows name, wrapper key, type)
|
|
230
|
+
$ opn-api resources
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## Table output and field filtering
|
|
234
|
+
|
|
235
|
+
By default, the table output shows only the first 5 fields to keep it readable. Use `-F` to select specific fields or `-A` to show all fields. Fields with empty values are hidden by default — use `-E` to show them. JSON and YAML output (`-f json`, `-f yaml`) always includes all data unmodified.
|
|
236
|
+
|
|
237
|
+
```
|
|
238
|
+
# Search resources (default: first 5 fields shown)
|
|
239
|
+
$ opn-api -d opnsense01 search firewall_alias
|
|
240
|
+
|
|
241
|
+
# Select specific fields
|
|
242
|
+
$ opn-api -d opnsense01 -F uuid,enabled,name,type search firewall_alias
|
|
243
|
+
|
|
244
|
+
# Show all fields
|
|
245
|
+
$ opn-api -d opnsense01 -A search firewall_alias
|
|
246
|
+
|
|
247
|
+
# Show empty fields (hidden by default)
|
|
248
|
+
$ opn-api -d opnsense01 -E show acmeclient_settings
|
|
249
|
+
|
|
250
|
+
# JSON output always includes all data (unaffected by -F/-A/-E)
|
|
251
|
+
$ opn-api -d opnsense01 -f json search haproxy_server
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
## Examples
|
|
255
|
+
|
|
256
|
+
### ACME Client
|
|
257
|
+
|
|
258
|
+
```
|
|
259
|
+
# List ACME accounts
|
|
260
|
+
$ opn-api -d opnsense01 search acmeclient_account
|
|
261
|
+
|
|
262
|
+
# List ACME certificates
|
|
263
|
+
$ opn-api -d opnsense01 search acmeclient_certificate
|
|
264
|
+
|
|
265
|
+
# List ACME validations
|
|
266
|
+
$ opn-api -d opnsense01 search acmeclient_validation
|
|
267
|
+
|
|
268
|
+
# List ACME actions
|
|
269
|
+
$ opn-api -d opnsense01 search acmeclient_action
|
|
270
|
+
|
|
271
|
+
# Show ACME settings (singleton)
|
|
272
|
+
$ opn-api -d opnsense01 show acmeclient_settings
|
|
273
|
+
|
|
274
|
+
# Update ACME settings (wrapper key: "acmeclient")
|
|
275
|
+
$ opn-api -d opnsense01 update acmeclient_settings \
|
|
276
|
+
-j '{"acmeclient":{"settings":{"environment":"production"}}}'
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### Backup
|
|
280
|
+
|
|
281
|
+
Download the OPNsense configuration backup (XML). The backup endpoint returns XML instead of JSON, so this command uses a raw (non-JSON) mode internally.
|
|
282
|
+
|
|
283
|
+
```
|
|
284
|
+
# Download backup to file
|
|
285
|
+
$ opn-api -d opnsense01 backup /tmp/opnsense01-backup.xml
|
|
286
|
+
|
|
287
|
+
# Print backup XML to stdout (e.g. for piping)
|
|
288
|
+
$ opn-api -d opnsense01 backup > /tmp/opnsense01-backup.xml
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
Ruby API:
|
|
292
|
+
|
|
293
|
+
```ruby
|
|
294
|
+
# Download backup as raw XML string
|
|
295
|
+
config = OpnApi::Config.new
|
|
296
|
+
client = config.client_for('opnsense01')
|
|
297
|
+
xml = client.get('core/backup/download/this', raw: true)
|
|
298
|
+
File.write('/tmp/backup.xml', xml)
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### Cron
|
|
302
|
+
|
|
303
|
+
```
|
|
304
|
+
# List cron jobs
|
|
305
|
+
$ opn-api -d opnsense01 search cron
|
|
306
|
+
|
|
307
|
+
# Show cron job details
|
|
308
|
+
$ opn-api -d opnsense01 show cron a1b2c3d4-...
|
|
309
|
+
|
|
310
|
+
# Create cron job (wrapper key: "job")
|
|
311
|
+
$ opn-api -d opnsense01 create cron \
|
|
312
|
+
-j '{"job":{"enabled":"1","minutes":"0","hours":"3","description":"nightly backup"}}'
|
|
313
|
+
|
|
314
|
+
# Delete cron job
|
|
315
|
+
$ opn-api -d opnsense01 delete cron a1b2c3d4-...
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### DHC Relay
|
|
319
|
+
|
|
320
|
+
```
|
|
321
|
+
# List DHC relays
|
|
322
|
+
$ opn-api -d opnsense01 search dhcrelay
|
|
323
|
+
|
|
324
|
+
# List DHC relay destinations
|
|
325
|
+
$ opn-api -d opnsense01 search dhcrelay_destination
|
|
326
|
+
|
|
327
|
+
# Create relay destination (wrapper key: "destination")
|
|
328
|
+
$ opn-api -d opnsense01 create dhcrelay_destination \
|
|
329
|
+
-j '{"destination":{"server":"10.0.0.5"}}'
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
### Firewall
|
|
333
|
+
|
|
334
|
+
```
|
|
335
|
+
# List all aliases
|
|
336
|
+
$ opn-api -d opnsense01 search firewall_alias
|
|
337
|
+
|
|
338
|
+
# Show single alias by UUID
|
|
339
|
+
$ opn-api -d opnsense01 show firewall_alias 8a2f3b4c-...
|
|
340
|
+
|
|
341
|
+
# Create alias (wrapper key: "alias")
|
|
342
|
+
$ opn-api -d opnsense01 create firewall_alias \
|
|
343
|
+
-j '{"alias":{"name":"test","type":"host","content":"10.0.0.1","enabled":"1"}}'
|
|
344
|
+
|
|
345
|
+
# Create via stdin
|
|
346
|
+
$ echo '{"alias":{"name":"test","type":"host","content":"10.0.0.1","enabled":"1"}}' \
|
|
347
|
+
| opn-api -d opnsense01 create firewall_alias
|
|
348
|
+
|
|
349
|
+
# Update alias
|
|
350
|
+
$ opn-api -d opnsense01 update firewall_alias 8a2f3b4c-... \
|
|
351
|
+
-j '{"alias":{"content":"10.0.0.2"}}'
|
|
352
|
+
|
|
353
|
+
# Delete alias
|
|
354
|
+
$ opn-api -d opnsense01 delete firewall_alias 8a2f3b4c-...
|
|
355
|
+
|
|
356
|
+
# List firewall rules
|
|
357
|
+
$ opn-api -d opnsense01 search firewall_rule
|
|
358
|
+
|
|
359
|
+
# List firewall categories
|
|
360
|
+
$ opn-api -d opnsense01 search firewall_category
|
|
361
|
+
|
|
362
|
+
# List firewall groups
|
|
363
|
+
$ opn-api -d opnsense01 search firewall_group
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
### Gateways
|
|
367
|
+
|
|
368
|
+
```
|
|
369
|
+
# List all gateways
|
|
370
|
+
$ opn-api -d opnsense01 search gateway
|
|
371
|
+
|
|
372
|
+
# Show gateway details
|
|
373
|
+
$ opn-api -d opnsense01 show gateway a1b2c3d4-...
|
|
374
|
+
|
|
375
|
+
# Create gateway (wrapper key: "gateway_item")
|
|
376
|
+
$ opn-api -d opnsense01 create gateway \
|
|
377
|
+
-j '{"gateway_item":{"name":"WAN_GW","interface":"wan","gateway":"192.168.1.1"}}'
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
### Groups
|
|
381
|
+
|
|
382
|
+
```
|
|
383
|
+
# List all groups
|
|
384
|
+
$ opn-api -d opnsense01 search group
|
|
385
|
+
|
|
386
|
+
# Show group details
|
|
387
|
+
$ opn-api -d opnsense01 show group a1b2c3d4-...
|
|
388
|
+
|
|
389
|
+
# Create group (wrapper key: "group")
|
|
390
|
+
$ opn-api -d opnsense01 create group \
|
|
391
|
+
-j '{"group":{"name":"admins","description":"Admin group"}}'
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
### HA Sync
|
|
395
|
+
|
|
396
|
+
HA Sync is a singleton resource (one per device).
|
|
397
|
+
|
|
398
|
+
```
|
|
399
|
+
# Show HA Sync settings (singleton)
|
|
400
|
+
$ opn-api -d opnsense01 show hasync
|
|
401
|
+
|
|
402
|
+
# Update HA Sync settings (wrapper key: "hasync")
|
|
403
|
+
$ opn-api -d opnsense01 update hasync \
|
|
404
|
+
-j '{"hasync":{"pfsyncenabled":"1","synchronizeinterface":"lan"}}'
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
### HAProxy
|
|
408
|
+
|
|
409
|
+
#### Servers
|
|
410
|
+
|
|
411
|
+
```
|
|
412
|
+
# List all servers
|
|
413
|
+
$ opn-api -d opnsense01 search haproxy_server
|
|
414
|
+
|
|
415
|
+
# Show server details
|
|
416
|
+
$ opn-api -d opnsense01 show haproxy_server 1a2b3c4d-...
|
|
417
|
+
|
|
418
|
+
# Create server (wrapper key: "server")
|
|
419
|
+
$ opn-api -d opnsense01 create haproxy_server \
|
|
420
|
+
-j '{"server":{"name":"web01","address":"10.0.0.10","port":"8080"}}'
|
|
421
|
+
|
|
422
|
+
# Update server
|
|
423
|
+
$ opn-api -d opnsense01 update haproxy_server 1a2b3c4d-... \
|
|
424
|
+
-j '{"server":{"port":"8443"}}'
|
|
425
|
+
|
|
426
|
+
# Delete server
|
|
427
|
+
$ opn-api -d opnsense01 delete haproxy_server 1a2b3c4d-...
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
#### Backends
|
|
431
|
+
|
|
432
|
+
```
|
|
433
|
+
# List all backends
|
|
434
|
+
$ opn-api -d opnsense01 search haproxy_backend
|
|
435
|
+
|
|
436
|
+
# Show backend details
|
|
437
|
+
$ opn-api -d opnsense01 show haproxy_backend 2b3c4d5e-...
|
|
438
|
+
|
|
439
|
+
# Create backend (wrapper key: "backend")
|
|
440
|
+
$ opn-api -d opnsense01 create haproxy_backend \
|
|
441
|
+
-j '{"backend":{"name":"web_pool","mode":"http","linkedServers":"1a2b3c4d-..."}}'
|
|
442
|
+
|
|
443
|
+
# Update backend
|
|
444
|
+
$ opn-api -d opnsense01 update haproxy_backend 2b3c4d5e-... \
|
|
445
|
+
-j '{"backend":{"mode":"tcp"}}'
|
|
446
|
+
|
|
447
|
+
# Delete backend
|
|
448
|
+
$ opn-api -d opnsense01 delete haproxy_backend 2b3c4d5e-...
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
#### Frontends
|
|
452
|
+
|
|
453
|
+
```
|
|
454
|
+
# List all frontends
|
|
455
|
+
$ opn-api -d opnsense01 search haproxy_frontend
|
|
456
|
+
|
|
457
|
+
# Show frontend details
|
|
458
|
+
$ opn-api -d opnsense01 show haproxy_frontend 3c4d5e6f-...
|
|
459
|
+
|
|
460
|
+
# Create frontend (wrapper key: "frontend")
|
|
461
|
+
$ opn-api -d opnsense01 create haproxy_frontend \
|
|
462
|
+
-j '{"frontend":{"name":"https_in","bind":"0.0.0.0:443","mode":"http","defaultBackend":"2b3c4d5e-..."}}'
|
|
463
|
+
|
|
464
|
+
# Update frontend
|
|
465
|
+
$ opn-api -d opnsense01 update haproxy_frontend 3c4d5e6f-... \
|
|
466
|
+
-j '{"frontend":{"bind":"0.0.0.0:8443"}}'
|
|
467
|
+
|
|
468
|
+
# Delete frontend
|
|
469
|
+
$ opn-api -d opnsense01 delete haproxy_frontend 3c4d5e6f-...
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
#### Settings and other sub-resources
|
|
473
|
+
|
|
474
|
+
```
|
|
475
|
+
# Show HAProxy settings (singleton)
|
|
476
|
+
$ opn-api -d opnsense01 show haproxy_settings
|
|
477
|
+
|
|
478
|
+
# Update HAProxy settings (wrapper key: "haproxy")
|
|
479
|
+
$ opn-api -d opnsense01 update haproxy_settings \
|
|
480
|
+
-j '{"haproxy":{"general":{"tuning":{"maxconn":"2000"}}}}'
|
|
481
|
+
|
|
482
|
+
# List other HAProxy sub-resources
|
|
483
|
+
$ opn-api -d opnsense01 search haproxy_acl
|
|
484
|
+
$ opn-api -d opnsense01 search haproxy_action
|
|
485
|
+
$ opn-api -d opnsense01 search haproxy_cpu
|
|
486
|
+
$ opn-api -d opnsense01 search haproxy_errorfile
|
|
487
|
+
$ opn-api -d opnsense01 search haproxy_fcgi
|
|
488
|
+
$ opn-api -d opnsense01 search haproxy_group
|
|
489
|
+
$ opn-api -d opnsense01 search haproxy_healthcheck
|
|
490
|
+
$ opn-api -d opnsense01 search haproxy_lua
|
|
491
|
+
$ opn-api -d opnsense01 search haproxy_mailer
|
|
492
|
+
$ opn-api -d opnsense01 search haproxy_mapfile
|
|
493
|
+
$ opn-api -d opnsense01 search haproxy_resolver
|
|
494
|
+
$ opn-api -d opnsense01 search haproxy_user
|
|
495
|
+
|
|
496
|
+
# Apply changes (includes configtest)
|
|
497
|
+
$ opn-api -d opnsense01 reconfigure haproxy
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
### IPsec
|
|
501
|
+
|
|
502
|
+
```
|
|
503
|
+
# List all IPsec connections
|
|
504
|
+
$ opn-api -d opnsense01 search ipsec_connection
|
|
505
|
+
|
|
506
|
+
# Show connection details
|
|
507
|
+
$ opn-api -d opnsense01 show ipsec_connection 4d5e6f7a-...
|
|
508
|
+
|
|
509
|
+
# Full JSON output
|
|
510
|
+
$ opn-api -d opnsense01 -f json show ipsec_connection 4d5e6f7a-...
|
|
511
|
+
|
|
512
|
+
# List other IPsec sub-resources
|
|
513
|
+
$ opn-api -d opnsense01 search ipsec_child
|
|
514
|
+
$ opn-api -d opnsense01 search ipsec_keypair
|
|
515
|
+
$ opn-api -d opnsense01 search ipsec_local
|
|
516
|
+
$ opn-api -d opnsense01 search ipsec_pool
|
|
517
|
+
$ opn-api -d opnsense01 search ipsec_presharedkey
|
|
518
|
+
$ opn-api -d opnsense01 search ipsec_remote
|
|
519
|
+
$ opn-api -d opnsense01 search ipsec_vti
|
|
520
|
+
|
|
521
|
+
# Show IPsec settings (singleton)
|
|
522
|
+
$ opn-api -d opnsense01 show ipsec_settings
|
|
523
|
+
|
|
524
|
+
# Apply changes
|
|
525
|
+
$ opn-api -d opnsense01 reconfigure ipsec
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
### Kea DHCP
|
|
529
|
+
|
|
530
|
+
```
|
|
531
|
+
# Show Kea DHCPv4 settings (singleton)
|
|
532
|
+
$ opn-api -d opnsense01 show kea_dhcpv4
|
|
533
|
+
|
|
534
|
+
# List DHCPv4 subnets
|
|
535
|
+
$ opn-api -d opnsense01 search kea_dhcpv4_subnet
|
|
536
|
+
|
|
537
|
+
# Create DHCPv4 subnet (wrapper key: "subnet4")
|
|
538
|
+
$ opn-api -d opnsense01 create kea_dhcpv4_subnet \
|
|
539
|
+
-j '{"subnet4":{"subnet":"10.0.1.0/24"}}'
|
|
540
|
+
|
|
541
|
+
# List DHCPv4 reservations
|
|
542
|
+
$ opn-api -d opnsense01 search kea_dhcpv4_reservation
|
|
543
|
+
|
|
544
|
+
# List DHCPv4 HA peers
|
|
545
|
+
$ opn-api -d opnsense01 search kea_dhcpv4_peer
|
|
546
|
+
|
|
547
|
+
# Show Kea DHCPv6 settings (singleton)
|
|
548
|
+
$ opn-api -d opnsense01 show kea_dhcpv6
|
|
549
|
+
|
|
550
|
+
# List DHCPv6 subnets, reservations, PD pools, peers
|
|
551
|
+
$ opn-api -d opnsense01 search kea_dhcpv6_subnet
|
|
552
|
+
$ opn-api -d opnsense01 search kea_dhcpv6_reservation
|
|
553
|
+
$ opn-api -d opnsense01 search kea_dhcpv6_pd_pool
|
|
554
|
+
$ opn-api -d opnsense01 search kea_dhcpv6_peer
|
|
555
|
+
|
|
556
|
+
# Show Kea control agent settings (singleton)
|
|
557
|
+
$ opn-api -d opnsense01 show kea_ctrl_agent
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
### Node Exporter
|
|
561
|
+
|
|
562
|
+
Node Exporter is a singleton resource.
|
|
563
|
+
|
|
564
|
+
```
|
|
565
|
+
# Show Node Exporter settings (singleton)
|
|
566
|
+
$ opn-api -d opnsense01 show node_exporter
|
|
567
|
+
|
|
568
|
+
# Update Node Exporter settings (wrapper key: "general")
|
|
569
|
+
$ opn-api -d opnsense01 update node_exporter \
|
|
570
|
+
-j '{"general":{"listen_address":"0.0.0.0","listen_port":"9100"}}'
|
|
571
|
+
```
|
|
572
|
+
|
|
573
|
+
### OpenVPN
|
|
574
|
+
|
|
575
|
+
```
|
|
576
|
+
# List all OpenVPN instances
|
|
577
|
+
$ opn-api -d opnsense01 search openvpn_instance
|
|
578
|
+
|
|
579
|
+
# Show instance details
|
|
580
|
+
$ opn-api -d opnsense01 show openvpn_instance 5e6f7a8b-...
|
|
581
|
+
|
|
582
|
+
# Full JSON output
|
|
583
|
+
$ opn-api -d opnsense01 -f json show openvpn_instance 5e6f7a8b-...
|
|
584
|
+
|
|
585
|
+
# List client-specific overrides
|
|
586
|
+
$ opn-api -d opnsense01 search openvpn_cso
|
|
587
|
+
|
|
588
|
+
# List static keys
|
|
589
|
+
$ opn-api -d opnsense01 search openvpn_statickey
|
|
590
|
+
|
|
591
|
+
# Apply changes
|
|
592
|
+
$ opn-api -d opnsense01 reconfigure openvpn
|
|
593
|
+
```
|
|
594
|
+
|
|
595
|
+
### Plugins
|
|
596
|
+
|
|
597
|
+
```
|
|
598
|
+
# List installed plugins
|
|
599
|
+
$ opn-api -d opnsense01 plugins
|
|
600
|
+
|
|
601
|
+
# Install a plugin
|
|
602
|
+
$ opn-api -d opnsense01 install os-haproxy
|
|
603
|
+
|
|
604
|
+
# Uninstall a plugin
|
|
605
|
+
$ opn-api -d opnsense01 uninstall os-haproxy
|
|
606
|
+
```
|
|
607
|
+
|
|
608
|
+
Note: Install/uninstall are asynchronous — the API returns immediately while the operation continues in the background.
|
|
609
|
+
|
|
610
|
+
### Routes
|
|
611
|
+
|
|
612
|
+
```
|
|
613
|
+
# List all routes
|
|
614
|
+
$ opn-api -d opnsense01 search route
|
|
615
|
+
|
|
616
|
+
# Show route details
|
|
617
|
+
$ opn-api -d opnsense01 show route a1b2c3d4-...
|
|
618
|
+
|
|
619
|
+
# Create route (wrapper key: "route")
|
|
620
|
+
$ opn-api -d opnsense01 create route \
|
|
621
|
+
-j '{"route":{"network":"10.0.2.0/24","gateway":"WAN_GW","descr":"office network"}}'
|
|
622
|
+
|
|
623
|
+
# Apply changes
|
|
624
|
+
$ opn-api -d opnsense01 reconfigure route
|
|
625
|
+
```
|
|
626
|
+
|
|
627
|
+
### Service reconfigure
|
|
628
|
+
|
|
629
|
+
After creating, updating, or deleting resources, trigger a service reconfigure to apply the changes.
|
|
630
|
+
|
|
631
|
+
```
|
|
632
|
+
# Trigger HAProxy reconfigure (includes configtest)
|
|
633
|
+
$ opn-api -d opnsense01 reconfigure haproxy
|
|
634
|
+
|
|
635
|
+
# Trigger IPsec reconfigure
|
|
636
|
+
$ opn-api -d opnsense01 reconfigure ipsec
|
|
637
|
+
|
|
638
|
+
# Trigger OpenVPN reconfigure
|
|
639
|
+
$ opn-api -d opnsense01 reconfigure openvpn
|
|
640
|
+
|
|
641
|
+
# Trigger tunable reconfigure
|
|
642
|
+
$ opn-api -d opnsense01 reconfigure tunable
|
|
643
|
+
|
|
644
|
+
# Trigger Zabbix agent reconfigure
|
|
645
|
+
$ opn-api -d opnsense01 reconfigure zabbix_agent
|
|
646
|
+
|
|
647
|
+
# List all available reconfigure groups
|
|
648
|
+
$ opn-api groups
|
|
649
|
+
```
|
|
650
|
+
|
|
651
|
+
### Snapshots
|
|
652
|
+
|
|
653
|
+
```
|
|
654
|
+
# List all snapshots (uses GET-based search)
|
|
655
|
+
$ opn-api -d opnsense01 search snapshot
|
|
656
|
+
```
|
|
657
|
+
|
|
658
|
+
### Syslog
|
|
659
|
+
|
|
660
|
+
```
|
|
661
|
+
# List syslog destinations
|
|
662
|
+
$ opn-api -d opnsense01 search syslog
|
|
663
|
+
|
|
664
|
+
# Show syslog destination details
|
|
665
|
+
$ opn-api -d opnsense01 show syslog a1b2c3d4-...
|
|
666
|
+
|
|
667
|
+
# Create syslog destination (wrapper key: "destination")
|
|
668
|
+
$ opn-api -d opnsense01 create syslog \
|
|
669
|
+
-j '{"destination":{"enabled":"1","transport":"udp4","hostname":"10.0.0.100","port":"514"}}'
|
|
670
|
+
|
|
671
|
+
# Apply changes
|
|
672
|
+
$ opn-api -d opnsense01 reconfigure syslog
|
|
673
|
+
```
|
|
674
|
+
|
|
675
|
+
### Trust certificates
|
|
676
|
+
|
|
677
|
+
```
|
|
678
|
+
# List all certificates
|
|
679
|
+
$ opn-api -d opnsense01 search trust_cert
|
|
680
|
+
|
|
681
|
+
# Show certificate details
|
|
682
|
+
$ opn-api -d opnsense01 show trust_cert 6f7a8b9c-...
|
|
683
|
+
|
|
684
|
+
# List all CAs
|
|
685
|
+
$ opn-api -d opnsense01 search trust_ca
|
|
686
|
+
|
|
687
|
+
# Show CA details
|
|
688
|
+
$ opn-api -d opnsense01 show trust_ca 7a8b9c0d-...
|
|
689
|
+
|
|
690
|
+
# List CRLs (uses GET-based search)
|
|
691
|
+
$ opn-api -d opnsense01 search trust_crl
|
|
692
|
+
```
|
|
693
|
+
|
|
694
|
+
### Tunables
|
|
695
|
+
|
|
696
|
+
The wrapper key for tunables is `sysctl` (not `tunable` or `item`).
|
|
697
|
+
|
|
698
|
+
```
|
|
699
|
+
# List all tunables
|
|
700
|
+
$ opn-api -d opnsense01 search tunable
|
|
701
|
+
|
|
702
|
+
# Show tunable details
|
|
703
|
+
$ opn-api -d opnsense01 show tunable a1b2c3d4-...
|
|
704
|
+
|
|
705
|
+
# Create tunable (wrapper key: "sysctl")
|
|
706
|
+
$ opn-api -d opnsense01 create tunable \
|
|
707
|
+
-j '{"sysctl":{"tunable":"net.inet.ip.forwarding","value":"1"}}'
|
|
708
|
+
|
|
709
|
+
# Update tunable
|
|
710
|
+
$ opn-api -d opnsense01 update tunable a1b2c3d4-... \
|
|
711
|
+
-j '{"sysctl":{"value":"0"}}'
|
|
712
|
+
|
|
713
|
+
# Delete tunable
|
|
714
|
+
$ opn-api -d opnsense01 delete tunable a1b2c3d4-...
|
|
715
|
+
|
|
716
|
+
# Apply changes
|
|
717
|
+
$ opn-api -d opnsense01 reconfigure tunable
|
|
718
|
+
```
|
|
719
|
+
|
|
720
|
+
### Users
|
|
721
|
+
|
|
722
|
+
```
|
|
723
|
+
# List all users
|
|
724
|
+
$ opn-api -d opnsense01 search user
|
|
725
|
+
|
|
726
|
+
# Show user details
|
|
727
|
+
$ opn-api -d opnsense01 show user a1b2c3d4-...
|
|
728
|
+
|
|
729
|
+
# Create user (wrapper key: "user")
|
|
730
|
+
$ opn-api -d opnsense01 create user \
|
|
731
|
+
-j '{"user":{"name":"testuser","email":"test@example.com"}}'
|
|
732
|
+
```
|
|
733
|
+
|
|
734
|
+
### Zabbix
|
|
735
|
+
|
|
736
|
+
#### Zabbix agent
|
|
737
|
+
|
|
738
|
+
Zabbix agent is a singleton resource (one per device).
|
|
739
|
+
|
|
740
|
+
```
|
|
741
|
+
# Show Zabbix agent settings (singleton)
|
|
742
|
+
$ opn-api -d opnsense01 show zabbix_agent
|
|
743
|
+
|
|
744
|
+
# Show as JSON
|
|
745
|
+
$ opn-api -d opnsense01 -f json show zabbix_agent
|
|
746
|
+
|
|
747
|
+
# Update Zabbix agent settings (wrapper key: "zabbixagent")
|
|
748
|
+
$ opn-api -d opnsense01 update zabbix_agent \
|
|
749
|
+
-j '{"zabbixagent":{"settings":{"main":{"enabled":"1","hostname":"opnsense01","serverList":"10.0.0.5"}}}}'
|
|
750
|
+
|
|
751
|
+
# Apply changes
|
|
752
|
+
$ opn-api -d opnsense01 reconfigure zabbix_agent
|
|
753
|
+
```
|
|
754
|
+
|
|
755
|
+
#### Zabbix agent sub-resources
|
|
756
|
+
|
|
757
|
+
Zabbix agent aliases and user parameters are CRUD resources within the Zabbix agent settings.
|
|
758
|
+
|
|
759
|
+
```
|
|
760
|
+
# List Zabbix agent aliases (uses GET-based search)
|
|
761
|
+
$ opn-api -d opnsense01 search zabbix_agent_alias
|
|
762
|
+
|
|
763
|
+
# Create alias (wrapper key: "alias")
|
|
764
|
+
$ opn-api -d opnsense01 create zabbix_agent_alias \
|
|
765
|
+
-j '{"alias":{"key":"system.uptime","item":"system.uptime"}}'
|
|
766
|
+
|
|
767
|
+
# List Zabbix agent user parameters
|
|
768
|
+
$ opn-api -d opnsense01 search zabbix_agent_userparameter
|
|
769
|
+
```
|
|
770
|
+
|
|
771
|
+
#### Zabbix proxy
|
|
772
|
+
|
|
773
|
+
Zabbix proxy is a singleton resource.
|
|
774
|
+
|
|
775
|
+
```
|
|
776
|
+
# Show Zabbix proxy settings (singleton)
|
|
777
|
+
$ opn-api -d opnsense01 show zabbix_proxy
|
|
778
|
+
|
|
779
|
+
# Update Zabbix proxy settings (wrapper key: "general")
|
|
780
|
+
$ opn-api -d opnsense01 update zabbix_proxy \
|
|
781
|
+
-j '{"general":{"enabled":"1","hostname":"zbxproxy01"}}'
|
|
782
|
+
```
|
|
783
|
+
|
|
784
|
+
### Error handling
|
|
785
|
+
|
|
786
|
+
On failure, the full API response is shown as JSON for debugging:
|
|
787
|
+
|
|
788
|
+
```
|
|
789
|
+
$ opn-api -d opnsense01 create firewall_alias -j '{"alias":{"name":"test"}}'
|
|
790
|
+
Error: create failed: {"result":"failed","validations":{"alias.type":"This field is required."}}
|
|
791
|
+
```
|
|
792
|
+
|
|
793
|
+
When OPNsense returns only `{"result":"failed"}` without validation details, the most common cause is a wrong wrapper key. The error message includes the expected wrapper key from the registry:
|
|
794
|
+
|
|
795
|
+
```
|
|
796
|
+
# Wrong wrapper key — error shows expected key
|
|
797
|
+
$ opn-api -d opnsense01 create firewall_alias -j '{"item":{"name":"test"}}'
|
|
798
|
+
Error: create failed: {"result":"failed"}
|
|
799
|
+
Hint: The JSON wrapper key is likely wrong. Expected wrapper key: 'alias'.
|
|
800
|
+
|
|
801
|
+
# Use -v to see full request/response details for debugging
|
|
802
|
+
$ opn-api -v -d opnsense01 create firewall_alias -j '{"alias":{"name":"test"}}'
|
|
803
|
+
```
|
|
804
|
+
|
|
805
|
+
### Wrapper keys
|
|
806
|
+
|
|
807
|
+
The OPNsense API uses different keys for endpoints and POST body wrappers. The wrapper key wraps the config in the JSON body. When using registry resource names, `opn-api resources` shows the correct wrapper key for each type.
|
|
808
|
+
|
|
809
|
+
Common examples:
|
|
810
|
+
|
|
811
|
+
| Resource name | Wrapper key |
|
|
812
|
+
|---|---|
|
|
813
|
+
| `cron` | `job` |
|
|
814
|
+
| `dhcrelay` | `relay` |
|
|
815
|
+
| `firewall_alias` | `alias` |
|
|
816
|
+
| `firewall_rule` | `rule` |
|
|
817
|
+
| `gateway` | `gateway_item` |
|
|
818
|
+
| `haproxy_backend` | `backend` |
|
|
819
|
+
| `haproxy_frontend` | `frontend` |
|
|
820
|
+
| `haproxy_server` | `server` |
|
|
821
|
+
| `ipsec_connection` | `connection` |
|
|
822
|
+
| `ipsec_keypair` | `keyPair` |
|
|
823
|
+
| `kea_dhcpv4_subnet` | `subnet4` |
|
|
824
|
+
| `openvpn_instance` | `instance` |
|
|
825
|
+
| `route` | `route` |
|
|
826
|
+
| `syslog` | `destination` |
|
|
827
|
+
| `trust_ca` | `ca` |
|
|
828
|
+
| `trust_cert` | `cert` |
|
|
829
|
+
| `tunable` | `sysctl` |
|
|
830
|
+
| `user` | `user` |
|
|
831
|
+
|
|
832
|
+
To find the correct wrapper key for any resource, use `show` to inspect an existing item — the top-level key in the raw JSON response (`-f json`) is the wrapper key.
|
|
833
|
+
|
|
834
|
+
### Raw API access
|
|
835
|
+
|
|
836
|
+
For endpoints not covered by the resource registry, use the `get` and `post` commands for direct API access.
|
|
837
|
+
|
|
838
|
+
```
|
|
839
|
+
# GET request to any API path
|
|
840
|
+
$ opn-api -d opnsense01 get core/firmware/info
|
|
841
|
+
|
|
842
|
+
# POST request with JSON body
|
|
843
|
+
$ opn-api -d opnsense01 post firewall/alias/search_item '{}'
|
|
844
|
+
```
|
|
845
|
+
|
|
846
|
+
### Ruby API
|
|
847
|
+
|
|
848
|
+
```ruby
|
|
849
|
+
#!/usr/bin/env ruby
|
|
850
|
+
|
|
851
|
+
require 'opn_api'
|
|
852
|
+
|
|
853
|
+
# Create client from config file
|
|
854
|
+
config = OpnApi::Config.new
|
|
855
|
+
client = config.client_for('opnsense01')
|
|
856
|
+
|
|
857
|
+
# Or create client directly
|
|
858
|
+
client = OpnApi::Client.new(
|
|
859
|
+
url: 'https://fw.example.com/api',
|
|
860
|
+
api_key: '+ABC...',
|
|
861
|
+
api_secret: '+XYZ...',
|
|
862
|
+
ssl_verify: false,
|
|
863
|
+
)
|
|
864
|
+
|
|
865
|
+
# Simple API calls
|
|
866
|
+
info = client.get('core/firmware/info')
|
|
867
|
+
puts "OPNsense version: #{info['product_version']}"
|
|
868
|
+
|
|
869
|
+
aliases = client.post('firewall/alias/search_item', {})
|
|
870
|
+
aliases['rows'].each { |a| puts a['name'] }
|
|
871
|
+
|
|
872
|
+
# CRUD via resource registry (preferred — handles endpoint quirks)
|
|
873
|
+
res = OpnApi::ResourceRegistry.build(client, 'haproxy_server')
|
|
874
|
+
servers = res.search
|
|
875
|
+
new_server = res.add('server' => { 'name' => 'web01', 'address' => '10.0.0.10', 'port' => '8080' })
|
|
876
|
+
res.set(new_server['uuid'], 'server' => { 'port' => '8443' })
|
|
877
|
+
res.del(new_server['uuid'])
|
|
878
|
+
|
|
879
|
+
# Singleton resources (settings)
|
|
880
|
+
settings = OpnApi::ResourceRegistry.build(client, 'haproxy_settings')
|
|
881
|
+
current = settings.show_settings
|
|
882
|
+
settings.update_settings('haproxy' => { 'general' => { 'tuning' => { 'maxconn' => '2000' } } })
|
|
883
|
+
|
|
884
|
+
# CRUD via explicit paths (for resources not in registry)
|
|
885
|
+
res = OpnApi::Resource.new(
|
|
886
|
+
client: client,
|
|
887
|
+
base_path: 'firewall/alias',
|
|
888
|
+
search_action: 'search_item',
|
|
889
|
+
crud_action: '%{action}_item',
|
|
890
|
+
)
|
|
891
|
+
all_aliases = res.search
|
|
892
|
+
|
|
893
|
+
# Legacy mode (module/controller/type) is also supported
|
|
894
|
+
res = OpnApi::Resource.new(
|
|
895
|
+
client: client,
|
|
896
|
+
module_name: 'firewall',
|
|
897
|
+
controller: 'alias',
|
|
898
|
+
resource_type: 'item',
|
|
899
|
+
)
|
|
900
|
+
|
|
901
|
+
# UUID resolution for ModelRelationField references
|
|
902
|
+
relation_fields = {
|
|
903
|
+
'linkedServers' => {
|
|
904
|
+
endpoint: 'haproxy/settings/search_servers',
|
|
905
|
+
multiple: true,
|
|
906
|
+
},
|
|
907
|
+
'sslCA' => {
|
|
908
|
+
endpoint: 'trust/ca/search',
|
|
909
|
+
id_field: 'refid',
|
|
910
|
+
name_field: 'descr',
|
|
911
|
+
},
|
|
912
|
+
}
|
|
913
|
+
config_with_names = OpnApi::IdResolver.translate_to_names(
|
|
914
|
+
client, 'opnsense01', relation_fields, config_hash,
|
|
915
|
+
)
|
|
916
|
+
config_with_uuids = OpnApi::IdResolver.translate_to_uuids(
|
|
917
|
+
client, 'opnsense01', relation_fields, config_hash,
|
|
918
|
+
)
|
|
919
|
+
|
|
920
|
+
# Service reconfigure orchestration
|
|
921
|
+
OpnApi::ServiceReconfigure.load_defaults!
|
|
922
|
+
OpnApi::ServiceReconfigure[:haproxy].mark('opnsense01', client)
|
|
923
|
+
results = OpnApi::ServiceReconfigure[:haproxy].run
|
|
924
|
+
# => { 'opnsense01' => :ok }
|
|
925
|
+
```
|
|
926
|
+
|
|
927
|
+
## Features
|
|
928
|
+
|
|
929
|
+
### Config loader
|
|
930
|
+
|
|
931
|
+
`OpnApi::Config` loads device credentials from YAML files with a hierarchical search path. Supports multiple devices and is compatible with puppet-opn's device file format.
|
|
932
|
+
|
|
933
|
+
### ID resolver
|
|
934
|
+
|
|
935
|
+
`OpnApi::IdResolver` translates between UUIDs/IDs and human-readable names for OPNsense ModelRelationField and CertificateField references. Features include:
|
|
936
|
+
|
|
937
|
+
- Per-run caching to minimize API calls
|
|
938
|
+
- Automatic cache refresh on miss (retry once)
|
|
939
|
+
- Support for dot-path field names (e.g. `general.stats.allowedUsers`)
|
|
940
|
+
- Custom `id_field` and `name_field` per relation (e.g. `refid`/`descr` for certificates)
|
|
941
|
+
- Multiple values (comma-separated) and single-value fields
|
|
942
|
+
|
|
943
|
+
### Normalize
|
|
944
|
+
|
|
945
|
+
`OpnApi::Normalize` handles OPNsense selection-hash normalization. OPNsense returns multi-select fields as hashes with `value`/`selected` keys. This module collapses them to comma-separated strings of selected keys, recursing into nested structures.
|
|
946
|
+
|
|
947
|
+
### Resource CRUD
|
|
948
|
+
|
|
949
|
+
`OpnApi::Resource` provides a generic CRUD wrapper for OPNsense API endpoints. It supports three resource patterns:
|
|
950
|
+
|
|
951
|
+
- **Standard CRUD**: search/get/add/set/del with UUID
|
|
952
|
+
- **Singleton settings**: GET get / POST set, no UUID, no search/add/del
|
|
953
|
+
- **GET-based search**: Resources using GET instead of POST for search (e.g. snapshots, trust_crl)
|
|
954
|
+
|
|
955
|
+
### Resource registry
|
|
956
|
+
|
|
957
|
+
`OpnApi::ResourceRegistry` maps user-friendly resource names to exact API endpoint paths. OPNsense has no consistent endpoint naming — some use snake_case with plural search (`search_servers`/`add_server`), others use camelCase (`searchConnection`/`addConnection`), bare names (`search`/`add`), or no separator (`searchroute`/`addroute`). The registry abstracts these differences so users and code don't need to know the implementation details.
|
|
958
|
+
|
|
959
|
+
Resource names follow the [puppet-opn](https://github.com/markt-de/puppet-opn) naming convention (`opn_` prefix stripped).
|
|
960
|
+
|
|
961
|
+
### Service reconfigure
|
|
962
|
+
|
|
963
|
+
`OpnApi::ServiceReconfigure` orchestrates service reloads after configuration changes. Features include:
|
|
964
|
+
|
|
965
|
+
- Registry pattern with 18 pre-registered OPNsense service groups
|
|
966
|
+
- Mark/run pattern: track devices with changes, then batch-reconfigure
|
|
967
|
+
- Configtest support (e.g. HAProxy validates config before reconfigure)
|
|
968
|
+
- Error tracking: skip reconfigure for devices with failed resource changes
|
|
969
|
+
- Custom group registration for plugins or custom services
|
|
970
|
+
|
|
971
|
+
## Development
|
|
972
|
+
|
|
973
|
+
### Contributing
|
|
974
|
+
|
|
975
|
+
Please use the GitHub issues functionality to report any bugs or requests for new features. Feel free to fork and submit pull requests for potential contributions.
|
|
976
|
+
|
|
977
|
+
## License
|
|
978
|
+
|
|
979
|
+
BSD-2-Clause
|