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
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class ZabbixManager
|
|
4
|
-
|
|
4
|
+
# 监控项查询与写入;通用 CRUD 使用名称,专用 upsert 使用 hostid + key_。
|
|
5
|
+
class Items < Resource
|
|
5
6
|
DEFAULT_OPTIONS = {
|
|
6
7
|
delay: "1m",
|
|
7
8
|
history: "1h",
|
|
@@ -19,13 +20,6 @@ class ZabbixManager
|
|
|
19
20
|
"item"
|
|
20
21
|
end
|
|
21
22
|
|
|
22
|
-
# 使用名称作为通用 CRUD 的业务标识。
|
|
23
|
-
#
|
|
24
|
-
# @return [String]
|
|
25
|
-
def identify
|
|
26
|
-
"name"
|
|
27
|
-
end
|
|
28
|
-
|
|
29
23
|
# 返回创建监控项时的克制默认值。
|
|
30
24
|
#
|
|
31
25
|
# @return [Hash]
|
|
@@ -35,10 +29,10 @@ class ZabbixManager
|
|
|
35
29
|
|
|
36
30
|
# 使用主机和名称组成通用 CRUD 的查询边界。
|
|
37
31
|
#
|
|
38
|
-
# @param data [Hash]
|
|
39
|
-
# @raise [ApiError]
|
|
40
|
-
# @raise [TransportError]
|
|
41
|
-
# @return [
|
|
32
|
+
# @param data [Hash] 包含 name 和 hostid 的监控项属性
|
|
33
|
+
# @raise [ApiError] Zabbix API 明确返回业务错误
|
|
34
|
+
# @raise [TransportError] HTTP 或网络请求失败,可能无法确认远端结果
|
|
35
|
+
# @return [Hash] 名称和所属主机组成的精确过滤条件
|
|
42
36
|
def identity_filter(data)
|
|
43
37
|
attributes = data.deep_symbolize_keys
|
|
44
38
|
{ name: attributes.fetch(:name), hostid: attributes.fetch(:hostid) }
|
|
@@ -59,7 +53,7 @@ class ZabbixManager
|
|
|
59
53
|
# 按主机和稳定 key 查询唯一监控项。
|
|
60
54
|
# @return [Hash, nil]
|
|
61
55
|
def find_by_key(hostid:, key:)
|
|
62
|
-
result = for_host(hostid, keys: key, output:
|
|
56
|
+
result = for_host(hostid, keys: key, output: "extend", select_preprocessing: "extend")
|
|
63
57
|
raise Conflict, "multiple items use key #{key} on host #{hostid}" if result.length > 1
|
|
64
58
|
|
|
65
59
|
result.first
|
|
@@ -68,25 +62,11 @@ class ZabbixManager
|
|
|
68
62
|
# 按 hostid + key_ 幂等创建或更新监控项。
|
|
69
63
|
# @return [Integer]
|
|
70
64
|
def upsert_by_key(data)
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
current = find_by_key(hostid: attributes[:hostid], key: attributes[:key_])
|
|
74
|
-
if current
|
|
75
|
-
itemid = current.fetch("itemid")
|
|
76
|
-
@client.api_request(
|
|
77
|
-
method: "item.update",
|
|
78
|
-
params: attributes.except(:hostid).merge(itemid: itemid)
|
|
79
|
-
)
|
|
80
|
-
itemid.to_i
|
|
81
|
-
else
|
|
82
|
-
create_attributes = default_options.merge(attributes)
|
|
83
|
-
validate_create_item!(create_attributes)
|
|
84
|
-
result = @client.api_request(method: "item.create", params: create_attributes)
|
|
85
|
-
result.fetch("itemids").first.to_i
|
|
86
|
-
end
|
|
65
|
+
apply_item(*plan_item(validate_item!(data)))
|
|
87
66
|
end
|
|
88
67
|
|
|
89
68
|
# 先校验整批数据,再按稳定 key 逐项幂等写入。
|
|
69
|
+
# @yieldparam effective [Array<Hash>] 合并已有配置或创建默认值后的有效属性;块失败时不写入
|
|
90
70
|
# @return [Array<Integer>]
|
|
91
71
|
def upsert_many(collection)
|
|
92
72
|
items = Array(collection).map { |data| validate_item!(data) }
|
|
@@ -94,28 +74,40 @@ class ZabbixManager
|
|
|
94
74
|
duplicate = identities.tally.find { |_identity, count| count > 1 }&.first
|
|
95
75
|
raise Invalid, "duplicate hostid + key_ identity #{duplicate.join(":")}" if duplicate
|
|
96
76
|
|
|
97
|
-
items.map { |item|
|
|
77
|
+
plans = items.map { |item| plan_item(item) }
|
|
78
|
+
if block_given?
|
|
79
|
+
effective = plans.map do |attributes, current|
|
|
80
|
+
if current && !%w[type value_type].all? { |field| current.key?(field) }
|
|
81
|
+
raise ProtocolError, "item.get must include type and value_type for effective configuration validation"
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
current ? current.deep_symbolize_keys.merge(attributes).deep_dup : attributes.deep_dup
|
|
85
|
+
end
|
|
86
|
+
yield effective
|
|
87
|
+
end
|
|
88
|
+
plans.map { |attributes, current| apply_item(attributes, current) }
|
|
98
89
|
end
|
|
99
90
|
|
|
100
91
|
# 批量启用或停用监控项。
|
|
101
92
|
# @return [Array<Integer>]
|
|
102
93
|
def set_status(hostid:, itemids:, enabled:)
|
|
103
|
-
|
|
94
|
+
validate_boolean!(enabled, "enabled")
|
|
95
|
+
ids = normalized_ids(itemids)
|
|
104
96
|
verify_host_ownership!(hostid, ids)
|
|
105
97
|
result = @client.api_request(
|
|
106
98
|
method: "item.update",
|
|
107
99
|
params: ids.map { |itemid| { itemid: itemid, status: enabled ? 0 : 1 } }
|
|
108
100
|
)
|
|
109
|
-
|
|
101
|
+
response_ids(result, expected: ids)
|
|
110
102
|
end
|
|
111
103
|
|
|
112
104
|
# 批量删除明确指定的监控项。
|
|
113
105
|
# @return [Array<Integer>]
|
|
114
106
|
def delete_many(hostid:, itemids:)
|
|
115
|
-
ids = normalized_ids(itemids
|
|
107
|
+
ids = normalized_ids(itemids)
|
|
116
108
|
verify_host_ownership!(hostid, ids)
|
|
117
109
|
result = @client.api_request(method: "item.delete", params: ids)
|
|
118
|
-
|
|
110
|
+
response_ids(result, expected: ids)
|
|
119
111
|
end
|
|
120
112
|
|
|
121
113
|
# 返回主机中可能表示接口流量的已启用监控项。
|
|
@@ -127,7 +119,7 @@ class ZabbixManager
|
|
|
127
119
|
params: {
|
|
128
120
|
hostids: [hostid],
|
|
129
121
|
monitored: true,
|
|
130
|
-
output: %w[itemid hostid name key_ snmp_oid value_type status units],
|
|
122
|
+
output: %w[itemid hostid name key_ type snmp_oid value_type status units],
|
|
131
123
|
selectPreprocessing: "extend",
|
|
132
124
|
sortfield: "name",
|
|
133
125
|
sortorder: "ASC"
|
|
@@ -143,7 +135,7 @@ class ZabbixManager
|
|
|
143
135
|
raise Invalid, "dns_name is required" if name.blank?
|
|
144
136
|
raise Invalid, "dns_name contains unsupported item key delimiters" if name.match?(/[\[\],]/)
|
|
145
137
|
|
|
146
|
-
|
|
138
|
+
upsert_by_key(
|
|
147
139
|
hostid: hostid,
|
|
148
140
|
interfaceid: interfaceid,
|
|
149
141
|
name: "【DNS域名解析监控】#{name}",
|
|
@@ -154,72 +146,84 @@ class ZabbixManager
|
|
|
154
146
|
history: "90d",
|
|
155
147
|
timeout: "3s"
|
|
156
148
|
)
|
|
157
|
-
log "Ensured DNS monitoring item for #{name}"
|
|
158
|
-
itemid
|
|
159
|
-
rescue StandardError => e
|
|
160
|
-
log "Failed to ensure DNS monitoring item: #{e.class}"
|
|
161
|
-
raise
|
|
162
149
|
end
|
|
163
150
|
|
|
164
151
|
private
|
|
165
152
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
153
|
+
# 创建必填字段必须在整批写入开始前校验。
|
|
154
|
+
def plan_item(attributes)
|
|
155
|
+
current = find_by_key(hostid: attributes[:hostid], key: attributes[:key_])
|
|
156
|
+
validate_item_type!(attributes[:type]) if attributes.key?(:type)
|
|
157
|
+
response_identifier(current["itemid"]) if current
|
|
158
|
+
unless current
|
|
159
|
+
attributes = default_options.merge(attributes)
|
|
160
|
+
validate_create_item!(attributes)
|
|
161
|
+
end
|
|
162
|
+
[attributes, current]
|
|
163
|
+
end
|
|
174
164
|
|
|
175
|
-
|
|
165
|
+
def apply_item(attributes, current)
|
|
166
|
+
if current
|
|
167
|
+
itemid = current.fetch("itemid")
|
|
168
|
+
result = @client.api_request(method: "item.update", params: attributes.except(:hostid).merge(itemid: itemid))
|
|
169
|
+
response_id(result, expected: [itemid])
|
|
170
|
+
else
|
|
171
|
+
result = @client.api_request(method: "item.create", params: attributes)
|
|
172
|
+
response_id(result)
|
|
176
173
|
end
|
|
174
|
+
end
|
|
177
175
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
176
|
+
# 规范化并校验幂等写入所需字段。
|
|
177
|
+
# @return [Hash]
|
|
178
|
+
# @api private
|
|
179
|
+
def validate_item!(data)
|
|
180
|
+
attributes = data.deep_symbolize_keys
|
|
181
|
+
raise Invalid, "hostid is required" if attributes[:hostid].blank?
|
|
182
|
+
raise Invalid, "key_ is required" if attributes[:key_].blank?
|
|
183
|
+
raise Invalid, "name is required" if attributes[:name].blank?
|
|
182
184
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
+
attributes
|
|
186
|
+
end
|
|
185
187
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
raise Invalid, "params is required for item type #{type}"
|
|
191
|
-
end
|
|
188
|
+
# 校验 item.create 的通用必填字段和 SNMP 条件字段。
|
|
189
|
+
def validate_create_item!(attributes)
|
|
190
|
+
raise Invalid, "type is required when creating an item" if attributes[:type].blank?
|
|
191
|
+
raise Invalid, "value_type is required when creating an item" if attributes[:value_type].blank?
|
|
192
192
|
|
|
193
|
-
|
|
194
|
-
"master_itemid is required for a dependent item" if type == 18 && attributes[:master_itemid].blank?
|
|
195
|
-
raise Invalid, "url is required for an HTTP item" if type == 19 && attributes[:url].blank?
|
|
196
|
-
return unless type == 20
|
|
193
|
+
type = validate_item_type!(attributes[:type])
|
|
197
194
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
195
|
+
if REQUIRED_INTERFACE_TYPES.include?(type) && attributes[:interfaceid].blank?
|
|
196
|
+
raise Invalid, "interfaceid is required for item type #{type}"
|
|
197
|
+
end
|
|
198
|
+
if REQUIRED_PARAMS_TYPES.include?(type) && attributes[:params].blank?
|
|
199
|
+
raise Invalid, "params is required for item type #{type}"
|
|
201
200
|
end
|
|
202
201
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
202
|
+
raise Invalid,
|
|
203
|
+
"master_itemid is required for a dependent item" if type == 18 && attributes[:master_itemid].blank?
|
|
204
|
+
raise Invalid, "url is required for an HTTP item" if type == 19 && attributes[:url].blank?
|
|
205
|
+
return unless type == 20
|
|
206
206
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
)
|
|
210
|
-
owned_ids = result.map { |item| item.fetch("itemid").to_s }
|
|
211
|
-
foreign_ids = ids - owned_ids
|
|
212
|
-
raise Conflict, "items do not belong to host #{hostid}: #{foreign_ids.join(", ")}" if foreign_ids.any?
|
|
213
|
-
end
|
|
207
|
+
raise Invalid, "snmp_oid is required for an SNMP item" if attributes[:snmp_oid].blank?
|
|
208
|
+
end
|
|
214
209
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
#
|
|
218
|
-
def normalized_ids(values, name)
|
|
219
|
-
ids = Array(values).filter_map { |value| value.to_s.strip.presence }.uniq
|
|
220
|
-
raise Invalid, "#{name} are required" if ids.empty?
|
|
210
|
+
def validate_item_type!(value)
|
|
211
|
+
type = integer_attribute(value, "type")
|
|
212
|
+
raise Invalid, "unsupported item type #{type}" unless ITEM_TYPES.include?(type)
|
|
221
213
|
|
|
222
|
-
|
|
223
|
-
|
|
214
|
+
type
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
# 回查监控项归属,阻止共享高权限令牌跨主机修改。
|
|
218
|
+
def verify_host_ownership!(hostid, ids)
|
|
219
|
+
raise Invalid, "hostid is required" if hostid.blank?
|
|
220
|
+
|
|
221
|
+
result = @client.api_request(
|
|
222
|
+
method: "item.get", params: { hostids: hostid, itemids: ids, output: ["itemid"] }
|
|
223
|
+
)
|
|
224
|
+
owned_ids = result.map { |item| item.fetch("itemid").to_s }
|
|
225
|
+
foreign_ids = ids - owned_ids
|
|
226
|
+
raise Conflict, "items do not belong to host #{hostid}: #{foreign_ids.join(", ")}" if foreign_ids.any?
|
|
227
|
+
end
|
|
224
228
|
end
|
|
225
229
|
end
|
|
@@ -1,19 +1,14 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class ZabbixManager
|
|
4
|
-
|
|
4
|
+
# 原生通知媒介资源;仅提供最小默认值,不推断端点、凭据或版本字段。
|
|
5
|
+
class MediaTypes < Resource
|
|
5
6
|
# 返回媒介类型对象对应的 Zabbix API 方法前缀。
|
|
6
7
|
# @return [String] API 方法前缀
|
|
7
8
|
def method_name
|
|
8
9
|
"mediatype"
|
|
9
10
|
end
|
|
10
11
|
|
|
11
|
-
# 返回媒介类型用于业务识别的字段名。
|
|
12
|
-
# @return [String] 识别字段名
|
|
13
|
-
def identify
|
|
14
|
-
"name"
|
|
15
|
-
end
|
|
16
|
-
|
|
17
12
|
# 返回媒介类型的最小默认属性;端点和凭据等版本相关字段由调用方显式提供。
|
|
18
13
|
# @return [Hash] 媒介类型默认属性
|
|
19
14
|
def default_options
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class ZabbixManager
|
|
4
|
-
|
|
4
|
+
# 原生问题查询与事件确认;问题身份使用 eventid,确认动作属于远端写入。
|
|
5
|
+
class Problems < Resource
|
|
5
6
|
# 返回问题对象对应的 Zabbix API 方法前缀。
|
|
6
7
|
#
|
|
7
8
|
# @return [String]
|
|
@@ -9,45 +10,18 @@ class ZabbixManager
|
|
|
9
10
|
"problem"
|
|
10
11
|
end
|
|
11
12
|
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
# @return [String]
|
|
15
|
-
def identify
|
|
16
|
-
"name"
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
# 返回问题对象的兼容 ID 字段名;问题对象本身没有独立的唯一标识。
|
|
13
|
+
# 使用触发问题的事件 ID 作为对象身份。
|
|
20
14
|
#
|
|
21
15
|
# @return [String]
|
|
22
16
|
def key
|
|
23
|
-
"
|
|
17
|
+
"eventid"
|
|
24
18
|
end
|
|
25
19
|
|
|
26
|
-
#
|
|
20
|
+
# 返回事件 ID 集合字段名。
|
|
27
21
|
#
|
|
28
22
|
# @return [String]
|
|
29
23
|
def keys
|
|
30
|
-
"
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
# 按识别字段查询问题对象的完整数据。
|
|
34
|
-
#
|
|
35
|
-
# @param data [Hash] 包含问题识别字段及其值的查询条件
|
|
36
|
-
# @raise [ApiError] Zabbix API 返回业务错误时抛出
|
|
37
|
-
# @raise [TransportError] Zabbix 服务端返回非成功 HTTP 状态时抛出
|
|
38
|
-
# @return [Hash] 匹配的问题数据
|
|
39
|
-
def dump_by_id(data)
|
|
40
|
-
log "[DEBUG] Call dump_by_id with parameters: #{data.inspect}"
|
|
41
|
-
|
|
42
|
-
@client.api_request(
|
|
43
|
-
method: "problem.get",
|
|
44
|
-
params: {
|
|
45
|
-
filter: {
|
|
46
|
-
identify.to_sym => data[identify.to_sym]
|
|
47
|
-
},
|
|
48
|
-
output: "extend"
|
|
49
|
-
}
|
|
50
|
-
)
|
|
24
|
+
"eventids"
|
|
51
25
|
end
|
|
52
26
|
|
|
53
27
|
# 获取问题及其确认、标签和抑制信息,并支持附加查询参数。
|
|
@@ -55,10 +29,8 @@ class ZabbixManager
|
|
|
55
29
|
# @param data [Hash] 问题过滤条件及附加 API 参数
|
|
56
30
|
# @raise [ApiError] Zabbix API 返回业务错误时抛出
|
|
57
31
|
# @raise [TransportError] Zabbix 服务端返回非成功 HTTP 状态时抛出
|
|
58
|
-
# @return [Hash] 匹配的问题完整数据
|
|
32
|
+
# @return [Array<Hash>] 匹配的问题完整数据
|
|
59
33
|
def get_full_data(data)
|
|
60
|
-
log "[DEBUG] Call get_full_data with parameters: #{data.inspect}"
|
|
61
|
-
|
|
62
34
|
data = data.deep_symbolize_keys
|
|
63
35
|
params = {
|
|
64
36
|
recent: false,
|
|
@@ -92,15 +64,14 @@ class ZabbixManager
|
|
|
92
64
|
# @param message [String, nil] 可选确认消息
|
|
93
65
|
# @return [Hash] 事件确认结果
|
|
94
66
|
def acknowledge_events(eventids, action: 2, message: nil)
|
|
95
|
-
ids =
|
|
96
|
-
raise Invalid, "eventids are required" if ids.empty?
|
|
67
|
+
ids = normalized_ids(eventids)
|
|
97
68
|
|
|
98
|
-
@client.api_request(
|
|
69
|
+
result = @client.api_request(
|
|
99
70
|
method: "event.acknowledge",
|
|
100
71
|
params: { eventids: ids, action: action, message: message }.compact
|
|
101
72
|
)
|
|
73
|
+
response_ids(result, expected: ids)
|
|
74
|
+
result
|
|
102
75
|
end
|
|
103
|
-
|
|
104
|
-
alias ack_event acknowledge_events
|
|
105
76
|
end
|
|
106
77
|
end
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class ZabbixManager
|
|
4
|
-
|
|
4
|
+
# 原生代理资源;按服务器版本选择 name 或 host 作为名称字段。
|
|
5
|
+
class Proxies < Resource
|
|
5
6
|
# 返回 Zabbix API 中代理对象的方法名前缀。
|
|
6
7
|
#
|
|
7
8
|
# @return [String] 代理对象的方法名前缀
|
|
@@ -13,18 +14,7 @@ class ZabbixManager
|
|
|
13
14
|
#
|
|
14
15
|
# @return [String] 代理对象的标识字段名
|
|
15
16
|
def identify
|
|
16
|
-
"host"
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
# 通过 Zabbix API 删除指定代理,并返回首个已删除代理的 ID。
|
|
20
|
-
#
|
|
21
|
-
# @param data [Array] 要删除的 proxyid 数组
|
|
22
|
-
# @raise [ApiError] Zabbix API 返回业务错误时抛出
|
|
23
|
-
# @raise [TransportError] Zabbix 服务返回非成功 HTTP 状态时抛出
|
|
24
|
-
# @return [Integer, nil] 已删除代理的 ID,无结果时返回 nil
|
|
25
|
-
def delete(data)
|
|
26
|
-
result = @client.api_request(method: "proxy.delete", params: data)
|
|
27
|
-
result.empty? ? nil : result["proxyids"][0].to_i
|
|
17
|
+
Gem::Version.new(@client.api_version) >= Gem::Version.new("7.0") ? "name" : "host"
|
|
28
18
|
end
|
|
29
19
|
|
|
30
20
|
# 检查当前凭证是否可读取指定代理。
|
|
@@ -58,9 +48,9 @@ class ZabbixManager
|
|
|
58
48
|
result = @client.api_request(
|
|
59
49
|
method: "proxy.get",
|
|
60
50
|
params: {
|
|
61
|
-
output:
|
|
51
|
+
output: ["proxyid", identify],
|
|
62
52
|
filter: {
|
|
63
|
-
|
|
53
|
+
identify.to_sym => proxy
|
|
64
54
|
}
|
|
65
55
|
}
|
|
66
56
|
)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class ZabbixManager
|
|
4
|
+
# Zabbix 7.0 起提供的原生代理组资源。
|
|
5
|
+
class ProxyGroups < Resource
|
|
6
|
+
# @return [String] 原生 API 方法前缀
|
|
7
|
+
def method_name
|
|
8
|
+
"proxygroup"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# @return [String] 原生代理组 ID 字段
|
|
12
|
+
def key
|
|
13
|
+
"proxy_groupid"
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class ZabbixManager
|
|
4
|
-
|
|
4
|
+
# 角色查询与权限规则更新;权限内容由调用方定义,服务端负责权限校验。
|
|
5
|
+
class Roles < Resource
|
|
5
6
|
# 返回 Zabbix API 中角色对象的方法名前缀。
|
|
6
7
|
#
|
|
7
8
|
# @return [String] 角色对象的方法名前缀
|
|
@@ -9,20 +10,6 @@ class ZabbixManager
|
|
|
9
10
|
"role"
|
|
10
11
|
end
|
|
11
12
|
|
|
12
|
-
# 返回角色对象的主键字段名。
|
|
13
|
-
#
|
|
14
|
-
# @return [String] 角色对象的主键字段名
|
|
15
|
-
def key
|
|
16
|
-
"roleid"
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
# 返回用于唯一识别角色的业务字段名。
|
|
20
|
-
#
|
|
21
|
-
# @return [String] 角色对象的业务标识字段名
|
|
22
|
-
def identify
|
|
23
|
-
"name"
|
|
24
|
-
end
|
|
25
|
-
|
|
26
13
|
# 更新指定角色的权限规则。
|
|
27
14
|
#
|
|
28
15
|
# @param data [Hash] 包含 roleid 和 rules 的角色规则数据
|
|
@@ -34,6 +21,8 @@ class ZabbixManager
|
|
|
34
21
|
raise Invalid, "roleid is required" if attributes[:roleid].blank?
|
|
35
22
|
raise Invalid, "rules is required" if attributes[:rules].blank?
|
|
36
23
|
|
|
24
|
+
normalized_ids([attributes[:roleid]])
|
|
25
|
+
|
|
37
26
|
result = @client.api_request(
|
|
38
27
|
method: "role.update",
|
|
39
28
|
params: {
|
|
@@ -41,24 +30,29 @@ class ZabbixManager
|
|
|
41
30
|
rules: attributes[:rules]
|
|
42
31
|
}
|
|
43
32
|
)
|
|
44
|
-
result
|
|
33
|
+
response_id(result, expected: [attributes[:roleid]])
|
|
45
34
|
end
|
|
46
35
|
|
|
47
36
|
# 按角色 ID 获取角色详情及完整规则。
|
|
48
37
|
#
|
|
49
|
-
# @param data [Hash] 包含 id
|
|
38
|
+
# @param data [Hash] 包含 roleid 的查询参数;旧 id 引用仍可使用,但不得矛盾
|
|
50
39
|
# @raise [ApiError] Zabbix API 返回业务错误时抛出
|
|
51
40
|
# @raise [TransportError] Zabbix 服务返回非成功 HTTP 状态时抛出
|
|
52
41
|
# @return [Array<Hash>] 匹配的角色详情
|
|
53
42
|
def dump_by_id(data)
|
|
54
|
-
|
|
43
|
+
attributes = data.deep_symbolize_keys
|
|
44
|
+
if attributes.key?(:roleid) && attributes.key?(:id) &&
|
|
45
|
+
normalized_ids([attributes[:roleid]]) != normalized_ids([attributes[:id]])
|
|
46
|
+
raise Invalid, "roleid and id disagree"
|
|
47
|
+
end
|
|
55
48
|
|
|
49
|
+
id = normalized_ids([attributes.fetch(:roleid) { attributes[:id] }]).first
|
|
56
50
|
@client.api_request(
|
|
57
51
|
method: "role.get",
|
|
58
52
|
params: {
|
|
59
53
|
output: "extend",
|
|
60
54
|
selectRules: "extend",
|
|
61
|
-
roleids:
|
|
55
|
+
roleids: id
|
|
62
56
|
}
|
|
63
57
|
)
|
|
64
58
|
end
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class ZabbixManager
|
|
4
|
-
|
|
4
|
+
# 旧版聚合图形的网格创建入口;目标服务器须提供 screen API。
|
|
5
|
+
class Screens < Resource
|
|
5
6
|
# 以下资源类型取自 frontends/php/include/defines.inc.php。
|
|
6
7
|
# SCREEN_RESOURCE_GRAPH => 0,
|
|
7
8
|
# SCREEN_RESOURCE_SIMPLE_GRAPH => 1,
|
|
@@ -28,24 +29,6 @@ class ZabbixManager
|
|
|
28
29
|
"screen"
|
|
29
30
|
end
|
|
30
31
|
|
|
31
|
-
# 返回用于唯一识别聚合图形的业务字段名。
|
|
32
|
-
#
|
|
33
|
-
# @return [String] 聚合图形的业务标识字段名
|
|
34
|
-
def identify
|
|
35
|
-
"name"
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
# 删除指定聚合图形并返回首个已删除对象的 ID。
|
|
39
|
-
#
|
|
40
|
-
# @param data [String, Array] 要删除的聚合图形 ID
|
|
41
|
-
# @raise [ApiError] Zabbix API 返回业务错误时抛出
|
|
42
|
-
# @raise [TransportError] Zabbix 服务返回非成功 HTTP 状态时抛出
|
|
43
|
-
# @return [Integer, nil] 已删除聚合图形的 ID,无结果时返回 nil
|
|
44
|
-
def delete(data)
|
|
45
|
-
result = @client.api_request(method: "screen.delete", params: [data])
|
|
46
|
-
result.empty? ? nil : result["screenids"][0].to_i
|
|
47
|
-
end
|
|
48
|
-
|
|
49
32
|
# 按名称获取聚合图形,不存在时按图形 ID 网格化创建。
|
|
50
33
|
#
|
|
51
34
|
# @param data [Hash] 包含 screen_name、graphids 及可选布局参数
|
|
@@ -97,17 +80,15 @@ class ZabbixManager
|
|
|
97
80
|
|
|
98
81
|
private
|
|
99
82
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
83
|
+
# 将横向格数转换为正整数,非法值直接拒绝。
|
|
84
|
+
#
|
|
85
|
+
# @param value [Object] 待校验的横向格数
|
|
86
|
+
# @return [Integer] 正整数横向格数
|
|
87
|
+
def positive_hsize(value)
|
|
88
|
+
size = integer_attribute(value, "hsize")
|
|
89
|
+
raise Invalid, "hsize must be a positive integer" unless size.positive?
|
|
107
90
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
raise Invalid, "hsize must be a positive integer"
|
|
111
|
-
end
|
|
91
|
+
size
|
|
92
|
+
end
|
|
112
93
|
end
|
|
113
94
|
end
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class ZabbixManager
|
|
4
|
-
|
|
4
|
+
# 远端脚本执行与可用脚本查询;执行请求可能产生 API 之外的设备副作用。
|
|
5
|
+
class Scripts < Resource
|
|
5
6
|
# 返回 Zabbix API 中脚本对象的方法名前缀。
|
|
6
7
|
#
|
|
7
8
|
# @return [String] 脚本对象的方法名前缀
|
|
@@ -9,13 +10,6 @@ class ZabbixManager
|
|
|
9
10
|
"script"
|
|
10
11
|
end
|
|
11
12
|
|
|
12
|
-
# 返回用于唯一识别脚本的业务字段名。
|
|
13
|
-
#
|
|
14
|
-
# @return [String] 脚本对象的业务标识字段名
|
|
15
|
-
def identify
|
|
16
|
-
"name"
|
|
17
|
-
end
|
|
18
|
-
|
|
19
13
|
# 在指定主机上执行 Zabbix 脚本。
|
|
20
14
|
#
|
|
21
15
|
# 示例:
|