Skip to content

Commit 4561090

Browse files
xprazak2akofink
authored andcommitted
Parse fixes (#26)
* Parse fixes * Parse multiple subs for fix * Parse additional attrs for Sub and Fix
1 parent 1198710 commit 4561090

File tree

8 files changed

+175
-0
lines changed

8 files changed

+175
-0
lines changed

lib/openscap_parser/fix.rb

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# frozen_string_literal: true
2+
require 'openscap_parser/xml_node'
3+
require 'openscap_parser/subs'
4+
5+
module OpenscapParser
6+
class Fix < XmlNode
7+
include OpenscapParser::Subs
8+
9+
def id
10+
@id ||= @parsed_xml['id']
11+
end
12+
13+
def system
14+
@system ||= @parsed_xml['system']
15+
end
16+
17+
def complexity
18+
@complexity ||= @parsed_xml['complexity']
19+
end
20+
21+
def disruption
22+
@disruption ||= @parsed_xml['disruption']
23+
end
24+
25+
def strategy
26+
@strategy ||= @parsed_xml['strategy']
27+
end
28+
29+
def to_h
30+
{
31+
:id => id,
32+
:system => system,
33+
:complexity => complexity,
34+
:disruption => disruption,
35+
:strategy => strategy,
36+
:text => text,
37+
:subs => subs.map(&:to_h)
38+
}
39+
end
40+
end
41+
end

lib/openscap_parser/fixes.rb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# frozen_string_literal: true
2+
3+
require 'openscap_parser/fix'
4+
5+
module OpenscapParser
6+
module Fixes
7+
def self.included(base)
8+
base.class_eval do
9+
def fixes
10+
@fixes ||= fix_nodes.map do |fix_node|
11+
OpenscapParser::Fix.new(parsed_xml: fix_node)
12+
end
13+
end
14+
15+
def fix_nodes(xpath = ".//fix")
16+
xpath_nodes(xpath)
17+
end
18+
end
19+
end
20+
end
21+
end

lib/openscap_parser/rule.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@
22

33
require 'openscap_parser/rule_identifier'
44
require 'openscap_parser/rule_references'
5+
require 'openscap_parser/fixes'
56
require 'openscap_parser/xml_file'
67

78
# Mimics openscap-ruby Rule interface
89
module OpenscapParser
910
class Rule < XmlNode
1011
include OpenscapParser::Util
1112
include OpenscapParser::RuleReferences
13+
include OpenscapParser::Fixes
1214

1315
def id
1416
@id ||= parsed_xml['id']

lib/openscap_parser/rule_result.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,16 @@ def result
2222
@result ||= parsed_xml.at_xpath('result') &&
2323
parsed_xml.at_xpath('result').text || ''
2424
end
25+
26+
def to_h
27+
{
28+
:id => id,
29+
:time => time,
30+
:severity => severity,
31+
:weight => weight,
32+
:result => result
33+
}
34+
end
2535
end
2636
end
2737

lib/openscap_parser/sub.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# frozen_string_literal: true
2+
require 'openscap_parser/xml_node'
3+
4+
module OpenscapParser
5+
class Sub < XmlNode
6+
def id
7+
@id ||= @parsed_xml['idref']
8+
end
9+
10+
def use
11+
@use ||= @parsed_xml['use']
12+
end
13+
14+
def to_h
15+
{ :id => id, :text => text, :use => use }
16+
end
17+
end
18+
end

lib/openscap_parser/subs.rb

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# frozen_string_literal: true
2+
3+
require 'openscap_parser/sub'
4+
5+
module OpenscapParser
6+
module Subs
7+
def self.included(base)
8+
base.class_eval do
9+
def subs
10+
return [] unless sub_nodes
11+
@subs ||= sub_nodes.map do |xml|
12+
Sub.new(parsed_xml: xml)
13+
end
14+
end
15+
16+
def sub_nodes(xpath = './/sub')
17+
@sub_nodes ||= xpath_nodes(xpath)
18+
end
19+
end
20+
end
21+
end
22+
end

lib/openscap_parser/xml_node.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ def parsed_xml(report_contents = '')
1919
@parsed_xml.remove_namespaces!
2020
end
2121

22+
def text
23+
@parsed_xml.text
24+
end
25+
2226
def xpath_node(xpath)
2327
parsed_xml && parsed_xml.at_xpath(xpath)
2428
end

test/openscap_parser/test_result_file_test.rb

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,63 @@ def setup
115115
parse_set_values @arf_result_file
116116
end
117117
end
118+
119+
context 'fixes' do
120+
test 'should parse fixes for xccdf report' do
121+
parse_fixes @test_result_file
122+
end
123+
124+
test 'should parse fixes for arf report' do
125+
parse_fixes @arf_result_file
126+
end
127+
128+
test 'should parse multiple fixes for one rule' do
129+
rule = @arf_result_file.benchmark.rules.find { |rule| rule.id == "xccdf_org.ssgproject.content_rule_ensure_gpgcheck_globally_activated" }
130+
fixes = rule.fixes
131+
assert_equal 2, fixes.count
132+
assert fixes.map(&:id).all? { |id| id == 'ensure_gpgcheck_globally_activated' }
133+
refute_equal fixes.first.system, fixes.last.system
134+
end
135+
136+
test "should parse one sub for fix" do
137+
rule = @arf_result_file.benchmark.rules.find { |rule| rule.id == "xccdf_org.ssgproject.content_rule_ensure_gpgcheck_globally_activated" }
138+
fix = rule.fixes.find { |fix| !fix.subs.empty? }
139+
assert_equal 1, fix.subs.count
140+
assert fix.subs.first.id
141+
assert fix.subs.first.text
142+
end
143+
144+
test "should parse attributes for fix" do
145+
rule = @arf_result_file.benchmark.rules.find { |rule| rule.id == "xccdf_org.ssgproject.content_rule_enable_selinux_bootloader" }
146+
fix = rule.fixes.find { |fx| fx.system == "urn:xccdf:fix:script:sh" }
147+
assert_empty fix.subs
148+
assert fix.text
149+
assert fix.complexity
150+
assert fix.disruption
151+
assert fix.strategy
152+
end
153+
154+
test "should parse multiple subs for fix" do
155+
rule = @arf_result_file.benchmark.rules.find { |rule| rule.id == "xccdf_org.ssgproject.content_rule_selinux_state" }
156+
fix = rule.fixes.find { |fix| !fix.subs.empty? }
157+
assert_equal 2, fix.subs.count
158+
sub = fix.subs.last
159+
assert sub.id
160+
assert sub.text
161+
assert sub.use
162+
end
163+
end
164+
end
165+
166+
private
167+
168+
def parse_fixes(result_file)
169+
fixes = result_file.benchmark.rules.flat_map(&:fixes).map(&:to_h)
170+
ids = fixes.map { |fix| fix[:id] }
171+
systems = fixes.map { |fix| fix[:system] }
172+
refute_empty fixes
173+
assert_equal ids, ids.compact
174+
assert_equal systems, systems.compact
118175
end
119176

120177
def parse_set_values(result_file)

0 commit comments

Comments
 (0)