openvas-cli 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. data/Gemfile +2 -0
  2. data/Gemfile.lock +50 -0
  3. data/VERSION +1 -1
  4. data/lib/openvas-cli/configuration.rb +25 -0
  5. data/lib/openvas-cli/conn_addin.rb +27 -0
  6. data/lib/openvas-cli/immutable_children_validator.rb +15 -0
  7. data/lib/openvas-cli/vas_administrator.rb +7 -0
  8. data/lib/openvas-cli/vas_base.rb +20 -30
  9. data/lib/openvas-cli/vas_config.rb +127 -0
  10. data/lib/openvas-cli/vas_connection.rb +140 -0
  11. data/lib/openvas-cli/vas_exceptions.rb +9 -7
  12. data/lib/openvas-cli/vas_lsc_credential.rb +110 -0
  13. data/lib/openvas-cli/vas_nvt.rb +64 -64
  14. data/lib/openvas-cli/vas_nvt_family.rb +39 -30
  15. data/lib/openvas-cli/vas_override.rb +6 -4
  16. data/lib/openvas-cli/vas_period.rb +89 -0
  17. data/lib/openvas-cli/vas_preference.rb +139 -49
  18. data/lib/openvas-cli/vas_report.rb +110 -103
  19. data/lib/openvas-cli/vas_result.rb +90 -89
  20. data/lib/openvas-cli/vas_schedule.rb +163 -55
  21. data/lib/openvas-cli/vas_target.rb +200 -23
  22. data/lib/openvas-cli/vas_task.rb +229 -30
  23. data/lib/openvas-cli/vas_task_progress.rb +29 -0
  24. data/lib/openvas-cli/xml_addin.rb +34 -0
  25. data/lib/openvas_cli.rb +19 -0
  26. data/openvas-cli.gemspec +28 -6
  27. data/spec/openvas-cli/vas_administrator_spec.rb +6 -0
  28. data/spec/openvas-cli/vas_config_spec.rb +81 -0
  29. data/spec/openvas-cli/vas_lsc_credential_spec.rb +72 -0
  30. data/spec/openvas-cli/vas_nvt_family_spec.rb +7 -5
  31. data/spec/openvas-cli/vas_nvt_spec.rb +30 -26
  32. data/spec/openvas-cli/vas_period_spec.rb +7 -0
  33. data/spec/openvas-cli/vas_preference_spec.rb +23 -21
  34. data/spec/openvas-cli/vas_report_spec.rb +65 -63
  35. data/spec/openvas-cli/vas_result_spec.rb +94 -93
  36. data/spec/openvas-cli/vas_schedule_spec.rb +154 -57
  37. data/spec/openvas-cli/vas_target_spec.rb +140 -28
  38. data/spec/openvas-cli/vas_task_spec.rb +92 -11
  39. data/spec/spec_helper.rb +15 -5
  40. metadata +72 -24
  41. data/lib/openvas-cli/openvas-cli.rb +0 -273
  42. data/spec/openvas-cli/openvas-cli_spec.rb +0 -45
@@ -1,118 +1,125 @@
1
1
  require 'vas_base'
2
2
 
3
- # Contains the details of a single OpenVAS report.
4
- class VasReport < VasBase
5
- attr_accessor :report_id
6
- attr_accessor :task_id
7
- attr_accessor :task_name
8
- attr_accessor :started_at
9
- # Overall Status Only
10
- attr_accessor :status
11
-
12
- validates :report_id, :presence => true, :UUID => true
13
- validates :task_id, :presence => true, :UUID => true
14
-
15
- # Pulls report details based off of the options passed. By default, pulls all
16
- # reports.
17
- # === Options:
18
- # [:report_id => [report_id]] Pulls a specific +report_id+. If the id provided is bogus, an empty set is returned.
19
- # [:filter => [array_of_filter_symbols]] Filters the report results by severity. Valid symbols are: [:high, :medium, :low, :log, :deubg].
20
- def self.get_all(options={})
21
- params = {}
22
- params[:report_id] = options[:report_id] if options[:report_id]
23
- if options[:filter]
24
- params[:levels] = ""
25
- options[:filter].each { |f|
26
- case f
27
- when :high
28
- params[:levels] += 'h'
29
- when :medium
30
- params[:levels] += 'm'
31
- when :low
32
- params[:levels] += 'l'
33
- when :log
34
- params[:levels] += 'g'
35
- when :debug
36
- params[:levels] += 'd'
3
+ module OpenvasCli
4
+ # Contains the details of a single OpenVAS report.
5
+ class VasReport < VasBase
6
+ attr_accessor :report_id
7
+ attr_accessor :task_id
8
+ attr_accessor :task_name
9
+ attr_accessor :started_at
10
+ # Overall Status Only
11
+ attr_accessor :status
12
+
13
+ validates :report_id, :presence => true, :UUID => true
14
+ validates :task_id, :presence => true, :UUID => true,
15
+ :unless => Proc.new { |report| report.empty? }
16
+
17
+ # Pulls report details based off of the options passed. By default, pulls all
18
+ # reports.
19
+ # === Options:
20
+ # [:report_id => [report_id]] Pulls a specific +report_id+. If the id provided is bogus, an empty set is returned.
21
+ # [:filter => [array_of_filter_symbols]] Filters the report results by severity. Valid symbols are: [:high, :medium, :low, :log, :deubg].
22
+ def self.get_all(options={})
23
+ params = {}
24
+ params[:report_id] = options[:report_id] if options[:report_id]
25
+ if options[:filter]
26
+ params[:levels] = ""
27
+ options[:filter].each { |f|
28
+ case f
29
+ when :high
30
+ params[:levels] += 'h'
31
+ when :medium
32
+ params[:levels] += 'm'
33
+ when :low
34
+ params[:levels] += 'l'
35
+ when :log
36
+ params[:levels] += 'g'
37
+ when :debug
38
+ params[:levels] += 'd'
39
+ end
40
+ }
41
+ end
42
+
43
+ req = Nokogiri::XML::Builder.new { |xml|
44
+ if params.empty?
45
+ xml.get_reports
46
+ else
47
+ xml.get_reports(params)
37
48
  end
38
49
  }
39
- end
40
-
41
- req = Nokogiri::XML::Builder.new { |xml|
42
- if params.empty?
43
- xml.get_reports
44
- else
45
- xml.get_reports(params)
50
+
51
+ begin
52
+ repts = connection.send_receive(req.doc)
53
+ rescue VasExceptions::CommandException => e
54
+ raise e unless e.message =~ /Failed to find/i
55
+ return []
46
56
  end
47
- }
48
-
49
- begin
50
- repts = client.send_receive(req.doc)
51
- rescue VasExceptions::CommandException => e
52
- raise e unless e.message =~ /Failed to find/i
53
- return []
54
- end
55
-
56
- ret = []
57
- repts.xpath('//report').each { |r|
58
- r_id = VasReport.new
59
- r_id.report_id = extract_value_from("@id", r)
60
- r_id.task_id = extract_value_from("task/@id", r)
61
- r_id.task_name = extract_value_from("task/name", r)
62
- r_id.status = extract_value_from("scan_run_status", r)
63
- r_id.started_at = extract_value_from("scan_start", r)
64
57
 
65
- r_id.result_count[:total] = extract_value_from("result_count/full", r).to_i
66
- r_id.result_count[:filtered] = extract_value_from("result_count/filtered", r).to_i
67
- r_id.result_count[:debug][:total] = extract_value_from("result_count/debug/full", r).to_i
68
- r_id.result_count[:debug][:filtered] = extract_value_from("result_count/debug/filtered", r).to_i
69
- r_id.result_count[:high][:total] = extract_value_from("result_count/hole/full", r).to_i
70
- r_id.result_count[:high][:filtered] = extract_value_from("result_count/hold/filtered", r).to_i
71
- r_id.result_count[:low][:total] = extract_value_from("result_count/info/full", r).to_i
72
- r_id.result_count[:low][:filtered] = extract_value_from("result_count/info/filtered", r).to_i
73
- r_id.result_count[:log][:total] = extract_value_from("result_count/log/full", r).to_i
74
- r_id.result_count[:log][:filtered] = extract_value_from("result_count/log/filtered", r).to_i
75
- r_id.result_count[:medium][:total] = extract_value_from("result_count/warning/full", r).to_i
76
- r_id.result_count[:medium][:filtered] = extract_value_from("result_count/warning/filtered", r).to_i
58
+ ret = []
59
+ repts.xpath('//report').each { |r|
60
+ r_id = VasReport.new
61
+ r_id.report_id = extract_value_from("@id", r)
62
+ r_id.task_id = extract_value_from("task/@id", r)
63
+ r_id.task_name = extract_value_from("task/name", r)
64
+ r_id.status = extract_value_from("scan_run_status", r)
65
+ r_id.started_at = extract_value_from("scan_start", r)
66
+
67
+ r_id.result_count[:total] = extract_value_from("result_count/full", r).to_i
68
+ r_id.result_count[:filtered] = extract_value_from("result_count/filtered", r).to_i
69
+ r_id.result_count[:debug][:total] = extract_value_from("result_count/debug/full", r).to_i
70
+ r_id.result_count[:debug][:filtered] = extract_value_from("result_count/debug/filtered", r).to_i
71
+ r_id.result_count[:high][:total] = extract_value_from("result_count/hole/full", r).to_i
72
+ r_id.result_count[:high][:filtered] = extract_value_from("result_count/hold/filtered", r).to_i
73
+ r_id.result_count[:low][:total] = extract_value_from("result_count/info/full", r).to_i
74
+ r_id.result_count[:low][:filtered] = extract_value_from("result_count/info/filtered", r).to_i
75
+ r_id.result_count[:log][:total] = extract_value_from("result_count/log/full", r).to_i
76
+ r_id.result_count[:log][:filtered] = extract_value_from("result_count/log/filtered", r).to_i
77
+ r_id.result_count[:medium][:total] = extract_value_from("result_count/warning/full", r).to_i
78
+ r_id.result_count[:medium][:filtered] = extract_value_from("result_count/warning/filtered", r).to_i
79
+
80
+ r.xpath("results/result").each { |result|
81
+ r_id.results << VasResult.parse_result_node(result)
82
+ }
83
+
84
+ ret << r_id
85
+ }
77
86
 
78
- r.xpath("results/result").each { |result|
79
- r_id.results << VasResult.parse_result_node(result)
87
+ ret
88
+ end
89
+
90
+ def to_xml
91
+ req = Nokogiri::XML::Builder.new { |xml|
92
+ xml.get_reports(:report_id => @report_id)
80
93
  }
81
94
 
82
- ret << r_id
83
- }
95
+ report = VasReport.connection.send_receive(req.doc)
96
+
97
+ report.at_xpath('//report').to_xml
98
+ end
84
99
 
85
- ret
86
- end
87
-
88
- def to_xml
89
- req = Nokogiri::XML::Builder.new { |xml|
90
- xml.get_reports(:report_id => @report_id)
91
- }
100
+ def task
101
+ @task ||= VasTask.get_all(:task_id => @task_id)[0]
102
+ end
103
+
104
+ def results
105
+ @results ||= []
106
+ end
92
107
 
93
- report = VasBase.client.send_receive(req.doc)
108
+ def result_count
109
+ unless @result_count
110
+ @result_count = {:total => 0, :filtered => 0,
111
+ :debug => {:total => 0, :filtered => 0},
112
+ :log => {:total => 0, :filtered => 0},
113
+ :low => {:total => 0, :filtered => 0},
114
+ :medium => {:total => 0, :filtered => 0},
115
+ :high => {:total => 0, :filtered => 0}
116
+ }
117
+ end
118
+ @result_count
119
+ end
94
120
 
95
- report.at_xpath('//report').to_xml
96
- end
97
-
98
- def task
99
- @task ||= VasTask.get_all(:task_id => @task_id)[0]
100
- end
101
-
102
- def results
103
- @results ||= []
104
- end
105
-
106
- def result_count
107
- unless @result_count
108
- @result_count = {:total => 0, :filtered => 0,
109
- :debug => {:total => 0, :filtered => 0},
110
- :log => {:total => 0, :filtered => 0},
111
- :low => {:total => 0, :filtered => 0},
112
- :medium => {:total => 0, :filtered => 0},
113
- :high => {:total => 0, :filtered => 0}
114
- }
121
+ def empty?
122
+ !(@result_count && @result_count[:total] > 0)
115
123
  end
116
- @result_count
117
124
  end
118
125
  end
@@ -1,102 +1,103 @@
1
1
  require 'vas_base'
2
2
  require 'vas_override'
3
3
 
4
- class VasResult < VasBase
5
- attr_accessor :result_id, :subnet, :host, :port, :rule_id, :threat,
6
- :description, :notes, :overrides, :task_id
7
-
8
- validates :result_id, :presence=>true, :UUID=>true
9
-
10
- def self.get_all(options = {})
11
- options[:sort_by] ||= :threat
12
-
13
- params = {:overrides => 0, :notes => 0}
14
- if options[:task_id]
15
- params[:task_id] = options[:task_id]
16
- params[:apply_overrides] = 1 if options[:apply_overrides]
17
- end
4
+ module OpenvasCli
5
+ class VasResult < VasBase
6
+ attr_accessor :result_id, :subnet, :host, :port, :rule_id, :threat,
7
+ :description, :notes, :overrides, :task_id
8
+
9
+ validates :result_id, :presence=>true, :UUID=>true
10
+
11
+ def self.get_all(options = {})
12
+ options[:sort_by] ||= :threat
13
+
14
+ params = {:overrides => 0, :notes => 0}
15
+ if options[:id]
16
+ params[:task_id] = options[:id]
17
+ params[:apply_overrides] = 1 if options[:apply_overrides]
18
+ end
18
19
 
19
- levels = []
20
- if options[:filter]
21
- options[:filter].each { |ft|
22
- case ft
23
- when :high
24
- levels << "High"
25
- when :medium
26
- levels << "Medium"
27
- when :low
28
- levels << "Low"
29
- when :log
30
- levels << "Log"
31
- when :debug
32
- levels << "Debug"
33
- end
34
- }
35
- end
36
- req = Nokogiri::XML::Builder.new { |xml|
37
- xml.get_results(params)
38
- }
39
- xml = client.send_receive(req.doc)
40
-
41
- results = {}
42
- xml.xpath("//result").each { |xr|
43
- id = extract_value_from("@id", xr)
44
- threat = extract_value_from("threat", xr)
45
- if (levels.empty? || levels.include?(threat)) && results.has_key?(id) == false
46
- res = parse_result_node(xr, options[:task_id])
47
- results[res.result_id] = res
20
+ levels = []
21
+ if options[:filter]
22
+ options[:filter].each { |ft|
23
+ case ft
24
+ when :high
25
+ levels << "High"
26
+ when :medium
27
+ levels << "Medium"
28
+ when :low
29
+ levels << "Low"
30
+ when :log
31
+ levels << "Log"
32
+ when :debug
33
+ levels << "Debug"
34
+ end
35
+ }
48
36
  end
49
- }
50
-
51
- ret = results.values
37
+ req = Nokogiri::XML::Builder.new { |xml|
38
+ xml.get_results(params)
39
+ }
40
+ xml = connection.send_receive(req.doc)
41
+
42
+ results = {}
43
+ xml.xpath("//result").each { |xr|
44
+ id = extract_value_from("@id", xr)
45
+ threat = extract_value_from("threat", xr)
46
+ if (levels.empty? || levels.include?(threat)) && results.has_key?(id) == false
47
+ res = parse_result_node(xr, options[:task_id])
48
+ results[res.result_id] = res
49
+ end
50
+ }
51
+
52
+ ret = results.values
52
53
 
53
- #Sort Results
54
- ret.sort!{ |a,b| a.result_id <=> b.result_id } if options[:sort_by] == :result_id
55
- ret.sort!{ |a,b| a.host <=> b.host } if options[:sort_by] == :host
56
- ret.sort!{ |a,b| a.rule_id <=> b.rule_id } if options[:sort_by] == :rule_id
57
- ret.sort!{ |a,b| a.subnet <=> b.subnet } if options[:sort_by] == :subnet
58
- ret.sort!{ |a,b| b.threat_level <=> a.threat_level } if options[:sort_by] == :threat
59
-
60
- #Fake Pagination
61
- if options[:start]
62
- if options[:count]
63
- ret = ret[options[:start], options[:count]]
64
- else
65
- ret = ret[options[:start], ret.length - options[:start]]
54
+ #Sort Results
55
+ ret.sort!{ |a,b| a.result_id <=> b.result_id } if options[:sort_by] == :result_id
56
+ ret.sort!{ |a,b| a.host <=> b.host } if options[:sort_by] == :host
57
+ ret.sort!{ |a,b| a.rule_id <=> b.rule_id } if options[:sort_by] == :rule_id
58
+ ret.sort!{ |a,b| a.subnet <=> b.subnet } if options[:sort_by] == :subnet
59
+ ret.sort!{ |a,b| b.threat_level <=> a.threat_level } if options[:sort_by] == :threat
60
+
61
+ #Fake Pagination
62
+ if options[:start]
63
+ if options[:count]
64
+ ret = ret[options[:start], options[:count]]
65
+ else
66
+ ret = ret[options[:start], ret.length - options[:start]]
67
+ end
66
68
  end
69
+
70
+ ret
67
71
  end
68
72
 
69
- ret
70
- end
71
-
72
- def self.parse_result_node(node, task_id = nil)
73
- res = VasResult.new
74
- res.result_id = extract_value_from("@id", node)
75
- res.threat = extract_value_from("threat", node)
76
- res.subnet = extract_value_from("subnet", node)
77
- res.host = extract_value_from("host", node)
78
- res.rule_id = extract_value_from("nvt/@oid", node)
79
- res.description = extract_value_from("description", node)
80
- res.task_id = task_id if task_id
73
+ def self.parse_result_node(node, task_id = nil)
74
+ res = VasResult.new
75
+ res.result_id = extract_value_from("@id", node)
76
+ res.threat = extract_value_from("threat", node)
77
+ res.subnet = extract_value_from("subnet", node)
78
+ res.host = extract_value_from("host", node)
79
+ res.rule_id = extract_value_from("nvt/@oid", node)
80
+ res.description = extract_value_from("description", node)
81
+ res.task_id = task_id if task_id
82
+
83
+ res
84
+ end
81
85
 
82
- res
83
- end
84
-
85
- def threat_level
86
- case @threat
87
- when "High"
88
- 5
89
- when "Medium"
90
- 4
91
- when "Low"
92
- 3
93
- when "Log"
94
- 2
95
- when "Debug"
96
- 1
97
- else
98
- 0
86
+ def threat_level
87
+ case @threat
88
+ when "High"
89
+ 5
90
+ when "Medium"
91
+ 4
92
+ when "Low"
93
+ 3
94
+ when "Log"
95
+ 2
96
+ when "Debug"
97
+ 1
98
+ else
99
+ 0
100
+ end
99
101
  end
100
102
  end
101
-
102
103
  end
@@ -1,63 +1,171 @@
1
1
  require 'vas_base'
2
+ require 'time'
2
3
 
3
- class VasSchedule < VasBase
4
- attr_accessor :schedule_id, :name, :comment, :first_time, :next_time,
5
- :period, :period_months, :duration, :in_use, :task_ids
6
-
7
- validates :schedule_id, :presence => true, :UUID => true
8
-
9
- def self.get_all(options = {})
10
-
11
- manual_sort = false
12
- params = {:details => '1'}
13
- params[:schedule_id] = options[:schedule_id] if options[:schedule_id]
14
- case options[:sort_by]
15
- when :schedule_id
16
- params[:sort_field] = 'id'
17
- when :next_time
18
- manual_sort = true
19
- when :first_time
20
- params[:first_time] = 'first_time'
21
- else
22
- params[:sort_field] = 'name'
23
- end
24
-
25
- req = Nokogiri::XML::Builder.new { |xml|
26
- xml.get_schedules(params)
27
- }
28
-
29
- schedules = client.send_receive(req.doc)
30
-
31
- ret = []
32
- schedules.xpath("//schedule").each { |s|
33
- sch = VasSchedule.new
34
- sch.schedule_id = extract_value_from("@id", s)
35
- sch.name = extract_value_from("name", s)
36
- sch.comment = extract_value_from("comment", s)
37
- t_time = extract_value_from("first_time", s)
38
- sch.first_time = Time.parse(t_time) unless t_time == ""
39
- t_time = extract_value_from("next_time", s)
40
- sch.next_time = Time.parse(t_time) unless t_time == "" or t_time == "done"
41
- sch.period = extract_value_from("period", s).to_i
42
- sch.period_months = extract_value_from("period_months", s).to_i
43
- t_time = extract_value_from("duration", s)
44
- unless t_time == ""
45
- sch.duration = t_time.to_i unless t_time == 0
46
- end
47
- sch.in_use = extract_value_from("in_use", s).to_i > 0
48
- sch.task_ids = []
49
- s.xpath('tasks/task/@id') { |t|
50
- sch.task_ids << t.value
4
+ module OpenvasCli
5
+ class VasSchedule < VasBase
6
+ attr_reader :name
7
+ attr_reader :comment
8
+ attr_reader :first_time
9
+ attr_accessor :next_time
10
+ attr_reader :period
11
+ attr_accessor :duration
12
+ attr_accessor :in_use
13
+ attr_accessor :task_ids
14
+
15
+ validates :id, :UUID => true, :if => Proc.new { |s| s.id }
16
+ validates :name, :presence => true, :length => { :minimum => 1 }
17
+ validates :first_time, :presence => true
18
+
19
+ define_attribute_methods [:name, :comment, :first_time, :period]
20
+
21
+ def initialize(params = {})
22
+ @name = params[:name] if params[:name]
23
+ @comment = params[:comment] if params[:comment]
24
+ @first_time = params[:first_time] if params[:first_time]
25
+ @period = params[:period] if params[:period]
26
+ reset_changes
27
+ end
28
+
29
+ def changed?
30
+ local_changes = false
31
+ local_changes = @period.changed? if @period
32
+
33
+ local_changes || super
34
+ end
35
+
36
+ def name=(v)
37
+ name_will_change! unless @name == v
38
+ @name = v
39
+ end
40
+
41
+ def comment=(v)
42
+ comment_will_change! unless @comment == v
43
+ @comment = v
44
+ end
45
+
46
+ def first_time=(v)
47
+ first_time_will_change! unless @first_time == v
48
+ @first_time = v
49
+ end
50
+
51
+ def period=(v)
52
+ period_will_change! unless @period == v
53
+ @period = v
54
+ end
55
+
56
+ def destroy!
57
+ return unless @id
58
+
59
+ req = Nokogiri::XML::Builder.new { |xml|
60
+ xml.delete_schedule(:schedule_id => @id)
51
61
  }
52
- ret << sch
53
- }
54
-
55
- if manual_sort
56
- if options[:sort_by] == :next_time
57
- ret.sort!{ |a,b| a.next_time <=> b.next_time }
62
+
63
+ VasSchedule.connection.send_receive(req.doc)
64
+ @id = nil
65
+ reset_changes
66
+ end
67
+
68
+ def save!
69
+ return unless changed? || @id == nil
70
+
71
+ if @id
72
+ destroy!
58
73
  end
74
+
75
+ req = Nokogiri::XML::Builder.new { |xml|
76
+ xml.create_schedule {
77
+ xml.name { xml.text(@name) }
78
+ xml.comment { xml.text(@comment) } if @comment
79
+ xml.first_time {
80
+ xml.minute { xml.text(@first_time.min) }
81
+ xml.hour { xml.text(@first_time.hour) }
82
+ xml.day_of_month { xml.text(@first_time.day) }
83
+ xml.month { xml.text(@first_time.month) }
84
+ xml.year { xml.text(@first_time.year) }
85
+ }
86
+ xml.duration { xml.text(@duration ? @duration : 0) }
87
+ xml.period {
88
+ if @period
89
+ xml.text(@period.number)
90
+ xml.unit { xml.text(@period.period.to_s) }
91
+ else
92
+ xml.text(0)
93
+ xml.unit { xml.text("second") }
94
+ end
95
+ }
96
+ }
97
+ }
98
+
99
+ resp = VasSchedule.connection.send_receive(req.doc)
100
+ @id = VasSchedule.extract_value_from("/create_schedule_response/@id", resp) unless @id
101
+ reset_changes
59
102
  end
60
103
 
61
- ret
104
+ def self.get_all(options = {})
105
+
106
+ manual_sort = false
107
+ params = {:details => '1'}
108
+ params[:schedule_id] = options[:id] if options[:id]
109
+ case options[:sort_by]
110
+ when :schedule_id
111
+ params[:sort_field] = 'id'
112
+ when :next_time
113
+ manual_sort = true
114
+ when :first_time
115
+ params[:first_time] = 'first_time'
116
+ else
117
+ params[:sort_field] = 'name'
118
+ end
119
+
120
+ req = Nokogiri::XML::Builder.new { |xml|
121
+ xml.get_schedules(params)
122
+ }
123
+ ret = []
124
+
125
+ begin
126
+ schedules = connection.send_receive(req.doc)
127
+ schedules.xpath("//schedule").each { |s|
128
+ sch = VasSchedule.new
129
+ sch.id = extract_value_from("@id", s)
130
+ sch.name = extract_value_from("name", s)
131
+ sch.comment = extract_value_from("comment", s)
132
+ t_time = extract_value_from("first_time", s)
133
+ sch.first_time = Time.parse(t_time) unless t_time == ""
134
+ t_time = extract_value_from("next_time", s)
135
+ sch.next_time = Time.parse(t_time) unless t_time == "" or t_time == "done"
136
+
137
+ period_num = extract_value_from("period", s).to_i
138
+ if period_num > 0
139
+ sch.period = VasPeriod.from_seconds(period_num)
140
+ end
141
+
142
+ period_num = extract_value_from("period_months", s).to_i
143
+ if period_num > 0
144
+ sch.period = VasPeriod.from_months(period_num)
145
+ end
146
+
147
+ t_time = extract_value_from("duration", s)
148
+ unless t_time == ""
149
+ sch.duration = t_time.to_i unless t_time == 0
150
+ end
151
+
152
+ sch.in_use = extract_value_from("in_use", s).to_i > 0
153
+ sch.task_ids = []
154
+ s.xpath('tasks/task/@id') { |t|
155
+ sch.task_ids << t.value
156
+ }
157
+ ret << sch
158
+ }
159
+
160
+ if manual_sort
161
+ if options[:sort_by] == :next_time
162
+ ret.sort!{ |a,b| a.next_time <=> b.next_time }
163
+ end
164
+ end
165
+ rescue VasExceptions::CommandException => e
166
+ raise e unless e.message =~ /Failed to find schedule/i
167
+ end
168
+ ret
169
+ end
62
170
  end
63
171
  end