risu 1.4.4 → 1.4.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.
Files changed (40) hide show
  1. data/NEWS.markdown +14 -1
  2. data/README.markdown +23 -41
  3. data/TODO.markdown +48 -39
  4. data/lib/risu.rb +4 -9
  5. data/lib/risu/base.rb +15 -0
  6. data/lib/risu/base/prawn_templater.rb +37 -0
  7. data/lib/risu/{schema.rb → base/schema.rb} +34 -15
  8. data/lib/risu/base/template_base.rb +23 -0
  9. data/lib/risu/base/template_manager.rb +106 -0
  10. data/lib/risu/base/templater.rb +37 -0
  11. data/lib/risu/cli/application.rb +28 -8
  12. data/lib/risu/models.rb +1 -2
  13. data/lib/risu/models/host.rb +147 -23
  14. data/lib/risu/models/item.rb +131 -43
  15. data/lib/risu/models/plugin.rb +1 -1
  16. data/lib/risu/models/report.rb +11 -1
  17. data/lib/risu/models/serverpreference.rb +0 -2
  18. data/lib/risu/models/servicedescription.rb +10 -0
  19. data/lib/risu/parsers.rb +2 -3
  20. data/lib/risu/parsers/nessus/nessus_document.rb +69 -0
  21. data/lib/risu/parsers/nessus/nessus_sax_listener.rb +278 -0
  22. data/lib/risu/templates/assets.rb +45 -18
  23. data/lib/risu/templates/cover_sheet.rb +70 -42
  24. data/lib/risu/templates/exec_summary.rb +64 -45
  25. data/lib/risu/templates/executive_summary.rb +185 -161
  26. data/lib/risu/templates/finding_statistics.rb +44 -17
  27. data/lib/risu/templates/findings_host.rb +70 -46
  28. data/lib/risu/templates/findings_summary.rb +78 -54
  29. data/lib/risu/templates/findings_summary_with_pluginid.rb +80 -54
  30. data/lib/risu/templates/graphs.rb +46 -19
  31. data/lib/risu/templates/host_summary.rb +62 -39
  32. data/lib/risu/templates/ms_patch_summary.rb +59 -35
  33. data/lib/risu/templates/ms_update_summary.rb +59 -35
  34. data/lib/risu/templates/pci_compliance.rb +88 -64
  35. data/lib/risu/templates/technical_findings.rb +132 -106
  36. data/lib/risu/templates/template.rb +24 -0
  37. metadata +12 -6
  38. data/lib/risu/listener.rb +0 -274
  39. data/lib/risu/nessusdocument.rb +0 -66
  40. data/lib/risu/prawn_templater.rb +0 -38
@@ -0,0 +1,106 @@
1
+ module Risu
2
+ module Base
3
+ class TemplateManager
4
+ attr_accessor :registered_templates
5
+
6
+ #
7
+ #
8
+ def initialize (path)
9
+ @registered_templates = Array.new
10
+ @templates = Array.new
11
+
12
+ load_templates(path)
13
+ end
14
+
15
+ #
16
+ #
17
+ def load_templates(path)
18
+ begin
19
+ base_dir = __FILE__.gsub("risu/base/template_manager.rb", "")
20
+ Dir["#{base_dir + path}/**/*.rb"].each do |x|
21
+ begin
22
+ load x
23
+ rescue => e
24
+ next
25
+ end
26
+ end
27
+
28
+ TemplateBase.possible_templates.each do |p|
29
+ if validate(p) == true
30
+ @registered_templates << p
31
+ end
32
+ end
33
+ rescue => e
34
+ puts "Bad plugin"
35
+ end
36
+ end
37
+
38
+ #
39
+ #
40
+ def validate(template)
41
+ t = template.new
42
+
43
+ if t == nil
44
+ return false
45
+ end
46
+
47
+ if t.respond_to?(:render) == false
48
+ return false
49
+ end
50
+
51
+ return true
52
+ end
53
+
54
+ #
55
+ #
56
+ def find_plugins(file_name)
57
+ Dir.new("#{file_name}").each do |file|
58
+ next if file.match(/^\.+/)
59
+ path = "#{file_name}/#{file}"
60
+
61
+ if FileTest.directory?("#{path}")
62
+ list("#{path}")
63
+ else
64
+ self.register_template path
65
+ end
66
+ end
67
+ end
68
+
69
+ #
70
+ #
71
+ def register_template(plugin)
72
+ load plugin
73
+
74
+ @templates.push(plugin)
75
+ end
76
+
77
+ #
78
+ #
79
+ def find_template_by_name(name)
80
+ @registered_templates.each do |template|
81
+ t = template.new
82
+ if t.template_info[:name] == name
83
+ return t
84
+ end
85
+ end
86
+
87
+ return nil
88
+ end
89
+
90
+ #
91
+ #
92
+ def display_templates
93
+ puts "Available Templates"
94
+ @registered_templates.each do |x|
95
+ p = x.new
96
+ puts "\t#{p.template_info[:name]} - #{p.template_info[:description]}\n",
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
102
+
103
+
104
+
105
+
106
+
@@ -0,0 +1,37 @@
1
+ module Risu
2
+ module Base
3
+ # Templater class for generating a report from a erb template
4
+ #
5
+ # @author Jacob Hammack
6
+ class Templater
7
+ attr_accessor :template, :template_manager, :findings, :output_file
8
+
9
+ # Setups of the Templater class initalizing all of the variables
10
+ #
11
+ # @return [Templater] New Instance
12
+ def initialize(template, findings, output, template_manager)
13
+ @template = template
14
+ @findings = findings
15
+ @output_file = output
16
+ @template_manager = template_manager
17
+ end
18
+
19
+ # Generates a report based on the erb template
20
+ #
21
+ def generate
22
+ begin
23
+ template = @template
24
+ template_manager = @template_manager
25
+
26
+ Prawn::Document.generate(@output_file, :margin => [75, 50, 75, 50]) do |output|
27
+ output.font_size 12
28
+ t = template_manager.find_template_by_name(template)
29
+ t.render(output) unless t == nil
30
+ end
31
+ rescue => e
32
+ puts "Error: #{e.message} \n #{e.backtrace.join("\n\t")}\n"
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -7,6 +7,7 @@ module Risu
7
7
  #
8
8
  # @author Jacob Hammack <jacob.hammack@hammackj.com>
9
9
  class Application
10
+ include Risu::Base
10
11
  attr_accessor :database
11
12
 
12
13
  #
@@ -18,6 +19,9 @@ module Risu
18
19
  @blacklist = {}
19
20
 
20
21
  @options[:debug] = false
22
+ @options[:list_templates] = false
23
+
24
+ @template_manager = Risu::Base::TemplateManager.new "risu/templates"
21
25
  end
22
26
 
23
27
  # Creates a blank config file
@@ -88,7 +92,7 @@ module Risu
88
92
  end
89
93
 
90
94
  ActiveRecord::Base.establish_connection(@database)
91
- require 'risu/schema'
95
+ require 'risu/base/schema'
92
96
  Schema.migrate(direction)
93
97
 
94
98
  if direction == :up
@@ -193,13 +197,23 @@ module Risu
193
197
  opt.separator('')
194
198
  opt.separator("Reporting Options")
195
199
 
196
- opt.on('-t','--template FILE','The filename of the template to use') do |option|
200
+ opt.on('-t', '--template FILE', 'The filename of the template to use') do |option|
197
201
  @options[:template] = option
198
202
  end
199
203
 
200
- opt.on('-o','--output-file FILE','The filename to output the generated report to') do |option|
204
+ opt.on('-o', '--output-file FILE', 'The filename to output the generated report to') do |option|
201
205
  @options[:output_file] = option
202
206
  end
207
+
208
+ opt.on('-l', '--list-templates', "Lists all of the templates available to #{APP_NAME}") do |option|
209
+ @options[:list_templates] = option
210
+ end
211
+
212
+ opt.on('--create-template NAME', "Creates a template file in the ~/.risu/templates directory") do |option|
213
+ if File.exists?(option) == true
214
+ puts "[!] Template "
215
+ end
216
+ end
203
217
 
204
218
  opt.separator('')
205
219
  opt.separator('Configuration Options')
@@ -287,6 +301,12 @@ module Risu
287
301
  #
288
302
  def run
289
303
  parse_options
304
+
305
+ if @options[:list_templates]
306
+ @template_manager.display_templates
307
+
308
+ exit
309
+ end
290
310
 
291
311
  if @options[:debug] == true
292
312
  puts "[*] Enabling Debug Mode"
@@ -326,8 +346,8 @@ module Risu
326
346
  end
327
347
 
328
348
  if @options[:template] != nil and @options[:output_file] != nil
329
- if File.exists?(@options[:template]) == false
330
- puts "[!] Template \"#{@options[:template]}\" does not exist. Please check the filename"
349
+ if @template_manager.find_template_by_name(@options[:template]) == nil
350
+ puts "[!] Template \"#{@options[:template]}\" does not exist. Please check the name"
331
351
  exit
332
352
  end
333
353
 
@@ -337,8 +357,8 @@ module Risu
337
357
  @findings.title = @report["title"]
338
358
  @findings.company = @report["company"]
339
359
  @findings.classification = @report["classification"]
340
-
341
- template = PrawnTemplater.new(@options[:template], @findings, @options[:output_file])
360
+
361
+ template = Templater.new(@options[:template], @findings, @options[:output_file], @template_manager)
342
362
  template.generate
343
363
  end
344
364
 
@@ -371,7 +391,7 @@ module Risu
371
391
  raise Risu::Exceptions::InvalidDocument, "[!] Document does not exist - #{file}"
372
392
  end
373
393
 
374
- doc = NessusDocument.new file
394
+ doc = Risu::Parsers::Nessus::NessusDocument.new file
375
395
  if doc.valid? == true
376
396
  doc.parse
377
397
 
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  module Risu
4
2
  module Models
5
3
  end
@@ -16,3 +14,4 @@ require 'risu/models/report'
16
14
  require 'risu/models/reference'
17
15
  require 'risu/models/policy'
18
16
  require 'risu/models/version'
17
+ require 'risu/models/servicedescription'
@@ -45,7 +45,7 @@ module Risu
45
45
  def os_windows
46
46
  where("os LIKE '%Windows%'")#.group(:os)
47
47
  end
48
-
48
+
49
49
  # Negation query for all hosts with a Windows based Operating system
50
50
  #
51
51
  # @return [ActiveRecord::Relation] with the query results
@@ -59,21 +59,21 @@ module Risu
59
59
  def os_windows_nt
60
60
  where("os LIKE '%Windows NT%'")
61
61
  end
62
-
62
+
63
63
  # Negation query for all hosts with a Windows NT based Operating system
64
64
  #
65
65
  # @return [ActiveRecord::Relation] with the query results
66
66
  def not_os_windows_nt
67
67
  where("os NOT LIKE '%Windows NT%'")
68
68
  end
69
-
69
+
70
70
  # Queries for hosts with a Windows 2000 based Operating System
71
71
  #
72
72
  # @return [ActiveRecord::Relation] with the query results
73
73
  def os_windows_2k
74
74
  where("os LIKE '%Windows 2000%'")
75
75
  end
76
-
76
+
77
77
  # Negation query for all hosts with a Windows 2000 based Operating system
78
78
  #
79
79
  # @return [ActiveRecord::Relation] with the query results
@@ -87,7 +87,7 @@ module Risu
87
87
  def os_windows_xp
88
88
  where("os LIKE '%Windows XP%'")
89
89
  end
90
-
90
+
91
91
  # Negation query for all hosts with a Windows XP based Operating system
92
92
  #
93
93
  # @return [ActiveRecord::Relation] with the query results
@@ -101,7 +101,7 @@ module Risu
101
101
  def os_windows_2k3
102
102
  where("os LIKE '%Windows Server 2003%'")
103
103
  end
104
-
104
+
105
105
  # Negation query for all hosts with a Windows Server 2003 based Operating system
106
106
  #
107
107
  # @return [ActiveRecord::Relation] with the query results
@@ -115,7 +115,7 @@ module Risu
115
115
  def os_windows_vista
116
116
  where("os LIKE '%Windows Vista%'")
117
117
  end
118
-
118
+
119
119
  # Negation query for all hosts with a Windows Vista based Operating system
120
120
  #
121
121
  # @return [ActiveRecord::Relation] with the query results
@@ -129,7 +129,7 @@ module Risu
129
129
  def os_windows_2k8
130
130
  where("os LIKE '%Windows Server 2008%'")
131
131
  end
132
-
132
+
133
133
  def not_os_windows_2k8
134
134
  where("os NOT LIKE '%Windows Server 2008%'")
135
135
  end
@@ -140,7 +140,7 @@ module Risu
140
140
  def os_windows_7
141
141
  where("os LIKE '%Windows 7%'")
142
142
  end
143
-
143
+
144
144
  # Negation query for all hosts with a Windows 7 based Operating system
145
145
  #
146
146
  # @return [ActiveRecord::Relation] with the query results
@@ -155,14 +155,14 @@ module Risu
155
155
  def os_windows_other
156
156
  not_os_windows_7.not_os_windows_2k8.not_os_windows_vista.not_os_windows_2k3.not_os_windows_xp.not_os_windows_2k.not_os_windows_nt
157
157
  end
158
-
158
+
159
159
  # Queries for all hosts with a Linux based Operating system
160
160
  #
161
161
  # @return [ActiveRecord::Relation] with the query results
162
162
  def os_linux
163
163
  where("os LIKE '%Linux%'")
164
164
  end
165
-
165
+
166
166
  # Negation query for all hosts with a Linux based Operating system
167
167
  #
168
168
  # @return [ActiveRecord::Relation] with the query results
@@ -176,7 +176,7 @@ module Risu
176
176
  def os_freebsd
177
177
  where("os LIKE '%FreeBSD%'")
178
178
  end
179
-
179
+
180
180
  # Negation query for all hosts with a FreeBSD based Operating system
181
181
  #
182
182
  # @return [ActiveRecord::Relation] with the query results
@@ -190,7 +190,7 @@ module Risu
190
190
  def os_netbsd
191
191
  where("os LIKE '%NetBsd%'")
192
192
  end
193
-
193
+
194
194
  # Negation query for all hosts with a NETbsd based Operating system
195
195
  #
196
196
  # @return [ActiveRecord::Relation] with the query results
@@ -204,7 +204,7 @@ module Risu
204
204
  def os_cisco
205
205
  where("os LIKE '%CISCO%'")
206
206
  end
207
-
207
+
208
208
  # Negation query for all hosts with a Cisco based Operating system
209
209
  #
210
210
  # @return [ActiveRecord::Relation] with the query results
@@ -218,7 +218,7 @@ module Risu
218
218
  def os_vxworks
219
219
  where("os LIKE '%VxWorks%'")
220
220
  end
221
-
221
+
222
222
  # Negation query for all hosts with a VXWorks based Operating system
223
223
  #
224
224
  # @return [ActiveRecord::Relation] with the query results
@@ -232,21 +232,21 @@ module Risu
232
232
  def os_vmware_esx
233
233
  where("os LIKE '%VMware ESX%'")
234
234
  end
235
-
235
+
236
236
  # Negation query for all hosts with a VMware ESX based Operating system
237
237
  #
238
238
  # @return [ActiveRecord::Relation] with the query results
239
239
  def not_os_vmware_esx
240
240
  where("os NOT LIKE '%VMware ESX%'")
241
241
  end
242
-
242
+
243
243
  # Queries for all hosts with a Mac OSX based Operating system
244
244
  #
245
245
  # @return [ActiveRecord::Relation] with the query results
246
246
  def os_osx
247
247
  where("os LIKE '%Mac OS X%'")
248
248
  end
249
-
249
+
250
250
  # Negation query for all hosts with a Mac OSX based Operating system
251
251
  #
252
252
  # @return [ActiveRecord::Relation] with the query results
@@ -254,11 +254,19 @@ module Risu
254
254
  where("os NOT LIKE '%Mac OS X%'")
255
255
  end
256
256
 
257
+ def os_aix
258
+ where("os LIKE '%AIX%'")
259
+ end
260
+
261
+ def not_os_aix
262
+ where("os NOT LIKE '%AIX%'")
263
+ end
264
+
257
265
  # Queries for all hosts with a Unknown Operating system
258
266
  #
259
267
  # @return [ActiveRecord::Relation] with the query results
260
268
  def os_other
261
- not_os_osx.not_os_linux.not_os_netbsd.not_os_freebsd.not_os_cisco.not_os_vxworks.not_os_vmware_esx.not_os_windows
269
+ not_os_osx.not_os_linux.not_os_netbsd.not_os_freebsd.not_os_cisco.not_os_vxworks.not_os_vmware_esx.not_os_windows.not_os_aix
262
270
  end
263
271
 
264
272
  # Generates a graph of the high and medium findings count per host
@@ -269,7 +277,7 @@ module Risu
269
277
  g.title = sprintf "Top %d High/Medium Finding Count Per Host ", Item.risks_by_host(limit).all.count
270
278
  g.sort = false
271
279
  g.theme = {
272
- :colors => %w(red green blue orange yellow purple black grey brown pink),
280
+ :colors => %w(red orange yellow blue green purple black grey brown pink),
273
281
  :background_colors => %w(white white)
274
282
  }
275
283
 
@@ -291,7 +299,7 @@ module Risu
291
299
  g.title = "Other Operating Systems Percentage"
292
300
  g.sort = false
293
301
  g.theme = {
294
- :colors => %w(red green blue orange yellow purple black grey brown pink),
302
+ :colors => %w(red orange yellow blue green purple black grey brown pink),
295
303
  :background_colors => %w(white white)
296
304
  }
297
305
 
@@ -302,6 +310,7 @@ module Risu
302
310
  cisco = Host.os_cisco.all.count
303
311
  vxworks = Host.os_vxworks.all.count
304
312
  esx = Host.os_vmware_esx.all.count
313
+ aix = Host.os_aix.all.count
305
314
  other = Host.os_other.all.count
306
315
 
307
316
  g.data("Linux", linux) unless linux == 0
@@ -311,11 +320,12 @@ module Risu
311
320
  g.data("Cisco ISO", cisco) unless cisco == 0
312
321
  g.data("VxWorks", vxworks) unless vxworks == 0
313
322
  g.data("VMware", esx) unless esx == 0
323
+ g.data("AIX", aix) unless aix == 0
314
324
  g.data("Other", other) unless other == 0
315
325
 
316
326
  #Creates very odd graphs
317
327
  #Host.os_other.each do |host|
318
- # g.data(host.os, Host.where(:os => host.os).count) unless host.os == nil
328
+ # g.data(host.os, Host.where(:os => host.os).count) unless host.os == nil
319
329
  #end
320
330
 
321
331
  StringIO.new(g.to_blob)
@@ -329,7 +339,7 @@ module Risu
329
339
  g.title = "Windows Operating Systems By Percentage"
330
340
  g.sort = false
331
341
  g.theme = {
332
- :colors => %w(red green blue orange yellow purple black grey brown pink),
342
+ :colors => %w(red orange yellow blue green purple black grey brown pink),
333
343
  :background_colors => %w(white white)
334
344
  }
335
345
 
@@ -353,6 +363,120 @@ module Risu
353
363
 
354
364
  StringIO.new(g.to_blob)
355
365
  end
366
+
367
+ #
368
+ #
369
+ def windows_os_graph_text
370
+ nt = Host.os_windows_nt.all.count
371
+ w2k = Host.os_windows_2k.all.count
372
+ xp = Host.os_windows_xp.all.count
373
+ w2k3 = Host.os_windows_2k3.all.count
374
+ vista = Host.os_windows_vista.all.count
375
+ w2k8 = Host.os_windows_2k8.all.count
376
+ w7 = Host.os_windows_7.all.count
377
+ other = (Host.os_windows.os_windows_other).all.count
378
+
379
+ windows_os_count = nt + w2k + xp + w2k3 + vista + w7 + w2k8
380
+
381
+ nt_percent = (nt.to_f / windows_os_count.to_f) * 100
382
+ w2k_percent = (w2k.to_f / windows_os_count.to_f) * 100
383
+ xp_percent = (xp.to_f / windows_os_count.to_f) * 100
384
+ w2k3_percent = (w2k3.to_f / windows_os_count.to_f) * 100
385
+ vista_percent = (vista.to_f / windows_os_count.to_f) * 100
386
+ w2k8_percent = (w2k8.to_f / windows_os_count.to_f) * 100
387
+ w7_percent = (w7.to_f / windows_os_count.to_f) * 100
388
+
389
+ text = "This graph shows the percentage of the different Microsoft Windows based operating systems " +
390
+ "found on the #{Report.title} network.\n\n"
391
+
392
+ text << "#{nt_percent.round.to_i}% of the network is Windows NT. " if nt > 0
393
+ text << "#{w2k_percent.round.to_i}% of the network is Windows 2000. " if w2k > 0
394
+ text << "#{xp_percent.round.to_i}% of the network is Windows XP. " if xp > 0
395
+ text << "#{w2k3_percent.round.to_i}% of the network is Windows Server 2003. " if w2k3 > 0
396
+ text << "#{vista_percent.round.to_i}% of the network is Windows Vista. " if vista > 0
397
+ text << "#{w2k8_percent.round.to_i}% of the network is Windows Server 2008. " if w2k8 > 0
398
+ text << "#{w7_percent.round.to_i}% of the network is Windows 7. " if w7 > 0
399
+
400
+ text << "\n\n" << unsupported_os_windows if nt > 0 or w2k > 0
401
+
402
+ return text
403
+ end
404
+
405
+ # @todo add plural check
406
+ #
407
+ def unsupported_os_text
408
+ aix_text = unsupported_os_aix
409
+ win_text = unsupported_os_windows
410
+
411
+ unsupported_os_text = "Several unsupported operating systems were also discovered on the network. " +
412
+ "These operating systems are no longer updated by the specific vendor. These operating systems should be " +
413
+ "updated and replaced as soon as possible.\n\n"
414
+
415
+ unsupported_os_text << "#{win_text}" if win_text != ""
416
+ unsupported_os_text << "#{aix_text}" if aix_text != ""
417
+
418
+ return unsupported_os_text
419
+ end
420
+
421
+ def unsupported_os_windows
422
+ win_nt_text = ""
423
+ win_2000_text = ""
424
+ win_nt = Host.os_windows_nt
425
+ win_2000 = Host.os_windows_2k
426
+
427
+ #Host.os_windows.not_os_windows_7.not_os_windows_2008.not_os_windows_vista.not_os_windows_2003.not_os_windows_xp
428
+
429
+ win_nt_text = "Windows NT is an unsupported sperating system since Microsoft has stopped support as of June 2004. " +
430
+ "Please see http://windows.microsoft.com/en-us/windows/products/lifecycle for more information.\n\n" if win_nt.count >= 1
431
+
432
+ win_2000_text = "Windows 2000 is an unsupported operating system since Microsoft has stopped support as of June 2004. " +
433
+ "Please see http://windows.microsoft.com/en-us/windows/products/lifecycle for more information.\n\n" if win_2000.count >= 1
434
+
435
+ return "#{win_nt_text}#{win_2000_text}"
436
+
437
+ end
438
+
439
+ #
440
+ #
441
+ def unsupported_os_aix
442
+ text = ""
443
+ aix = Host.os_aix.where("OS LIKE 'AIX 5.%'")
444
+
445
+ text = "AIX 5.x is an unsupported operating system since IBM has stopped support as of April 2011. " +
446
+ "Please see http://www-03.ibm.com/systems/power/software/aix/ for more information " +
447
+ "about obtaining a newer supported version.\n\n" if aix.count >= 1
448
+
449
+ return text
450
+ end
451
+
452
+ def other_os_graph_text
453
+ text = "This graph shows the percentage of the different Non-Windows based operating systems " +
454
+ "found on the #{Report.title} network.\n\n"
455
+
456
+ linux = Host.os_linux.all.count
457
+ osx = Host.os_osx.all.count
458
+ freebsd = Host.os_freebsd.all.count
459
+ netbsd = Host.os_netbsd.all.count
460
+ cisco = Host.os_cisco.all.count
461
+ vxworks = Host.os_vxworks.all.count
462
+ esx = Host.os_vmware_esx.all.count
463
+ aix = Host.os_aix.all.count
464
+ other = Host.os_other.all.count
465
+
466
+ other_os_count = linux + osx + freebsd + netbsd + cisco + vxworks + esx + aix + other
467
+
468
+ linux_percent = (linux.to_f / other_os_count.to_f) * 100
469
+ aix_percent = (aix.to_f / other_os_count.to_f) * 100
470
+
471
+ #todo add other os's here
472
+
473
+
474
+ text << "#{linux_percent.to_i}% of the network is running Linux based operating systems. " if linux > 0
475
+ text << "#{aix_percent.to_i}% of the network is running AIX based operating systems. " if aix > 0
476
+ text << "\n\n"<< unsupported_os_aix if aix > 0
477
+
478
+ return text
479
+ end
356
480
  end
357
481
  end
358
482
  end