onering-report-plugins 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/facter/onering_properties_chef.rb +41 -0
- data/lib/facter/onering_properties_id.rb +32 -0
- data/lib/facter/onering_properties_netstat.rb +86 -0
- data/lib/facter/onering_properties_network.rb +173 -0
- data/lib/facter/onering_properties_physical.rb +87 -0
- data/lib/facter/onering_properties_services.rb +25 -0
- data/lib/facter/onering_properties_xen.rb +32 -0
- data/lib/reporter/default/properties_chef.rb +15 -0
- data/lib/reporter/default/properties_facter.rb +41 -0
- data/lib/reporter/default/properties_network.rb +55 -0
- data/lib/reporter/default/properties_ohai.rb +62 -0
- data/lib/reporter/default/properties_physical.rb +14 -0
- data/lib/reporter/default/properties_services.rb +6 -0
- data/lib/reporter/default/properties_xen.rb +16 -0
- data/lib/reporter/default/stats_base.rb +94 -0
- data/lib/reporter/default/stats_network.rb +9 -0
- metadata +72 -0
@@ -0,0 +1,41 @@
|
|
1
|
+
# Onering Facts - Chef Properties
|
2
|
+
# provides collection of Chef metadata
|
3
|
+
#
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
chef = Facter::Util::Resolution.exec("knife node show $(hostname -f) -c /etc/chef/client.rb -k /etc/chef/client.pem -u $(hostname -f) -F json 2> /dev/null | grep -v 'json_class' 2> /dev/null")
|
7
|
+
|
8
|
+
|
9
|
+
if chef
|
10
|
+
begin
|
11
|
+
chef = (JSON.load(chef) rescue {})
|
12
|
+
|
13
|
+
unless chef.empty?
|
14
|
+
Facter.add('chef_nodename') do
|
15
|
+
setcode { chef['name'].to_s.strip.chomp.downcase rescue nil }
|
16
|
+
end
|
17
|
+
|
18
|
+
Facter.add('chef_version') do
|
19
|
+
setcode { %x{chef-client --version}.chomp.split(' ').last.strip rescue nil }
|
20
|
+
end
|
21
|
+
|
22
|
+
Facter.add('chef_environment') do
|
23
|
+
setcode { chef['environment'].to_s.strip.chomp.downcase rescue nil }
|
24
|
+
end
|
25
|
+
|
26
|
+
Facter.add('chef_runlist') do
|
27
|
+
setcode { chef['run_list'].collect{|i| i.gsub('[','-').gsub(']','').gsub('::','-') } rescue nil }
|
28
|
+
end
|
29
|
+
|
30
|
+
Facter.add('chef_enabled') do
|
31
|
+
setcode { !File.exists?('/outbrain/no_chef_run') }
|
32
|
+
end
|
33
|
+
|
34
|
+
Facter.add('chef_lastrun') do
|
35
|
+
setcode { File.mtime('/etc/chef/last_ran_at').to_i rescue nil }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
rescue Exception => e
|
39
|
+
STDERR.puts "#{e.name}: #{e.message}"
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
Facter.add('signature') do
|
2
|
+
setcode do
|
3
|
+
if Facter.value('macaddress')
|
4
|
+
if Facter.value('is_virtual')
|
5
|
+
if File.exists?('/sys/hypervisor/uuid')
|
6
|
+
parts = [
|
7
|
+
File.read('/sys/hypervisor/uuid').strip.chomp.delete('-'),
|
8
|
+
Facter.value('macaddress').strip.delete(':')
|
9
|
+
]
|
10
|
+
end
|
11
|
+
elsif Facter::Util::Resolution.which('dmidecode')
|
12
|
+
parts = [
|
13
|
+
Facter::Util::Resolution.exec('dmidecode -s system-uuid').strip.chomp.delete('-'),
|
14
|
+
Facter.value('macaddress').strip.delete(':')
|
15
|
+
]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
(parts ? parts.collect{|i| i.upcase }.join('-') : nil)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
Facter.add('hardwareid') do
|
24
|
+
setcode do
|
25
|
+
if File.size?('/etc/hardware.id')
|
26
|
+
File.read('/etc/hardware.id').strip.chomp rescue nil
|
27
|
+
elsif Facter.value('signature')
|
28
|
+
require 'digest'
|
29
|
+
Digest::SHA256.new.update(Facter.value('signature')).hexdigest[0..5]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'resolv'
|
2
|
+
|
3
|
+
protocols = %w{tcp}
|
4
|
+
|
5
|
+
flags = "--numeric-hosts --numeric-ports --programs --tcp -ee"
|
6
|
+
|
7
|
+
case Facter.value('osfamily').to_s.downcase
|
8
|
+
when 'debian' then flags += " -W"
|
9
|
+
when 'redhat' then flags += " -T"
|
10
|
+
end
|
11
|
+
|
12
|
+
listening = Facter::Util::Resolution.exec("netstat #{flags} -l | tr -s ' '")
|
13
|
+
nonlistening = Facter::Util::Resolution.exec("netstat #{flags} | tr -s ' '")
|
14
|
+
|
15
|
+
netstat = {
|
16
|
+
'listening' => [],
|
17
|
+
'connections' => []
|
18
|
+
}
|
19
|
+
|
20
|
+
def getcommandline(pid)
|
21
|
+
return nil unless pid.to_i > 0
|
22
|
+
(File.read("/proc/#{pid}/cmdline").to_s.strip.chomp.squeeze("\u0000").squeeze("\0").gsub("\u0000", ' ').gsub("\0", ' '))
|
23
|
+
end
|
24
|
+
|
25
|
+
listening.lines.to_a[2..-1].each do |line|
|
26
|
+
protocol, recvq, sendq, local, foreign, state, user, inode, program = line.split(' ', 9)
|
27
|
+
next unless protocols.include?(protocol)
|
28
|
+
|
29
|
+
local = local.split(':')
|
30
|
+
foreign = foreign.split(':')
|
31
|
+
local_host = local[-2]
|
32
|
+
local_port = local[-1]
|
33
|
+
foreign_host = foreign[-2]
|
34
|
+
foreign_port = foreign[-1]
|
35
|
+
pid = program.split('/').first
|
36
|
+
|
37
|
+
netstat['listening'] << {
|
38
|
+
"protocol" => protocol,
|
39
|
+
"address" => local_host,
|
40
|
+
"fqdn" => (Resolv.getname(local_host) rescue nil),
|
41
|
+
"port" => local_port.to_i,
|
42
|
+
"user" => user,
|
43
|
+
"program" => {
|
44
|
+
"pid" => pid.to_i,
|
45
|
+
"command" => getcommandline(pid)
|
46
|
+
}
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
nonlistening.lines.to_a[2..-1].each do |line|
|
51
|
+
protocol, recvq, sendq, local, foreign, state, user, inode, program = line.split(' ', 9)
|
52
|
+
next unless protocols.include?(protocol)
|
53
|
+
|
54
|
+
local = local.split(':')
|
55
|
+
foreign = foreign.split(':')
|
56
|
+
local_host = local[-2]
|
57
|
+
local_port = local[-1]
|
58
|
+
foreign_host = foreign[-2]
|
59
|
+
foreign_port = foreign[-1]
|
60
|
+
pid = program.split('/').first
|
61
|
+
|
62
|
+
netstat['connections'] << {
|
63
|
+
"protocol" => protocol,
|
64
|
+
"from" => {
|
65
|
+
"address" => local_host,
|
66
|
+
"port" => local_port.to_i
|
67
|
+
},
|
68
|
+
"to" => {
|
69
|
+
"address" => foreign_host,
|
70
|
+
"fqdn" => (Resolv.getname(foreign_host) rescue nil),
|
71
|
+
"port" => foreign_port.to_i
|
72
|
+
},
|
73
|
+
"user" => user,
|
74
|
+
"state" => state.downcase,
|
75
|
+
"program" => {
|
76
|
+
"pid" => pid.to_i,
|
77
|
+
"command" => getcommandline(pid)
|
78
|
+
}
|
79
|
+
}
|
80
|
+
end
|
81
|
+
|
82
|
+
Facter.add("netstat") do
|
83
|
+
setcode do
|
84
|
+
netstat
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,173 @@
|
|
1
|
+
|
2
|
+
def _format(key, value)
|
3
|
+
rv = []
|
4
|
+
value = nil if value =~ /Not received/i
|
5
|
+
|
6
|
+
begin
|
7
|
+
case key
|
8
|
+
when :autoneg
|
9
|
+
v0, v1 = value.split('/')
|
10
|
+
rv << [:autoneg_supported, (v0 == 'supported')]
|
11
|
+
rv << [:autoneg_enabled, (v1 == 'enabled')]
|
12
|
+
|
13
|
+
when :mgmt_ip
|
14
|
+
rv << [:management_ip, value]
|
15
|
+
|
16
|
+
when :mau_oper_type
|
17
|
+
rv << [:mau_type, value]
|
18
|
+
|
19
|
+
when :port_id
|
20
|
+
value = value.split(' ')
|
21
|
+
value = value.select{|i| i =~ /..:..:..:..:..:../ }.first
|
22
|
+
|
23
|
+
rv << [:port_mac, value.upcase]
|
24
|
+
|
25
|
+
when :chassis_id
|
26
|
+
value = value.split(' ')
|
27
|
+
value = value.select{|i| i =~ /..:..:..:..:..:../ }.first
|
28
|
+
|
29
|
+
rv << [:chassis_mac, value.upcase]
|
30
|
+
|
31
|
+
when :port_descr
|
32
|
+
port = value.split(/[^0-9]([0-9])/, 2)
|
33
|
+
port.shift
|
34
|
+
port = port.join('')
|
35
|
+
|
36
|
+
rv << [:port_name, value]
|
37
|
+
rv << [:port, port]
|
38
|
+
|
39
|
+
when :mfs
|
40
|
+
rv << [:mfs, (value.split(' ').first.to_i rescue nil)]
|
41
|
+
|
42
|
+
when :sys_name
|
43
|
+
|
44
|
+
rv << [:switch, value]
|
45
|
+
|
46
|
+
when :lldp_med_device_type,
|
47
|
+
:lldp_med_capabilities,
|
48
|
+
:caps,
|
49
|
+
:sys_descr
|
50
|
+
return []
|
51
|
+
|
52
|
+
else
|
53
|
+
rv << [key, value]
|
54
|
+
end
|
55
|
+
rescue
|
56
|
+
nil
|
57
|
+
end
|
58
|
+
|
59
|
+
return rv
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
# Typefix for interfaces fact
|
64
|
+
Facter.add('network_interfaces') do
|
65
|
+
setcode do
|
66
|
+
Facter.value("interfaces").split(',')
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
default_if = Facter::Util::Resolution.exec('route -n | grep "^0.0.0.0" | tr -s " " | cut -d " " -f8')
|
71
|
+
|
72
|
+
Facter.add('default_gateway') do
|
73
|
+
setcode do
|
74
|
+
Facter::Util::Resolution.exec('route -n | grep "UG" | tr -s " " | cut -d" " -f2')
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
if default_if
|
79
|
+
begin
|
80
|
+
default_if.strip!
|
81
|
+
default_if.chomp!
|
82
|
+
|
83
|
+
Facter.add('default_interface') do
|
84
|
+
setcode { default_if }
|
85
|
+
end
|
86
|
+
|
87
|
+
Facter.add('default_macaddress') do
|
88
|
+
setcode { Facter.value("macaddress_#{default_if}") }
|
89
|
+
end
|
90
|
+
rescue
|
91
|
+
nil
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# LLDP
|
96
|
+
begin
|
97
|
+
current_iface = nil
|
98
|
+
network_lldp = {}
|
99
|
+
|
100
|
+
output = Facter::Util::Resolution.exec('lldpctl')
|
101
|
+
|
102
|
+
if output
|
103
|
+
output.gsub(/^\s+/,'').lines do |line|
|
104
|
+
key, value = line.strip.chomp.squeeze(' ').split(/:\s+/, 2)
|
105
|
+
|
106
|
+
if key and value
|
107
|
+
key.gsub!(/ID$/, '_id')
|
108
|
+
key.gsub!(/[\-\s]+/, '_')
|
109
|
+
key.gsub!(/([a-z])([A-Z])/, '\1_\2')
|
110
|
+
key = key.downcase.strip.to_sym
|
111
|
+
value.strip!
|
112
|
+
kvs = _format(key,value)
|
113
|
+
|
114
|
+
kvs.each do |k, v|
|
115
|
+
next unless k and v
|
116
|
+
|
117
|
+
if k == :interface
|
118
|
+
current_iface = v.split(',').first.to_sym
|
119
|
+
else
|
120
|
+
network_lldp[current_iface] = {} unless network_lldp[current_iface]
|
121
|
+
network_lldp[current_iface][k] = v
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
network_lldp.each do |iface, lldp|
|
129
|
+
lldp.each do |key, value|
|
130
|
+
Facter.add("lldp_#{key}_#{iface}") do
|
131
|
+
setcode { value }
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
|
137
|
+
# Bonding Configuration
|
138
|
+
if Facter.value("osfamily") == "RedHat"
|
139
|
+
interfaces = {}
|
140
|
+
|
141
|
+
Facter.value('network_interfaces').each do |iface|
|
142
|
+
if File.exists?("/etc/sysconfig/network-scripts/ifcfg-#{iface}")
|
143
|
+
sysconfig = Hash[File.read("/etc/sysconfig/network-scripts/ifcfg-#{iface}").lines.collect {|line|
|
144
|
+
key, value = line.split('=', 2)
|
145
|
+
next unless key and value
|
146
|
+
[key.downcase.to_sym, value.strip.chomp]
|
147
|
+
}]
|
148
|
+
|
149
|
+
|
150
|
+
if sysconfig[:master] and (sysconfig[:slave] == 'yes')
|
151
|
+
Facter.add("bonding_master_#{iface}") do
|
152
|
+
setcode { sysconfig[:master] }
|
153
|
+
end
|
154
|
+
elsif not (sysconfig[:slave] == 'yes')
|
155
|
+
if sysconfig[:bonding_opts]
|
156
|
+
opts = Hash[sysconfig[:bonding_opts].gsub(/(^\"|\"$)/,'').split(/\s+/).collect{ |pair|
|
157
|
+
pair.split('=')
|
158
|
+
}]
|
159
|
+
|
160
|
+
opts.each do |key, value|
|
161
|
+
Facter.add("bonding_#{key}_#{iface}") do
|
162
|
+
setcode { value }
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
rescue Exception => e
|
172
|
+
STDERR.puts "#{e.name}: #{e.message}"
|
173
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
Facter.add('site') do
|
2
|
+
setcode do
|
3
|
+
if File.size?('/etc/onering/static/site')
|
4
|
+
site = File.read('/etc/onering/static/site').strip.chomp
|
5
|
+
|
6
|
+
else
|
7
|
+
if File.exists?('/proc/cmdline')
|
8
|
+
site = (File.read('/proc/cmdline').chomp.split(' ').select{|i| i =~ /^domain=/ }.first rescue nil)
|
9
|
+
site = site.split('=', 2).last if site
|
10
|
+
site = site.split('.').first if site
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
site = nil if ['test', 'hw', 'vm'].include?(site)
|
15
|
+
|
16
|
+
if site
|
17
|
+
site
|
18
|
+
else
|
19
|
+
Facter.value('fqdn').split('.')[-3].downcase rescue nil
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
Facter.add('environment') do
|
25
|
+
setcode do
|
26
|
+
env = (Facter.value('fqdn').split('.').first.split('-')[-2].downcase rescue nil)
|
27
|
+
|
28
|
+
case env
|
29
|
+
when 'dev'
|
30
|
+
'development'
|
31
|
+
when /(stg|stage)/
|
32
|
+
'staging'
|
33
|
+
when 'prod'
|
34
|
+
'production'
|
35
|
+
else
|
36
|
+
nil
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
Facter.add('slot') do
|
42
|
+
setcode do
|
43
|
+
slot = Integer(Facter::Util::Resolution.exec("bmc node_number 2> /dev/null")) rescue nil
|
44
|
+
slot = nil if slot == 0
|
45
|
+
slot
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
ipmi_ok = (Facter::Util::Resolution.exec("ipmiutil health 2> /dev/null | tail -n1 | grep failed") === nil)
|
51
|
+
|
52
|
+
if ipmi_ok
|
53
|
+
ipmi_lan = Facter::Util::Resolution.exec("ipmitool lan print 1 2> /dev/null")
|
54
|
+
|
55
|
+
if ipmi_lan
|
56
|
+
ipmi_lan_data = {}
|
57
|
+
|
58
|
+
ipmi_lan.lines.each do |line|
|
59
|
+
key, value = line.split(/:/, 2)
|
60
|
+
value = value.strip.squeeze(' ').chomp
|
61
|
+
|
62
|
+
case key
|
63
|
+
when /^IP Address/i
|
64
|
+
ipmi_lan_data[:ip] = value
|
65
|
+
|
66
|
+
when /^Subnet Mask/i
|
67
|
+
ipmi_lan_data[:netmask] = value
|
68
|
+
|
69
|
+
when /^MAC Address/i
|
70
|
+
ipmi_lan_data[:macaddress] = value.upcase
|
71
|
+
|
72
|
+
when /^Default Gateway IP/i
|
73
|
+
ipmi_lan_data[:gateway] = value
|
74
|
+
|
75
|
+
when /^SNMP Community String/i
|
76
|
+
ipmi_lan_data[:snmp_community] = value
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
ipmi_lan_data.each do |key, value|
|
82
|
+
Facter.add("ipmi_#{key}") do
|
83
|
+
setcode { value }
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# Onering Facts - Service List
|
2
|
+
# provides list of certain services that are running on a machine
|
3
|
+
#
|
4
|
+
|
5
|
+
|
6
|
+
Facter.add('services') do
|
7
|
+
def get_service_list()
|
8
|
+
rv = []
|
9
|
+
case Facter.value('osfamily')
|
10
|
+
when 'Debian'
|
11
|
+
rv = IO.popen('find /etc/init.d -maxdepth 1 -type f -executable | cut -d"/" -f4 | sort | uniq').lines
|
12
|
+
when 'RedHat'
|
13
|
+
rv = IO.popen('chkconfig --list | grep "3:on" | tr "\t" " " | cut -d" " -f1 | sort | uniq').lines
|
14
|
+
end
|
15
|
+
|
16
|
+
rv.collect {|i| i.strip.chomp }.reject{|i| i.empty? }
|
17
|
+
end
|
18
|
+
|
19
|
+
setcode do
|
20
|
+
acceptable = (File.read('/etc/onering/services.list').lines.collect{|i| i.strip.chomp }.reject{|i| i.empty? } rescue [])
|
21
|
+
actual = get_service_list()
|
22
|
+
|
23
|
+
(acceptable & actual)
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# Onering Facts - Xen Properties
|
2
|
+
# provides collection of Xen (host and guest) properties
|
3
|
+
#
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
# get list of xen guest UUIDs
|
7
|
+
xen = Facter::Util::Resolution.exec("xm list --long 2> /dev/null | grep uuid")
|
8
|
+
|
9
|
+
if xen
|
10
|
+
xen_uuid = []
|
11
|
+
|
12
|
+
xen.lines.each do |line|
|
13
|
+
xen_uuid << line.strip.chomp.split(/[\s+\)]/).last
|
14
|
+
end
|
15
|
+
|
16
|
+
if not xen_uuid.empty?
|
17
|
+
Facter.add('xen_guests') do
|
18
|
+
setcode { xen_uuid.reject{|i| i =~ /^0{8}/ } }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# current xen guest: uuid
|
24
|
+
if File.exists?("/sys/hypervisor/uuid")
|
25
|
+
uuid = (File.read("/sys/hypervisor/uuid").strip.chomp rescue nil)
|
26
|
+
|
27
|
+
if uuid and not uuid =~ /^0{8}/
|
28
|
+
Facter.add("xen_uuid") do
|
29
|
+
setcode { uuid }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# Onering Collector - Chef Properties plugin
|
2
|
+
# provides collection of Chef metadata
|
3
|
+
#
|
4
|
+
report do
|
5
|
+
chef = {
|
6
|
+
:name => Facter.value('chef_nodename'),
|
7
|
+
:environment => Facter.value('chef_environment'),
|
8
|
+
:@run_list => Facter.value('chef_runlist'),
|
9
|
+
:enabled => Facter.value('chef_enabled'),
|
10
|
+
:version => Facter.value('chef_version'),
|
11
|
+
:last_ran_at => (Time.at(Facter.value('chef_lastrun')) rescue nil)
|
12
|
+
}.reject{|k,v| v === nil }
|
13
|
+
|
14
|
+
property :chef, chef unless chef.empty?
|
15
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# Onering Collector - Facter Properties plugin
|
2
|
+
# provides a configurable list of Facter facts that should be sent to the
|
3
|
+
# Onering API
|
4
|
+
#
|
5
|
+
# Properties defined in /etc/onering/facter.list
|
6
|
+
#
|
7
|
+
|
8
|
+
report do
|
9
|
+
def cleanup_dirty_values(k, v)
|
10
|
+
return case k
|
11
|
+
when 'mbserial' then v.to_s.gsub(/(^\.+|\.+$)/,'').gsub('.','-')
|
12
|
+
else (v.strip.chomp rescue nil)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
if defined?(Facter)
|
17
|
+
# get a list of Facter attributes to list
|
18
|
+
if File.exists?("/etc/onering/facter.list")
|
19
|
+
IO.readlines("/etc/onering/facter.list").each do |line|
|
20
|
+
# strip whitespace/kill newline
|
21
|
+
line.strip!
|
22
|
+
line.chomp!
|
23
|
+
next if line.empty?
|
24
|
+
line = line.downcase
|
25
|
+
|
26
|
+
unless line =~ /^#/
|
27
|
+
begin
|
28
|
+
line = line.split(':')
|
29
|
+
key = (line.length == 1 ? line.first : line.last)
|
30
|
+
val = cleanup_dirty_values(key, Facter.value(line.first))
|
31
|
+
|
32
|
+
property key.to_sym, val
|
33
|
+
rescue Exception
|
34
|
+
STDERR.puts e.message
|
35
|
+
next
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
report do
|
2
|
+
interfaces = {}
|
3
|
+
|
4
|
+
Facter.value('network_interfaces').each do |iface|
|
5
|
+
iface = iface.to_sym
|
6
|
+
next if [:dummy0, :lo, :sit0].include?(iface)
|
7
|
+
interfaces[iface] ||= {}
|
8
|
+
|
9
|
+
mac = (Facter.value("macaddress_#{iface}").upcase rescue nil)
|
10
|
+
mtu = (Integer(Facter.value("mtu_#{iface}")) rescue nil)
|
11
|
+
|
12
|
+
interfaces[iface][:name] = iface
|
13
|
+
interfaces[iface][:mac] = mac if mac
|
14
|
+
interfaces[iface][:mtu] = mtu if mtu
|
15
|
+
|
16
|
+
addresses = [{
|
17
|
+
:ip => Facter.value("ipaddress_#{iface}"),
|
18
|
+
:netmask => Facter.value("netmask_#{iface}")
|
19
|
+
}.reject{|k,v| v === nil }]
|
20
|
+
|
21
|
+
interfaces[iface][:addresses] = addresses unless addresses.empty? or addresses.reject{|i| i.empty? }.empty?
|
22
|
+
|
23
|
+
# LLDP autodiscovery
|
24
|
+
switch = {
|
25
|
+
:name => Facter.value("lldp_switch_#{iface}"),
|
26
|
+
:port => Facter.value("lldp_port_#{iface}"),
|
27
|
+
:port_name => Facter.value("lldp_port_name_#{iface}"),
|
28
|
+
:port_mac => Facter.value("lldp_port_mac_#{iface}"),
|
29
|
+
:ip => Facter.value("lldp_management_ip_#{iface}"),
|
30
|
+
:chassis_mac => Facter.value("lldp_chassis_mac_#{iface}"),
|
31
|
+
:mfs => Facter.value("lldp_mfs_#{iface}")
|
32
|
+
}.reject{|k,v| v === nil }
|
33
|
+
|
34
|
+
|
35
|
+
# Bonding configuration
|
36
|
+
|
37
|
+
# slaves
|
38
|
+
master = Facter.value("bonding_master_#{iface}")
|
39
|
+
interfaces[iface][:master] = master if master
|
40
|
+
|
41
|
+
# masters
|
42
|
+
bond = {
|
43
|
+
:arp_ip_target => Facter.value("bonding_arp_ip_target_#{iface}")
|
44
|
+
}.reject {|k,v| v === nil }
|
45
|
+
|
46
|
+
|
47
|
+
# conditionally add applicable subsections
|
48
|
+
interfaces[iface][:switch] = switch unless switch.empty?
|
49
|
+
interfaces[iface][:bonding] = bond unless bond.empty?
|
50
|
+
end
|
51
|
+
|
52
|
+
property :network, {
|
53
|
+
:@interfaces => interfaces.values
|
54
|
+
}
|
55
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# Onering Collector - Ohai Properties plugin
|
2
|
+
# provides a configurable list of Ohai attributes that should be sent to the
|
3
|
+
# Onering API
|
4
|
+
#
|
5
|
+
# Properties defined in /etc/onering/ohai.list
|
6
|
+
#
|
7
|
+
|
8
|
+
report do
|
9
|
+
if defined?(Ohai)
|
10
|
+
def cleanup_dirty_values(k, v)
|
11
|
+
return case k
|
12
|
+
when 'mbserial' then v.to_s.gsub(/(^\.+|\.+$)/,'').gsub('.','-')
|
13
|
+
else v
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# get a list of ohai attributes to list
|
18
|
+
if File.exists?("/etc/onering/ohai.list")
|
19
|
+
IO.readlines("/etc/onering/ohai.list").each do |line|
|
20
|
+
# trip whitespace/kill newline
|
21
|
+
line.strip!
|
22
|
+
line.chomp!
|
23
|
+
next if line.empty?
|
24
|
+
line = line.downcase
|
25
|
+
|
26
|
+
unless line =~ /^#/
|
27
|
+
begin
|
28
|
+
parts = line.split(".")
|
29
|
+
root = @ohai
|
30
|
+
|
31
|
+
parts.each do |part|
|
32
|
+
part = part.split(':')
|
33
|
+
key = part.first
|
34
|
+
alt = part.last
|
35
|
+
|
36
|
+
if root[key]
|
37
|
+
if root[key].is_a?(Hash)
|
38
|
+
root = root[key]
|
39
|
+
next
|
40
|
+
else
|
41
|
+
val = [*root[key]].collect{|i| i.strip.chomp rescue i }
|
42
|
+
val = val.first if val.length == 1
|
43
|
+
val = cleanup_dirty_values(alt, val)
|
44
|
+
val.strip! if val.is_a?(String)
|
45
|
+
|
46
|
+
# set property value
|
47
|
+
property alt, val
|
48
|
+
break
|
49
|
+
end
|
50
|
+
else
|
51
|
+
break
|
52
|
+
end
|
53
|
+
end
|
54
|
+
rescue Exception
|
55
|
+
STDERR.puts e.message
|
56
|
+
next
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# Onering Collector - Physical Properties plugin
|
2
|
+
# provides collection of hardware location data using vendor tools
|
3
|
+
#
|
4
|
+
|
5
|
+
report do
|
6
|
+
property :site, Facter.value('site')
|
7
|
+
property :environment, Facter.value('environment')
|
8
|
+
property :slot, Facter.value('slot')
|
9
|
+
property :virtual, Facter.value('is_virtual')
|
10
|
+
property :ipmi_ip, Facter.value('ipmi_ip')
|
11
|
+
property :ipmi_netmask, Facter.value('ipmi_netmask')
|
12
|
+
property :ipmi_gateway, Facter.value('ipmi_gateway')
|
13
|
+
property :ipmi_macaddress, Facter.value('ipmi_macaddress')
|
14
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# Onering Collector - Xen Properties plugin
|
2
|
+
# provides collection of Xen metadata
|
3
|
+
#
|
4
|
+
report do
|
5
|
+
xen_guests = Facter.value('xen_guests')
|
6
|
+
xen_guest_uuid = Facter.value('xen_uuid')
|
7
|
+
xen = {}
|
8
|
+
|
9
|
+
# xen host
|
10
|
+
xen[:@guests] = xen_guests if xen_guests
|
11
|
+
|
12
|
+
# xen guest
|
13
|
+
xen[:uuid] = xen_guest_uuid if xen_guest_uuid
|
14
|
+
|
15
|
+
property :xen, xen
|
16
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# Onering Collector - Base Statistics plugin
|
2
|
+
# provides basic system statistics and hardware profile to the Onering API
|
3
|
+
#
|
4
|
+
|
5
|
+
report do
|
6
|
+
# ------------------------------------------------------------------------------
|
7
|
+
# filesystem
|
8
|
+
#
|
9
|
+
stats_fs = {}
|
10
|
+
current_dev = nil
|
11
|
+
|
12
|
+
# logical mounts
|
13
|
+
File.open("/etc/mtab").each do |line|
|
14
|
+
dev,mount,fstype,flags,dump,pass = line.split(/\s+/)
|
15
|
+
|
16
|
+
stats_fs[dev] = {
|
17
|
+
:mount => mount,
|
18
|
+
:device => dev,
|
19
|
+
:filesystem => fstype,
|
20
|
+
:flags => flags.split(/\s*,\s*/)
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
# logical space utilization
|
25
|
+
IO.popen("df").lines.each do |line|
|
26
|
+
next if line =~ /^Filesystem/
|
27
|
+
parts = line.split(/\s+/)
|
28
|
+
|
29
|
+
if parts.length == 1
|
30
|
+
current_dev = parts.first
|
31
|
+
next
|
32
|
+
|
33
|
+
else
|
34
|
+
dev,kblk,used,free,percent,mount = parts
|
35
|
+
dev = current_dev if dev.empty?
|
36
|
+
next unless stats_fs[dev] and stats_fs[dev].is_a?(Hash)
|
37
|
+
|
38
|
+
stats_fs[dev][:used] = (used.to_i * 1024)
|
39
|
+
stats_fs[dev][:available] = (free.to_i * 1024)
|
40
|
+
stats_fs[dev][:total] = (stats_fs[dev][:available] + stats_fs[dev][:used])
|
41
|
+
stats_fs[dev][:percent_used] = percent.delete('%').to_i
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
# ------------------------------------------------------------------------------
|
47
|
+
# memory
|
48
|
+
#
|
49
|
+
stats_mem = {}
|
50
|
+
|
51
|
+
File.open("/proc/meminfo").each do |line|
|
52
|
+
case line
|
53
|
+
when /^MemTotal:\s+(\d+)/
|
54
|
+
stats_mem[:total] = ($1.to_i * 1024)
|
55
|
+
when /^SwapTotal:\s+(\d+)/
|
56
|
+
stats_mem[:swap] = ($1.to_i * 1024)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
# ------------------------------------------------------------------------------
|
62
|
+
# cpu
|
63
|
+
#
|
64
|
+
stats_cpu = {
|
65
|
+
:count => 0,
|
66
|
+
:processors => []
|
67
|
+
}
|
68
|
+
|
69
|
+
current_cpu = nil
|
70
|
+
|
71
|
+
File.open("/proc/cpuinfo").each do |line|
|
72
|
+
case line
|
73
|
+
when /processor\s+:\s(.+)/
|
74
|
+
current_cpu = $1.to_i
|
75
|
+
stats_cpu[:count] += 1
|
76
|
+
stats_cpu[:processors][current_cpu] = {
|
77
|
+
:number => current_cpu
|
78
|
+
}
|
79
|
+
when /cpu MHz\s+:\s(.+)/
|
80
|
+
stats_cpu[:processors][current_cpu][:speed] = $1.to_f
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
# ------------------------------------------------------------------------------
|
86
|
+
# set stat properties
|
87
|
+
#
|
88
|
+
stat :disk, stats_fs.select{|k,v| k =~ /^\/dev\/((h|s|xv|v)d|mapper)/ }.values rescue []
|
89
|
+
stat :memory, stats_mem
|
90
|
+
stat :cpu, ({
|
91
|
+
'count' => stats_cpu[:count].to_i,
|
92
|
+
'speed' => stats_cpu[:processors].collect{|i| i[:speed] }.compact.uniq.sort{|a,b| a.to_f <=> b.to_f }.last.to_f
|
93
|
+
} rescue nil)
|
94
|
+
end
|
metadata
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: onering-report-plugins
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Gary Hetzel
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-04-09 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: onering-client
|
16
|
+
requirement: &18089540 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *18089540
|
25
|
+
description: Base plugins for providing system information via the Onering client
|
26
|
+
utility
|
27
|
+
email: ghetzel@outbrain.com
|
28
|
+
executables: []
|
29
|
+
extensions: []
|
30
|
+
extra_rdoc_files: []
|
31
|
+
files:
|
32
|
+
- lib/facter/onering_properties_network.rb
|
33
|
+
- lib/facter/onering_properties_netstat.rb
|
34
|
+
- lib/facter/onering_properties_services.rb
|
35
|
+
- lib/facter/onering_properties_chef.rb
|
36
|
+
- lib/facter/onering_properties_physical.rb
|
37
|
+
- lib/facter/onering_properties_id.rb
|
38
|
+
- lib/facter/onering_properties_xen.rb
|
39
|
+
- lib/reporter/default/properties_physical.rb
|
40
|
+
- lib/reporter/default/properties_facter.rb
|
41
|
+
- lib/reporter/default/properties_xen.rb
|
42
|
+
- lib/reporter/default/properties_chef.rb
|
43
|
+
- lib/reporter/default/stats_network.rb
|
44
|
+
- lib/reporter/default/properties_ohai.rb
|
45
|
+
- lib/reporter/default/properties_network.rb
|
46
|
+
- lib/reporter/default/properties_services.rb
|
47
|
+
- lib/reporter/default/stats_base.rb
|
48
|
+
homepage: https://github.com/outbrain/onering-report-plugins
|
49
|
+
licenses: []
|
50
|
+
post_install_message:
|
51
|
+
rdoc_options: []
|
52
|
+
require_paths:
|
53
|
+
- lib
|
54
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
56
|
+
requirements:
|
57
|
+
- - ! '>='
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '0'
|
60
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
requirements: []
|
67
|
+
rubyforge_project:
|
68
|
+
rubygems_version: 1.8.11
|
69
|
+
signing_key:
|
70
|
+
specification_version: 3
|
71
|
+
summary: Onering system reporting plugins
|
72
|
+
test_files: []
|