mu 5.7.39 → 5.7.40

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/lib/mu/command/cmd_runanalysis.rb +519 -46
  2. data/version.rb +1 -1
  3. metadata +107 -79
@@ -3,7 +3,7 @@
3
3
  require 'mu/api/muapi'
4
4
  class Mu
5
5
  class Command
6
- class Cmd_runfuzz < Command
6
+ class Cmd_runanalysis < Command
7
7
 
8
8
  attr_accessor :host, :username, :password, :api, :docroot
9
9
 
@@ -12,6 +12,12 @@ class Cmd_runfuzz < Command
12
12
  def cmd_help argv
13
13
  help
14
14
  end
15
+
16
+ # logging in this script
17
+ def log(message="",level=nil)
18
+ msg message, level
19
+ File.open(@@output_log, "a") {|f| f.write(message) }
20
+ end
15
21
 
16
22
  # capture has a set of three commands that are used to generate
17
23
  # packet captures, poll the status and return the resulting file
@@ -23,8 +29,12 @@ class Cmd_runfuzz < Command
23
29
  # * port = the Mu interface on which to capture packets
24
30
  def cmd_run argv
25
31
  setup argv
26
- # set all aparms
32
+ # set all params
27
33
  archive = @hash['archive']
34
+ if archive == nil
35
+ archive = false
36
+ end
37
+ archive_options = @hash['archive_options']
28
38
  directory = @hash['directory']
29
39
  force = @hash['force']
30
40
  interval = @hash['interval']
@@ -32,6 +42,14 @@ class Cmd_runfuzz < Command
32
42
  prepend = @hash['prepend']
33
43
  template = @hash['template']
34
44
  uuid = @hash['uuid']
45
+ verify = @hash['verify']
46
+ if verify == nil
47
+ verify = false
48
+ end
49
+ verifyonly = @hash['verifyonly']
50
+ if verifyonly == nil
51
+ verifyonly = false
52
+ end
35
53
 
36
54
  # set any timers to minimum non psychotic numbers
37
55
  sleeptime = 10 # 10 sec
@@ -64,7 +82,7 @@ class Cmd_runfuzz < Command
64
82
  files = Dir.glob(File.join(@hash["directory"],"","*.xml"))
65
83
  files.each do | file |
66
84
  response = @api.import_templates(file)
67
- msg response, Logger::DEBUG
85
+ log response, Logger::DEBUG
68
86
  doc = make_xml(response)
69
87
  unless doc.xpath("//model_object").empty?
70
88
  doc.xpath("//model_object").each do |node|
@@ -72,7 +90,7 @@ class Cmd_runfuzz < Command
72
90
  my_name = node.xpath("name").text
73
91
  my_type = node.xpath("type").text
74
92
  if my_type=="Analysis"
75
- msg "type = #{my_type} uuid = #{my_uuid} name = #{my_name}", Logger::DEBUG
93
+ log "type = #{my_type} uuid = #{my_uuid} name = #{my_name}", Logger::DEBUG
76
94
  my_uuid_hash[my_uuid] = my_name
77
95
  end
78
96
  end
@@ -82,7 +100,7 @@ class Cmd_runfuzz < Command
82
100
  if template != nil
83
101
  # import template file into mu and add all uuids to list
84
102
  response = @api.import_templates(template)
85
- msg response, Logger::DEBUG
103
+ log response, Logger::DEBUG
86
104
  doc = make_xml(response)
87
105
  unless doc.xpath("//model_object").empty?
88
106
  doc.xpath("//model_object").each do |node|
@@ -90,7 +108,7 @@ class Cmd_runfuzz < Command
90
108
  my_name = node.xpath("name").text
91
109
  my_type = node.xpath("type").text
92
110
  if my_type=="Analysis"
93
- msg "type = #{my_type} uuid = #{my_uuid} name = #{my_name}", Logger::DEBUG
111
+ log "type = #{my_type} uuid = #{my_uuid} name = #{my_name}", Logger::DEBUG
94
112
  my_uuid_hash[my_uuid] = my_name
95
113
  end
96
114
  end
@@ -111,13 +129,15 @@ class Cmd_runfuzz < Command
111
129
  end
112
130
  end
113
131
  if my_uuid_hash.empty?
114
- msg "no valid test option selected, please specify directory, template file, or uuid"
132
+ log "no valid test option selected, please specify directory, template file, or uuid"
115
133
  help
116
134
  exit
135
+ else
136
+ log "#{my_uuid_hash.size} tests in queue."
117
137
  end
118
138
 
119
139
  # now we run all the tests
120
- #msg "RUNNING"
140
+ #log "RUNNING"
121
141
  results = {}
122
142
  map = my_uuid_hash.each_pair do |key,value|
123
143
  t1 = Time.now.localtime.tv_sec
@@ -125,23 +145,47 @@ class Cmd_runfuzz < Command
125
145
  suspend_time = t1
126
146
  polling_time = t1
127
147
  if prepend != nil
128
- name = "#{prepend} #{value}"
148
+ name = "#{prepend}#{value}"
129
149
  else
130
- name = value
150
+ name = "#{value}#{Time.now.localtime}"
151
+ end
152
+ if @@output_dir != nil
153
+ name = "#{@@output_dir}/#{prepend}#{value}"
154
+ end
155
+ log "my name = #{name} with uuid = #{key}", Logger::DEBUG
156
+ # need to set new host values if host values are present
157
+ hosts = @hash['hosts']
158
+ if hosts != nil
159
+ log "SET ALL HOSTS USING: #{hosts}", Logger::DEBUG
160
+ new_uuid = set_hosts(key,hosts)
161
+ end
162
+ verify_good = false
163
+ log "verify = #{verify} and verifyonly = #{verifyonly}"
164
+ if verify || verifyonly
165
+ log "verify = #{verify} and verifyonly = #{verifyonly}"
166
+ verify_good = verify_analysis(key,name)
167
+ end
168
+ if verifyonly
169
+ log "Verify Only! executing next test."
170
+ next
171
+ end
172
+ if verify && !verify_good
173
+ log "Analysis #{name} failed to verify! Executing next test."
174
+ next
131
175
  end
132
- msg "my name = #{name} with uuid = #{key}"
133
176
  run = true
177
+ run_uuid = ""
134
178
  run_uuid = @api.run(key, URI.encode(name))
135
179
  while run
136
180
  sleep(sleeptime)
137
181
  status = @api.status(run_uuid)
138
- msg status
182
+ log status
139
183
  t2 = Time.now.localtime.tv_sec
140
- msg t2-t1
184
+ log t2-t1
141
185
  if interval > 0
142
186
  if t2-polling_time > interval
143
187
  faults = @api.get_faults(run_uuid)
144
- msg faults, Logger::DEBUG
188
+ log faults, Logger::DEBUG
145
189
  # faults should be an xml doc already
146
190
  unless faults.xpath("//fault_list_summary").empty?
147
191
  count = 0
@@ -165,7 +209,7 @@ class Cmd_runfuzz < Command
165
209
  confidence_level_1 += 1
166
210
  end
167
211
  end
168
- msg "Current fault count: #{count}, confidence_level 5: #{confidence_level_5}"+
212
+ log "Current fault count: #{count}, confidence_level 5: #{confidence_level_5}"+
169
213
  ", confidence_level 4: #{confidence_level_4}, confidence_level 3: #{confidence_level_3}"+
170
214
  ", confidence_level 2: #{confidence_level_2}, confidence_level 1: #{confidence_level_1}"
171
215
  end
@@ -175,36 +219,66 @@ class Cmd_runfuzz < Command
175
219
  if status =~ /ABORTED/ or status =~ /FINISHED/ or status =~ /FAILED/
176
220
  run = false
177
221
  elsif status =~ /SUSPENDED/
178
- msg "SUSPEND--->"
222
+ log "SUSPEND--->"
179
223
  if t2-suspend_time > force*60
180
224
  response = @api.resume(run_uuid)
181
- msg response
225
+ log response
182
226
  suspend_time = Time.now.localtime.tv_sec
183
227
  end
184
228
  end
185
229
  end
186
- # now we pull results for run and tabulate fault list
187
- job_id = @api.archive("run",run_uuid,"",name,"Run via Mu Ruby Gem API #{Time.now}",true,true,true,false,false,false)
188
- job = true
189
- count = 0
190
- while job
191
- job_status = @api.archive("status", job_id)
192
- msg "job_status = #{job_status}"
193
- if job_status =~ /Finished/
194
- job = false
230
+ # now we pull results for run and tabulate fault list if needed
231
+ if archive
232
+ evts = false
233
+ pcaps = false
234
+ samples = false
235
+ logo = false
236
+ audit = false
237
+ sign = false
238
+ if archive_options =~ /evts/
239
+ evts = true
240
+ end
241
+ if archive_options =~ /pcaps/
242
+ pcaps = true
243
+ end
244
+ if archive_options =~ /samples/
245
+ samples = true
246
+ end
247
+ if archive_options =~ /logo/
248
+ logo = true
249
+ end
250
+ if archive_options =~ /audit/
251
+ audit = true
252
+ end
253
+ if archive_options =~ /sign/
254
+ sign = true
255
+ end
256
+ log "evts = #{evts}, pcaps = #{pcaps}, samples = #{samples}, logo = #{logo}, audit = #{audit}, sign = #{sign}", Logger::DEBUG
257
+ job_id = @api.archive("run",run_uuid,"",name,"Run via Mu Ruby Gem API #{Time.now}",evts,pcaps,samples,logo,audit,sign)
258
+ job = true
259
+ count = 0
260
+ while job
261
+ job_status = @api.archive("status", job_id)
262
+ log "archive job_status = #{job_status}"
263
+ if job_status =~ /Finished/
264
+ job = false
265
+ end
266
+ sleep(sleeptime)
267
+ count += 1
268
+ if count > 30
269
+ job = false
270
+ end
195
271
  end
196
- sleep(sleeptime)
197
- count += 1
198
- if count > 30
199
- job = false
200
- end
272
+ if File.exists?(name) && File.directory?(name)
273
+ log "directiry #{name} already exists", Logger::DEBUG
274
+ else
275
+ log "creating directory for archive results: #{name}", Logger::DEBUG
276
+ Dir.mkdir(name)
277
+ end
278
+ response = @api.archive("get",job_id,name)
201
279
  end
202
- if Dir[name] == nil
203
- Dir.mkdir(name)
204
- end
205
- response = @api.archive("get",job_id,name)
206
280
  faults = @api.get_faults(run_uuid)
207
- msg faults, Logger::DEBUG
281
+ log faults, Logger::DEBUG
208
282
  # faults should be an xml doc already
209
283
  unless faults.xpath("//fault_list_summary").empty?
210
284
  count = 0
@@ -229,7 +303,7 @@ class Cmd_runfuzz < Command
229
303
  end
230
304
  end
231
305
 
232
- msg "Ending fault countfor #{name}: #{count}, confidence_level 5: #{confidence_level_5}"+
306
+ log "Ending fault countfor #{name}: #{count}, confidence_level 5: #{confidence_level_5}"+
233
307
  ", confidence_level 4: #{confidence_level_4}, confidence_level 3: #{confidence_level_3}"+
234
308
  ", confidence_level 2: #{confidence_level_2}, confidence_level 1: #{confidence_level_1}"
235
309
  end
@@ -244,6 +318,18 @@ private
244
318
 
245
319
  def setup argv
246
320
  parse_cli argv
321
+ @@output_dir = @hash['output_dir']
322
+ if @@output_dir != nil
323
+ @@output_log = "#{@@output_dir}/cmd_runanalysis_#{Time.now.localtime}.log"
324
+ begin
325
+ Dir.mkdir(@@output_dir)
326
+ rescue
327
+ msg "Directory already exists", Logger::DEBUG
328
+ end
329
+ else
330
+ @@output_dir = ""
331
+ @@output_log = "cmd_runanalysis_#{Time.now.localtime}.log"
332
+ end
247
333
  @host = (@@mu_ip.nil?) ? "127.0.0.1" : @@mu_ip
248
334
  @username = (@@mu_admin_user.nil?) ? "admin" : @@mu_admin_user
249
335
  @password = (@@mu_admin_pass.nil?) ? "admin" : @@mu_admin_pass
@@ -251,7 +337,8 @@ private
251
337
  @params = nil
252
338
  @expected_error = nil
253
339
  @api = Muapi.new(@host, @username, @password)
254
- msg "Created API object to :#{@host}", Logger::DEBUG
340
+ @http = Mu::HttpHelper.new(@host, @username, @password, @docroot)
341
+ log "Created API object to :#{@host}", Logger::DEBUG
255
342
  end
256
343
 
257
344
  def parse_cli argv
@@ -261,9 +348,13 @@ private
261
348
  args << argv.shift if argv.first[0,1] != '-'
262
349
 
263
350
  k = argv.shift
351
+
352
+ #@hash['verifyonly'] = false
353
+ #@hash['verify'] = false
264
354
 
265
355
  if [ '-a', '--archive' ].member? k
266
- @hash['archive'] = shift(k, argv)
356
+ @hash['archive'] = true
357
+ @hash['archive_options'] = shift(k, argv)
267
358
  next
268
359
  end
269
360
 
@@ -282,6 +373,11 @@ private
282
373
  exit
283
374
  end
284
375
 
376
+ if [ '-H', '--hosts' ].member? k
377
+ @hash['hosts'] = shift(k, argv)
378
+ next
379
+ end
380
+
285
381
  if [ '-i', '--interval' ].member? k
286
382
  @hash['interval'] = shift(k, argv)
287
383
  next
@@ -303,7 +399,7 @@ private
303
399
  end
304
400
 
305
401
  if [ '-o', '--output' ].member? k
306
- $stdout.reopen(shift(k, argv), "w")
402
+ @hash['output_dir'] = shift(k, argv)
307
403
  next
308
404
  end
309
405
 
@@ -326,7 +422,18 @@ private
326
422
  $log.level = Logger::DEBUG
327
423
  next
328
424
  end
329
- msg "Unknown argument #{k}"
425
+
426
+ if [ '-z', '--verify' ].member? k
427
+ @hash['verify'] = true
428
+ next
429
+ end
430
+
431
+ if [ '-Z', '--verifyonly' ].member? k
432
+ @hash['verifyonly'] = true
433
+ next
434
+ end
435
+
436
+ log "Unknown argument #{k}"
330
437
  help
331
438
  exit
332
439
 
@@ -341,23 +448,48 @@ private
341
448
  { :short => '-d', :long => '--dir', :value => '<string>', :help => 'directory containing the scenario files' },
342
449
  { :short => '-f', :long => '--force', :value => '<integer>', :help => 'force resume on pause after time elapse in min' },
343
450
  { :short => '-h', :long => '--help', :value => '', :help => 'help on command line options' },
451
+ { :short => '-H', :long => '--hosts', :value => '<string>', :help => 'list of hosts: host_0:a1:HOST_V4,host_1:a2:HOST_V4 or src:a1:IF_V6_LOCAL,dst:my_host_name:HOST_MAC,src_proxy:a1:HOST_V4,dst_proxy:a1:HOST_V4' },
344
452
  { :short => '-i', :long => '--interval', :value => '<integer>', :help => 'execute fault status update at intervalin seconds. minimum = 5' },
345
453
  { :short => '-m', :long => '--mu_string', :value => '<string>', :help => 'user, password, mu_ip in the form of admin:admin@10.9.8.7' },
346
- { :short => '-o', :long => '--output', :value => '<string>', :help => 'output logging to this file' },
454
+ { :short => '-o', :long => '--output', :value => '<string>', :help => 'save all output to this directory or path location' },
347
455
  { :short => '-p', :long => '--prepend', :value => '<string>', :help => 'prepend test name with <string>' },
348
- { :short => '-t', :long => '--template', :value => '', :help => 'the template file to run' },
456
+ { :short => '-t', :long => '--template', :value => '<string>', :help => 'the template file to run' },
349
457
  { :short => '-u', :long => '--uuid', :value => '<string>', :help => 'comma seperated uuid list of template uuids' },
350
- { :short => '-v', :long => '--verbose', :value => '', :help => 'set Logger::DEBUG level' }
458
+ { :short => '-v', :long => '--verbose', :value => '', :help => 'set Logger::DEBUG level' },
459
+ { :short => '-z', :long => '--verify', :value => '', :help => 'test if instrumentation is sucessfull' },
460
+ { :short => '-Z', :long => '--verifyonly', :value => '', :help => 'only test instrumentation, run no test cases' }
351
461
  ]
352
462
 
353
463
  cmds = [
354
- "mu cmd_runfuzz:run -f <string /path/my-template-name.xml> -p <string> -a <string pcaps,evts,samples,logo,audit,sign ",
464
+ "Run a basic test:",
465
+ " mu cmd_runanalysis:run -t /path/my-template-name.xml -p <string> -a <string pcaps,evts,samples,logo,audit,sign ",
466
+ "Run a DoS test seting interfaces:",
467
+ " mu cmd_runanalysis:run -t /path/my-template-name.xml -p My_Name_To_Append -m admin:admin@192.168.1.253 -H src:a1:IF_V4,dst:MS_SQL:HOST_V4,dos_inst_src:a1:IF_V4,dos_inst_dst:Mu_IP:HOST_V4",
468
+ "Run a Sceanrio mutation test seting interfaces:",
469
+ " mu cmd_runanalysis:run -t /path/my-template-name.xml -p My_Name_To_Append -m admin:admin@192.168.1.253 -f 5 -H host_0:a1:IF_V4,host_1:a2:IF_V4,host_2:a2:IF_V4,host_3:a1:IF_V4,host_4:a1:IF_V4",
470
+ "Run a PVA test seting interfaces:",
471
+ " mu cmd_runanalysis:run -t /path/my-template-name.xml -p My_Name_To_Append -m admin:admin@192.168.1.253 -f 5 -H src:a1:IF_V4,dst:a2:IF_V4",
472
+ "Run a Protocal mutation test seting interfaces:",
473
+ " mu cmd_runanalysis:run -t /path/my-template-name.xml -p My_Name_To_Append -m admin:admin@192.168.1.253 -H src:a1:IF_V4,dst:a2:IF_V4",
474
+ "Run a protocal mutation test and force verifiaction before saving all output to a specified directory:",
475
+ " mu cmd_runanalysis:run -t /path/my-template-name.xml -m admin:admin@192.168.1.253 -p My_Name_To_Append -o /path/my-output-dir -z",
476
+ "Run a test with aditional instrumentation setting all additional instramentation to same source and destination:",
477
+ " mu cmd_runanalysis:run -t /path/my-template-name.xml -p My_Name_To_Append -m admin:admin@192.168.1.253 -H src:a1:IF_V4,dst:a2:IF_V4,add_inst_src:a1:IF_V4,add_inst_dst:My_Target_Host,HOST_V4",
478
+ "Run a scenario test with ssh chanels:",
479
+ " mu cmd_runanalysis:run -t /path/my-template-name.xml -p My_Name_To_Append -m admin:admin@192.168.1.253 -H host_0:a1:IF_V4,host_1:a2:IF_V4,channel:TargetHost,channel_1:TargetHost2",
480
+ "Run a protocal test setting all monitors to a new target:",
481
+ " mu cmd_runanalysis:run -t /path/my-template-name.xml -m admin:admin@192.168.1.253 -p My_Name_To_Append -o /path/my-output-dir -H src:a1:IF_V4,dst:a2:IF_V4,monitor:MyHost",
482
+ "Run a test with actions:",
483
+ " mu cmd_runanalysis:run -t /path/my-template-name.xml -m admin:admin@192.168.1.253 -p My_Name_To_Append -o /path/my-output-dir -H src:a1:IF_V4,dst:a2:IF_V4,action:MyHost",
484
+ "Run a test seting restarter host:",
485
+ " mu cmd_runanalysis:run -t /path/my-template-name.xml -m admin:admin@192.168.1.253 -p My_Name_To_Append -o /path/my-output-dir -H src:a1:IF_V4,dst:a2:IF_V4,restart:MyHost",
486
+
355
487
  ]
356
488
 
357
489
  max_long_size = helps.inject(0) { |memo, obj| [ obj[:long].size, memo ].max }
358
490
  max_value_size = helps.inject(0) { |memo, obj| [ obj[:value].size, memo ].max }
359
491
  puts
360
- puts "Usage: mu cmd_runfuzz <options>"
492
+ puts "Usage: mu cmd_runanalysis <options>"
361
493
  puts
362
494
  helps.each do |h|
363
495
  puts "%-*s %*s %-*s %s" % [max_long_size, h[:long], 2, h[:short], max_value_size, h[:value], h[:help]]
@@ -371,6 +503,347 @@ private
371
503
  puts
372
504
  end
373
505
 
506
+ def set_hosts(uuid, hosts)
507
+ log uuid,Logger::DEBUG
508
+ template_uuid = ""
509
+ verify_uuid = ""
510
+ # 1. get the test template from Mu server. return false if not an analysis template
511
+ doc = @api.export_by_uuid(uuid)
512
+ if doc.xpath("//analysis").size <= 0
513
+ log "Unexpected template type found at uuid: #{uuid}"
514
+ return "ERROR_SETTING_HOSTS"
515
+ end
516
+
517
+ host_list = hosts.split(",")
518
+ # 3. replace all host data
519
+ doc.xpath("//endpoint").each do |endpoint|
520
+ role = ""
521
+ host_data = ""
522
+ children = endpoint.children()
523
+ children.each do |child|
524
+ if child.name =~ /role/
525
+ role = child.content
526
+ elsif child.name =~ /reference/
527
+ host_data = child
528
+ end
529
+ end
530
+ #log role, Logger::INFO
531
+ #log host_data, Logger::INFO
532
+ host_list.each do |host|
533
+ if host =~ /#{role}/
534
+ host_parts = host.split(":")
535
+ host_data['name'] = host_parts[1]
536
+ host_data['type'] = host_parts[2]
537
+ end
538
+ end
539
+ log endpoint, Logger::DEBUG
540
+ end
541
+ # 4. replace any DoS monitoring host data
542
+ dst_data = ""
543
+ src_data = ""
544
+ begin
545
+ doc.xpath("//availability_monitor").children().each do |data|
546
+ if data.name =~ /src/
547
+ src_data = data
548
+ elsif data.name =~ /dst/
549
+ dst_data = data
550
+ end
551
+ #log data, Logger::INFO
552
+ end
553
+ host_list.each do |host|
554
+ if host =~ /dos_inst_src/
555
+ host_parts = host.split(":")
556
+ src_data['name'] = host_parts[1]
557
+ src_data['type'] = host_parts[2]
558
+ elsif host =~ /dos_inst_dst/
559
+ host_parts = host.split(":")
560
+ dst_data['name'] = host_parts[1]
561
+ dst_data['type'] = host_parts[2]
562
+ end
563
+ end
564
+ rescue
565
+ log "No host settings for DoS Instrumentation", Logger::DEBUG
566
+ end
567
+
568
+ # 5. replace any additional instrumentation host data
569
+ begin
570
+ dst_data_name = ""
571
+ dst_data_type = ""
572
+ src_data_name = ""
573
+ src_data_type = ""
574
+ host_list.each do |host|
575
+ if host =~ /add_inst_src/
576
+ host_parts = host.split(":")
577
+ src_data_name = host_parts[1]
578
+ src_data_type = host_parts[2]
579
+ elsif host =~ /add_inst_dst/
580
+ host_parts = host.split(":")
581
+ dst_data_name = host_parts[1]
582
+ dst_data_type = host_parts[2]
583
+ end
584
+ end
585
+ doc.xpath("//additional_instrumentation").children().each do |data|
586
+ if data.name =~ /dst/
587
+ data['name'] = dst_data_name
588
+ data['type'] = dst_data_type
589
+ elsif data.name =~ /src/
590
+ data['name'] = src_data_name
591
+ data['type'] = src_data_type
592
+ end
593
+ end
594
+ rescue
595
+ log "No host settings for Additional Instrumentation", Logger::DEBUG
596
+ end
597
+
598
+ # 6. replace any channel host data using role channel, channel_1, channel_2
599
+ begin
600
+ channel_host = ""
601
+ channel_type = ""
602
+ doc.xpath("//channel").each do |channel|
603
+ role = ""
604
+ host_data = ""
605
+ children = channel.children()
606
+ children.each do |child|
607
+ begin
608
+ if child.name =~ /role/
609
+ role = child.content
610
+ elsif child.name =~ /reference/
611
+ host_data = child
612
+ end
613
+ end
614
+ end
615
+ host_list.each do |host|
616
+ host_parts = host.split(":")
617
+ if role =~ /#{host_parts[0]}/
618
+ host_data['name'] = host_parts[1]
619
+ #host_data['type'] = host_parts[2]
620
+ end
621
+ end
622
+ log channel, Logger::DEBUG
623
+ end
624
+ rescue
625
+ log "No channel settings found", Logger::ERROR
626
+ end
627
+
628
+ # 7. replace any monitor host data
629
+ begin
630
+ mon_host_name = ""
631
+ #mon_host_type = ""
632
+ host_list.each do |host|
633
+ if host =~ /^monitor/
634
+ host_parts = host.split(":")
635
+ mon_host_name = host_parts[1]
636
+ #mon_host_type = host_parts[2]
637
+ end
638
+ end
639
+ doc.xpath("//remote_log_monitor").children().each do |data|
640
+ if data.name =~ /host/
641
+ data['name'] = mon_host_name
642
+ #data['type'] = mon_host_type
643
+ end
644
+ end
645
+ doc.xpath("//snmp_monitor").children().each do |data|
646
+ if data.name =~ /host/
647
+ data['name'] = mon_host_name
648
+ #data['type'] = mon_host_type
649
+ end
650
+ end
651
+ doc.xpath("//console_monitor").children().each do |data|
652
+ if data.name =~ /host/
653
+ data['name'] = mon_host_name
654
+ #data['type'] = mon_host_type
655
+ end
656
+ end
657
+ doc.xpath("//command_monitor").children().each do |data|
658
+ if data.name =~ /host/
659
+ data['name'] = mon_host_name
660
+ #data['type'] = mon_host_type
661
+ end
662
+ end
663
+ rescue
664
+ log "No monitors found", Logger::DEBUG
665
+ end
666
+
667
+ # 8. replace any action host data. host type is always "HOST"
668
+ begin
669
+ action_host_name = ""
670
+ action_host_type = "HOST"
671
+ host_list.each do |host|
672
+ if host =~ /action/
673
+ host_parts = host.split(":")
674
+ action_host_name = host_parts[1]
675
+ #action_host_type = host_parts[2]
676
+ end
677
+ end
678
+ doc.xpath("//syslog_notifier").children().each do |data|
679
+ if data.name =~ /host/
680
+ data['name'] = action_host_name
681
+ #data['type'] = action_host_type
682
+ end
683
+ end
684
+ doc.xpath("//remote_trigger").children().each do |data|
685
+ if data.name =~ /host/
686
+ data['name'] = action_host_name
687
+ #data['type'] = action_host_type
688
+ end
689
+ end
690
+ rescue
691
+ log "No actions found", Logger::DEBUG
692
+ end
693
+
694
+ # 9. replace any restarter host data
695
+ begin
696
+ action_host_name = ""
697
+ action_host_type = "HOST"
698
+ host_list.each do |host|
699
+ if host =~ /restart/
700
+ host_parts = host.split(":")
701
+ action_host_name = host_parts[1]
702
+ end
703
+ end
704
+ # service restarter
705
+ doc.xpath("//service_controller").children().each do |data|
706
+ if data.name =~ /host/
707
+ data['name'] = action_host_name
708
+ #data['type'] = action_host_type
709
+ end
710
+ end
711
+ # proces restarter
712
+ doc.xpath("//process_controller").children().each do |data|
713
+ if data.name =~ /host/
714
+ data['name'] = action_host_name
715
+ #data['type'] = action_host_type
716
+ end
717
+ end
718
+ # power restarter
719
+ doc.xpath("//internal_restarter").children().each do |data|
720
+ if data.name =~ /port/
721
+ data.content = action_host_name
722
+ end
723
+ end
724
+ rescue
725
+ log "No restarters found", Logger::DEBUG
726
+ end
727
+
728
+ # 10. upload to mu with new host information overwriting old info.
729
+ log "Updting test on appliance with host info"
730
+ template_uuid = ""
731
+ response = @http.post("/templates/import",doc.to_s())
732
+ log response, Logger::DEBUG
733
+ return uuid
734
+ end
735
+
736
+ def verify_analysis(uuid='', name='')
737
+ log "Verify analysis instrumentation"
738
+ status = "NOT_RUN"
739
+ template_uuid = ""
740
+ verify_uuid = ""
741
+ # 1. get the test template from Mu server. return false if not an analysis template
742
+ doc = @api.export_by_uuid(uuid)
743
+ if doc.xpath("//analysis").size <= 0
744
+ log "Unexpected template type found at uuid: #{uuid}"
745
+ return false
746
+ end
747
+
748
+ # 2. replace the exclude/include portions of the template
749
+ doc.search("//analysis").each do |analysis|
750
+ template_uuid = new_uuid
751
+ analysis['uuid'] = "#{template_uuid}"
752
+ analysis['name'] = "VERIFY "+analysis['name']
753
+ end
754
+ doc.xpath("//excludes").each do |excludes|
755
+ excludes.content = nil
756
+ end
757
+ filter = Nokogiri::XML("<include><variant_filter><name>123abc454bca321</name><operator>CONTAINS</operator></variant_filter></include>").xpath("//include")
758
+ doc.xpath("//includes").each do |includes|
759
+ includes.content = nil
760
+ includes.children.first.add_previous_sibling(filter)
761
+ log doc, Logger::DEBUG
762
+ end
763
+
764
+ # 3. upload to mu with VERIFY name tag.
765
+ log "Importing 'verify' template"
766
+ template_uuid = ""
767
+ response = @http.post("/templates/import",doc.to_s())
768
+ log response, Logger::DEBUG
769
+ doc = make_xml(response)
770
+ name = ""
771
+ unless doc.xpath("//model_object").empty?
772
+ doc.xpath("//model_object").each do |node|
773
+ my_uuid = node.xpath("uuid").text
774
+ my_name = node.xpath("name").text
775
+ my_type = node.xpath("type").text
776
+ if my_type=="Analysis"
777
+ template_uuid = my_uuid
778
+ name = my_name
779
+ end
780
+ end
781
+ end
782
+
783
+ # 4. run verify and pull status from result
784
+ verify_uuid = @api.run(template_uuid,URI.encode(name))
785
+ log "verify_uuid = #{verify_uuid}"
786
+ run = true
787
+ while run
788
+ sleep(10)
789
+ status = @api.status(verify_uuid)
790
+ log "verify status = #{status}"
791
+ if status =~ /ABORTED/ or status =~ /FINISHED/ or status =~ /FAILED/
792
+ run = false
793
+ end
794
+ end
795
+
796
+ # 5. delete template and result from Mu
797
+ response = @api.delete(template_uuid)
798
+ log response, Logger::DEBUG
799
+ response = @api.delete(verify_uuid)
800
+ log response, Logger::DEBUG
801
+
802
+ # end of verify process #########################
803
+ log "Analysis #{name} verify result: #{status}."
804
+
805
+ if status=~/FINISHED/
806
+ return true
807
+ else
808
+ return false
809
+ end
810
+ return false
811
+ end
812
+
813
+ def new_uuid
814
+ uuid = ""
815
+ validChars = ("A".."F").to_a + ("0".."9").to_a
816
+ length = validChars.size
817
+ hexCode=""
818
+ 1.upto(8) do |i|
819
+ hexCode << validChars[rand(length-1)]
820
+ end
821
+ uuid = hexCode
822
+ hexCode=""
823
+ 1.upto(4) do |i|
824
+ hexCode << validChars[rand(length-1)]
825
+ end
826
+ uuid = "#{uuid}-#{hexCode}"
827
+ hexCode=""
828
+ 1.upto(4) do |i|
829
+ hexCode << validChars[rand(length-1)]
830
+ end
831
+ uuid = "#{uuid}-#{hexCode}"
832
+ hexCode=""
833
+ 1.upto(4) do |i|
834
+ hexCode << validChars[rand(length-1)]
835
+ end
836
+ uuid = "#{uuid}-#{hexCode}"
837
+ hexCode=""
838
+ 1.upto(12) do |i|
839
+ hexCode << validChars[rand(length-1)]
840
+ end
841
+ uuid = "#{uuid}-#{hexCode}"
842
+ uuid = uuid.downcase
843
+ log "uuid = #{uuid}"
844
+ return uuid
845
+ end
846
+
374
847
  end
375
848
  end # Command
376
849
  end # Mu
data/version.rb CHANGED
@@ -1 +1 @@
1
- VERSION='5.7.39'
1
+ VERSION='5.7.40'
metadata CHANGED
@@ -1,90 +1,122 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: mu
3
- version: !ruby/object:Gem::Version
4
- version: 5.7.39
3
+ version: !ruby/object:Gem::Version
4
+ version: 5.7.40
5
+ prerelease:
5
6
  platform: ruby
6
- authors:
7
+ authors:
7
8
  - MuEng
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
-
12
- date: 2012-08-17 00:00:00 -07:00
13
- default_executable:
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
12
+ date: 2012-11-16 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
16
15
  name: nokogiri
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 1.4.4
17
22
  type: :runtime
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
20
- requirements:
21
- - - ">="
22
- - !ruby/object:Gem::Version
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
23
29
  version: 1.4.4
24
- version:
25
- - !ruby/object:Gem::Dependency
30
+ - !ruby/object:Gem::Dependency
26
31
  name: rest-client
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: 1.6.1
27
38
  type: :runtime
28
- version_requirement:
29
- version_requirements: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
33
45
  version: 1.6.1
34
- version:
35
- - !ruby/object:Gem::Dependency
46
+ - !ruby/object:Gem::Dependency
36
47
  name: mime-types
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '1.16'
37
54
  type: :runtime
38
- version_requirement:
39
- version_requirements: !ruby/object:Gem::Requirement
40
- requirements:
41
- - - ">="
42
- - !ruby/object:Gem::Version
43
- version: "1.16"
44
- version:
45
- - !ruby/object:Gem::Dependency
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '1.16'
62
+ - !ruby/object:Gem::Dependency
46
63
  name: json
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
47
70
  type: :runtime
48
- version_requirement:
49
- version_requirements: !ruby/object:Gem::Requirement
50
- requirements:
51
- - - ">="
52
- - !ruby/object:Gem::Version
53
- version: "0"
54
- version:
55
- - !ruby/object:Gem::Dependency
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
56
79
  name: hexy
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: 0.1.1
57
86
  type: :runtime
58
- version_requirement:
59
- version_requirements: !ruby/object:Gem::Requirement
60
- requirements:
61
- - - ">="
62
- - !ruby/object:Gem::Version
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
63
93
  version: 0.1.1
64
- version:
65
- - !ruby/object:Gem::Dependency
94
+ - !ruby/object:Gem::Dependency
66
95
  name: uuid
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: 2.0.2
67
102
  type: :runtime
68
- version_requirement:
69
- version_requirements: !ruby/object:Gem::Requirement
70
- requirements:
71
- - - ">="
72
- - !ruby/object:Gem::Version
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
73
109
  version: 2.0.2
74
- version:
75
- description: |-
76
- The Mu gem allows users to include Mu libraries within scripts
77
- that interact with the appliance software. The gem also supplies command line interfaces
78
- to many of these same libraries
79
- email:
110
+ description: ! "The Mu gem allows users to include Mu libraries within scripts\n that
111
+ interact with the appliance software. The gem also supplies command line interfaces\n
112
+ \ to many of these same libraries"
113
+ email:
80
114
  - support@mudynamics.com
81
- executables:
115
+ executables:
82
116
  - mu
83
117
  extensions: []
84
-
85
118
  extra_rdoc_files: []
86
-
87
- files:
119
+ files:
88
120
  - lib/mu/api/ddt.rb
89
121
  - lib/mu/api/homepage.rb
90
122
  - lib/mu/api/muapi.rb
@@ -119,33 +151,29 @@ files:
119
151
  - version.rb
120
152
  - LICENSE.txt
121
153
  - README.md
122
- has_rdoc: true
123
154
  homepage: http://www.spirent.com
124
155
  licenses: []
125
-
126
156
  post_install_message:
127
157
  rdoc_options: []
128
-
129
- require_paths:
158
+ require_paths:
130
159
  - lib
131
- required_ruby_version: !ruby/object:Gem::Requirement
132
- requirements:
133
- - - ">="
134
- - !ruby/object:Gem::Version
160
+ required_ruby_version: !ruby/object:Gem::Requirement
161
+ none: false
162
+ requirements:
163
+ - - ! '>='
164
+ - !ruby/object:Gem::Version
135
165
  version: 1.8.7
136
- version:
137
- required_rubygems_version: !ruby/object:Gem::Requirement
138
- requirements:
139
- - - ">="
140
- - !ruby/object:Gem::Version
141
- version: "0"
142
- version:
166
+ required_rubygems_version: !ruby/object:Gem::Requirement
167
+ none: false
168
+ requirements:
169
+ - - ! '>='
170
+ - !ruby/object:Gem::Version
171
+ version: '0'
143
172
  requirements: []
144
-
145
173
  rubyforge_project:
146
- rubygems_version: 1.3.5
174
+ rubygems_version: 1.8.24
147
175
  signing_key:
148
176
  specification_version: 3
149
177
  summary: Spirent Communications General Purpose Library and Command Line Tool
150
178
  test_files: []
151
-
179
+ has_rdoc: