zabbix_manager 5.1.6 → 6.0.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 +4 -4
- data/CHANGELOG.md +31 -1
- data/README.md +69 -46
- data/lib/zabbix_manager/classes/actions.rb +3 -11
- data/lib/zabbix_manager/classes/applications.rb +2 -8
- data/lib/zabbix_manager/classes/configurations.rb +4 -9
- data/lib/zabbix_manager/classes/{drules.rb → discovery_rules.rb} +2 -8
- data/lib/zabbix_manager/classes/errors.rb +3 -0
- data/lib/zabbix_manager/classes/events.rb +2 -1
- data/lib/zabbix_manager/classes/graphs.rb +19 -15
- data/lib/zabbix_manager/classes/{hostgroups.rb → host_groups.rb} +5 -11
- data/lib/zabbix_manager/classes/host_interfaces.rb +261 -0
- data/lib/zabbix_manager/classes/hosts.rb +135 -89
- data/lib/zabbix_manager/classes/{httptests.rb → http_tests.rb} +2 -8
- data/lib/zabbix_manager/classes/items.rb +91 -87
- data/lib/zabbix_manager/classes/maintenance.rb +2 -1
- data/lib/zabbix_manager/classes/{mediatypes.rb → media_types.rb} +2 -7
- data/lib/zabbix_manager/classes/problems.rb +11 -40
- data/lib/zabbix_manager/classes/proxies.rb +5 -15
- data/lib/zabbix_manager/classes/proxy_groups.rb +16 -0
- data/lib/zabbix_manager/classes/roles.rb +13 -19
- data/lib/zabbix_manager/classes/screens.rb +11 -30
- data/lib/zabbix_manager/classes/scripts.rb +2 -8
- data/lib/zabbix_manager/classes/server.rb +1 -0
- data/lib/zabbix_manager/classes/templates.rb +2 -65
- data/lib/zabbix_manager/classes/triggers.rb +42 -45
- data/lib/zabbix_manager/classes/user_groups.rb +63 -0
- data/lib/zabbix_manager/classes/user_macros.rb +110 -0
- data/lib/zabbix_manager/classes/users.rb +15 -54
- data/lib/zabbix_manager/classes/value_maps.rb +52 -0
- data/lib/zabbix_manager/client.rb +148 -277
- data/lib/zabbix_manager/configuration.rb +107 -0
- data/lib/zabbix_manager/http_transport.rb +145 -97
- data/lib/zabbix_manager/log_sanitizer.rb +9 -19
- data/lib/zabbix_manager/monitoring/device.rb +393 -0
- data/lib/zabbix_manager/monitoring/expressions.rb +36 -0
- data/lib/zabbix_manager/monitoring/line.rb +175 -0
- data/lib/zabbix_manager/monitoring/line_items.rb +110 -0
- data/lib/zabbix_manager/monitoring/line_lifecycle.rb +169 -0
- data/lib/zabbix_manager/monitoring/line_plan.rb +113 -0
- data/lib/zabbix_manager/monitoring/thresholds.rb +182 -0
- data/lib/zabbix_manager/monitoring/traffic_items.rb +132 -0
- data/lib/zabbix_manager/monitoring/validation.rb +92 -0
- data/lib/zabbix_manager/monitoring.rb +216 -642
- data/lib/zabbix_manager/resource.rb +235 -0
- data/lib/zabbix_manager/traffic.rb +238 -0
- data/lib/zabbix_manager/version.rb +1 -1
- data/lib/zabbix_manager.rb +66 -179
- data/zabbix_manager.gemspec +6 -22
- metadata +41 -190
- data/lib/zabbix_manager/basic/basic_alias.rb +0 -42
- data/lib/zabbix_manager/basic/basic_func.rb +0 -55
- data/lib/zabbix_manager/basic/basic_init.rb +0 -50
- data/lib/zabbix_manager/basic/basic_logic.rb +0 -239
- data/lib/zabbix_manager/classes/hostinterfaces.rb +0 -189
- data/lib/zabbix_manager/classes/usergroups.rb +0 -75
- data/lib/zabbix_manager/classes/usermacros.rb +0 -222
- data/lib/zabbix_manager/classes/valuemaps.rb +0 -26
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b40a4744edcbba667b1c548c576b6451e637dee80bce28755a151f58e02a553b
|
|
4
|
+
data.tar.gz: 5d5ee350721f10da7ea9f93582bf06fc6c5b6ac4e5a9bbaa445058f43c205a45
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: db558e058564904b417225b8f59df28a741b7f73d787f104180dd878e017899fadfe077d4194b2e2f2b2995639cf9c42ab585abf25f0d06308af9f8a6549eeba
|
|
7
|
+
data.tar.gz: 5c6a2e519171dec793941f13ba766aad04679a008196dad090b784614fa59882c851c810554c0c8ee479ba8aa7493779c5c2f770bfc1d24c0efb8da4a730da7d
|
data/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,36 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## 6.0.0 (2026-10-01)
|
|
4
|
+
|
|
5
|
+
* Fix role ID queries and host-scoped value map identities, keeping immutable host fields out of updates.
|
|
6
|
+
* Reject incomplete interface creation and duplicate resolved interface targets before remote writes.
|
|
7
|
+
* Preserve distinct interface names, validate standard 32-bit octet conversion, and check effective numeric item configuration before writing monitoring updates.
|
|
8
|
+
* Bound network request duration and decompressed response size, close failed connections, and never replay uncertain mutations.
|
|
9
|
+
* Complete Chinese module comments and correct public return-type documentation.
|
|
10
|
+
|
|
11
|
+
* Extract reusable Motor monitoring scenarios through native Zabbix APIs only, without SQL or application persistence.
|
|
12
|
+
* Add `traffic.series` and `traffic.for_interface` for precise history/trend reads with missing-data and truncation states.
|
|
13
|
+
* Add device name resolution, proxy groups, SNMP secret macros and caller-owned membership receipts; preserve unrelated configuration.
|
|
14
|
+
* Add line previews, low-traffic/status/ICMP checks, dependencies, scoped problem reads and managed trigger retirement.
|
|
15
|
+
* Return device receipts and per-kind line `triggerids`; expand public method contracts and executable workflow examples.
|
|
16
|
+
|
|
17
|
+
* Validate mutation receipts against requested IDs; empty, malformed or mismatched receipts remain unconfirmed outcomes.
|
|
18
|
+
* Require desired trigger state during lost-response recovery and serialize dependency replacement with appends.
|
|
19
|
+
* Replace obsolete template-side host-link helpers with `hosts.link_templates`, `replace_templates`, and `unlink_templates` using current host APIs.
|
|
20
|
+
* Use explicit `user_groups.replace_users` and `replace_host_group_permissions` operations with version-correct server fields.
|
|
21
|
+
* Verify packaged source inventory and isolated authenticated requests, then publish the exact verified artifact; declare IRB for Ruby 4 development consoles.
|
|
22
|
+
|
|
23
|
+
* Normalize multiword resource classes, files and accessors to Ruby CamelCase/snake_case without compatibility aliases.
|
|
24
|
+
|
|
25
|
+
* Require Ruby 3.4 or newer; refresh the dependency lockfile and remove development-tool version pins and duplicate declarations.
|
|
26
|
+
* Replace the split `Basic` hierarchy with `Resource`, remove compatibility aliases and parameter logging, and use keyword connection/request options.
|
|
27
|
+
* Use ActiveSupport logger/tagging/parameter filtering; make logging failure independent of API results.
|
|
28
|
+
* Add explicit `from_env` loading for `ZABBIX_URL`, `ZABBIX_API_TOKEN`, `ZABBIX_USERNAME`, and `ZABBIX_PASSWORD` only.
|
|
29
|
+
* Remove `current`, `user`, `debug`, `manager_request`, low-level client request helpers and legacy inventory field aliases; use explicit managers, `username`, `logger`/`log_level` and canonical monitoring fields.
|
|
30
|
+
* Validate JSON-RPC response shapes and IDs, report unconfirmed responses as `ProtocolError`, and prevent server text or exception causes from leaking secrets.
|
|
31
|
+
* Delegate proxy discovery and exclusions to Ruby, validate finite timeouts, and avoid closing an inherited parent TLS session after fork.
|
|
32
|
+
* Validate complete interface/item batches before writes, refuse ambiguous macro ownership, and distinguish missing values from empty strings during updates.
|
|
33
|
+
* Separate monitoring input, threshold and traffic-item rules, reject invalid units/expressions, and retain unknown write outcomes in batch results.
|
|
4
34
|
|
|
5
35
|
* Add Zabbix 7.x API-token authentication through the Bearer header while retaining the legacy 4.x-6.x authentication body.
|
|
6
36
|
* Reuse a thread-safe persistent `Net::HTTP` session and add explicit `close` lifecycle handling.
|
data/README.md
CHANGED
|
@@ -4,8 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
[gem]: https://rubygems.org/gems/zabbix_manager
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
Simple and lightweight ruby module for working with [Zabbix][Zabbix] via the [Zabbix API][Zabbix API]
|
|
7
|
+
A Ruby client for the [Zabbix API][Zabbix API], with reusable device, interface and circuit monitoring workflows.
|
|
9
8
|
|
|
10
9
|
## Installation
|
|
11
10
|
```sh
|
|
@@ -41,6 +40,25 @@ zabbix.close
|
|
|
41
40
|
|
|
42
41
|
Zabbix 7.x requests use the `Authorization: Bearer` header. Earlier supported servers use the JSON-RPC `auth` property. Supplying `api_token` skips `user.login`, and `logout` only closes the local connection because an API token is not a Zabbix user session. API tokens are rejected on plain HTTP unless `allow_insecure_http: true` is explicitly set.
|
|
43
42
|
|
|
43
|
+
### Environment configuration
|
|
44
|
+
|
|
45
|
+
Environment loading is explicit. `connect` uses only its keyword arguments; `from_env` reads exactly four variables:
|
|
46
|
+
|
|
47
|
+
| Variable | Option |
|
|
48
|
+
| --- | --- |
|
|
49
|
+
| `ZABBIX_URL` | `url` |
|
|
50
|
+
| `ZABBIX_API_TOKEN` | `api_token` |
|
|
51
|
+
| `ZABBIX_USERNAME` | `username` |
|
|
52
|
+
| `ZABBIX_PASSWORD` | `password` |
|
|
53
|
+
|
|
54
|
+
```ruby
|
|
55
|
+
zabbix = ZabbixManager.from_env(verify_ssl: true)
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Explicit keyword arguments override environment values, including `nil` to clear an inherited credential. Set either an API token or a username/password pair. Unknown options and non-boolean flags are rejected before connecting. Timeouts, logging and locking remain ordinary keyword options.
|
|
59
|
+
|
|
60
|
+
The HTTP transport uses Ruby's standard proxy discovery (`http_proxy`/`HTTP_PROXY`, `no_proxy`/`NO_PROXY`, with CGI protection). `no_proxy: true` disables proxies; `proxy: "http://proxy.example:8080"` selects an explicit HTTP proxy. HTTPS proxy URLs are rejected because this transport does not encrypt the connection to the proxy itself.
|
|
61
|
+
|
|
44
62
|
### Username and password
|
|
45
63
|
|
|
46
64
|
```ruby
|
|
@@ -61,7 +79,7 @@ A client keeps one persistent `Net::HTTP` session and serializes access to it, s
|
|
|
61
79
|
|
|
62
80
|
### Logging and HTTPS
|
|
63
81
|
|
|
64
|
-
Pass
|
|
82
|
+
Pass a Ruby Logger or ActiveSupport logger to receive connection, request completion, duration, and failure events:
|
|
65
83
|
|
|
66
84
|
```ruby
|
|
67
85
|
zabbix = ZabbixManager.connect(
|
|
@@ -71,28 +89,31 @@ zabbix = ZabbixManager.connect(
|
|
|
71
89
|
)
|
|
72
90
|
```
|
|
73
91
|
|
|
74
|
-
|
|
92
|
+
Logging uses `ActiveSupport::Logger` and `ActiveSupport::TaggedLogging`; structured credential filtering uses `ActiveSupport::ParameterFilter`. Pass `log_level: :info` to create a logger on standard error, or inject your application's logger. Logging is disabled unless one of these options is supplied, and logging failures do not change API outcomes.
|
|
93
|
+
|
|
94
|
+
Passwords, API tokens, authorization values, cookies, and session IDs are filtered. Request parameters and response bodies are not logged. API exceptions expose the server error code and request ID, without remote messages or data that might echo arbitrary secrets. Malformed or mismatched JSON-RPC responses and invalid mutation ID receipts raise `ProtocolError < TransportError`: a write may already have happened, so it must not be blindly replayed.
|
|
75
95
|
|
|
76
96
|
HTTPS certificate verification is disabled by default as required by this project. Set `verify_ssl: true` (and optionally `ca_file:`) to enable peer verification.
|
|
77
97
|
|
|
78
98
|
Zabbix 7 API-token requests need the `Authorization` header, so they cannot share that header with HTTP Basic authentication. The client rejects that combination instead of silently overwriting either credential.
|
|
79
99
|
|
|
80
|
-
Timeouts can be set together with `timeout:` or independently with `open_timeout:`, `read_timeout:`, and `write_timeout:`. `keep_alive_timeout:` controls persistent connection reuse.
|
|
100
|
+
Timeouts can be set together with `timeout:` or independently with `open_timeout:`, `read_timeout:`, and `write_timeout:`. `keep_alive_timeout:` controls persistent connection reuse. `request_timeout:` bounds the complete network operation, including a continuously progressing response, and defaults to `timeout:`. Waiting for another request on the same client is outside that budget. `max_response_bytes:` limits the decompressed response body (64 MiB by default). Exceeding either limit closes the connection and raises `TransportError`; mutations are never automatically replayed.
|
|
81
101
|
|
|
82
102
|
### Device and interface monitoring
|
|
83
103
|
|
|
84
|
-
`monitoring` provides
|
|
104
|
+
`monitoring` provides device and line workflows using native Zabbix APIs only. There are no SQL operations, Rails models or persistence dependencies. Item identity is the stable pair `hostid + key_`; managed triggers use a dedicated `zabbix_manager_id` tag. Missing objects are created and existing ones are updated. Optional line checks removed from a definition are disabled after the remaining desired checks succeed; objects are never automatically deleted.
|
|
85
105
|
|
|
86
|
-
For a line inventory that already has interface traffic items discovered by Zabbix, use `reconcile_line`. It
|
|
106
|
+
For a line inventory that already has interface traffic items discovered by Zabbix, use `reconcile_line`. It locates the host and unique inbound/outbound items, then creates or updates the selected checks. Use canonical fields `host` (or `host_candidates`), `interface_name`, `capacity_mbps`, and a stable, non-secret endpoint `line_id`. Convert external inventory column names before calling the library.
|
|
107
|
+
|
|
108
|
+
The complete workflows and return values are documented in [device monitoring](examples/device_monitoring.md), [line monitoring](examples/line_monitoring.md), and [traffic queries](examples/traffic.md). Public method comments document input, output, failures and remote side effects.
|
|
87
109
|
|
|
88
110
|
```ruby
|
|
89
111
|
zabbix.monitoring.reconcile_line(
|
|
90
112
|
line_id: "line-42",
|
|
91
113
|
description: "Example upstream circuit",
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
iface1: "Ten-GigabitEthernet1/0/49",
|
|
114
|
+
capacity_mbps: 200,
|
|
115
|
+
host_candidates: ["edge-switch-01", "192.0.2.10"],
|
|
116
|
+
interface_name: "Ten-GigabitEthernet1/0/49",
|
|
96
117
|
isp: "Example ISP",
|
|
97
118
|
high_water: 0.90,
|
|
98
119
|
recovery_water: 0.80,
|
|
@@ -102,11 +123,11 @@ zabbix.monitoring.reconcile_line(
|
|
|
102
123
|
)
|
|
103
124
|
```
|
|
104
125
|
|
|
105
|
-
The lookup accepts full and abbreviated interface names such as `Ten-GigabitEthernet1/0/49` and `Te1/0/49`. It refuses zero or multiple direction matches instead of selecting an item by response order.
|
|
126
|
+
The lookup accepts full and abbreviated interface names such as `Ten-GigabitEthernet1/0/49` and `Te1/0/49`. It refuses zero or multiple direction matches instead of selecting an item by response order. Trigger ownership comes from the managed identity tag; matching descriptions alone never adopt unrelated triggers.
|
|
106
127
|
|
|
107
128
|
Use `reconcile_lines(lines)` for imports. It reuses host and item discovery results within the batch, avoiding a full `item.get` scan for every line.
|
|
108
129
|
|
|
109
|
-
For a device-and-line batch, use `reconcile_network`. The whole input is structurally validated before the first device write. Devices are reconciled first, then lines, and the return value contains per-entry results plus a summary. Template linking and low-level discovery are asynchronous in Zabbix:
|
|
130
|
+
For a device-and-line batch, use `reconcile_network`. The whole input is structurally validated before the first device write. Devices are reconciled first, then lines, and the return value contains per-entry results plus a summary. Template linking and low-level discovery are asynchronous in Zabbix: retry discovery after the required items become available. Inspect any `:unknown` write outcome before repeating that entry.
|
|
110
131
|
|
|
111
132
|
```ruby
|
|
112
133
|
result = zabbix.monitoring.reconcile_network(
|
|
@@ -114,16 +135,13 @@ result = zabbix.monitoring.reconcile_network(
|
|
|
114
135
|
{
|
|
115
136
|
host: "edge-router-01",
|
|
116
137
|
name: "Example edge router",
|
|
117
|
-
groups: [
|
|
118
|
-
|
|
119
|
-
type: 2, main: 1, useip: 1, ip: "192.0.2.10", dns: "", port: "161",
|
|
120
|
-
details: { version: 2, community: ENV.fetch("SNMP_COMMUNITY") }
|
|
121
|
-
}]
|
|
138
|
+
groups: ["Network devices"],
|
|
139
|
+
snmp: { ip: "192.0.2.10", community: ENV.fetch("SNMP_COMMUNITY") }
|
|
122
140
|
}
|
|
123
141
|
],
|
|
124
142
|
lines: [
|
|
125
143
|
{
|
|
126
|
-
line_id: "line-42",
|
|
144
|
+
line_id: "line-42", host: "edge-router-01",
|
|
127
145
|
interface_name: "Ten-GigabitEthernet1/0/49", capacity_mbps: 200,
|
|
128
146
|
high_water: 0.90, recovery_water: 0.80
|
|
129
147
|
}
|
|
@@ -134,7 +152,7 @@ result.fetch(:summary)
|
|
|
134
152
|
```
|
|
135
153
|
|
|
136
154
|
```ruby
|
|
137
|
-
|
|
155
|
+
receipt = zabbix.monitoring.reconcile_device(
|
|
138
156
|
host: "router-01",
|
|
139
157
|
name: "Core router 01",
|
|
140
158
|
groups: [{ groupid: 20 }],
|
|
@@ -148,10 +166,14 @@ hostid = zabbix.monitoring.reconcile_device(
|
|
|
148
166
|
details: { version: 2, community: ENV.fetch("SNMP_COMMUNITY") }
|
|
149
167
|
}]
|
|
150
168
|
)
|
|
169
|
+
hostid = receipt.fetch(:hostid)
|
|
170
|
+
snmp_interface = zabbix.host_interfaces.for_host(hostid).find do |interface|
|
|
171
|
+
interface["type"] == "2" && interface["main"] == "1"
|
|
172
|
+
end
|
|
151
173
|
|
|
152
174
|
zabbix.monitoring.reconcile_interface(
|
|
153
175
|
host: { hostid: hostid, host: "router-01" },
|
|
154
|
-
interface: { name: "GigabitEthernet1/0/1", interfaceid:
|
|
176
|
+
interface: { name: "GigabitEthernet1/0/1", interfaceid: snmp_interface.fetch("interfaceid") },
|
|
155
177
|
items: {
|
|
156
178
|
inbound_bps: {
|
|
157
179
|
key_: "if.hc.in.bps[1]", name: "WAN inbound", type: 20, value_type: 0,
|
|
@@ -192,9 +214,9 @@ zabbix.monitoring.reconcile_interface(
|
|
|
192
214
|
)
|
|
193
215
|
```
|
|
194
216
|
|
|
195
|
-
The library does not guess that SNMP discard/error counters equal packet-loss percentage. Supply an actual packet-loss item key (for example an ICMP loss item) and its item definition. Raw HC-octet traffic items must expose `bps` units and include change-per-second plus multiplier-8 preprocessing; otherwise line reconciliation refuses to build a dimensionally incorrect trigger. Thresholds use separate high and recovery values to avoid alert flapping.
|
|
217
|
+
The library does not guess that SNMP discard/error counters equal packet-loss percentage. Supply an actual packet-loss item key (for example an ICMP loss item) and its item definition. Raw HC-octet traffic items must expose `bps` units and include change-per-second plus multiplier-8 preprocessing; otherwise line reconciliation refuses to build a dimensionally incorrect trigger. Thresholds use separate high and recovery values to avoid alert flapping. Line `high_water` and `recovery_water` are ratios greater than zero and at most one; percentages such as `90` are rejected. Interface threshold recovery is inclusive (`<=`), so a zero recovery threshold remains attainable.
|
|
196
218
|
|
|
197
|
-
Reconciliation is a sequence of remote API calls, not a transaction. Single-object methods raise immediately; batch methods return a sanitized error for each failed entry unless `fail_fast: true` is passed.
|
|
219
|
+
Reconciliation is a sequence of remote API calls, not a transaction. Single-object methods raise immediately; batch methods return a sanitized error for each failed entry unless `fail_fast: true` is passed. Batch results distinguish `ok`, `error`, and `unknown`; summaries count each status. Transport failures during device reconciliation are conservatively `unknown`, since that workflow includes both lookup and write calls. Successful earlier remote writes are not rolled back if a later operation fails. After an uncertain outcome has been resolved, a retry can converge already-created items by stable keys. If a trigger create loses its response, readback must confirm both its managed identity and requested attributes. If that cannot be confirmed, `ResultUnknown` is raised and must not be automatically retried. A definite API rejection is propagated. The readback schedule can be set with `uncertain_write_delays:` (up to 60 seconds total). Trigger upserts and dependency read/modify/write operations are serialized within one client process. For multiple workers, inject a callable `upsert_lock` adapter that runs the block under an application-level distributed lock.
|
|
198
220
|
|
|
199
221
|
```ruby
|
|
200
222
|
ZabbixManager.connect(
|
|
@@ -204,40 +226,32 @@ ZabbixManager.connect(
|
|
|
204
226
|
)
|
|
205
227
|
```
|
|
206
228
|
|
|
207
|
-
Invalid caller input raises `ZabbixManager::Invalid`, ambiguous remote ownership raises `ZabbixManager::Conflict`, Zabbix JSON-RPC failures raise `ZabbixManager::ApiError`, HTTP/network failures raise `ZabbixManager::TransportError`, and uncertain remote writes raise `ZabbixManager::ResultUnknown`.
|
|
229
|
+
Invalid caller input raises `ZabbixManager::Invalid`, ambiguous remote ownership raises `ZabbixManager::Conflict`, Zabbix JSON-RPC failures raise `ZabbixManager::ApiError`, HTTP/network failures raise `ZabbixManager::TransportError`, and uncertain remote writes raise `ZabbixManager::ResultUnknown`. The focused item/interface/trigger deletion, status and dependency helpers require `hostid:` and verify existing ownership before writing. Custom trigger expressions and raw resource methods accept trusted Zabbix definitions; the host lookup context does not replace application authorization. Dependencies default to the same host; cross-host dependencies require `allow_cross_host_dependencies: true`. Do not pass untrusted page parameters directly to `query`, raw resource methods, or custom expressions.
|
|
208
230
|
|
|
209
231
|
### High-frequency API modules
|
|
210
232
|
|
|
211
|
-
|
|
233
|
+
`traffic.series` reads explicit item IDs; `traffic.for_interface` discovers both interface directions. Both expose missing data and query truncation, preserve numeric precision, and keep raw history separate from hourly trends. They never substitute zero or a stale last value for missing samples.
|
|
212
234
|
|
|
213
|
-
|
|
214
|
-
|
|
235
|
+
Multiword resource accessors use Ruby snake_case: `host_groups`, `host_interfaces`, `http_tests`, `media_types`, `proxy_groups`, `user_groups`, `user_macros`, `value_maps`, and `discovery_rules`.
|
|
236
|
+
|
|
237
|
+
The focused modules expose explicit operations:
|
|
238
|
+
|
|
239
|
+
* `hosts.reconcile`, `hosts.resolve`, `hosts.find_by_id`, `hosts.find_by_candidates`, `hosts.set_status`
|
|
240
|
+
* `monitoring.reconcile_device`, `monitoring.reconcile_devices`, `monitoring.reconcile_network`
|
|
241
|
+
* `monitoring.plan_line`, `monitoring.reconcile_line`, `monitoring.line_triggers`, `monitoring.line_problems`, `monitoring.disable_line`
|
|
242
|
+
* `hosts.link_templates`, `hosts.replace_templates`, `hosts.unlink_templates`
|
|
243
|
+
* `user_groups.replace_users`, `user_groups.replace_host_group_permissions`
|
|
244
|
+
* `host_interfaces.for_host`, `host_interfaces.reconcile_for_host`, `host_interfaces.delete_many`
|
|
215
245
|
* `items.for_host`, `items.upsert_by_key`, `items.upsert_many`, `items.set_status`, `items.delete_many`
|
|
216
246
|
* `triggers.for_host`, `triggers.upsert_for_host`, `triggers.add_dependencies`, `triggers.replace_dependencies`, `triggers.set_status`, `triggers.delete_many`
|
|
217
247
|
|
|
218
248
|
|
|
219
249
|
## Supported Ruby Versions
|
|
220
|
-
|
|
221
|
-
versions:
|
|
222
|
-
|
|
223
|
-
* Ruby 2.7 and newer
|
|
224
|
-
|
|
225
|
-
If something doesn't work on one of these versions, it's a bug.
|
|
226
|
-
|
|
227
|
-
This library may inadvertently work (or seem to work) on other Ruby versions,
|
|
228
|
-
however support will only be provided for the versions listed above.
|
|
229
|
-
|
|
230
|
-
If you would like this library to support another Ruby version or
|
|
231
|
-
implementation, you may volunteer to be a maintainer. Being a maintainer
|
|
232
|
-
entails making sure all tests run and pass on that implementation. When
|
|
233
|
-
something breaks on your implementation, you will be responsible for providing
|
|
234
|
-
patches in a timely fashion. If critical issues for a particular implementation
|
|
235
|
-
exist at the time of a major release, support for that Ruby version may be
|
|
236
|
-
dropped.
|
|
250
|
+
The minimum Ruby version is **3.4**. CI runs Ruby 3.4 and 4.0.
|
|
237
251
|
|
|
238
252
|
## Dependencies
|
|
239
253
|
|
|
240
|
-
* net
|
|
254
|
+
* net-http
|
|
241
255
|
* active_support
|
|
242
256
|
* json
|
|
243
257
|
* logger
|
|
@@ -247,11 +261,16 @@ dropped.
|
|
|
247
261
|
* Fork the project.
|
|
248
262
|
* Base your work on the master branch.
|
|
249
263
|
* Make your feature addition or bug fix, write tests, write documentation/examples.
|
|
250
|
-
*
|
|
264
|
+
* Run `bundle exec rake` and `bundle exec ruby script/verify_package.rb`.
|
|
251
265
|
* Make a pull request.
|
|
252
266
|
|
|
253
267
|
## CI and release
|
|
254
268
|
|
|
269
|
+
`script/verify_package.rb` checks the complete library inventory, installs into an isolated gem directory, exercises authentication and a resource request over a local HTTP socket, then saves that exact verified archive under `pkg/`. It also works when invoked outside the checkout.
|
|
270
|
+
|
|
271
|
+
Development tools are declared once in `Gemfile`, without historical version pins. `Gemfile.lock` records the versions verified together. Runtime dependencies declare only the minimum API version needed by the library; update the lockfile and run the gates when changing dependencies.
|
|
272
|
+
|
|
273
|
+
|
|
255
274
|
Pull requests and pushes to `master` run RSpec, documentation coverage, RuboCop, whitespace checks, and a built-Gem install smoke test. A `v<gem-version>` tag repeats the project gate, validates the tag/version, builds and installs a release candidate, then publishes that exact file through RubyGems Trusted Publishing. Configure the RubyGems trusted publisher for repository `gatework/zabbix_manager`, workflow `release.yml`, and environment `release` before pushing a release tag.
|
|
256
275
|
|
|
257
276
|
## Zabbix documentation
|
|
@@ -261,3 +280,7 @@ Pull requests and pushes to `master` run RSpec, documentation coverage, RuboCop,
|
|
|
261
280
|
|
|
262
281
|
[Zabbix]: https://www.zabbix.com
|
|
263
282
|
[Zabbix API]: https://www.zabbix.com/documentation/current/en/manual/api
|
|
283
|
+
|
|
284
|
+
### Upgrading to 6.0
|
|
285
|
+
|
|
286
|
+
Version 6.0 requires Ruby 3.4 or newer. Use keyword connection and query arguments, snake_case resource accessors, the explicit exception classes, and the current monitoring result shapes shown above. Legacy aliases and the former `Basic` API are removed.
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class ZabbixManager
|
|
4
|
-
|
|
4
|
+
# 告警动作资源;完整读取包含执行、恢复、确认操作及过滤条件。
|
|
5
|
+
class Actions < Resource
|
|
5
6
|
# 返回操作对象对应的 Zabbix API 方法前缀。
|
|
6
7
|
#
|
|
7
8
|
# @return [String]
|
|
@@ -9,22 +10,13 @@ class ZabbixManager
|
|
|
9
10
|
"action"
|
|
10
11
|
end
|
|
11
12
|
|
|
12
|
-
# 返回操作对象用于业务识别的字段名。
|
|
13
|
-
#
|
|
14
|
-
# @return [String]
|
|
15
|
-
def identify
|
|
16
|
-
"name"
|
|
17
|
-
end
|
|
18
|
-
|
|
19
13
|
# 获取操作及其执行、恢复、确认操作和过滤条件的完整数据。
|
|
20
14
|
#
|
|
21
15
|
# @param data [Hash] 包含识别字段及其值的查询条件
|
|
22
16
|
# @raise [ApiError] Zabbix API 返回业务错误时抛出
|
|
23
17
|
# @raise [TransportError] Zabbix 服务端返回非成功 HTTP 状态时抛出
|
|
24
|
-
# @return [Hash] 匹配的操作完整数据
|
|
18
|
+
# @return [Array<Hash>] 匹配的操作完整数据
|
|
25
19
|
def get_full_data(data)
|
|
26
|
-
log "[DEBUG] Call get_full_data with parameters: #{data.inspect}"
|
|
27
|
-
|
|
28
20
|
@client.api_request(
|
|
29
21
|
method: "#{method_name}.get",
|
|
30
22
|
params: {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class ZabbixManager
|
|
4
|
-
|
|
4
|
+
# 应用集以 hostid + name 定位;端点是否可用由目标 Zabbix 版本决定。
|
|
5
|
+
class Applications < Resource
|
|
5
6
|
# 返回应用集对象对应的 Zabbix API 方法前缀。
|
|
6
7
|
#
|
|
7
8
|
# @return [String]
|
|
@@ -9,13 +10,6 @@ class ZabbixManager
|
|
|
9
10
|
"application"
|
|
10
11
|
end
|
|
11
12
|
|
|
12
|
-
# 返回应用集对象用于业务识别的字段名。
|
|
13
|
-
#
|
|
14
|
-
# @return [String]
|
|
15
|
-
def identify
|
|
16
|
-
"name"
|
|
17
|
-
end
|
|
18
|
-
|
|
19
13
|
# 生成由应用集名称和所属主机构成的稳定查询条件。
|
|
20
14
|
# @param data [Hash] 包含 name 和 hostid 的应用集属性
|
|
21
15
|
# @return [Hash] 应用集唯一查询条件
|
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class ZabbixManager
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
# @return [Boolean] 始终返回 true
|
|
7
|
-
def array_flag
|
|
8
|
-
true
|
|
9
|
-
end
|
|
10
|
-
|
|
4
|
+
# 原生配置导入/导出入口;导入可能修改多个远端对象,不提供本地回滚。
|
|
5
|
+
class Configurations < Resource
|
|
11
6
|
# 返回配置对象对应的 Zabbix API 方法前缀。
|
|
12
7
|
#
|
|
13
8
|
# @return [String]
|
|
@@ -27,7 +22,7 @@ class ZabbixManager
|
|
|
27
22
|
# @param data [Hash] 配置导出参数
|
|
28
23
|
# @raise [ApiError] Zabbix API 返回业务错误时抛出
|
|
29
24
|
# @raise [TransportError] Zabbix 服务端返回非成功 HTTP 状态时抛出
|
|
30
|
-
# @return [
|
|
25
|
+
# @return [String] 服务端按指定格式序列化的配置内容
|
|
31
26
|
def export(data)
|
|
32
27
|
@client.api_request(method: "configuration.export", params: data)
|
|
33
28
|
end
|
|
@@ -37,7 +32,7 @@ class ZabbixManager
|
|
|
37
32
|
# @param data [Hash] 配置导入参数及内容
|
|
38
33
|
# @raise [ApiError] Zabbix API 返回业务错误时抛出
|
|
39
34
|
# @raise [TransportError] Zabbix 服务端返回非成功 HTTP 状态时抛出
|
|
40
|
-
# @return [
|
|
35
|
+
# @return [Boolean] 服务端确认的导入结果
|
|
41
36
|
def import(data)
|
|
42
37
|
@client.api_request(method: "configuration.import", params: data)
|
|
43
38
|
end
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class ZabbixManager
|
|
4
|
-
|
|
4
|
+
# 网络发现规则(drule),区别于主机内的低级发现(discoveryrule)。
|
|
5
|
+
class DiscoveryRules < Resource
|
|
5
6
|
# 返回网络发现规则对应的 Zabbix API 方法前缀。
|
|
6
7
|
#
|
|
7
8
|
# @return [String]
|
|
@@ -9,13 +10,6 @@ class ZabbixManager
|
|
|
9
10
|
"drule"
|
|
10
11
|
end
|
|
11
12
|
|
|
12
|
-
# 返回网络发现规则用于业务识别的字段名。
|
|
13
|
-
#
|
|
14
|
-
# @return [String]
|
|
15
|
-
def identify
|
|
16
|
-
"name"
|
|
17
|
-
end
|
|
18
|
-
|
|
19
13
|
# 返回创建网络发现规则时使用的默认周期和启用状态。
|
|
20
14
|
#
|
|
21
15
|
# @return [Hash] 网络发现规则默认属性
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class ZabbixManager
|
|
4
|
-
|
|
4
|
+
# 图形以 hostid + name 查询;写入所有者由 gitems 中的监控项确定。
|
|
5
|
+
class Graphs < Resource
|
|
5
6
|
# 返回图形对象对应的 Zabbix API 方法前缀。
|
|
6
7
|
#
|
|
7
8
|
# @return [String]
|
|
@@ -9,22 +10,13 @@ class ZabbixManager
|
|
|
9
10
|
"graph"
|
|
10
11
|
end
|
|
11
12
|
|
|
12
|
-
# 返回图形对象用于业务识别的字段名。
|
|
13
|
-
#
|
|
14
|
-
# @return [String]
|
|
15
|
-
def identify
|
|
16
|
-
"name"
|
|
17
|
-
end
|
|
18
|
-
|
|
19
13
|
# 按名称搜索并获取图形的完整数据。
|
|
20
14
|
#
|
|
21
15
|
# @param data [Hash] 包含图形识别字段及其值的查询条件
|
|
22
16
|
# @raise [ApiError] Zabbix API 返回业务错误时抛出
|
|
23
17
|
# @raise [TransportError] Zabbix 服务端返回非成功 HTTP 状态时抛出
|
|
24
|
-
# @return [Hash] 匹配的图形完整数据
|
|
18
|
+
# @return [Array<Hash>] 匹配的图形完整数据
|
|
25
19
|
def get_full_data(data)
|
|
26
|
-
log "[DEBUG] Call get_full_data with parameters: #{data.inspect}"
|
|
27
|
-
|
|
28
20
|
@client.api_request(
|
|
29
21
|
method: "#{method_name}.get",
|
|
30
22
|
params: {
|
|
@@ -67,7 +59,7 @@ class ZabbixManager
|
|
|
67
59
|
# @param data [Hash, String, Integer] 图形 ID
|
|
68
60
|
# @raise [ApiError] Zabbix API 返回业务错误时抛出
|
|
69
61
|
# @raise [TransportError] Zabbix 服务端返回非成功 HTTP 状态时抛出
|
|
70
|
-
# @return [Hash] 图形监控项数据
|
|
62
|
+
# @return [Array<Hash>] 图形监控项数据
|
|
71
63
|
def get_items(data)
|
|
72
64
|
@client.api_request(
|
|
73
65
|
method: "graphitem.get",
|
|
@@ -78,12 +70,24 @@ class ZabbixManager
|
|
|
78
70
|
)
|
|
79
71
|
end
|
|
80
72
|
|
|
81
|
-
#
|
|
82
|
-
#
|
|
73
|
+
# 生成由图形名称和所属主机或模板构成的稳定查询条件。
|
|
74
|
+
# graph.templateid 是继承源图形 ID,不是所属模板 ID。
|
|
75
|
+
# @param data [Hash] 包含 name 和 hostid 的图形属性
|
|
83
76
|
# @return [Hash] 图形唯一查询条件
|
|
84
77
|
def identity_filter(data)
|
|
85
78
|
attributes = data.deep_symbolize_keys
|
|
86
|
-
{ name: attributes.fetch(:name),
|
|
79
|
+
{ name: attributes.fetch(:name), hostid: attributes.fetch(:hostid) }
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# 图形所有者由 gitems 确定,hostid 仅用于调用方的身份查询。
|
|
83
|
+
# @return [Integer, nil]
|
|
84
|
+
def create(data)
|
|
85
|
+
super(data.deep_symbolize_keys.except(:hostid))
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# @return [Integer, nil] 更新的图形 ID
|
|
89
|
+
def update(data)
|
|
90
|
+
super(data.deep_symbolize_keys.except(:hostid))
|
|
87
91
|
end
|
|
88
92
|
end
|
|
89
93
|
end
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class ZabbixManager
|
|
4
|
-
|
|
4
|
+
# 主机群组名称解析与按需创建;批量创建按顺序执行,不是远端事务。
|
|
5
|
+
class HostGroups < Resource
|
|
5
6
|
# 返回主机群组对应的 Zabbix API 方法前缀。
|
|
6
7
|
#
|
|
7
8
|
# @return [String]
|
|
@@ -9,13 +10,6 @@ class ZabbixManager
|
|
|
9
10
|
"hostgroup"
|
|
10
11
|
end
|
|
11
12
|
|
|
12
|
-
# 返回主机群组用于业务识别的字段名。
|
|
13
|
-
#
|
|
14
|
-
# @return [String]
|
|
15
|
-
def identify
|
|
16
|
-
"name"
|
|
17
|
-
end
|
|
18
|
-
|
|
19
13
|
# 返回主机群组的 Zabbix ID 字段名。
|
|
20
14
|
#
|
|
21
15
|
# @return [String]
|
|
@@ -44,7 +38,7 @@ class ZabbixManager
|
|
|
44
38
|
# 批量查询并创建缺失的主机群组,避免逐名称重复查询。
|
|
45
39
|
# @param data [Array<String>, String] 待确保存在的群组名称
|
|
46
40
|
# @return [Array<Hash>] 群组 ID 列表
|
|
47
|
-
def
|
|
41
|
+
def get_or_create_host_groups(data)
|
|
48
42
|
names = normalized_names(data)
|
|
49
43
|
existing = @client.api_request(
|
|
50
44
|
method: "hostgroup.get",
|
|
@@ -53,10 +47,10 @@ class ZabbixManager
|
|
|
53
47
|
|
|
54
48
|
names.map do |name|
|
|
55
49
|
group = existing[name]
|
|
56
|
-
next({ groupid: group
|
|
50
|
+
next({ groupid: response_identifier(group["groupid"]).to_s }) if group
|
|
57
51
|
|
|
58
52
|
result = @client.api_request(method: "hostgroup.create", params: { name: name })
|
|
59
|
-
{ groupid: result
|
|
53
|
+
{ groupid: response_id(result).to_s }
|
|
60
54
|
end
|
|
61
55
|
end
|
|
62
56
|
|