@@ -156,23 +156,45 @@ def write_report(report)
156156 end
157157 end
158158
159- # Retrieve a subset of test results based on a match to
160- # filter
159+ # Retrieve a subset of test results based on a match to filter
160+ #
161+ # @param filter [String, Array[String]]
162+ # A 'short name' filter that will be matched against the rule ID name
163+ #
164+ # @param exclusions [String, Array[String]]
165+ # A 'short name' filter of items that will be removed from the `filter`
166+ # matches
167+ #
168+ # @return [Hash] A Hash of statistics and a formatted report
161169 #
162170 # FIXME:
163171 # - This is a hack! Should be searching for rules based on a set
164172 # set of STIG ids, but don't see those ids in the oscap results xml.
165173 # Further mapping is required...
166174 # - Create the same report structure as inspec
167- def process_ssg_results ( filter = nil )
168- self . class . process_ssg_results ( File . join ( @output_dir , @result_file ) + '.xml' , filter )
175+ def process_ssg_results ( filter = nil , exclusions = nil )
176+ self . class . process_ssg_results (
177+ File . join ( @output_dir , @result_file ) + '.xml' ,
178+ filter ,
179+ exclusions
180+ )
169181 end
170182
171183 # Process the results of an SSG run
172184 #
185+ # @param result_file [String]
186+ # The oscap result XML file to process
187+ #
188+ # @param filter [String, Array[String]]
189+ # A 'short name' filter that will be matched against the rule ID name
190+ #
191+ # @param exclusions [String, Array[String]]
192+ # A 'short name' filter of items that will be removed from the `filter`
193+ # matches
194+ #
173195 # @return [Hash] A Hash of statistics and a formatted report
174196 #
175- def self . process_ssg_results ( result_file , filter = nil )
197+ def self . process_ssg_results ( result_file , filter = nil , exclusions = nil )
176198 require 'highline'
177199 require 'nokogiri'
178200
@@ -187,10 +209,39 @@ def self.process_ssg_results(result_file, filter=nil)
187209 doc . remove_namespaces!
188210
189211 if filter
212+ filter = Array ( filter )
213+
214+ xpath_query = [
215+ '//rule-result[(' ,
216+ ]
217+
218+ xpath_query << filter . map do |flt |
219+ "contains(@idref,'#{ flt } ')"
220+ end . join ( ' or ' )
221+
222+ xpath_query << ')' if filter . size > 1
223+
224+ if exclusions
225+ exclusions = Array ( exclusions )
226+
227+ xpath_query << 'and not('
228+
229+ xpath_query << exclusions . map do |exl |
230+ "contains(@idref,'#{ exl } ')"
231+ end . join ( ' or ' )
232+
233+ xpath_query << ')' if exclusions . size > 1
234+ end
235+
236+ xpath_query << ')]'
237+
238+ xpath_query = xpath_query . join ( ' ' )
239+
190240 # XPATH to get the pertinent test results:
191241 # Any node named 'rule-result' for which the attribute 'idref'
192- # contains filter
193- result_nodes = doc . xpath ( "//rule-result[contains(@idref,'#{ filter } ')]" )
242+ # contains any of the `filter` Strings and does not contain any of the
243+ # `exclusions` Strings
244+ result_nodes = doc . xpath ( xpath_query )
194245 else
195246 result_nodes = doc . xpath ( '//rule-result' )
196247 end
0 commit comments