cloudstack-nagios 0.1.3 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +1 -1
- data/lib/cloudstack-nagios/base.rb +9 -0
- data/lib/cloudstack-nagios/cli.rb +3 -1
- data/lib/cloudstack-nagios/commands/check.rb +147 -0
- data/lib/cloudstack-nagios/commands/nagios_config.rb +5 -5
- data/lib/cloudstack-nagios/commands/snmpd_config.rb +58 -25
- data/lib/cloudstack-nagios/files/snmpd.conf +2 -1
- data/lib/cloudstack-nagios/helper.rb +2 -6
- data/lib/cloudstack-nagios/templates/cloudstack_routers_hosts.cfg.erb +4 -8
- data/lib/cloudstack-nagios/templates/cloudstack_routers_services.cfg.erb +15 -12
- data/lib/cloudstack-nagios/version.rb +1 -1
- metadata +3 -2
data/Gemfile.lock
CHANGED
@@ -64,6 +64,15 @@ module CloudstackNagios
|
|
64
64
|
def filter_by(objects, tag_name, tag)
|
65
65
|
objects.select {|r| r[tag_name].downcase == tag.downcase}
|
66
66
|
end
|
67
|
+
|
68
|
+
def sshoptions
|
69
|
+
{
|
70
|
+
timeout: 5,
|
71
|
+
keys: %w(/var/lib/cloud/management/.ssh/id_rsa),
|
72
|
+
auth_methods: %w(publickey)
|
73
|
+
}
|
74
|
+
end
|
75
|
+
|
67
76
|
end
|
68
77
|
end
|
69
78
|
end
|
@@ -85,11 +85,13 @@ module CloudstackNagios
|
|
85
85
|
require command
|
86
86
|
end
|
87
87
|
|
88
|
-
desc "nagios_config SUBCOMMAND ...ARGS", "Nagios configuration commands"
|
88
|
+
desc ":nagios_config SUBCOMMAND ...ARGS", "Nagios configuration commands"
|
89
89
|
subcommand :nagios_config, NagiosConfig
|
90
90
|
|
91
91
|
desc "snmpd_config SUBCOMMAND ...ARGS", "snmpd configuration commands"
|
92
92
|
subcommand :snmpd_config, SnmpdConfig
|
93
93
|
|
94
|
+
desc "check SUBCOMMAND ...ARGS", "nagios checks"
|
95
|
+
subcommand :check, Check
|
94
96
|
end # class
|
95
97
|
end # module
|
@@ -0,0 +1,147 @@
|
|
1
|
+
require 'sshkit/dsl'
|
2
|
+
|
3
|
+
class Check < CloudstackNagios::Base
|
4
|
+
|
5
|
+
RETURN_CODES = {0 => 'ok', 1 => 'warning', 2 => 'critical'}
|
6
|
+
|
7
|
+
desc "check memory HOST", "check memory on host"
|
8
|
+
option :host,
|
9
|
+
desc: 'hostname or ipaddress',
|
10
|
+
required: true,
|
11
|
+
aliases: '-H'
|
12
|
+
option :warning,
|
13
|
+
desc: 'warning level',
|
14
|
+
type: :numeric,
|
15
|
+
default: 90,
|
16
|
+
aliases: '-w'
|
17
|
+
option :critical,
|
18
|
+
desc: 'critical level',
|
19
|
+
type: :numeric,
|
20
|
+
default: 95,
|
21
|
+
aliases: '-c'
|
22
|
+
def memory
|
23
|
+
host = SSHKit::Host.new("root@#{options[:host]}")
|
24
|
+
host.ssh_options = sshoptions
|
25
|
+
host.port = 3922
|
26
|
+
free_output = ""
|
27
|
+
on host do |h|
|
28
|
+
free_output = capture(:free)
|
29
|
+
end
|
30
|
+
values = free_output.scan(/\d+/)
|
31
|
+
total = values[0].to_i
|
32
|
+
free = values[2].to_i
|
33
|
+
free_b = values[7].to_i
|
34
|
+
data = check_data(total, free_b, options[:warning], options[:critical])
|
35
|
+
puts "MEMORY #{RETURN_CODES[data[0]]} - usage = #{data[1]}% | usage=#{data[1]}% total=#{total}, free=#{free}, free_wo_buffers=#{free_b}"
|
36
|
+
exit data[0]
|
37
|
+
end
|
38
|
+
|
39
|
+
desc "check cpu", "check memory on host"
|
40
|
+
option :host,
|
41
|
+
desc: 'hostname or ipaddress',
|
42
|
+
required: true,
|
43
|
+
aliases: '-H'
|
44
|
+
option :warning,
|
45
|
+
desc: 'warning level',
|
46
|
+
type: :numeric,
|
47
|
+
default: 90
|
48
|
+
option :critical,
|
49
|
+
desc: 'critical level',
|
50
|
+
type: :numeric,
|
51
|
+
default: 95
|
52
|
+
def cpu(host)
|
53
|
+
host = SSHKit::Host.new("root@#{options[:host]}")
|
54
|
+
host.ssh_options = sshoptions
|
55
|
+
host.port = 3922
|
56
|
+
mpstat_output = ""
|
57
|
+
on host do |h|
|
58
|
+
mpstat_output = capture(:mpstat)
|
59
|
+
end
|
60
|
+
values = mpstat_output.scan(/\d+/)
|
61
|
+
usage = 100 - values[-1].to_f
|
62
|
+
data = check_data(100, usage, options[:warning], options[:critical])
|
63
|
+
puts "CPU #{RETURN_CODES[data[0]]} - usage = #{data[1]}% | usage=#{usage}"
|
64
|
+
exit data[0]
|
65
|
+
end
|
66
|
+
|
67
|
+
desc "check rootfs_rw", "check if the rootfs is read/writeable on host"
|
68
|
+
option :host,
|
69
|
+
desc: 'hostname or ipaddress',
|
70
|
+
required: true,
|
71
|
+
aliases: '-H'
|
72
|
+
option :warning,
|
73
|
+
desc: 'warning level',
|
74
|
+
type: :numeric,
|
75
|
+
default: 90,
|
76
|
+
aliases: '-w'
|
77
|
+
option :critical,
|
78
|
+
desc: 'critical level',
|
79
|
+
type: :numeric,
|
80
|
+
default: 95,
|
81
|
+
aliases: '-c'
|
82
|
+
def rootfs_rw
|
83
|
+
host = SSHKit::Host.new("root@#{options[:host]}")
|
84
|
+
host.ssh_options = sshoptions
|
85
|
+
host.port = 3922
|
86
|
+
mpstat_output = ""
|
87
|
+
on host do |h|
|
88
|
+
proc_out = capture(:cat, '/proc/mounts')
|
89
|
+
end
|
90
|
+
rootfs_rw = proc_out.match(/rootfs\srw\s/)
|
91
|
+
data = check_data(100, usage, options[:warning], options[:critical])
|
92
|
+
puts "ROOTFS_RW #{rootfs_rw ? 'OK - root fs writeable' : 'CRITICAL - rootfs not writeable'}"
|
93
|
+
exit data[0]
|
94
|
+
end
|
95
|
+
|
96
|
+
desc "check network", "check network usage on host"
|
97
|
+
option :host,
|
98
|
+
desc: 'hostname or ipaddress',
|
99
|
+
required: true,
|
100
|
+
aliases: '-H'
|
101
|
+
option :warning,
|
102
|
+
desc: 'warning level',
|
103
|
+
type: :numeric,
|
104
|
+
default: 90,
|
105
|
+
aliases: '-w'
|
106
|
+
option :critical,
|
107
|
+
desc: 'critical level',
|
108
|
+
type: :numeric,
|
109
|
+
default: 95,
|
110
|
+
aliases: '-c'
|
111
|
+
def network
|
112
|
+
host = SSHKit::Host.new("root@#{options[:host]}")
|
113
|
+
host.ssh_options = sshoptions
|
114
|
+
host.port = 3922
|
115
|
+
r1, t1, r2, t2 = ""
|
116
|
+
on host do |h|
|
117
|
+
r1 = capture(:cat, '/sys/class/net/eth0/statistics/rx_bytes').to_f
|
118
|
+
t1 = capture(:cat, '/sys/class/net/eth0/statistics/tx_bytes').to_f
|
119
|
+
sleep 1
|
120
|
+
r2 = capture(:cat, '/sys/class/net/eth0/statistics/rx_bytes').to_f
|
121
|
+
t2 = capture(:cat, '/sys/class/net/eth0/statistics/tx_bytes').to_f
|
122
|
+
end
|
123
|
+
rbps = (r2 - r1) / 1024
|
124
|
+
tbps = (t2 - t1) / 1024
|
125
|
+
data = check_data(1048576, tbps, options[:warning], options[:critical])
|
126
|
+
puts "NETWORK #{RETURN_CODES[data[0]]} - usage = #{data[1]}% | rxbps=#{rbps.round(0)}, txbps=#{tbps.round(0)}"
|
127
|
+
exit data[0]
|
128
|
+
end
|
129
|
+
|
130
|
+
no_commands do
|
131
|
+
|
132
|
+
def check_data(total, usage, warning, critical)
|
133
|
+
usage_percent = 100.0 / total * usage
|
134
|
+
code = 3
|
135
|
+
if usage_percent < warning
|
136
|
+
code = 0
|
137
|
+
elsif usage_percent < critical
|
138
|
+
code = 1
|
139
|
+
else
|
140
|
+
code = 2
|
141
|
+
end
|
142
|
+
[code, usage_percent.round(0)]
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
@@ -1,13 +1,13 @@
|
|
1
1
|
class NagiosConfig < CloudstackNagios::Base
|
2
2
|
|
3
|
-
desc "hosts", "generate nagios hosts configuration for virtual routers"
|
3
|
+
desc "nagios_config hosts", "generate nagios hosts configuration for virtual routers"
|
4
4
|
def hosts
|
5
|
-
|
5
|
+
puts load_template("cloudstack_routers_hosts.cfg.erb").result(routers: routers)
|
6
6
|
end
|
7
7
|
|
8
|
-
desc "services", "generate nagios services configuration for virtual routers"
|
8
|
+
desc "nagios_config services", "generate nagios services configuration for virtual routers"
|
9
9
|
def services
|
10
|
-
|
10
|
+
puts load_template("cloudstack_routers_services.cfg.erb").result(routers: routers)
|
11
11
|
end
|
12
12
|
|
13
|
-
end
|
13
|
+
end
|
@@ -1,37 +1,70 @@
|
|
1
1
|
require 'sshkit/dsl'
|
2
|
-
require '
|
2
|
+
require 'socket'
|
3
|
+
require 'timeout'
|
3
4
|
|
4
5
|
class SnmpdConfig < CloudstackNagios::Base
|
5
6
|
|
6
|
-
desc "check", "check if
|
7
|
-
def check
|
8
|
-
|
7
|
+
desc "snmpd_config check [vms]", "check if snmpd is configured on virtual routers"
|
8
|
+
def check(*vms)
|
9
|
+
if vms.size == 0
|
10
|
+
say 'Get a list of all routers from cloudstack..', :yellow
|
11
|
+
vms = router_ips(routers)
|
12
|
+
end
|
13
|
+
vms.each do |host|
|
14
|
+
begin
|
15
|
+
Timeout::timeout(1) do
|
16
|
+
socket = TCPSocket.new(host, "161")
|
17
|
+
socket.close
|
18
|
+
puts "port is open on host #{host}"
|
19
|
+
end
|
20
|
+
rescue => e
|
21
|
+
puts "port is closed on host #{host}"
|
22
|
+
end
|
23
|
+
end
|
9
24
|
end
|
10
25
|
|
11
|
-
desc "enable", "enable snmpd configuration on virtual routers"
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
26
|
+
desc "snmpd_config enable [vms]", "enable snmpd configuration on virtual routers"
|
27
|
+
option :apt,
|
28
|
+
desc: 'use apt-get to install snmpd packages',
|
29
|
+
type: :boolean
|
30
|
+
def enable(*vms)
|
31
|
+
apt = options[:apt]
|
32
|
+
if vms.size == 0
|
33
|
+
say 'Get a list of all routers from cloudstack..', :yellow
|
34
|
+
vms = router_ips
|
35
|
+
end
|
36
|
+
hosts = vms.map do |router|
|
37
|
+
host = SSHKit::Host.new("root@#{router}")
|
38
|
+
host.ssh_options = sshoptions
|
39
|
+
host.port = 3922
|
40
|
+
host
|
41
|
+
end
|
42
|
+
say 'Connect to router and enable snmpd...', :yellow
|
43
|
+
on hosts, in: :sequence, wait: 10 do
|
44
|
+
begin
|
45
|
+
execute 'apt-get', 'update'
|
46
|
+
execute 'apt-get', '-y', 'install', 'snmpd'
|
47
|
+
upload! File.join(File.dirname(__FILE__), '..', 'files', 'snmpd.conf'), '/etc/snmp/snmpd.conf'
|
48
|
+
execute 'service', 'snmpd', 'restart'
|
49
|
+
execute 'iptables', '-A INPUT -p tcp -m tcp --dport 161 -j ACCEPT'
|
50
|
+
rescue StandardError => e
|
51
|
+
puts 'configuration failed!'
|
52
|
+
puts e.message
|
53
|
+
puts e.backtrace
|
54
|
+
end
|
55
|
+
end
|
24
56
|
end
|
25
57
|
|
26
58
|
no_commands do
|
27
59
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
60
|
+
def router_ips(vrs = routers)
|
61
|
+
ips = []
|
62
|
+
vrs.each do |router|
|
63
|
+
ips << router['linklocalip'] unless router['linklocalip'] == nil
|
64
|
+
end
|
65
|
+
ips
|
66
|
+
end
|
34
67
|
|
35
|
-
|
68
|
+
end
|
36
69
|
|
37
|
-
end
|
70
|
+
end
|
@@ -23,6 +23,7 @@
|
|
23
23
|
# then remember to update the other occurances in this example config file to match.
|
24
24
|
|
25
25
|
|
26
|
+
agentaddress udp:161,udp6:161,tcp:161,tcp6:161
|
26
27
|
|
27
28
|
###############################################################################
|
28
29
|
#
|
@@ -99,4 +100,4 @@ includeAllDisks 10%
|
|
99
100
|
load 12 10 5
|
100
101
|
|
101
102
|
# Walk the UCD-SNMP-MIB::laTable to see the resulting output
|
102
|
-
# Note that this table *will* be populated, even without a "load" entry in the snmpd.conf file
|
103
|
+
# Note that this table *will* be populated, even without a "load" entry in the snmpd.conf file
|
@@ -6,12 +6,8 @@ module CloudstackNagios
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def routers
|
9
|
-
|
10
|
-
|
11
|
-
projects.each do |project|
|
12
|
-
routers = routers + client.list_routers({projectid: project['id']})
|
13
|
-
end
|
14
|
-
routers
|
9
|
+
routers = client.list_routers
|
10
|
+
routers += client.list_routers(projectid: -1)
|
15
11
|
end
|
16
12
|
end
|
17
13
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
# Host configuration file
|
4
4
|
#
|
5
5
|
# Created by:
|
6
|
-
# Date: <%= Date.new
|
6
|
+
# Date: <%= Date.new -%>
|
7
7
|
# Version: Nagios 3.x config file
|
8
8
|
#
|
9
9
|
# --- DO NOT EDIT THIS FILE BY HAND ---
|
@@ -11,20 +11,16 @@
|
|
11
11
|
#
|
12
12
|
###############################################################################
|
13
13
|
<% routers.each do |router| -%>
|
14
|
-
|
14
|
+
<% if router['linklocalip'] -%>
|
15
15
|
define host {
|
16
16
|
host_name <%= router['name'] %>
|
17
|
-
alias <%= router['name'] %>
|
18
17
|
display_name <%= router['name'] %> <%= " - #{router['project']}" if router['project'] %>
|
19
18
|
address <%= router['linklocalip'] %>
|
20
|
-
hostgroups Cloudstack-
|
19
|
+
hostgroups Cloudstack-SystemVM
|
21
20
|
check_command check-host-alive
|
22
|
-
use Linux-Host,host-pnp
|
23
|
-
notification_period S1
|
24
|
-
_COMMUNITY public
|
25
21
|
register 1
|
26
22
|
}
|
27
|
-
|
23
|
+
<% end -%>
|
28
24
|
<% end -%>
|
29
25
|
|
30
26
|
###############################################################################
|
@@ -8,22 +8,25 @@
|
|
8
8
|
# Version: Nagios 3.x config file
|
9
9
|
#
|
10
10
|
# --- DO NOT EDIT THIS FILE BY HAND ---
|
11
|
-
# cloudstack-
|
11
|
+
# cloudstack-nagios will overwite all manual settings during the next update
|
12
12
|
#
|
13
13
|
###############################################################################
|
14
|
-
<% routers.each do |router| -%>
|
15
|
-
|
16
|
-
define service {
|
17
|
-
host_name <%= router['name'] %>
|
18
|
-
service_description <%= router['name'] %> <%= " - #{router['project']}" if router['project'] %> - Memory
|
19
|
-
display_name Memory
|
20
|
-
use Generic-Service,service-pnp
|
21
|
-
check_command checkcommand.rb!memory
|
22
|
-
register 1
|
23
|
-
}
|
24
14
|
|
15
|
+
define command {
|
16
|
+
command_name cs-nagios_check-memory
|
17
|
+
command_line cs-nagios check memory -H $HOSTADDRESS$ -w $ARG1$ -c $ARG$
|
18
|
+
register 1
|
19
|
+
}
|
25
20
|
|
26
|
-
|
21
|
+
define service {
|
22
|
+
hostgroup_name Cloudstack-SystemVM
|
23
|
+
service_description Memory
|
24
|
+
display_name Memory
|
25
|
+
servicegroups Cloudstack-SystemVM
|
26
|
+
use Generic-Service,service-pnp
|
27
|
+
check_command cs-nagios_check-memory!80!90
|
28
|
+
register 1
|
29
|
+
}
|
27
30
|
|
28
31
|
###############################################################################
|
29
32
|
#
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cloudstack-nagios
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-11-
|
12
|
+
date: 2013-11-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rdoc
|
@@ -150,6 +150,7 @@ files:
|
|
150
150
|
- lib/cloudstack-client/version.rb
|
151
151
|
- lib/cloudstack-nagios/base.rb
|
152
152
|
- lib/cloudstack-nagios/cli.rb
|
153
|
+
- lib/cloudstack-nagios/commands/check.rb
|
153
154
|
- lib/cloudstack-nagios/commands/nagios_config.rb
|
154
155
|
- lib/cloudstack-nagios/commands/snmpd_config.rb
|
155
156
|
- lib/cloudstack-nagios/files/snmpd.conf
|