onering-report-plugins 0.0.1
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/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: []
|