Skip to content

Commit 580b484

Browse files
authored
Merge pull request #591 from syseleven/feature/upstream_zabbix_host_self.prefetch
Implement self.prefetch for zabbix_host
2 parents 2ca6bc1 + a4750d4 commit 580b484

File tree

10 files changed

+679
-158
lines changed

10 files changed

+679
-158
lines changed

lib/puppet/provider/zabbix.rb

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ class Puppet::Provider::Zabbix < Puppet::Provider
33
# This method is vendored from the AWS SDK, rather than including an
44
# extra library just to parse an ini file
55
# Copied from https://github.com/puppetlabs/puppetlabs-aws/blob/2d34b1602bdd564b3f882f683dc000878f539343/lib/puppet_x/puppetlabs/aws.rb#L120
6-
def ini_parse(file)
6+
def self.ini_parse(file)
77
current_section = {}
88
map = {}
99
file.rewind
@@ -23,16 +23,28 @@ def ini_parse(file)
2323
map
2424
end
2525

26-
def api_config
26+
def ini_parse(file)
27+
self.class.ini_parse(file)
28+
end
29+
30+
def self.api_config
2731
@api_config ||= ini_parse(File.new('/etc/zabbix/api.conf'))
2832
end
2933

30-
def zbx
34+
def api_config
35+
self.class.api_config
36+
end
37+
38+
def self.zbx
3139
@zbx ||= create_connection
3240
end
3341

42+
def zbx
43+
self.class.zbx
44+
end
45+
3446
# Create the api connection
35-
def create_connection
47+
def self.create_connection
3648
protocol = api_config['default']['apache_use_ssl'] == 'true' ? 'https' : 'http'
3749
zbx = ZabbixApi.connect(
3850
url: "#{protocol}://#{api_config['default']['zabbix_url']}/api_jsonrpc.php",
@@ -44,6 +56,10 @@ def create_connection
4456
zbx
4557
end
4658

59+
def create_connection
60+
self.class.create_connection
61+
end
62+
4763
# Check if host exists. When error raised, return false.
4864
def check_host(host)
4965
zbx.query(
@@ -80,6 +96,10 @@ def check_template_in_host(host)
8096
template_array.include?(template_id.to_s)
8197
end
8298

99+
def transform_to_array_hash(key, value_array)
100+
value_array.map { |a| { key => a } }
101+
end
102+
83103
# Is it a number?
84104
def a_number?(s)
85105
s.to_s.match(%r{\A[+-]?\d+?(\.\d+)?\Z}).nil? ? false : true

lib/puppet/provider/zabbix_host/ruby.rb

Lines changed: 155 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -2,97 +2,182 @@
22
Puppet::Type.type(:zabbix_host).provide(:ruby, parent: Puppet::Provider::Zabbix) do
33
confine feature: :zabbixapi
44

5-
def create
6-
# Set some vars
7-
host = @resource[:hostname]
8-
ipaddress = @resource[:ipaddress]
9-
use_ip = @resource[:use_ip]
10-
port = @resource[:port]
11-
hostgroup = @resource[:group]
12-
hostgroup_create = @resource[:group_create]
13-
templates = @resource[:templates]
14-
proxy = @resource[:proxy]
15-
16-
# Get the template ids.
17-
template_array = []
18-
if templates.is_a?(Array)
19-
templates.each do |template|
20-
template_id = get_template_id(zbx, template)
21-
template_array.push template_id
22-
end
23-
else
24-
template_array.push get_template_id(zbx, templates)
5+
def self.instances
6+
proxies = zbx.proxies.all
7+
api_hosts = zbx.query(
8+
method: 'host.get',
9+
params: {
10+
selectParentTemplates: ['host'],
11+
selectInterfaces: %w[interfaceid type main ip port useip],
12+
selectGroups: ['name'],
13+
output: %w[host proxy_hostid]
14+
}
15+
)
16+
17+
api_hosts.map do |h|
18+
interface = h['interfaces'].select { |i| i['type'].to_i == 1 && i['main'].to_i == 1 }.first
19+
use_ip = !interface['useip'].to_i.zero?
20+
new(
21+
ensure: :present,
22+
id: h['hostid'].to_i,
23+
name: h['host'],
24+
interfaceid: interface['interfaceid'].to_i,
25+
ipaddress: interface['ip'],
26+
use_ip: use_ip,
27+
port: interface['port'].to_i,
28+
groups: h['groups'].map { |g| g['name'] },
29+
group_create: nil,
30+
templates: h['parentTemplates'].map { |x| x['host'] },
31+
proxy: proxies.select { |_name, id| id == h['proxy_hostid'] }.keys.first
32+
)
2533
end
34+
end
2635

27-
# Check if we need to connect via ip or fqdn
28-
use_ip = use_ip ? 1 : 0
36+
def self.prefetch(resources)
37+
instances.each do |prov|
38+
if (resource = resources[prov.name])
39+
resource.provider = prov
40+
end
41+
end
42+
end
2943

30-
# When using DNS you still have to send a value for ip
31-
ipaddress = '' if ipaddress.nil? && use_ip.zero?
44+
def create
45+
template_ids = get_templateids(@resource[:templates])
46+
templates = transform_to_array_hash('templateid', template_ids)
3247

33-
hostgroup_create = hostgroup_create ? 1 : 0
48+
gids = get_groupids(@resource[:groups], @resource[:group_create])
49+
groups = transform_to_array_hash('groupid', gids)
3450

35-
# First check if we have an correct hostgroup and if not, we raise an error.
36-
search_hostgroup = zbx.hostgroups.get_id(name: hostgroup)
37-
if search_hostgroup.nil? && hostgroup_create == 1
38-
zbx.hostgroups.create(name: hostgroup)
39-
search_hostgroup = zbx.hostgroups.get_id(name: hostgroup)
40-
elsif search_hostgroup.nil? && hostgroup_create.zero?
41-
raise Puppet::Error, 'The hostgroup (' + hostgroup + ') does not exist in zabbix. Please use the correct one.'
42-
end
51+
proxy_hostid = @resource[:proxy].nil? || @resource[:proxy].empty? ? nil : zbx.proxies.get_id(host: @resource[:proxy])
4352

4453
# Now we create the host
45-
hostid = zbx.hosts.create_or_update(
46-
host: host,
54+
zbx.hosts.create(
55+
host: @resource[:hostname],
56+
proxy_hostid: proxy_hostid,
4757
interfaces: [
4858
{
4959
type: 1,
5060
main: 1,
51-
ip: ipaddress,
52-
dns: host,
53-
port: port,
54-
useip: use_ip
61+
ip: @resource[:ipaddress],
62+
dns: @resource[:hostname],
63+
port: @resource[:port],
64+
useip: @resource[:use_ip] ? 1 : 0
5565
}
5666
],
57-
templates: template_array,
58-
groups: [groupid: search_hostgroup]
67+
templates: templates,
68+
groups: groups
5969
)
70+
end
6071

61-
zbx.templates.mass_add(hosts_id: [hostid], templates_id: template_array)
72+
def exists?
73+
@property_hash[:ensure] == :present
74+
end
6275

63-
return if proxy.nil? || proxy.empty?
64-
zbx.hosts.update(
65-
hostid: zbx.hosts.get_id(host: host),
66-
proxy_hostid: zbx.proxies.get_id(host: proxy)
67-
)
76+
def destroy
77+
zbx.hosts.delete(zbx.hosts.get_id(host: @resource[:hostname]))
6878
end
6979

70-
def exists?
71-
host = @resource[:hostname]
72-
templates = @resource[:templates]
73-
74-
templates = [templates] unless templates.is_a?(Array)
75-
76-
host = check_host(host)
77-
if host.any?
78-
template_ids = host[0]['parentTemplates'].map { |x| x['templateid'] }
79-
template_names = host[0]['parentTemplates'].map { |x| x['host'] }
80-
res = []
81-
templates.each do |template|
82-
if a_number?(template)
83-
res.push(template_ids.include?(template))
84-
else
85-
res.push(template_names.include?(template))
86-
end
80+
#
81+
# Helper methods
82+
#
83+
def get_groupids(group_array, create)
84+
groupids = []
85+
group_array.each do |g|
86+
id = zbx.hostgroups.get_id(name: g)
87+
if id.nil?
88+
raise Puppet::Error, 'The hostgroup (' + g + ') does not exist in zabbix. Please use the correct one or set group_create => true.' unless create
89+
groupids << zbx.hostgroups.create(name: g)
90+
else
91+
groupids << id
8792
end
88-
res.all?
89-
else
90-
false
9193
end
94+
groupids
9295
end
9396

94-
def destroy
95-
host = @resource[:hostname]
96-
zbx.hosts.delete(zbx.hosts.get_id(host: host))
97+
def get_templateids(template_array)
98+
templateids = []
99+
template_array.each do |t|
100+
template_id = zbx.templates.get_id(host: t)
101+
raise Puppet::Error, "The template #{t} does not exist in Zabbix. Please use a correct one." if template_id.nil?
102+
templateids << template_id
103+
end
104+
templateids
105+
end
106+
107+
#
108+
# zabbix_host properties
109+
#
110+
mk_resource_methods
111+
112+
def ipaddress=(string)
113+
zbx.query(
114+
method: 'hostinterface.update',
115+
params: {
116+
interfaceid: @property_hash[:interfaceid],
117+
ip: string
118+
}
119+
)
120+
end
121+
122+
def use_ip=(boolean)
123+
zbx.query(
124+
method: 'hostinterface.update',
125+
params: {
126+
interfaceid: @property_hash[:interfaceid],
127+
useip: boolean ? 1 : 0,
128+
dns: @resource[:hostname]
129+
}
130+
)
131+
end
132+
133+
def port=(int)
134+
zbx.query(
135+
method: 'hostinterface.update',
136+
params: {
137+
interfaceid: @property_hash[:interfaceid],
138+
port: int
139+
}
140+
)
141+
end
142+
143+
def groups=(hostgroups)
144+
gids = get_groupids(hostgroups, @resource[:group_create])
145+
groups = transform_to_array_hash('groupid', gids)
146+
147+
zbx.hosts.create_or_update(
148+
host: @resource[:hostname],
149+
groups: groups
150+
)
151+
end
152+
153+
def templates=(array)
154+
should_template_ids = get_templateids(array)
155+
156+
# Get templates we have to clear. Unlinking only isn't really helpful.
157+
is_template_ids = zbx.query(
158+
method: 'host.get',
159+
params: {
160+
hostids: @property_hash[:id],
161+
selectParentTemplates: ['templateid'],
162+
output: ['host']
163+
}
164+
).first['parentTemplates'].map { |t| t['templateid'].to_i }
165+
templates_clear = is_template_ids - should_template_ids
166+
167+
zbx.query(
168+
method: 'host.update',
169+
params: {
170+
hostid: @property_hash[:id],
171+
templates: transform_to_array_hash('templateid', should_template_ids),
172+
templates_clear: transform_to_array_hash('templateid', templates_clear)
173+
}
174+
)
175+
end
176+
177+
def proxy=(string)
178+
zbx.hosts.create_or_update(
179+
host: @resource[:hostname],
180+
proxy_hostid: zbx.proxies.get_id(host: string)
181+
)
97182
end
98183
end

0 commit comments

Comments
 (0)