Created
June 20, 2017 19:37
-
-
Save doertedev/b1340b0e7fa754dcef79365f6473ca30 to your computer and use it in GitHub Desktop.
XML / CSS resource selector for Inspec
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'nokogiri' | |
require 'utils/simpleconfig' | |
class XML_CSS < Inspec.resource(1) | |
name 'xml_css' | |
desc 'XML for Chef Inspec using Nokogiri\'s CSS selector feature' | |
example ' | |
Given this set of XML: | |
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> | |
<this> | |
<but> | |
<some>XML</some> | |
</but> | |
<but> | |
<some>More</some> | |
</but> | |
</this> | |
Run this | |
describe xml_css "/tmp/file.xml", "but+but" do | |
its("inner_text") { should eq "More" } | |
end | |
The CSS is being put as a second variable in the describe block so we | |
can blindly call the its-descriptor as a Nokogiri::XML::NodeSet-method. | |
This way, not only to_s, to_a but also empty? and length are working as | |
expected. | |
' | |
def initialize(filename, xpath) | |
@file = inspec.file(filename) | |
@file_content = @file.content | |
# check if file is available | |
if !@file.file? | |
skip_resource "Can't find file \"#{@path}\"" | |
return @params = {} | |
end | |
# check if file is readable | |
if @file_content.nil? && !@file.empty? | |
skip_resource "Can't read file \"#{@path}\"" | |
return @params = {} | |
end | |
begin | |
doc = Nokogiri::XML(@file_content) do |config| | |
config.options = Nokogiri::XML::ParseOptions::NOERROR | |
end | |
doc.remove_namespaces! | |
rescue | |
unless doc.is_a?(Nokogiri::XML::Document) | |
skip_resource "Error parsing #{@file}'s XML!" | |
end | |
end | |
@object = doc.root.css(xpath) | |
@type = @object.class | |
skip_resource "#{@file}'s XML doesn't yielded nil at css-path #{xpath}" if @type.nil? | |
end | |
def method_missing(*keys) | |
skip_resource 'Please specify a method to call!' unless keys[0].is_a? String | |
skip_resource 'Unknown method called!' unless @object.methods.include? keys[0] | |
return @object.send keys[0].to_sym | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Another form (for parsing once then re-querying all over the place):