rubix 0.0.1 → 0.0.2
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.
- data/VERSION +1 -1
- data/lib/rubix.rb +9 -16
- data/lib/rubix/associations.rb +14 -0
- data/lib/rubix/associations/belongs_to_host.rb +32 -0
- data/lib/rubix/associations/has_many_applications.rb +32 -0
- data/lib/rubix/associations/has_many_host_groups.rb +37 -0
- data/lib/rubix/associations/has_many_hosts.rb +32 -0
- data/lib/rubix/associations/has_many_templates.rb +37 -0
- data/lib/rubix/associations/has_many_user_macros.rb +37 -0
- data/lib/rubix/log.rb +31 -18
- data/lib/rubix/models.rb +9 -0
- data/lib/rubix/models/application.rb +44 -50
- data/lib/rubix/models/host.rb +70 -74
- data/lib/rubix/models/host_group.rb +40 -51
- data/lib/rubix/models/item.rb +80 -69
- data/lib/rubix/models/model.rb +126 -0
- data/lib/rubix/models/template.rb +57 -55
- data/lib/rubix/models/user_macro.rb +84 -0
- data/lib/rubix/monitors.rb +5 -0
- data/lib/rubix/{monitor.rb → monitors/monitor.rb} +0 -0
- data/spec/requests/application_request_spec.rb +45 -0
- data/spec/requests/host_group_request_spec.rb +23 -0
- data/spec/requests/host_request_spec.rb +70 -0
- data/spec/requests/item_request_spec.rb +68 -0
- data/spec/requests/template_request_spec.rb +52 -0
- data/spec/requests/user_macro_request_spec.rb +36 -0
- data/spec/rubix/{monitor_spec.rb → monitors/monitor_spec.rb} +0 -0
- data/spec/spec_helper.rb +16 -1
- data/spec/support/integration_helper.rb +9 -0
- data/spec/test.yml +5 -0
- metadata +25 -8
- data/lib/rubix/model.rb +0 -56
- data/spec/rubix/models/host_group_spec.rb +0 -56
data/lib/rubix/models/host.rb
CHANGED
@@ -2,6 +2,10 @@ module Rubix
|
|
2
2
|
|
3
3
|
class Host < Model
|
4
4
|
|
5
|
+
#
|
6
|
+
# == Properties & Finding ==
|
7
|
+
#
|
8
|
+
|
5
9
|
# The IP for a Host that not supposed to be polled by the Zabbix
|
6
10
|
# server.
|
7
11
|
BLANK_IP = '0.0.0.0'
|
@@ -9,11 +13,8 @@ module Rubix
|
|
9
13
|
# The default port.
|
10
14
|
DEFAULT_PORT = 10050
|
11
15
|
|
12
|
-
attr_accessor :name, :ip, :port, :profile, :status
|
13
|
-
|
14
|
-
#
|
15
|
-
# Initialization and properties.
|
16
|
-
#
|
16
|
+
attr_accessor :name, :ip, :port, :profile, :status
|
17
|
+
|
17
18
|
def initialize properties={}
|
18
19
|
super(properties)
|
19
20
|
@name = properties[:name]
|
@@ -21,14 +22,62 @@ module Rubix
|
|
21
22
|
@port = properties[:port]
|
22
23
|
@profile = properties[:profile]
|
23
24
|
@status = properties[:status]
|
24
|
-
|
25
|
-
|
25
|
+
|
26
|
+
self.host_group_ids = properties[:host_group_ids]
|
27
|
+
self.host_groups = properties[:host_groups]
|
28
|
+
|
29
|
+
self.template_ids = properties[:template_ids]
|
30
|
+
self.templates = properties[:templates]
|
31
|
+
|
32
|
+
self.user_macro_ids = properties[:user_macro_ids]
|
33
|
+
self.user_macros = properties[:user_macros]
|
26
34
|
end
|
27
35
|
|
36
|
+
def self.find_request options={}
|
37
|
+
request('host.get', 'filter' => {'host' => options[:name], 'hostid' => options[:id]}, 'select_groups' => 'refer', 'selectParentTemplates' => 'refer', 'select_profile' => 'refer', 'select_macros' => 'extend', 'output' => 'extend')
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.build host
|
41
|
+
new({
|
42
|
+
:id => host['hostid'].to_i,
|
43
|
+
:name => host['host'],
|
44
|
+
:host_group_ids => host['groups'].map { |group| group['groupid'].to_i },
|
45
|
+
:template_ids => host['parentTemplates'].map { |template| (template['templateid'] || template['hostid']).to_i },
|
46
|
+
:user_macros => host['macros'].map { |um| UserMacro.new(:host_id => um['hostid'].to_i, :id => um['hostmacroid'], :value => um['value'], :macro => um['macro']) },
|
47
|
+
:profile => host['profile'],
|
48
|
+
:port => host['port']
|
49
|
+
})
|
50
|
+
end
|
51
|
+
|
28
52
|
def log_name
|
29
53
|
"HOST #{name || id}"
|
30
54
|
end
|
55
|
+
|
56
|
+
def self.id_field
|
57
|
+
'hostid'
|
58
|
+
end
|
59
|
+
|
60
|
+
#
|
61
|
+
# == Associations ==
|
62
|
+
#
|
63
|
+
|
64
|
+
include Associations::HasManyHostGroups
|
65
|
+
include Associations::HasManyTemplates
|
66
|
+
include Associations::HasManyUserMacros
|
67
|
+
|
68
|
+
#
|
69
|
+
# == Validation ==
|
70
|
+
#
|
71
|
+
|
72
|
+
def validate
|
73
|
+
raise ValidationError.new("A host must have at least one host group.") if host_group_ids.nil? || host_group_ids.empty?
|
74
|
+
true
|
75
|
+
end
|
31
76
|
|
77
|
+
#
|
78
|
+
# == CRUD ==
|
79
|
+
#
|
80
|
+
|
32
81
|
def params
|
33
82
|
{}.tap do |hp|
|
34
83
|
hp['host'] = name
|
@@ -47,81 +96,28 @@ module Rubix
|
|
47
96
|
end
|
48
97
|
end
|
49
98
|
|
50
|
-
|
51
|
-
|
52
|
-
#
|
53
|
-
|
54
|
-
def validate
|
55
|
-
raise ValidationError.new("A host must have at least one host group.") if host_groups.nil? || host_groups.empty?
|
56
|
-
end
|
57
|
-
|
58
|
-
def load
|
59
|
-
response = request('host.get', 'filter' => {'host' => name}, 'select_groups' => 'refer', 'selectParentTemplates' => 'refer', 'select_profile' => 'refer', 'output' => 'extend')
|
60
|
-
case
|
61
|
-
when response.has_data?
|
62
|
-
host = response.result.first
|
63
|
-
@id = host['hostid'].to_i
|
64
|
-
@host_groups = host['groups'].map { |group| HostGroup.new(:id => group['groupid'].to_i) }
|
65
|
-
@templates = host['parentTemplates'].map { |template| Template.new((template['templateid'] || template['hostid']).to_i) }
|
66
|
-
@profile = host['profile']
|
67
|
-
@port = host['port']
|
68
|
-
@exists = true
|
69
|
-
@loaded = true
|
70
|
-
when response.success?
|
71
|
-
@exists = false
|
72
|
-
@loaded = true
|
73
|
-
else
|
74
|
-
error("Could not load: #{response.error_message}")
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
def create
|
79
|
-
validate
|
80
|
-
|
81
|
-
host_group_ids = (host_groups || []).map { |g| { 'groupid' => g.id } }
|
82
|
-
template_ids = (templates || []).map { |t| { 'templateid' => t.id } }
|
83
|
-
response = request('host.create', params.merge('groups' => host_group_ids, 'templates' => template_ids))
|
84
|
-
|
85
|
-
if response.has_data?
|
86
|
-
@exists = true
|
87
|
-
@id = response.result['hostids'].first.to_i
|
88
|
-
info("Created")
|
89
|
-
else
|
90
|
-
error("Could not create: #{response.error_message}.")
|
91
|
-
end
|
99
|
+
def create_request
|
100
|
+
request('host.create', params.merge('groups' => host_group_params, 'templates' => template_params, 'macros' => user_macro_params))
|
92
101
|
end
|
93
102
|
|
94
|
-
def
|
95
|
-
|
96
|
-
response = request('host.update', params.merge('hostid' => id))
|
97
|
-
if response.has_data?
|
98
|
-
info("Updated")
|
99
|
-
else
|
100
|
-
error("Could not update: #{response.error_message}.")
|
101
|
-
end
|
102
|
-
mass_update_templates_and_host_groups
|
103
|
+
def update_request
|
104
|
+
request('host.update', params.merge('hostid' => id))
|
103
105
|
end
|
104
106
|
|
105
|
-
def
|
106
|
-
response = request('host.massUpdate', { '
|
107
|
+
def after_update
|
108
|
+
response = request('host.massUpdate', { 'groups' => host_group_params, 'templates' => template_params, 'macros' => user_macro_params, 'hosts' => [{'hostid' => id}]})
|
107
109
|
if response.has_data?
|
108
|
-
info("Updated templates
|
110
|
+
info("Updated templates, host groups, & macros")
|
111
|
+
true
|
109
112
|
else
|
110
|
-
error("Could not update all templates and/or
|
113
|
+
error("Could not update all templates, host groups, and/or macros: #{response.error_message}")
|
114
|
+
false
|
111
115
|
end
|
112
116
|
end
|
113
|
-
|
114
|
-
def
|
115
|
-
|
116
|
-
case
|
117
|
-
when response.has_data? && response.result['hostids'].first.to_i == id
|
118
|
-
info("Deleted")
|
119
|
-
when response.error_message =~ /does not exist/i
|
120
|
-
# was never there...
|
121
|
-
else
|
122
|
-
error("Could not delete: #{response.error_message}")
|
123
|
-
end
|
117
|
+
|
118
|
+
def destroy_request
|
119
|
+
request('host.delete', [{'hostid' => id}])
|
124
120
|
end
|
125
|
-
|
121
|
+
|
126
122
|
end
|
127
123
|
end
|
@@ -2,73 +2,62 @@ module Rubix
|
|
2
2
|
|
3
3
|
class HostGroup < Model
|
4
4
|
|
5
|
-
|
5
|
+
#
|
6
|
+
# == Properties & Finding ==
|
7
|
+
#
|
6
8
|
|
7
9
|
def initialize properties={}
|
8
10
|
super(properties)
|
9
|
-
@name
|
11
|
+
@name = properties[:name]
|
12
|
+
|
13
|
+
self.host_ids = properties[:host_ids]
|
14
|
+
self.hosts = properties[:hosts]
|
10
15
|
end
|
16
|
+
|
17
|
+
attr_accessor :name
|
11
18
|
|
12
|
-
def
|
13
|
-
|
19
|
+
def self.find_request options={}
|
20
|
+
request('hostgroup.get', 'filter' => {'groupid' => options[:id], 'name' => options[:name]}, 'select_hosts' => 'refer', 'output' => 'extend')
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.build host_group
|
24
|
+
new({
|
25
|
+
:id => host_group['groupid'].to_i,
|
26
|
+
:name => host_group['name'],
|
27
|
+
:host_ids => host_group['hosts'].map { |host_info| host_info['hostid'].to_i }
|
28
|
+
})
|
14
29
|
end
|
15
30
|
|
16
|
-
def
|
17
|
-
|
18
|
-
case
|
19
|
-
when response.has_data?
|
20
|
-
@id = response.first['groupid'].to_i
|
21
|
-
@name = response.first['name']
|
22
|
-
@host_ids = response.first['hosts'].map { |host_info| host_info['hostid'].to_i }
|
23
|
-
@exists = true
|
24
|
-
@loaded = true
|
25
|
-
when response.success?
|
26
|
-
@exists = false
|
27
|
-
@loaded = true
|
28
|
-
else
|
29
|
-
error("Could not load: #{response.error_message}")
|
30
|
-
end
|
31
|
+
def log_name
|
32
|
+
"GROUP #{name || id}"
|
31
33
|
end
|
32
34
|
|
33
|
-
def
|
34
|
-
|
35
|
-
if response.has_data?
|
36
|
-
@id = response['groupids'].first.to_i
|
37
|
-
@exists = true
|
38
|
-
@loaded = true
|
39
|
-
info("Created")
|
40
|
-
else
|
41
|
-
error("Could not create: #{response.error_message}")
|
42
|
-
end
|
35
|
+
def self.id_field
|
36
|
+
'groupid'
|
43
37
|
end
|
38
|
+
|
44
39
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
40
|
+
#
|
41
|
+
# == Associations ==
|
42
|
+
#
|
43
|
+
|
44
|
+
include Associations::HasManyHosts
|
49
45
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
# was never there...
|
57
|
-
else
|
58
|
-
error("Could not delete: #{response.error_message}.")
|
59
|
-
end
|
46
|
+
#
|
47
|
+
# == CRUD ==
|
48
|
+
#
|
49
|
+
|
50
|
+
def create_request
|
51
|
+
request('hostgroup.create', [{'name' => name}])
|
60
52
|
end
|
61
53
|
|
62
|
-
def
|
63
|
-
|
64
|
-
host_ids.include?(host.id)
|
54
|
+
def update_request
|
55
|
+
request('hostgroup.update', [{'groupid' => id, 'name' => name}])
|
65
56
|
end
|
66
57
|
|
67
|
-
def
|
68
|
-
|
69
|
-
group.create unless group.exists?
|
70
|
-
end
|
58
|
+
def destroy_request
|
59
|
+
request('hostgroup.delete', [{'groupid' => id}])
|
71
60
|
end
|
72
|
-
|
61
|
+
|
73
62
|
end
|
74
63
|
end
|
data/lib/rubix/models/item.rb
CHANGED
@@ -2,6 +2,10 @@ module Rubix
|
|
2
2
|
|
3
3
|
class Item < Model
|
4
4
|
|
5
|
+
#
|
6
|
+
# == Properties & Finding ==
|
7
|
+
#
|
8
|
+
|
5
9
|
# The numeric code for a Zabbix item of type 'Zabbix trapper'. The
|
6
10
|
# item must have this type in order for the Zabbix server to listen
|
7
11
|
# and accept data submitted by +zabbix_sender+.
|
@@ -25,97 +29,104 @@ module Rubix
|
|
25
29
|
3 => :unsigned_int, # Numeric (unsigned)
|
26
30
|
4 => :text # Text
|
27
31
|
}.freeze
|
28
|
-
|
29
|
-
attr_accessor :host, :applications, :key, :description, :value_type
|
30
32
|
|
33
|
+
# Return the +value_type+ name (:float, :text, &c.) for a Zabbix
|
34
|
+
# item's value type by examining the given +value+.
|
35
|
+
def self.value_type_from_value value
|
36
|
+
case
|
37
|
+
when value =~ /\d+/ then :unsigned_int
|
38
|
+
when value =~ /-?[\d\.]+/ then :float
|
39
|
+
when value.include?("\n") then :text
|
40
|
+
else :character
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Return the +value_type+'s numeric code for a Zabbix item's value
|
45
|
+
# type by examining the given +value+.
|
46
|
+
def self.value_code_from_value value
|
47
|
+
self::VALUE_CODES[value_type_from_value(value)]
|
48
|
+
end
|
49
|
+
|
50
|
+
attr_accessor :key, :description
|
51
|
+
attr_reader :value_type
|
52
|
+
|
31
53
|
def initialize properties={}
|
32
54
|
super(properties)
|
33
|
-
@
|
34
|
-
@
|
35
|
-
|
36
|
-
|
37
|
-
|
55
|
+
@key = properties[:key]
|
56
|
+
@description = properties[:description]
|
57
|
+
|
58
|
+
self.value_type = properties[:value_type]
|
59
|
+
|
60
|
+
self.host = properties[:host]
|
61
|
+
self.host_id = properties[:host_id]
|
62
|
+
self.applications = properties[:applications]
|
63
|
+
self.application_ids = properties[:application_ids]
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.find_request options={}
|
67
|
+
request('item.get', 'hostids' => [options[:host_id]], 'filter' => {'key_' => options[:key], 'id' => options[:id]}, "select_applications" => "refer", "output" => "extend")
|
38
68
|
end
|
39
69
|
|
70
|
+
def self.build item
|
71
|
+
new({
|
72
|
+
:id => item['itemid'].to_i,
|
73
|
+
:host_id => item['hostid'].to_i,
|
74
|
+
:description => item['description'],
|
75
|
+
:value_type => item['value_type'] ? self::VALUE_NAMES[item['value_type'].to_i] : :character,
|
76
|
+
:application_ids => (item['applications'] || []).map { |app| app['applicationid'].to_i },
|
77
|
+
:key => item['key_']
|
78
|
+
})
|
79
|
+
end
|
80
|
+
|
40
81
|
def log_name
|
41
82
|
"ITEM #{key}@#{host.name}"
|
42
83
|
end
|
43
84
|
|
44
|
-
def
|
45
|
-
|
46
|
-
:hostid => host.id,
|
47
|
-
:description => (description || 'Unknown'),
|
48
|
-
:type => self.class::TRAPPER_TYPE,
|
49
|
-
:key_ => key,
|
50
|
-
:value_type => self.class::VALUE_CODES[value_type],
|
51
|
-
}.tap do |p|
|
52
|
-
p[:applications] = applications.map(&:id) if applications
|
53
|
-
end
|
85
|
+
def self.id_field
|
86
|
+
'itemid'
|
54
87
|
end
|
55
88
|
|
56
|
-
def
|
57
|
-
|
58
|
-
|
59
|
-
when response.has_data?
|
60
|
-
item = response.first
|
61
|
-
@id = item['itemid'].to_i
|
62
|
-
@host = Host.new(:id => item['hostid'])
|
63
|
-
@description = item['description']
|
64
|
-
@value_type = self.class::VALUE_NAMES[item['value_type']] # it's actually a 'code' that's returned...
|
65
|
-
@key = item['key_']
|
66
|
-
@exists = true
|
67
|
-
@loaded = true
|
68
|
-
when response.success?
|
69
|
-
@exists = false
|
70
|
-
@loaded = true
|
89
|
+
def value_type= vt
|
90
|
+
if vt.nil? || vt.to_s.empty? || !self.class::VALUE_CODES.include?(vt.to_sym)
|
91
|
+
@value_type = :character
|
71
92
|
else
|
72
|
-
|
93
|
+
@value_type = vt.to_sym
|
73
94
|
end
|
74
95
|
end
|
75
96
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
@id = response['itemids'].first.to_i
|
80
|
-
@exists = true
|
81
|
-
info("Created")
|
82
|
-
else
|
83
|
-
error("Could not create: #{response.error_message}.")
|
84
|
-
end
|
85
|
-
end
|
97
|
+
#
|
98
|
+
# == Associations ==
|
99
|
+
#
|
86
100
|
|
87
|
-
|
88
|
-
|
89
|
-
info("Updated")
|
90
|
-
end
|
101
|
+
include Associations::BelongsToHost
|
102
|
+
include Associations::HasManyApplications
|
91
103
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
104
|
+
#
|
105
|
+
# == CRUD ==
|
106
|
+
#
|
107
|
+
|
108
|
+
def params
|
109
|
+
{
|
110
|
+
:hostid => host_id,
|
111
|
+
:description => (description || 'Unknown'),
|
112
|
+
:type => self.class::TRAPPER_TYPE,
|
113
|
+
:key_ => key,
|
114
|
+
:value_type => self.class::VALUE_CODES[value_type],
|
115
|
+
}.tap do |p|
|
116
|
+
p[:applications] = application_ids if application_ids
|
101
117
|
end
|
102
118
|
end
|
119
|
+
|
120
|
+
def create_request
|
121
|
+
request('item.create', params)
|
122
|
+
end
|
103
123
|
|
104
|
-
|
105
|
-
|
106
|
-
def self.value_type_from_value value
|
107
|
-
case
|
108
|
-
when value =~ /\d+/ then :unsigned_int
|
109
|
-
when value =~ /-?[\d\.]+/ then :float
|
110
|
-
when value.include?("\n") then :text
|
111
|
-
else :character
|
112
|
-
end
|
124
|
+
def update_request
|
125
|
+
request('item.update', params.merge('itemid' => id))
|
113
126
|
end
|
114
127
|
|
115
|
-
|
116
|
-
|
117
|
-
def self.value_code_from_value value
|
118
|
-
self::VALUE_CODES[value_type_from_value(value)]
|
128
|
+
def destroy_request
|
129
|
+
request('item.delete', [id])
|
119
130
|
end
|
120
131
|
|
121
132
|
end
|