onering-report 0.6.5
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.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +57 -0
- data/Makefile +2 -0
- data/Rakefile +8 -0
- data/lib/etc/facter.list +19 -0
- data/lib/facter/onering_disk_smart.rb +38 -0
- data/lib/facter/onering_properties_chef.rb +41 -0
- data/lib/facter/onering_properties_haproxy.rb +155 -0
- data/lib/facter/onering_properties_id.rb +69 -0
- data/lib/facter/onering_properties_netstat.rb +94 -0
- data/lib/facter/onering_properties_network.rb +253 -0
- data/lib/facter/onering_properties_onering.rb +17 -0
- data/lib/facter/onering_properties_openvz.rb +17 -0
- data/lib/facter/onering_properties_physical.rb +87 -0
- data/lib/facter/onering_properties_services.rb +25 -0
- data/lib/facter/onering_properties_system.rb +18 -0
- data/lib/facter/onering_properties_virident.rb +93 -0
- data/lib/facter/onering_properties_xen.rb +32 -0
- data/lib/facter/onering_properties_zfs.rb +174 -0
- data/lib/reporter/default/properties_chef.rb +15 -0
- data/lib/reporter/default/properties_facter.rb +51 -0
- data/lib/reporter/default/properties_haproxy.rb +8 -0
- data/lib/reporter/default/properties_ipmi.rb +10 -0
- data/lib/reporter/default/properties_network.rb +63 -0
- data/lib/reporter/default/properties_ohai.rb +62 -0
- data/lib/reporter/default/properties_openvz.rb +12 -0
- data/lib/reporter/default/properties_physical.rb +10 -0
- data/lib/reporter/default/properties_services.rb +6 -0
- data/lib/reporter/default/properties_system_cpu.rb +30 -0
- data/lib/reporter/default/properties_system_disk_block.rb +35 -0
- data/lib/reporter/default/properties_system_disk_lvm.rb +73 -0
- data/lib/reporter/default/properties_system_disk_mounts.rb +46 -0
- data/lib/reporter/default/properties_system_disk_smart.rb +3 -0
- data/lib/reporter/default/properties_system_memory.rb +111 -0
- data/lib/reporter/default/properties_xen.rb +16 -0
- data/lib/reporter/default/stats_virident.rb +8 -0
- data/lib/reporter/default/stats_zfs.rb +8 -0
- data/onering-report.gemspec +18 -0
- metadata +126 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2ec8274d268a961e2138cb05c7371610982db522
|
4
|
+
data.tar.gz: 0faf9d2467b487596783743c9485940149016d89
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 73c92ee34a7b60620f9c9d232a1ee11ea72d53dd5f23e32c29e3baeb74b995f1a3aee9eb2397181971a9fc2f755bea98f5cade44ce5bc9be3471c768b6a51d2e
|
7
|
+
data.tar.gz: 9a79363d52c99399801d87206bf9171708f5930b698d5e2dea9174ab2468495329d9ffd2a2ecab3b53c60eb6418c531e7c2f132111498a9057d271a6e40eb664
|
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
*.gem
|
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
onering-report
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby-2.1.2
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
onering-report (0.6.5)
|
5
|
+
onering-client
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
CFPropertyList (2.2.8)
|
11
|
+
addressable (2.3.5)
|
12
|
+
coderay (1.1.0)
|
13
|
+
deep_merge (1.0.0)
|
14
|
+
facter (2.1.0)
|
15
|
+
CFPropertyList (~> 2.2.6)
|
16
|
+
hashlib (0.0.35)
|
17
|
+
hiera (1.3.4)
|
18
|
+
json_pure
|
19
|
+
httparty (0.11.0)
|
20
|
+
multi_json (~> 1.0)
|
21
|
+
multi_xml (>= 0.5.2)
|
22
|
+
json_pure (1.8.1)
|
23
|
+
method_source (0.8.2)
|
24
|
+
multi_json (1.7.9)
|
25
|
+
multi_xml (0.5.5)
|
26
|
+
onering-client (0.4.3)
|
27
|
+
addressable (= 2.3.5)
|
28
|
+
deep_merge (= 1.0.0)
|
29
|
+
facter (>= 1.7.2)
|
30
|
+
hashlib (>= 0.0.35)
|
31
|
+
httparty (= 0.11.0)
|
32
|
+
multi_json (= 1.7.9)
|
33
|
+
rainbow (<= 1.1.4)
|
34
|
+
trollop (= 2.0)
|
35
|
+
xml-simple (= 1.1.2)
|
36
|
+
pry (0.10.0)
|
37
|
+
coderay (~> 1.1.0)
|
38
|
+
method_source (~> 0.8.1)
|
39
|
+
slop (~> 3.4)
|
40
|
+
puppet (3.6.2)
|
41
|
+
facter (> 1.6, < 3)
|
42
|
+
hiera (~> 1.0)
|
43
|
+
json_pure
|
44
|
+
rgen (~> 0.6.5)
|
45
|
+
rainbow (1.1.4)
|
46
|
+
rgen (0.6.6)
|
47
|
+
slop (3.6.0)
|
48
|
+
trollop (2.0)
|
49
|
+
xml-simple (1.1.2)
|
50
|
+
|
51
|
+
PLATFORMS
|
52
|
+
ruby
|
53
|
+
|
54
|
+
DEPENDENCIES
|
55
|
+
onering-report!
|
56
|
+
pry
|
57
|
+
puppet
|
data/Makefile
ADDED
data/Rakefile
ADDED
data/lib/etc/facter.list
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
serialnumber:serial
|
2
|
+
manufacturer:make
|
3
|
+
productname:model
|
4
|
+
boardmanufacturer:mbmake
|
5
|
+
boardproductname:mbmodel
|
6
|
+
boardserialnumber:mbserial
|
7
|
+
hostname
|
8
|
+
fqdn
|
9
|
+
default_ipaddress:ip
|
10
|
+
default_macaddress:mac
|
11
|
+
default_gateway:gateway
|
12
|
+
kernelrelease:kernel
|
13
|
+
kernelarguments:@kernelarguments
|
14
|
+
architecture:arch
|
15
|
+
operatingsystem:distro
|
16
|
+
operatingsystemrelease:version
|
17
|
+
signature
|
18
|
+
boottime:booted_at
|
19
|
+
onering:@onering
|
@@ -0,0 +1,38 @@
|
|
1
|
+
if Facter::Util::Resolution.which('smartctl')
|
2
|
+
disks = []
|
3
|
+
letters = (('a'..'z').to_a + ('a'..'z').to_a.collect{|i| ('a'..'z').to_a.collect{|j| i+j }}.flatten)
|
4
|
+
|
5
|
+
letters.each do |i|
|
6
|
+
if File.exists?("/dev/sd#{i}")
|
7
|
+
smart = {}
|
8
|
+
|
9
|
+
Facter::Util::Resolution.exec("smartctl -A /dev/sd#{i}").to_s.lines.each do |line|
|
10
|
+
next unless line =~ /^\s*[0-9]+/
|
11
|
+
id, name, flag, value, worst, threshold, type, updated, failed, raw = line.strip.chomp.split(/\s+/)
|
12
|
+
|
13
|
+
smart[:attributes] ||= []
|
14
|
+
smart[:attributes] << {
|
15
|
+
:id => id.to_i,
|
16
|
+
:name => name.downcase.gsub(/[\s\-]+/, '_'),
|
17
|
+
:value => value.to_i,
|
18
|
+
:worst => worst.to_i,
|
19
|
+
:threshold => threshold.to_i,
|
20
|
+
:type => type.downcase,
|
21
|
+
:raw => raw
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
smart[:name] = "/dev/sd#{i}"
|
26
|
+
|
27
|
+
disks << smart
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
disks = disks.reject{|i| (i[:attributes] || {}).empty? }
|
32
|
+
|
33
|
+
unless disks.empty?
|
34
|
+
Facter.add('smart') do
|
35
|
+
setcode { disks }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -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,155 @@
|
|
1
|
+
# Onering Facts - HAProxy Stats
|
2
|
+
# provides collection of statistics from HAProxy
|
3
|
+
#
|
4
|
+
require 'set'
|
5
|
+
require 'socket'
|
6
|
+
|
7
|
+
haproxy = nil
|
8
|
+
sockets_seen = Set.new()
|
9
|
+
|
10
|
+
# find all haproxy configs, ensuring haproxy.cfg is always front of the line
|
11
|
+
Dir["/etc/haproxy/*.cfg"].sort{|a,b| (b == 'haproxy.cfg' ? 1 : a<=>b) }.each do |cfg|
|
12
|
+
haproxy ||= []
|
13
|
+
pools = {}
|
14
|
+
cfg_data = (File.read(cfg).lines rescue [])
|
15
|
+
|
16
|
+
description = (cfg_data.select{|i| i =~ /^\s* description / }.first.strip.split(' ',2).last.gsub('"','') rescue nil)
|
17
|
+
socket = (cfg_data.select{|i| i =~ /^\s* stats socket / }.first.strip.split(' ')[2] rescue nil)
|
18
|
+
|
19
|
+
# stats socket must be present in the config, a real file, and not have been seen before
|
20
|
+
if not socket.nil? and File.exists?(socket) and not sockets_seen.include?(socket)
|
21
|
+
sockets_seen << socket
|
22
|
+
stats = UNIXSocket.new(socket)
|
23
|
+
stats.puts("show stat")
|
24
|
+
|
25
|
+
instance = {
|
26
|
+
:name => File.basename(cfg, '.cfg'),
|
27
|
+
:socket => socket,
|
28
|
+
:path => cfg,
|
29
|
+
:description => description,
|
30
|
+
:pools => []
|
31
|
+
}
|
32
|
+
|
33
|
+
stats.read.lines.each do |line|
|
34
|
+
next if line[0].chr == '#'
|
35
|
+
line = line.strip.chomp
|
36
|
+
next if line.empty?
|
37
|
+
line = line.split(',')
|
38
|
+
|
39
|
+
begin
|
40
|
+
pools[line[0]] ||= {
|
41
|
+
:name => line[0],
|
42
|
+
:services => []
|
43
|
+
}
|
44
|
+
|
45
|
+
pools[line[0]][:services] << ({
|
46
|
+
:name => line[1],
|
47
|
+
:queue => {
|
48
|
+
:current => line[2].to_i,
|
49
|
+
:maximum => line[3].to_i,
|
50
|
+
:limit => line[25].to_i
|
51
|
+
},
|
52
|
+
:sessions => {
|
53
|
+
:rate => line[33].to_i,
|
54
|
+
:rate_limit => line[34].to_i,
|
55
|
+
:rate_maximum => line[35].to_i,
|
56
|
+
:current => line[4].to_i,
|
57
|
+
:maximum => line[5].to_i,
|
58
|
+
:limit => line[6].to_i,
|
59
|
+
:total => line[7].to_i
|
60
|
+
},
|
61
|
+
:bytes => {
|
62
|
+
:in => line[8].to_i,
|
63
|
+
:out => line[9].to_i
|
64
|
+
},
|
65
|
+
:denied => {
|
66
|
+
:request => line[10].to_i,
|
67
|
+
:response => line[11].to_i
|
68
|
+
},
|
69
|
+
:errors => {
|
70
|
+
:request => line[12].to_i,
|
71
|
+
:connection => line[13].to_i,
|
72
|
+
:response => line[14].to_i
|
73
|
+
},
|
74
|
+
:warnings => {
|
75
|
+
:retry => line[15].to_i,
|
76
|
+
:redispatch => line[16].to_i
|
77
|
+
},
|
78
|
+
:status => line[17].downcase,
|
79
|
+
:online => (line[17].downcase == 'up'),
|
80
|
+
:weight => line[18].to_i,
|
81
|
+
:checks => {
|
82
|
+
:status => (case line[36].upcase.to_sym
|
83
|
+
when :UNK then :unknown
|
84
|
+
when :INI then :initializing
|
85
|
+
when :SOCKERR then :socket_error
|
86
|
+
when :L4OK then :layer4_ok
|
87
|
+
when :L4TMOUT then :layer4_timeout
|
88
|
+
when :L4CON then :layer4_connection_failed
|
89
|
+
when :L6OK then :layer6_ok
|
90
|
+
when :L6TOUT then :layer6_ssl_timeout
|
91
|
+
when :L6RSP then :layer6_ssl_protocol_error
|
92
|
+
when :L7OK then :layer7_ok
|
93
|
+
when :L7OKC then :layer7_ok
|
94
|
+
when :L7TOUT then :layer7_timeout
|
95
|
+
when :L7RSP then :layer7_protocol_error
|
96
|
+
when :L7STS then :layer7_server_error
|
97
|
+
else nil
|
98
|
+
end
|
99
|
+
),
|
100
|
+
:response_code => line[37].to_i,
|
101
|
+
:duration => line[38].to_i,
|
102
|
+
:fail_details => line[45],
|
103
|
+
:failed => line[21].to_i,
|
104
|
+
:downs => line[22].to_i
|
105
|
+
},
|
106
|
+
:http => {
|
107
|
+
:request => {
|
108
|
+
:rate => line[46].to_i,
|
109
|
+
:rate_maximum => line[47].to_i,
|
110
|
+
:total => line[48].to_i,
|
111
|
+
:client_abort => line[49].to_i,
|
112
|
+
:server_abort => line[50].to_i
|
113
|
+
},
|
114
|
+
:response => {
|
115
|
+
'100' => line[39].to_i,
|
116
|
+
'200' => line[40].to_i,
|
117
|
+
'300' => line[41].to_i,
|
118
|
+
'400' => line[42].to_i,
|
119
|
+
'500' => line[43].to_i,
|
120
|
+
'other' => line[44].to_i
|
121
|
+
}
|
122
|
+
},
|
123
|
+
:last_changed_at => Time.at(Time.now.to_i - line[23].to_i).strftime('%Y-%m-%d %H:%M:%S %z'),
|
124
|
+
:downtime => line[24].to_i,
|
125
|
+
:pid => line[26].to_i,
|
126
|
+
:proxy_id => line[27].to_i,
|
127
|
+
:service_id => line[28].to_i,
|
128
|
+
:throttle => line[29],
|
129
|
+
:selected => line[30].to_i,
|
130
|
+
:tracked => line[31],
|
131
|
+
:type => (case line[32].to_i
|
132
|
+
when 0 then :frontend
|
133
|
+
when 1 then :backend
|
134
|
+
when 2 then :server
|
135
|
+
when 3 then :socket
|
136
|
+
else nil
|
137
|
+
end
|
138
|
+
)
|
139
|
+
})
|
140
|
+
rescue
|
141
|
+
next
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
instance[:pools] = pools.values()
|
146
|
+
haproxy << instance
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
|
151
|
+
if not haproxy.nil?
|
152
|
+
Facter.add('haproxy') do
|
153
|
+
setcode { haproxy }
|
154
|
+
end
|
155
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
Facter.add('uuid') do
|
2
|
+
setcode do
|
3
|
+
if not Facter.value('uuid').nil?
|
4
|
+
Facter.value('uuid')
|
5
|
+
elsif Facter::Util::Resolution.which('dmidecode')
|
6
|
+
Facter::Util::Resolution.exec('dmidecode -s system-uuid').strip.chomp
|
7
|
+
elsif File.exists?('/sys/hypervisor/uuid')
|
8
|
+
File.read('/sys/hypervisor/uuid').lines.first.strip.chomp
|
9
|
+
else
|
10
|
+
nil
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
Facter.add('signature') do
|
16
|
+
setcode do
|
17
|
+
parts = []
|
18
|
+
|
19
|
+
if Facter.value('uuid')
|
20
|
+
parts << Facter.value('uuid').gsub(/[\W\_]+/,'').upcase
|
21
|
+
end
|
22
|
+
|
23
|
+
if Facter.value('macaddress')
|
24
|
+
parts << Facter.value('macaddress').gsub(/[\W\_]+/,'').upcase
|
25
|
+
end
|
26
|
+
|
27
|
+
# still empty, now we really have to grasp at straws
|
28
|
+
if parts.empty?
|
29
|
+
if Facter.value('ipaddress')
|
30
|
+
parts << Facter.value('ipaddress').split(',').first.strip.chomp.delete('.')
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
# final pruning
|
36
|
+
parts = parts.reject{|i| i.nil? || i.empty? }
|
37
|
+
|
38
|
+
# still empty?
|
39
|
+
if parts.empty?
|
40
|
+
nil
|
41
|
+
else
|
42
|
+
parts.join('-')
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
Facter.add('hardwareid') do
|
48
|
+
setcode do
|
49
|
+
# 1. contents of /etc/hardware.id takes absolute precedence
|
50
|
+
if File.size?('/etc/hardware.id')
|
51
|
+
File.read('/etc/hardware.id').strip.chomp rescue nil
|
52
|
+
|
53
|
+
# 2. value of kernel boot argument 'hardwareid' is checked
|
54
|
+
elsif Facter.value('kernelarguments').is_a?(Hash) and
|
55
|
+
not Facter.value('kernelarguments')['hardwareid'].nil? and
|
56
|
+
not Facter.value('kernelarguments')['hardwareid'].to_s.strip.empty?
|
57
|
+
Facter.value('kernelarguments')['hardwareid'].to_s.strip
|
58
|
+
|
59
|
+
# 3. calculate a new hardwareid from the system signature
|
60
|
+
elsif Facter.value('signature')
|
61
|
+
require 'digest'
|
62
|
+
Digest::SHA256.new.update(Facter.value('signature')).hexdigest[0..5]
|
63
|
+
|
64
|
+
# 4. i got nothing...
|
65
|
+
else
|
66
|
+
nil
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'resolv'
|
2
|
+
|
3
|
+
protocols = %w{tcp tcp6 udp udp6}
|
4
|
+
|
5
|
+
flags = "--numeric-hosts --numeric-ports --programs --tcp --udp -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("nice -n 19 netstat #{flags} -l | tr -s ' ' | sed 's/ LISTEN//g'")
|
13
|
+
#nonlistening = Facter::Util::Resolution.exec("nice -n 19 netstat #{flags} | tr -s ' '")
|
14
|
+
|
15
|
+
# netstat = {
|
16
|
+
# 'listening' => [],
|
17
|
+
# 'connections' => []
|
18
|
+
# }
|
19
|
+
|
20
|
+
netstat = {
|
21
|
+
'listening' => []
|
22
|
+
}
|
23
|
+
|
24
|
+
def getcommandline(pid)
|
25
|
+
return nil unless pid.to_i > 0
|
26
|
+
(File.read("/proc/#{pid}/cmdline").to_s.strip.chomp.squeeze("\u0000").squeeze("\0").gsub("\u0000", ' ').gsub("\0", ' '))
|
27
|
+
end
|
28
|
+
|
29
|
+
[*listening.to_s.lines.to_a[2..-1]].each do |line|
|
30
|
+
protocol, recvq, sendq, local, foreign, user, inode, program = line.split(' ', 8)
|
31
|
+
|
32
|
+
next unless protocols.include?(protocol)
|
33
|
+
|
34
|
+
local = local.split(':')
|
35
|
+
foreign = foreign.split(':')
|
36
|
+
local_host = local[-2]
|
37
|
+
local_port = local[-1]
|
38
|
+
foreign_host = foreign[-2]
|
39
|
+
foreign_port = foreign[-1]
|
40
|
+
pid = program.split('/').first
|
41
|
+
|
42
|
+
command = getcommandline(pid)
|
43
|
+
next if command.nil?
|
44
|
+
|
45
|
+
netstat['listening'] << {
|
46
|
+
"protocol" => protocol,
|
47
|
+
"address" => local_host,
|
48
|
+
"fqdn" => (Resolv.getname(local_host) rescue nil),
|
49
|
+
"port" => local_port.to_i,
|
50
|
+
"user" => user,
|
51
|
+
"program" => {
|
52
|
+
"pid" => pid.to_i,
|
53
|
+
"command" => getcommandline(pid)
|
54
|
+
}
|
55
|
+
}
|
56
|
+
end
|
57
|
+
|
58
|
+
# nonlistening.lines.to_a[2..-1].each do |line|
|
59
|
+
# protocol, recvq, sendq, local, foreign, state, user, inode, program = line.split(' ', 9)
|
60
|
+
# next unless protocols.include?(protocol)
|
61
|
+
|
62
|
+
# local = local.split(':')
|
63
|
+
# foreign = foreign.split(':')
|
64
|
+
# local_host = local[-2]
|
65
|
+
# local_port = local[-1]
|
66
|
+
# foreign_host = foreign[-2]
|
67
|
+
# foreign_port = foreign[-1]
|
68
|
+
# pid = program.split('/').first
|
69
|
+
|
70
|
+
# netstat['connections'] << {
|
71
|
+
# "protocol" => protocol,
|
72
|
+
# "from" => {
|
73
|
+
# "address" => local_host,
|
74
|
+
# "port" => local_port.to_i
|
75
|
+
# },
|
76
|
+
# "to" => {
|
77
|
+
# "address" => foreign_host,
|
78
|
+
# "fqdn" => (Resolv.getname(foreign_host) rescue nil),
|
79
|
+
# "port" => foreign_port.to_i
|
80
|
+
# },
|
81
|
+
# "user" => user,
|
82
|
+
# "state" => state.downcase,
|
83
|
+
# "program" => {
|
84
|
+
# "pid" => pid.to_i,
|
85
|
+
# "command" => getcommandline(pid)
|
86
|
+
# }
|
87
|
+
# }
|
88
|
+
# end
|
89
|
+
|
90
|
+
Facter.add("netstat") do
|
91
|
+
setcode do
|
92
|
+
netstat
|
93
|
+
end
|
94
|
+
end
|