diff --git a/lib/inspec/platform.rb.bak b/lib/inspec/platform.rb.bak new file mode 100644 index 0000000000..47f0b2e973 --- /dev/null +++ b/lib/inspec/platform.rb.bak @@ -0,0 +1,224 @@ +require 'inspec/resource' +require 'rubygems/version' + +module Inspec::Resources + class PlatformResource < Inspec.resource(1) + name 'platform' + desc 'Use the platform InSpec resource to test the platform on which the system is running.' + example <<~EXAMPLE + describe platform do + its('name') { should eq 'redhat' } + end + + describe platform do + it { should be_in_family('unix') } + end + EXAMPLE + + class Version < Gem::Version + def initialize(version_string) + super(version_string) + end + + def major + segments[0] + end + + def minor + segments[1] + end + + def patch + segments[2] + end + + def build + segments[3..-1].join('.') if segments.size > 3 + end + + def to_s + @version.to_s + end + + def <=>(other) + other_version = convert_to_version(other) + puts "Comparing #{@version} with #{other_version}" + @version <=> other_version + end + + def eql?(other) + other_version = convert_to_version(other) + puts "Comparing #{@version} with #{other_version}" + @version.eql?(other_version) + end + + def ==(other) + other_version = convert_to_version(other) + puts "Comparing #{@version} with #{other_version}" + @version == other_version + end + + def ===(other) + other_version = convert_to_version(other) + puts "Comparing #{@version} with #{other_version}" + @version === other_version + end + + def <=(other) + other_version = convert_to_version(other) + puts "Comparing #{@version} with #{other_version}" + @version <= other_version + end + + def >=(other) + other_version = convert_to_version(other) + puts "Comparing #{@version} with #{other_version}" + @version >= other_version + end + + def <(other) + other_version = convert_to_version(other) + puts "Comparing #{@version} with #{other_version}" + @version < other_version + end + + def >(other) + other_version = convert_to_version(other) + puts "Comparing #{@version} with #{other_version}" + @version > other_version + end + + private + + def convert_to_version(value) + value = format('%.2f', value) if value.is_a?(Numeric) + Gem::Version.new(value.to_s) + end + end + + def initialize + @platform = inspec.backend.platform + end + + def family + @platform[:family] + end + + def release + @platform[:release] + end + + def arch + @platform[:arch] + end + + def families + @platform[:family_hierarchy] + end + + def name + @platform[:name] + end + + def [](key) + # convert string to symbol + key = key.to_sym if key.is_a?(String) + return name if key == :name + + # For other keys, retrieve them directly from the Train platform object: + case key + when :family + family + when :release + release + when :arch + arch + when :family_hierarchy + families + else + @platform[key] + end + end + + def platform?(name) + @platform.name == name || + @platform.family_hierarchy.include?(name) + end + + def in_family?(family) + @platform.family_hierarchy.include?(family) + end + + def version + Version.new(release) + end + + def params + { + name:, + families:, + release:, + arch:, + version: { + major: version.major, + minor: version.minor, + patch: version.patch, + build: version.build + } + }.tap { |h| h.delete(:arch) if in_family?('api') } + end + + def supported?(supports) + raise ArgumentError, '`supports` is nil.' unless supports + + supports.any? do |support| + support.all? do |k, v| + case normalize(k) + when :os_family, :platform_family + in_family?(v) + when :os, :platform + platform?(v) + when :os_name, :platform_name + check_name(v) + when :release + check_release(v) + end + end + end || supports.empty? + end + + def normalize(key) # TODO: dumb... push this up or remove need + key.to_s.tr('-', '_').to_sym + end + + def resource_id + @platform.name || 'platform' + end + + def to_s + 'Platform Detection' + end + + private + + def check_name(value) + # allow wild card matching + if value include?('*') + cleaned = Regexp.escape(value).gsub('\*', '.*?') + name =~ /#{cleaned}/ + else + name == value + end + end + + def check_release(value) + # allow wild card matching + if value include?('*') + cleaned = Regexp.escape(value).gsub('\*', '.*?') + release =~ /#{cleaned}/ + else + release == value + end + end + end +end diff --git a/lib/inspec/resources/os.rb b/lib/inspec/resources/os.rb index d7acbe0bb0..4317e131b9 100644 --- a/lib/inspec/resources/os.rb +++ b/lib/inspec/resources/os.rb @@ -1,11 +1,11 @@ -require "inspec/resources/platform" +require 'inspec/resources/platform' module Inspec::Resources class OSResource < PlatformResource - name "os" - supports platform: "unix" - supports platform: "windows" - desc "Use the os InSpec audit resource to test the platform on which the system is running." + name 'os' + supports platform: 'unix' + supports platform: 'windows' + desc 'Use the os InSpec audit resource to test the platform on which the system is running.' example <<~EXAMPLE describe os[:family] do it { should eq 'redhat' } @@ -20,19 +20,74 @@ class OSResource < PlatformResource end EXAMPLE + def initialize + super + @platform = inspec.backend.platform + end + # reuse helper methods from backend - %w{aix? redhat? debian? suse? bsd? solaris? linux? unix? windows? hpux? darwin?}.each do |os_family| + %w[aix? redhat? debian? suse? bsd? solaris? linux? unix? windows? hpux? darwin?].each do |os_family| define_method(os_family.to_sym) do - @platform.send(os_family) + platform.send(os_family) end end def resource_id - @platform.name || "OS" + platform_info[:name] || 'OS' end def to_s - "Operating System Detection" + 'Operating System Detection' + end + + def release + platform_specific_info('release') || platform_info[:release] + end + + def version + Version.new(release, platform_specific_info('build')) + end + + def params + { + name: platform_info[:name], + families: platform_info[:families], + release: platform_info[:release], + arch: platform_info[:arch], + version: { + major: version.major, + minor: version.minor, + patch: version.patch, + build: version.build + } + }.tap { |h| h.delete(:arch) if in_family?('api') } + end + + def platform + @platform ||= super + end + + private + + def platform_info + @platform_info ||= { + name: platform[:name], + families: platform[:family_hierarchy], + release: platform[:release], + arch: platform[:arch] + } + end + + def platform_specific_info(type) + case platform_info[:families].first + when 'darwin' + case type + when 'release' + inspec.command('sw_vers -productVersion').stdout.strip + when 'build' + inspec.command('sw_vers -buildVersion').stdout.strip + end + end end end end diff --git a/lib/inspec/resources/platform.rb b/lib/inspec/resources/platform.rb index cabf7b2cac..21a5639353 100644 --- a/lib/inspec/resources/platform.rb +++ b/lib/inspec/resources/platform.rb @@ -1,9 +1,11 @@ -require "inspec/resource" +require 'inspec/resource' +require 'rubygems/version' +require 'logger' module Inspec::Resources class PlatformResource < Inspec.resource(1) - name "platform" - desc "Use the platform InSpec resource to test the platform on which the system is running." + name 'platform' + desc 'Use the platform InSpec resource to test the platform on which the system is running.' example <<~EXAMPLE describe platform do its('name') { should eq 'redhat' } @@ -14,99 +16,212 @@ class PlatformResource < Inspec.resource(1) end EXAMPLE + # rubocop:disable Style/Documentation + class Version + def initialize(version_string, build_version = nil) + @version = Gem::Version.new(version_string) + @build_version = build_version + end + + def major + @version.segments[0] + end + + def minor + @version.segments[1] + end + + def patch + @version.segments[2] + end + + def build + @build_version || (@version.segments.size > 3 ? @version.segments[3..-1].join('.') : nil) + end + + def to_s + @version.to_s + end + + def <=>(other) + other_version = convert_to_version(other) + @version <=> other_version + end + + def eql?(other) + other_version = convert_to_version(other) + @version.eql?(other_version) + end + + def ==(other) + other_version = convert_to_version(other) + @version == other_version + end + + def ===(other) + other_version = convert_to_version(other) + @version === other_version + end + + def <=(other) + other_version = convert_to_version(other) + @version <= other_version + end + + def >=(other) + other_version = convert_to_version(other) + @version >= other_version + end + + def <(other) + other_version = convert_to_version(other) + @version < other_version + end + + def >(other) + other_version = convert_to_version(other) + @version > other_version + end + + private + + def convert_to_version(value) + value = format('%.2f', value) if value.is_a? Numeric + Gem::Version.new(value.to_s) + end + end + + # store a single shared platform + @shared_platform = nil + + def self.reset_shared_platform + @shared_platform = nil + end + def initialize - @platform = inspec.backend.platform + # only query backend once + unless self.class.instance_variable_get(:@shared_platform) + self.class.instance_variable_set(:@shared_platform, inspec.backend.platform.tap do |plat| + # puts "Initialized platform: #{plat.inspect}" + end) + end + @platform = self.class.instance_variable_get(:@shared_platform) end + attr_reader :platform + def family - @platform[:family] + platform.family end def release - @platform[:release] + platform.release end def arch - @platform[:arch] + platform.arch end def families - @platform[:family_hierarchy] + platform.family_hierarchy end def name - @platform[:name] + platform.name end def [](key) - # convert string to symbol - key = key.to_sym if key.is_a? String + key = key.to_sym if key.is_a?(String) return name if key == :name - @platform[key] + # For other keys, retrieve them directly from the Train platform object: + case key + when :family + family + when :release + release + when :arch + arch + when :family_hierarchy + families + else + @platform[key] + end end def platform?(name) - @platform.name == name || - @platform.family_hierarchy.include?(name) + if name.is_a?(String) && name.include?('*') + regex = Regexp.new('^' + Regexp.escape(name).gsub('\\*', '.*') + '$') + platform.name =~ regex || platform.family_hierarchy.any? { |family| family =~ regex } + else + platform.name == name || platform.family_hierarchy.include?(name) + end end def in_family?(family) - @platform.family_hierarchy.include?(family) + platform.family_hierarchy.include?(family) + end + + def version + Version.new(release) end + # rubocop:disable Style/HashSyntax def params - # rubocop:disable Layout/AlignHash - h = { - name: name, + { + name: name, families: families, - release: release, - arch: arch, - } - # rubocop:enable Layout/AlignHash - - h.delete :arch if in_family?("api") # not applicable if api - - h + release: release, + arch: arch, + version: { + major: version.major, + minor: version.minor, + patch: version.patch, + build: version.build + } + }.tap { |h| h.delete(:arch) if in_family?('api') } end def supported?(supports) - raise ArgumentError, "`supports` is nil." unless supports + raise ArgumentError, '`supports` is nil.' unless supports - supports.any? { |support| - support.all? { |k, v| + supports.any? do |support| + support.all? do |k, v| case normalize(k) - when :os_family, :platform_family then + when :os_family, :platform_family in_family?(v) - when :os, :platform then + when :os, :platform + platform?(v) + when :os_name, :platform_name platform?(v) - when :os_name, :platform_name then - check_name(v) - when :release then + when :release check_release(v) + else + false # Handle unexpected keys gracefully end - } - } || supports.empty? + end + end || supports.empty? end - def normalize(key) # TODO: dumb... push this up or remove need - key.to_s.tr("-", "_").to_sym + # TODO: dumb... push this up or remove need + def normalize(key) + key.to_s.tr('-', '_').to_sym end def resource_id - @platform.name || "platform" + platform.name || 'platform' end def to_s - "Platform Detection" + 'Platform Detection' end private def check_name(value) # allow wild card matching - if value.include?("*") - cleaned = Regexp.escape(value).gsub('\*', ".*?") + if value.include?('*') + cleaned = Regexp.escape(value).gsub('\*', '.*?') name =~ /#{cleaned}/ else name == value @@ -115,8 +230,8 @@ def check_name(value) def check_release(value) # allow wild card matching - if value.include?("*") - cleaned = Regexp.escape(value).gsub('\*', ".*?") + if value.include?('*') + cleaned = Regexp.escape(value).gsub('\*', '.*?') release =~ /#{cleaned}/ else release == value diff --git a/lib/matchers/matchers.rb b/lib/matchers/matchers.rb index e52dfec30e..2163b2cf10 100644 --- a/lib/matchers/matchers.rb +++ b/lib/matchers/matchers.rb @@ -1,6 +1,6 @@ # copyright: 2015, Vulcano Security GmbH -require "rspec/matchers" +require 'rspec/matchers' RSpec::Matchers.define :be_readable do match do |file| @@ -16,13 +16,27 @@ end description do - res = "be readable" + res = 'be readable' res += " by #{@by}" unless @by.nil? res += " by user #{@by_user}" unless @by_user.nil? res end end +RSpec::Matchers.define :be_readable? do + match do |resource| + resource.readable? + end + + failure_message do |resource| + "expected that #{resource} would be readable" + end + + failure_message_when_negated do |resource| + "expected that #{resource} would not be readable" + end +end + RSpec::Matchers.define :be_writable do match do |file| file.writable?(@by, @by_user) @@ -37,13 +51,27 @@ end description do - res = "be writable" + res = 'be writable' res += " by #{@by}" unless @by.nil? res += " by user #{@by_user}" unless @by_user.nil? res end end +RSpec::Matchers.define :be_writable? do + match do |resource| + resource.writable? + end + + failure_message do |resource| + "expected that #{resource} would be writable" + end + + failure_message_when_negated do |resource| + "expected that #{resource} would not be writable" + end +end + RSpec::Matchers.define :be_executable do match do |file| file.executable?(@by, @by_user) @@ -58,18 +86,40 @@ end description do - res = "be executable" + res = 'be executable' res += " by #{@by}" unless @by.nil? res += " by user #{@by_user}" unless @by_user.nil? res end end +RSpec::Matchers.define :be_executable? do + match do |resource| + resource.executable? + end + + failure_message do |resource| + "expected that #{resource} would be executable" + end + + failure_message_when_negated do |resource| + "expected that #{resource} would not be executable" + end +end + RSpec::Matchers.define :contain_duplicates do match do |arr| dup = arr.select { |element| arr.count(element) > 1 } !dup.uniq.empty? end + + failure_message do |arr| + "expected that #{arr} would contain duplicates, but found none" + end + + failure_message_when_negated do |arr| + "expected that #{arr} would not contain duplicates, but found some" + end end # for packages @@ -94,7 +144,7 @@ end chain :with_level do |_level| - raise "[UNSUPPORTED] with level is not supported" + raise '[UNSUPPORTED] with level is not supported' end failure_message do |service| @@ -110,7 +160,7 @@ end chain :under do |_under| - raise "[UNSUPPORTED] under is not supported" + raise '[UNSUPPORTED] under is not supported' end failure_message do |service| @@ -125,7 +175,7 @@ end chain :with do |_attr| - raise "[UNSUPPORTED] `with` is not supported in combination with `be_reachable`" + raise '[UNSUPPORTED] `with` is not supported in combination with `be_reachable`' end failure_message do |host| @@ -161,6 +211,14 @@ chain :with_chain do |_chain| raise "[UNSUPPORTED] `with_table` is not supported in combination with `with_chain`. Please use the following syntax `iptables(table:'mangle', chain: 'input')`." end + + failure_message do |_tables| + "expected that tables would have rule #{rule}, but it was not found" + end + + failure_message_when_negated do |_tables| + "expected that tables would not have rule #{rule}, but it was found" + end end # matcher for nftables sets @@ -168,6 +226,14 @@ match do |sets| sets.has_element?(elem) end + + failure_message do |_sets| + "expected that sets would have element #{elem}, but it does not" + end + + failure_message_when_negated do |_sets| + "expected that sets would not have element #{elem}, but it does" + end end # `be_in` matcher @@ -193,7 +259,7 @@ failure_message do |item| if item.is_a?(Array) - "expected `#{item}` to be in the list: `#{list}` \nDiff:\n #{(item - list)}" + "expected `#{item}` to be in the list: `#{list}` \nDiff:\n #{item - list}" else "expected `#{item}` to be in the list: `#{list}`" end @@ -201,7 +267,7 @@ failure_message_when_negated do |item| if item.is_a?(Array) - "expected `#{item}` not to be in the list: `#{list}` \nComm:\n #{(item & list)}" + "expected `#{item}` not to be in the list: `#{list}` \nComm:\n #{item & list}" else "expected `#{item}` not to be in the list: `#{list}`" end @@ -215,7 +281,6 @@ # - you expect a number (strings will be converted if possible) # RSpec::Matchers.define :cmp do |first_expected| # rubocop:disable Metrics/BlockLength - def integer?(value) !(value =~ /\A-?0+\Z|\A-?[1-9]\d*\Z/).nil? end @@ -232,28 +297,61 @@ def octal?(value) end def boolean?(value) - if value.respond_to?("downcase") - %w{true false}.include?(value.downcase) + if value.respond_to?('downcase') + %w[true false].include?(value.downcase) else value.is_a?(TrueClass) || value.is_a?(FalseClass) end end def version?(value) + # Support partial version strings like "14.2" + return true if value.to_s =~ /\A\d+(\.\d+)*\Z/ + Gem::Version.new(value) true - rescue ArgumentError => _ex + rescue ArgumentError => _e false end + def semver?(value) + # Relaxed pattern to match partial version strings like "14.2" + value.to_s =~ /\A\d+(\.\d+)*(-[A-Za-z0-9\-.]+)?(\+[A-Za-z0-9\-.]+)?\Z/ + end + + def fuzzy_version_match?(actual, expected) + actual_segments = actual.split('.') + expected_segments = expected.split('.') + + # Use specified segment count or all segments from expected + compare_segments = @segment_count || expected_segments.length + @segment_count = compare_segments + + # Compare only the specified number of segments + compare_segments.times do |index| + return false if actual_segments[index] != expected_segments[index] + end + true + end + # expects that the values have been checked with boolean? def to_boolean(value) - value.casecmp("true") == 0 + value.casecmp('true') == 0 end - def try_match(actual, op, expected) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/AbcSize + # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/AbcSize + # rubocop:disable Metrics/MethodLength + def try_match(actual, op, expected) + # Convert numeric expected value to string for version comparison + if (expected.is_a?(Integer) || expected.is_a?(Float)) && version?(actual.to_s) && @loose + expected = expected.to_s + elsif expected.is_a?(Float) && actual.is_a?(String) && version?(actual) + return Gem::Version.new(actual).send(op, Gem::Version.new(expected.to_s)) + end + # if actual and expected are strings if expected.is_a?(String) && actual.is_a?(String) + return fuzzy_version_match?(actual, expected) if op == :== && @loose && version?(expected) && version?(actual) return actual.casecmp(expected) == 0 if op == :== return Gem::Version.new(actual).send(op, Gem::Version.new(expected)) if version?(expected) && version?(actual) @@ -263,7 +361,7 @@ def try_match(actual, op, expected) # rubocop:disable Metrics/CyclomaticComplexi return actual.send(op, expected.to_i) elsif expected.is_a?(String) && boolean?(expected) && [true, false].include?(actual) return actual.send(op, to_boolean(expected)) - elsif boolean?(expected) && %w{true false}.include?(actual) + elsif boolean?(expected) && %w[true false].include?(actual) return actual.send(op, expected.to_s) elsif expected.is_a?(Integer) && actual.is_a?(String) && integer?(actual) return actual.to_i.send(op, expected) @@ -277,7 +375,7 @@ def try_match(actual, op, expected) # rubocop:disable Metrics/CyclomaticComplexi # fallback to simple operation actual.send(op, expected) - rescue NameError => _ + rescue NameError => _e false rescue ArgumentError false @@ -286,29 +384,62 @@ def try_match(actual, op, expected) # rubocop:disable Metrics/CyclomaticComplexi match do |actual| @operation ||= :== @expected ||= first_expected + @loose ||= false + @segment_count = nil return actual === @expected if @operation == :=== # rubocop:disable Style/CaseEquality actual = actual[0] if actual.is_a?(Array) && !@expected.is_a?(Array) && actual.length == 1 try_match(actual, @operation, @expected) end - %i{== != < <= >= > === =~}.each do |op| + %i[== != < <= >= > === =~].each do |op| chain(op) do |x| @operation = op @expected = x end end - def format_actual(actual, negate = false) - actual = "0%o" % actual if octal?(@expected) && !actual.nil? - "\n%s\n got: %s\n\n(compared using `cmp` matcher)\n" % [format_expectation(negate), actual] + chain :loose do + @loose = true + @segment_count = 1 # loose is an alias for segments(1) + end + + chain :segments do |count| + @loose = true + @segment_count = count + end + + def humanize_segments(count) + return '' unless count + return '(comparing first segment)' if count == 1 + + actual_segments = @actual.to_s.split('.').length if @actual + if actual_segments && count >= actual_segments + '(comparing all segments)' + else + "(comparing first #{count} segments)" + end end def format_expectation(negate) - return "expected: %s" % [@expected] if @operation == :== && !negate + return format('expected: %s', @expected) if @operation == :== && !negate - negate_str = negate ? "not " : "" - "expected it %sto be %s %p" % [negate_str, @operation, @expected] + negate_str = negate ? 'not ' : '' + format('expected it %sto be %s %p', negate_str, @operation, @expected) + end + + def format_actual(actual, negate: false) + @actual = actual # Store for humanize_segments + actual_str = if octal?(@expected) && !actual.nil? + '0%o' % actual + else + actual + end + segment_info = humanize_segments(@segment_count) + format("\n%s\n got: %s\n\n(compared using `cmp` matcher%s)\n", + format_expectation(negate), + actual_str, + segment_info.empty? ? '' : " #{segment_info}") end failure_message do |actual| @@ -316,11 +447,12 @@ def format_expectation(negate) end failure_message_when_negated do |actual| - format_actual actual, true + format_actual actual, negate: true end description do - "cmp %s %p" % [@operation, @expected] + segment_info = humanize_segments(@segment_count) + format('cmp %s %p%s', @operation, @expected, segment_info.empty? ? '' : " #{segment_info}") end end @@ -352,4 +484,12 @@ def format_expectation(negate) "\n#{path} is not mounted\n" end end + + failure_message_when_negated do |path| + if !@options.nil? + "\n#{path} is mounted with options #{@options}, but it was expected not to.\n" + else + "\n#{path} is mounted, but it was expected not to.\n" + end + end end diff --git a/test/helper.rb b/test/helper.rb index 8e93703ade..47afb3d65a 100644 --- a/test/helper.rb +++ b/test/helper.rb @@ -5,15 +5,15 @@ # Do not add any other code to this code block. Simplecov # only until the next code block: -if ENV["CI_ENABLE_COVERAGE"] - require "simplecov/no_defaults" - require "helpers/simplecov_minitest" +if ENV['CI_ENABLE_COVERAGE'] + require 'simplecov/no_defaults' + require 'helpers/simplecov_minitest' SimpleCov.start do - add_filter "/test/" - add_group "Resources", ["lib/resources", "lib/inspec/resources"] - add_group "Matchers", ["lib/matchers", "lib/inspec/matchers"] - add_group "Backends", "lib/inspec/backend" + add_filter '/test/' + add_group 'Resources', ['lib/resources', 'lib/inspec/resources'] + add_group 'Matchers', ['lib/matchers', 'lib/inspec/matchers'] + add_group 'Backends', 'lib/inspec/backend' end end @@ -31,13 +31,13 @@ # # Explanation: eventually, our tests get around to inspec/runner_rspec # (and a few others), and they load rspec. By default, when rspec -# loads, it creates it's own global `describe` method, overwriting +# loads, it creates its own global `describe` method, overwriting # minitest's. # # Another aspect of rspec's expose_globally! is that it also messes # with mocha's methods. Any tests that occur after our runner has run # RSpec::Core::ExampleGroup.describe will fail if they use any mocha -# stubs (specifially any_instance) as the method will be gone. Don't +# stubs (specifically any_instance) as the method will be gone. Don't # know why, but the above sequence avoids that. # # Before this, the tests would get to the point of loading rspec, then @@ -46,9 +46,9 @@ # test count and vast differences in test time (which should have been # a clue that something was up--windows is just NOT THAT FAST). -require "minitest/autorun" +require 'minitest/autorun' -require "rspec/core/dsl" +require 'rspec/core/dsl' module RSpec::Core::DSL class << self alias expose_globally! expose_globally! # alias prevents duplicate warning @@ -59,17 +59,17 @@ def self.expose_globally! end # rubocop:enable Lint/DuplicateMethods end -require "rspec" +require 'rspec' # End of rspec vs minitest fight ######################################################################## -require "webmock/minitest" -require "mocha/minitest" -require "inspec/log" -require "inspec/backend" -require_relative "helpers/mock_loader" -require_relative "helpers/resources" +require 'webmock/minitest' +require 'mocha/minitest' +require 'inspec/log' +require 'inspec/backend' +require_relative 'helpers/mock_loader' +require_relative 'helpers/resources' TMP_CACHE = {} # rubocop: disable Style/MutableConstant @@ -87,7 +87,7 @@ def load_resource(*args) # a_group => :tolerate # No opinion # all => ... # Any of the 5 values above # all_others => ... # Any of the 5 values above -def handle_deprecations(opts_in, &block) +def handle_deprecations(opts_in) opts = opts_in.dup # Determine the default expectation @@ -140,7 +140,7 @@ def expect_deprecation(group, &block) end def darwin? - !!(RbConfig::CONFIG["host_os"] =~ /darwin/) + !!(RbConfig::CONFIG['host_os'] =~ /darwin/) end class Minitest::Test @@ -154,17 +154,17 @@ def skip_until(y, m, d, msg) # These tests are being worked on. These are github issues for them. # Related: https://github.com/inspec/inspec/pull/5063 def skip_windows! - skip "These have never passed" if windows? + skip 'These have never passed' if windows? end def unmock(&blk) # eg: resource = unmock { group "staff" } - require "inspec/fetcher/mock" - require "inspec/runner" + require 'inspec/fetcher/mock' + require 'inspec/runner' # TODO: there is WAY too much magic going on in here runner = Inspec::Runner.new - runner.add_target("inspec.yml" => "name: inspec-shell") + runner.add_target('inspec.yml' => 'name: inspec-shell') profile = runner.target_profiles.first ctx = profile.runner_context diff --git a/test/helpers/mock_loader.rb b/test/helpers/mock_loader.rb index 0722b7fa64..a71b69cca4 100644 --- a/test/helpers/mock_loader.rb +++ b/test/helpers/mock_loader.rb @@ -1,59 +1,66 @@ class MockLoader # collects emulation operating systems OPERATING_SYSTEMS = { # rubocop:disable Style/MutableConstant - alpine: { name: "alpine", family: "alpine", release: "3.6.2", arch: "x86_64" }, - arch: { name: "arch", family: "arch", release: nil, arch: nil }, - centos5: { name: "centos", family: "redhat", release: "5.11", arch: "x86_64" }, - centos6: { name: "centos", family: "redhat", release: "6.6", arch: "x86_64" }, - centos7: { name: "centos", family: "redhat", release: "7.1.1503", arch: "x86_64" }, - centos8: { name: "centos", family: "redhat", release: "8.0.1905", arch: "x86_64" }, - cloudlinux: { name: "cloudlinux", family: "redhat", release: "7.4", arch: "x86_64" }, - coreos: { name: "coreos", family: "coreos", release: "1437.0.0", arch: "x86_64" }, - debian6: { name: "debian", family: "debian", release: "6", arch: "x86_64" }, - debian7: { name: "debian", family: "debian", release: "7", arch: "x86_64" }, - debian8: { name: "debian", family: "debian", release: "8", arch: "x86_64" }, - debian10: { name: "debian", family: "debian", release: "buster/sid", arch: "x86_64" }, - freebsd9: { name: "freebsd", family: "bsd", release: "9", arch: "amd64" }, - freebsd10: { name: "freebsd", family: "bsd", release: "10", arch: "amd64" }, - freebsd11: { name: "freebsd", family: "bsd", release: "11", arch: "amd64" }, - freebsd12: { name: "freebsd", family: "bsd", release: "12", arch: "amd64" }, - macos10_10: { name: "mac_os_x", family: "darwin", release: "10.10.4", arch: nil }, - macos10_16: { name: "darwin", family: "darwin", release: "10.16", arch: nil }, - ubuntu1404: { name: "ubuntu", family: "debian", release: "14.04", arch: "x86_64" }, - ubuntu: { name: "ubuntu", family: "debian", release: "22.04", arch: "x86_64" }, - mint17: { name: "linuxmint", family: "debian", release: "17.3", arch: "x86_64" }, - mint18: { name: "linuxmint", family: "debian", release: "18", arch: "x86_64" }, - windows: { name: "windows", family: "windows", release: "6.2.9200", arch: "x86_64" }, - windows2016: { name: "windows_server_2016_datacenter", family: "windows", release: "10.0.14393", arch: "x86_64" }, - windows2019: { name: "windows_server_2019_datacenter", family: "windows", release: "10.0.17763", arch: "x86_64" }, - wrlinux: { name: "wrlinux", family: "redhat", release: "7.0(3)I2(2)", arch: "x86_64" }, - solaris11: { name: "solaris", family: "solaris", release: "11", arch: "i386" }, - solaris10: { name: "solaris", family: "solaris", release: "10", arch: "i386" }, - hpux: { name: "hpux", family: "hpux", release: "B.11.31", arch: "ia64" }, - aix: { name: "aix", family: "aix", release: "7.2", arch: "powerpc" }, - amazon: { name: "amazon", family: "redhat", release: "2015.03", arch: "x86_64" }, - amazon2: { name: "amazon", family: "redhat", release: "2", arch: "x86_64" }, - aliyun3: { name: "alibaba", family: "redhat", release: "3", arch: "x86_64" }, - yocto: { name: "yocto", family: "yocto", release: "0.0.1", arch: "aarch64" }, - undefined: { name: nil, family: nil, release: nil, arch: nil }, + alpine: { name: 'alpine', family: 'alpine', release: '3.6.2', arch: 'x86_64' }, + arch: { name: 'arch', family: 'arch', release: nil, arch: nil }, + centos5: { name: 'centos', family: 'redhat', release: '5.11', arch: 'x86_64' }, + centos6: { name: 'centos', family: 'redhat', release: '6.6', arch: 'x86_64' }, + centos7: { name: 'centos', family: 'redhat', release: '7.1.1503', arch: 'x86_64' }, + centos8: { name: 'centos', family: 'redhat', release: '8.0.1905', arch: 'x86_64' }, + cloudlinux: { name: 'cloudlinux', family: 'redhat', release: '7.4', arch: 'x86_64' }, + coreos: { name: 'coreos', family: 'coreos', release: '1437.0.0', arch: 'x86_64' }, + debian6: { name: 'debian', family: 'debian', release: '6', arch: 'x86_64' }, + debian7: { name: 'debian', family: 'debian', release: '7', arch: 'x86_64' }, + debian8: { name: 'debian', family: 'debian', release: '8', arch: 'x86_64' }, + debian10: { name: 'debian', family: 'debian', release: 'buster/sid', arch: 'x86_64' }, + freebsd9: { name: 'freebsd', family: 'bsd', release: '9', arch: 'amd64' }, + freebsd10: { name: 'freebsd', family: 'bsd', release: '10', arch: 'amd64' }, + freebsd11: { name: 'freebsd', family: 'bsd', release: '11', arch: 'amd64' }, + freebsd12: { name: 'freebsd', family: 'bsd', release: '12', arch: 'amd64' }, + macos10_10: { name: 'mac_os_x', family: 'darwin', release: '10.10.4', arch: nil }, + macos10_16: { name: 'darwin', family: 'darwin', release: '10.16', arch: nil }, + ubuntu1404: { name: 'ubuntu', family: 'debian', release: '14.04', arch: 'x86_64' }, + ubuntu: { name: 'ubuntu', family: 'debian', release: '22.04', arch: 'x86_64' }, + mint17: { name: 'linuxmint', family: 'debian', release: '17.3', arch: 'x86_64' }, + mint18: { name: 'linuxmint', family: 'debian', release: '18', arch: 'x86_64' }, + windows: { name: 'windows', family: 'windows', release: '6.2.9200', arch: 'x86_64' }, + windows_server_2016: { name: 'windows_server_2016_datacenter', family: 'windows', release: '10.0.14393', + arch: 'x86_64' }, + windows2019: { name: 'windows_server_2019_datacenter', family: 'windows', release: '10.0.17763', arch: 'x86_64' }, + wrlinux: { name: 'wrlinux', family: 'redhat', release: '7.0(3)I2(2)', arch: 'x86_64' }, + solaris11: { name: 'solaris', family: 'solaris', release: '11', arch: 'i386' }, + solaris10: { name: 'solaris', family: 'solaris', release: '10', arch: 'i386' }, + hpux: { name: 'hpux', family: 'hpux', release: 'B.11.31', arch: 'ia64' }, + aix: { name: 'aix', family: 'aix', release: '7.2', arch: 'powerpc' }, + amazon: { name: 'amazon', family: 'redhat', release: '2015.03', arch: 'x86_64' }, + amazon2: { name: 'amazon', family: 'redhat', release: '2', arch: 'x86_64' }, + aliyun3: { name: 'alibaba', family: 'redhat', release: '3', arch: 'x86_64' }, + yocto: { name: 'yocto', family: 'yocto', release: '0.0.1', arch: 'aarch64' }, + undefined: { name: nil, family: nil, release: nil, arch: nil } } OPERATING_SYSTEMS[:linux] = OPERATING_SYSTEMS[:ubuntu] + # Add a method to reset the shared platform + def self.reset_shared_platform + @shared_platform = nil + end + # pass the os identifier to emulate a specific operating system def initialize(os = :ubuntu) + self.class.reset_shared_platform # selects operating system @platform = OPERATING_SYSTEMS[os] end def self.connection - @connection ||= Train.create("local", command_runner: :generic).connection + @connection ||= Train.create('local', command_runner: :generic).connection end def backend return @backend if defined?(@backend) - scriptpath = ::File.expand_path "..", __dir__ + scriptpath = ::File.expand_path '..', __dir__ # create mock backend @backend = Inspec::Backend.create(Inspec::Config.mock) @@ -66,7 +73,7 @@ def backend mock.mock_os(@platform) mockfile = lambda { |x| - path = ::File.join(scriptpath, "/fixtures/files", x) + path = ::File.join(scriptpath, '/fixtures/files', x) local.file(path) } @@ -85,131 +92,131 @@ def md.directory? } emptyfile = lambda { - mockfile.call("emptyfile") + mockfile.call('emptyfile') } mock_files = { - "/proc/net/bonding/bond0" => mockfile.call("bond0"), - "/etc/ssh/ssh_config" => mockfile.call("ssh_config"), - "/etc/ssh/sshd_config" => mockfile.call("sshd_config"), - "/etc/ssh/sshd_config_does_not_exist" => mockfile.call("sshd_config_does_not_exist"), - "/etc/ssh/sshd_config_empty" => emptyfile.call, - "/etc/passwd" => mockfile.call("passwd"), - "/etc/shadow" => mockfile.call("shadow"), - "/etc/ntp.conf" => mockfile.call("ntp.conf"), - "/etc/chrony.conf" => mockfile.call("chrony.conf"), - "/etc/login.defs" => mockfile.call("login.defs"), - "/etc/security/limits.conf" => mockfile.call("limits.conf"), - "/etc/inetd.conf" => mockfile.call("inetd.conf"), - "/etc/group" => mockfile.call("etcgroup"), - "/etc/grub.conf" => mockfile.call("grub.conf"), - "/etc/non_indented_grub.conf" => mockfile.call("non_indented_grub.conf"), - "/boot/grub2/grub.cfg" => mockfile.call("grub2.cfg"), - "/boot/grub2/grubenv" => mockfile.call("grubenv"), - "/boot/grub2/grubenv_invalid" => mockfile.call("grubenv_invalid"), - "/etc/default/grub" => mockfile.call("grub_defaults"), - "/etc/default/grub_with_saved" => mockfile.call("grub_defaults_with_saved"), - "/etc/audit/auditd.conf" => mockfile.call("auditd.conf"), - "/etc/mysql/my.cnf" => mockfile.call("mysql.conf"), - "/etc/mysql/mysql2.conf" => mockfile.call("mysql2.conf"), - "/etc/mongod.conf" => mockfile.call("mongod.conf"), - "/opt/oracle/product/18c/dbhomeXE/network/admin/listener.ora" => mockfile.call("listener.ora"), - "C:\\app\\Administrator\\product\\18.0.0\\dbhomeXE\\network\\admin\\listener.ora" => mockfile.call("listener.ora"), - "/etc/cassandra/cassandra.yaml" => mockfile.call("cassandra.yaml"), - "C:\\Program Files\\apache-cassandra-3.11.4-bin\\apache-cassandra-3.11.4\\conf\\cassandra.yaml" => mockfile.call("cassandra.yaml"), - "/etc/rabbitmq/rabbitmq.config" => mockfile.call("rabbitmq.config"), - "kitchen.yml" => mockfile.call("kitchen.yml"), - "example.csv" => mockfile.call("example.csv"), - "policyfile.lock.json" => mockfile.call("policyfile.lock.json"), - "nonexistent.json" => mockfile.call("nonexistent.json"), - "/sys/class/net/br0/bridge" => mockdir.call(true), - "rootwrap.conf" => mockfile.call("rootwrap.conf"), - "/etc/apache2/ports.conf" => mockfile.call("ports.conf"), - "/etc/httpd/conf/httpd.conf" => mockfile.call("httpd.conf"), - "/etc/httpd/conf.d/ssl.conf" => mockfile.call("ssl.conf"), - "/etc/httpd/mods-enabled/status.conf" => mockfile.call("status.conf"), - "/etc/httpd/conf-enabled/security.conf" => mockfile.call("security.conf"), - "/etc/apache2/conf-enabled/serve-cgi-bin.conf" => mockfile.call("serve-cgi-bin.conf"), - "/etc/apache2/conf-enabled/security.conf" => mockfile.call("security.conf"), - "/etc/nginx/failed.conf" => mockfile.call("nginx_failed.conf"), - "/etc/nginx/nginx.conf" => mockfile.call("nginx.conf"), - "/etc/nginx/proxy.conf" => mockfile.call("nginx_proxy.conf"), - "/etc/nginx/conf/mime.types" => mockfile.call("nginx_mime.types"), - "/etc/nginx/conf.d/comments_only.conf" => mockfile.call("nginx_confd_comments_only.conf"), - "/etc/nginx/conf.d/empty.conf" => mockfile.call("nginx_confd_empty.conf"), - "/etc/nginx/conf.d/foobar.conf" => mockfile.call("nginx_confd_foobar.conf"), - "/etc/nginx/conf.d/multiple.conf" => mockfile.call("nginx_confd_multiple.conf"), - "/etc/nginx/quotes.d/example.conf" => mockfile.call("nginx_quotesd_example.conf"), - "/etc/xinetd.conf" => mockfile.call("xinetd.conf"), - "/etc/xinetd.d" => mockfile.call("xinetd.d"), - "/etc/xinetd.d/chargen-stream" => mockfile.call("xinetd.d_chargen-stream"), - "/etc/xinetd.d/chargen-dgram" => mockfile.call("xinetd.d_chargen-dgram"), - "/etc/xinetd.d/echo" => mockfile.call("xinetd.d_echo"), - "/etc/sysctl.conf" => mockfile.call("sysctl.conf"), - "/etc/postgresql/9.4/main/postgresql.conf" => mockfile.call("postgresql.conf"), + '/proc/net/bonding/bond0' => mockfile.call('bond0'), + '/etc/ssh/ssh_config' => mockfile.call('ssh_config'), + '/etc/ssh/sshd_config' => mockfile.call('sshd_config'), + '/etc/ssh/sshd_config_does_not_exist' => mockfile.call('sshd_config_does_not_exist'), + '/etc/ssh/sshd_config_empty' => emptyfile.call, + '/etc/passwd' => mockfile.call('passwd'), + '/etc/shadow' => mockfile.call('shadow'), + '/etc/ntp.conf' => mockfile.call('ntp.conf'), + '/etc/chrony.conf' => mockfile.call('chrony.conf'), + '/etc/login.defs' => mockfile.call('login.defs'), + '/etc/security/limits.conf' => mockfile.call('limits.conf'), + '/etc/inetd.conf' => mockfile.call('inetd.conf'), + '/etc/group' => mockfile.call('etcgroup'), + '/etc/grub.conf' => mockfile.call('grub.conf'), + '/etc/non_indented_grub.conf' => mockfile.call('non_indented_grub.conf'), + '/boot/grub2/grub.cfg' => mockfile.call('grub2.cfg'), + '/boot/grub2/grubenv' => mockfile.call('grubenv'), + '/boot/grub2/grubenv_invalid' => mockfile.call('grubenv_invalid'), + '/etc/default/grub' => mockfile.call('grub_defaults'), + '/etc/default/grub_with_saved' => mockfile.call('grub_defaults_with_saved'), + '/etc/audit/auditd.conf' => mockfile.call('auditd.conf'), + '/etc/mysql/my.cnf' => mockfile.call('mysql.conf'), + '/etc/mysql/mysql2.conf' => mockfile.call('mysql2.conf'), + '/etc/mongod.conf' => mockfile.call('mongod.conf'), + '/opt/oracle/product/18c/dbhomeXE/network/admin/listener.ora' => mockfile.call('listener.ora'), + 'C:\\app\\Administrator\\product\\18.0.0\\dbhomeXE\\network\\admin\\listener.ora' => mockfile.call('listener.ora'), + '/etc/cassandra/cassandra.yaml' => mockfile.call('cassandra.yaml'), + 'C:\\Program Files\\apache-cassandra-3.11.4-bin\\apache-cassandra-3.11.4\\conf\\cassandra.yaml' => mockfile.call('cassandra.yaml'), + '/etc/rabbitmq/rabbitmq.config' => mockfile.call('rabbitmq.config'), + 'kitchen.yml' => mockfile.call('kitchen.yml'), + 'example.csv' => mockfile.call('example.csv'), + 'policyfile.lock.json' => mockfile.call('policyfile.lock.json'), + 'nonexistent.json' => mockfile.call('nonexistent.json'), + '/sys/class/net/br0/bridge' => mockdir.call(true), + 'rootwrap.conf' => mockfile.call('rootwrap.conf'), + '/etc/apache2/ports.conf' => mockfile.call('ports.conf'), + '/etc/httpd/conf/httpd.conf' => mockfile.call('httpd.conf'), + '/etc/httpd/conf.d/ssl.conf' => mockfile.call('ssl.conf'), + '/etc/httpd/mods-enabled/status.conf' => mockfile.call('status.conf'), + '/etc/httpd/conf-enabled/security.conf' => mockfile.call('security.conf'), + '/etc/apache2/conf-enabled/serve-cgi-bin.conf' => mockfile.call('serve-cgi-bin.conf'), + '/etc/apache2/conf-enabled/security.conf' => mockfile.call('security.conf'), + '/etc/nginx/failed.conf' => mockfile.call('nginx_failed.conf'), + '/etc/nginx/nginx.conf' => mockfile.call('nginx.conf'), + '/etc/nginx/proxy.conf' => mockfile.call('nginx_proxy.conf'), + '/etc/nginx/conf/mime.types' => mockfile.call('nginx_mime.types'), + '/etc/nginx/conf.d/comments_only.conf' => mockfile.call('nginx_confd_comments_only.conf'), + '/etc/nginx/conf.d/empty.conf' => mockfile.call('nginx_confd_empty.conf'), + '/etc/nginx/conf.d/foobar.conf' => mockfile.call('nginx_confd_foobar.conf'), + '/etc/nginx/conf.d/multiple.conf' => mockfile.call('nginx_confd_multiple.conf'), + '/etc/nginx/quotes.d/example.conf' => mockfile.call('nginx_quotesd_example.conf'), + '/etc/xinetd.conf' => mockfile.call('xinetd.conf'), + '/etc/xinetd.d' => mockfile.call('xinetd.d'), + '/etc/xinetd.d/chargen-stream' => mockfile.call('xinetd.d_chargen-stream'), + '/etc/xinetd.d/chargen-dgram' => mockfile.call('xinetd.d_chargen-dgram'), + '/etc/xinetd.d/echo' => mockfile.call('xinetd.d_echo'), + '/etc/sysctl.conf' => mockfile.call('sysctl.conf'), + '/etc/postgresql/9.4/main/postgresql.conf' => mockfile.call('postgresql.conf'), # Test certificate/key for x509_certificate using RSA keys in PEM format - "test_certificate.rsa.crt.pem" => mockfile.call("test_certificate.rsa.crt.pem"), - "test_certificate.rsa.key.pem" => mockfile.call("test_certificate.rsa.key.pem"), - "test_ca_public.key.pem" => mockfile.call("test_ca_public.key.pem"), - "test/fixtures/files/test_rsa_key" => mockfile.call("test_rsa_key"), + 'test_certificate.rsa.crt.pem' => mockfile.call('test_certificate.rsa.crt.pem'), + 'test_certificate.rsa.key.pem' => mockfile.call('test_certificate.rsa.key.pem'), + 'test_ca_public.key.pem' => mockfile.call('test_ca_public.key.pem'), + 'test/fixtures/files/test_rsa_key' => mockfile.call('test_rsa_key'), # Test DH parameters, 2048 bit long safe prime, generator 2 for dh_params in PEM format - "dh_params.dh_pem" => mockfile.call("dh_params.dh_pem"), - "default.toml" => mockfile.call("default.toml"), - "default.xml" => mockfile.call("default.xml"), - "database.xml" => mockfile.call("database.xml"), - "/test/path/to/postgres/pg_hba.conf" => mockfile.call("pg_hba.conf"), - "/etc/postgresql/9.5/main/pg_ident.conf" => mockfile.call("pg_ident.conf"), - "C:/Program Files/PostgreSQL/9.5/main/pg_ident.conf" => mockfile.call("pg_ident.conf"), - "/etc/postgresql/9.5/main" => mockfile.call("9.5.main"), - "/var/lib/postgresql/9.5/main" => mockfile.call("var.9.5.main"), - "/etc/hosts" => mockfile.call("hosts"), - 'C:\windows\system32\drivers\etc\hosts' => mockfile.call("hosts"), - "/etc/fstab" => mockfile.call("fstab"), - "fstab_no_home" => mockfile.call("fstab_no_home"), - "fstab_one_mount" => mockfile.call("fstab_one_mount"), - "/etc/aide.conf" => mockfile.call("aide.conf"), - "/var/lib/fake_rpmdb" => mockdir.call(true), - "/var/lib/rpmdb_does_not_exist" => mockdir.call(false), - "/etc/init/ssh.conf" => mockfile.call("upstart_ssh_enabled.conf"), - "/etc/hosts.allow" => mockfile.call("hosts.allow"), - "/etc/hosts.deny" => mockfile.call("hosts.deny"), - "/fakepath/fakefile" => emptyfile.call, - "C:/fakepath/fakefile" => emptyfile.call, - "/etc/cron.d/crondotd" => mockfile.call("crondotd"), - "/etc/postfix/main.cf" => mockfile.call("main.cf"), - "/etc/postfix/other.cf" => mockfile.call("other.cf"), - "/etc/selinux/selinux_conf" => mockfile.call("selinux_conf"), - "/etc/apache2/apache2.conf" => mockfile.call("apache2.conf"), - "/etc/test-serverroot/apache2/apache2.conf" => mockfile.call("apache2_server_root_void.conf"), + 'dh_params.dh_pem' => mockfile.call('dh_params.dh_pem'), + 'default.toml' => mockfile.call('default.toml'), + 'default.xml' => mockfile.call('default.xml'), + 'database.xml' => mockfile.call('database.xml'), + '/test/path/to/postgres/pg_hba.conf' => mockfile.call('pg_hba.conf'), + '/etc/postgresql/9.5/main/pg_ident.conf' => mockfile.call('pg_ident.conf'), + 'C:/Program Files/PostgreSQL/9.5/main/pg_ident.conf' => mockfile.call('pg_ident.conf'), + '/etc/postgresql/9.5/main' => mockfile.call('9.5.main'), + '/var/lib/postgresql/9.5/main' => mockfile.call('var.9.5.main'), + '/etc/hosts' => mockfile.call('hosts'), + 'C:\windows\system32\drivers\etc\hosts' => mockfile.call('hosts'), + '/etc/fstab' => mockfile.call('fstab'), + 'fstab_no_home' => mockfile.call('fstab_no_home'), + 'fstab_one_mount' => mockfile.call('fstab_one_mount'), + '/etc/aide.conf' => mockfile.call('aide.conf'), + '/var/lib/fake_rpmdb' => mockdir.call(true), + '/var/lib/rpmdb_does_not_exist' => mockdir.call(false), + '/etc/init/ssh.conf' => mockfile.call('upstart_ssh_enabled.conf'), + '/etc/hosts.allow' => mockfile.call('hosts.allow'), + '/etc/hosts.deny' => mockfile.call('hosts.deny'), + '/fakepath/fakefile' => emptyfile.call, + 'C:/fakepath/fakefile' => emptyfile.call, + '/etc/cron.d/crondotd' => mockfile.call('crondotd'), + '/etc/postfix/main.cf' => mockfile.call('main.cf'), + '/etc/postfix/other.cf' => mockfile.call('other.cf'), + '/etc/selinux/selinux_conf' => mockfile.call('selinux_conf'), + '/etc/apache2/apache2.conf' => mockfile.call('apache2.conf'), + '/etc/test-serverroot/apache2/apache2.conf' => mockfile.call('apache2_server_root_void.conf'), # myjson.json, myyaml.yml and myinvalid.file mocks are used for file unit test in file_test - "myjson.json" => mockfile.call("node.json"), - "myyaml.yml" => mockfile.call("kitchen.yml"), - "myinvalid.file" => mockfile.call("default.xml"), + 'myjson.json' => mockfile.call('node.json'), + 'myyaml.yml' => mockfile.call('kitchen.yml'), + 'myinvalid.file' => mockfile.call('default.xml'), # x509_secret_key - "/home/openssl_activity/bob_private.pem" => mockfile.call("x509-secret-key"), - "/home/openssl_activity/alice_private.pem" => mockfile.call("x509-encrypted-secret-key"), + '/home/openssl_activity/bob_private.pem' => mockfile.call('x509-secret-key'), + '/home/openssl_activity/alice_private.pem' => mockfile.call('x509-encrypted-secret-key') } mock.files = mock_files # create all mock commands cmd = lambda { |x| - stdout = ::File.read(::File.join(scriptpath, "/fixtures/cmd/" + x)) - mock.mock_command("", stdout, "", 0) + stdout = ::File.read(::File.join(scriptpath, '/fixtures/cmd/' + x)) + mock.mock_command('', stdout, '', 0) } cmd_stderr = lambda { |x = nil| - stderr = x.nil? ? "" : File.read(File.join(scriptpath, "fixtures/cmd", x)) - mock.mock_command("", "", stderr, 1) + stderr = x.nil? ? '' : File.read(File.join(scriptpath, 'fixtures/cmd', x)) + mock.mock_command('', '', stderr, 1) } empty = lambda { - mock.mock_command("", "", "", 0) + mock.mock_command('', '', '', 0) } cmd_exit_1 = lambda { |x = nil| - stderr = x.nil? ? "" : File.read(File.join(scriptpath, "fixtures/cmd", x)) - mock.mock_command("", "", stderr, 1) + stderr = x.nil? ? '' : File.read(File.join(scriptpath, 'fixtures/cmd', x)) + mock.mock_command('', '', stderr, 1) } # DEV NOTES: Most of the key=>value pairs below represent inspec commands=>responses to mock in testing. @@ -218,7 +225,7 @@ def md.directory? # And the content of 'get-wmiobject' can be found in this file: 'test/fixtures/cmd/get-wmiobject'. If you change the script # that the inspec resource sends, you have to calculate the new sha256sum of it and update it here mock_cmds = { - "" => empty.call, + '' => empty.call, "sh -c 'find /no/such/mock -type f -maxdepth 1'" => empty.call, 'type "brew"' => empty.call, 'sh -c \'type "pip"\'' => empty.call, @@ -235,547 +242,547 @@ def md.directory? "sh -c 'find /etc/httpd/conf-enabled/*.conf -type f -maxdepth 1'" => empty.call, 'find /sys/class/net/eth1/ -maxdepth 1 -type f -exec sh -c \'echo "[$(basename {})]"; cat {} || echo -n\' \;' => empty.call, "Get-Package -Name 'Not available' | ConvertTo-Json" => empty.call, - "ps axo pid,pcpu,pmem,vsz,rss,tty,stat,start,time,user,command" => cmd.call("ps-axo"), - "ps wwaxo label,pid,pcpu,pmem,vsz,rss,tty,stat,start,time,user:32,command" => cmd.call("ps-axoZ"), - "ps -o pid,vsz,rss,tty,stat,time,ruser,args" => cmd.call("ps-busybox"), - "env" => cmd.call("env"), - "${Env:PATH}" => cmd.call("$env-PATH"), - "timedatectl status | grep -i 'Time zone'" => cmd.call("timedatectl-timezone"), + 'ps axo pid,pcpu,pmem,vsz,rss,tty,stat,start,time,user,command' => cmd.call('ps-axo'), + 'ps wwaxo label,pid,pcpu,pmem,vsz,rss,tty,stat,start,time,user:32,command' => cmd.call('ps-axoZ'), + 'ps -o pid,vsz,rss,tty,stat,time,ruser,args' => cmd.call('ps-busybox'), + 'env' => cmd.call('env'), + '${Env:PATH}' => cmd.call('$env-PATH'), + "timedatectl status | grep -i 'Time zone'" => cmd.call('timedatectl-timezone'), # registry key test using winrm 2.0 - "9417f24311a9dcd90f1b1734080a2d4c6516ec8ff2d452a2328f68eb0ed676cf" => cmd.call("reg_schedule"), - "Auditpol /get /subcategory:'User Account Management' /r" => cmd.call("auditpol"), - "/sbin/auditctl -l" => cmd.call("auditctl"), - "/sbin/auditctl -s" => cmd.call("auditctl-s"), - "dpkg -s curl" => cmd.call("dpkg-s-curl"), - "apt list curl -a" => cmd.call("apt-list-curl"), - "dpkg -s held-package" => cmd.call("dpkg-s-held-package"), - "rpm -qi curl" => cmd.call("rpm-qi-curl"), - "yum list curl" => cmd.call("yum-list-curl"), - "Get-Package Chef Client v12.12.15 -AllVersions" => cmd.call("get-pkg-versions"), - "rpm -qi --dbpath /var/lib/fake_rpmdb curl" => cmd.call("rpm-qi-curl"), - "rpm -qi --dbpath /var/lib/rpmdb_does_not_exist curl" => cmd_exit_1.call, - "pacman -Qi curl" => cmd.call("pacman-qi-curl"), - "pacman -Ss curl | grep curl | grep installed" => cmd.call("pacman-ss-grep-curl"), - "brew info --json=v1 curl" => cmd.call("brew-info--json-v1-curl"), - "brew info --json=v1 nginx" => cmd.call("brew-info--json-v1-nginx"), - "brew info --json=v1 nope" => cmd_exit_1.call, - "/usr/local/bin/brew info --json=v1 curl" => cmd.call("brew-info--json-v1-curl"), - "gem list --local -a -q ^not-installed$" => cmd.call("gem-list-local-a-q-not-installed"), - "gem list --local -a -q ^rubocop$" => cmd.call("gem-list-local-a-q-rubocop"), - "/opt/ruby-2.3.1/embedded/bin/gem list --local -a -q ^pry$" => cmd.call("gem-list-local-a-q-pry"), - "/opt/chef/embedded/bin/gem list --local -a -q ^chef-sugar$" => cmd.call("gem-list-local-a-q-chef-sugar"), - 'c:\opscode\chef\embedded\bin\gem.bat list --local -a -q ^json$' => cmd.call("gem-list-local-a-q-json"), - "/opt/opscode/embedded/bin/gem list --local -a -q ^knife-backup$" => cmd.call("gem-list-local-a-q-knife-backup"), - "sh -c 'npm -g ls --json bower'" => cmd.call("npm-g-ls--json-bower"), - "sh -c 'cd /path/to/project && npm ls --json bower'" => cmd.call("npm-ls--json-bower"), - "Rscript -e 'packageVersion(\"DBI\")'" => cmd.call("r-print-version"), - "Rscript -e 'packageVersion(\"DoesNotExist\")'" => cmd.call("r-print-version-not-installed"), - "perl -le 'eval \"require $ARGV[0]\" and print $ARGV[0]->VERSION or exit 1' DBD::Pg" => cmd.call("perl-print-version"), + '9417f24311a9dcd90f1b1734080a2d4c6516ec8ff2d452a2328f68eb0ed676cf' => cmd.call('reg_schedule'), + "Auditpol /get /subcategory:'User Account Management' /r" => cmd.call('auditpol'), + '/sbin/auditctl -l' => cmd.call('auditctl'), + '/sbin/auditctl -s' => cmd.call('auditctl-s'), + 'dpkg -s curl' => cmd.call('dpkg-s-curl'), + 'apt list curl -a' => cmd.call('apt-list-curl'), + 'dpkg -s held-package' => cmd.call('dpkg-s-held-package'), + 'rpm -qi curl' => cmd.call('rpm-qi-curl'), + 'yum list curl' => cmd.call('yum-list-curl'), + 'Get-Package Chef Client v12.12.15 -AllVersions' => cmd.call('get-pkg-versions'), + 'rpm -qi --dbpath /var/lib/fake_rpmdb curl' => cmd.call('rpm-qi-curl'), + 'rpm -qi --dbpath /var/lib/rpmdb_does_not_exist curl' => cmd_exit_1.call, + 'pacman -Qi curl' => cmd.call('pacman-qi-curl'), + 'pacman -Ss curl | grep curl | grep installed' => cmd.call('pacman-ss-grep-curl'), + 'brew info --json=v1 curl' => cmd.call('brew-info--json-v1-curl'), + 'brew info --json=v1 nginx' => cmd.call('brew-info--json-v1-nginx'), + 'brew info --json=v1 nope' => cmd_exit_1.call, + '/usr/local/bin/brew info --json=v1 curl' => cmd.call('brew-info--json-v1-curl'), + 'gem list --local -a -q ^not-installed$' => cmd.call('gem-list-local-a-q-not-installed'), + 'gem list --local -a -q ^rubocop$' => cmd.call('gem-list-local-a-q-rubocop'), + '/opt/ruby-2.3.1/embedded/bin/gem list --local -a -q ^pry$' => cmd.call('gem-list-local-a-q-pry'), + '/opt/chef/embedded/bin/gem list --local -a -q ^chef-sugar$' => cmd.call('gem-list-local-a-q-chef-sugar'), + 'c:\opscode\chef\embedded\bin\gem.bat list --local -a -q ^json$' => cmd.call('gem-list-local-a-q-json'), + '/opt/opscode/embedded/bin/gem list --local -a -q ^knife-backup$' => cmd.call('gem-list-local-a-q-knife-backup'), + "sh -c 'npm -g ls --json bower'" => cmd.call('npm-g-ls--json-bower'), + "sh -c 'cd /path/to/project && npm ls --json bower'" => cmd.call('npm-ls--json-bower'), + "Rscript -e 'packageVersion(\"DBI\")'" => cmd.call('r-print-version'), + "Rscript -e 'packageVersion(\"DoesNotExist\")'" => cmd.call('r-print-version-not-installed'), + "perl -le 'eval \"require $ARGV[0]\" and print $ARGV[0]->VERSION or exit 1' DBD::Pg" => cmd.call('perl-print-version'), "perl -le 'eval \"require $ARGV[0]\" and print $ARGV[0]->VERSION or exit 1' DOES::Not::Exist" => cmd_exit_1.call, - "pip show jinja2" => cmd.call("pip-show-jinja2"), - "pip show django" => cmd.call("pip-show-django"), - "/test/path/pip show django" => cmd.call("pip-show-non-standard-django"), - "Get-Package -Name 'Mozilla Firefox' | ConvertTo-Json" => cmd.call("get-package-firefox"), - "Get-Package -Name 'Ruby 2.1.6-p336-x64' | ConvertTo-Json" => cmd.call("get-package-ruby"), + 'pip show jinja2' => cmd.call('pip-show-jinja2'), + 'pip show django' => cmd.call('pip-show-django'), + '/test/path/pip show django' => cmd.call('pip-show-non-standard-django'), + "Get-Package -Name 'Mozilla Firefox' | ConvertTo-Json" => cmd.call('get-package-firefox'), + "Get-Package -Name 'Ruby 2.1.6-p336-x64' | ConvertTo-Json" => cmd.call('get-package-ruby'), 'Get-Command "choco"' => empty.call, - "Get-TimeZone" => cmd.call("get-timezone"), + 'Get-TimeZone' => cmd.call('get-timezone'), 'sh -c \'type "choco"\'' => cmd_exit_1.call, - '(choco list --local-only --exact --include-programs --limit-output \'nssm\') -Replace "\|", "=" | ConvertFrom-StringData | ConvertTo-JSON' => cmd.call("choco-list-nssm"), + '(choco list --local-only --exact --include-programs --limit-output \'nssm\') -Replace "\|", "=" | ConvertFrom-StringData | ConvertTo-JSON' => cmd.call('choco-list-nssm'), '(choco list --local-only --exact --include-programs --limit-output \'git\') -Replace "\|", "=" | ConvertFrom-StringData | ConvertTo-JSON' => empty.call, - "New-Object -Type PSObject | Add-Member -MemberType NoteProperty -Name Service -Value (Get-Service -Name 'dhcp'| Select-Object -Property Name, DisplayName, Status) -PassThru | Add-Member -MemberType NoteProperty -Name WMI -Value (Get-WmiObject -Class Win32_Service | Where-Object {$_.Name -eq 'dhcp' -or $_.DisplayName -eq 'dhcp'} | Select-Object -Property StartMode, StartName) -PassThru | ConvertTo-Json" => cmd.call("get-service-dhcp"), - "New-Object -Type PSObject | Add-Member -MemberType NoteProperty -Name Pip -Value (Invoke-Command -ScriptBlock {where.exe pip}) -PassThru | Add-Member -MemberType NoteProperty -Name Python -Value (Invoke-Command -ScriptBlock {where.exe python}) -PassThru | ConvertTo-Json" => cmd.call("get-windows-pip-package"), - "Get-WindowsFeature | Where-Object {$_.Name -eq 'DHCP' -or $_.DisplayName -eq 'DHCP'} | Select-Object -Property Name,DisplayName,Description,Installed,InstallState | ConvertTo-Json" => cmd.call("get-windows-feature"), - "Get-WindowsFeature | Where-Object {$_.Name -eq 'IIS-WebServer' -or $_.DisplayName -eq 'IIS-WebServer'} | Select-Object -Property Name,DisplayName,Description,Installed,InstallState | ConvertTo-Json" => cmd_exit_1.call("get-windows-feature-iis-webserver"), - "dism /online /get-featureinfo /featurename:IIS-WebServer" => cmd.call("dism-iis-webserver"), - "lsmod" => cmd.call("lsmod"), - "/sbin/sysctl -q -n net.ipv4.conf.all.forwarding" => cmd.call("sbin_sysctl"), - "/sbin/sysctl -a" => cmd.call("sbin_sysctl_all"), + "New-Object -Type PSObject | Add-Member -MemberType NoteProperty -Name Service -Value (Get-Service -Name 'dhcp'| Select-Object -Property Name, DisplayName, Status) -PassThru | Add-Member -MemberType NoteProperty -Name WMI -Value (Get-WmiObject -Class Win32_Service | Where-Object {$_.Name -eq 'dhcp' -or $_.DisplayName -eq 'dhcp'} | Select-Object -Property StartMode, StartName) -PassThru | ConvertTo-Json" => cmd.call('get-service-dhcp'), + 'New-Object -Type PSObject | Add-Member -MemberType NoteProperty -Name Pip -Value (Invoke-Command -ScriptBlock {where.exe pip}) -PassThru | Add-Member -MemberType NoteProperty -Name Python -Value (Invoke-Command -ScriptBlock {where.exe python}) -PassThru | ConvertTo-Json' => cmd.call('get-windows-pip-package'), + "Get-WindowsFeature | Where-Object {$_.Name -eq 'DHCP' -or $_.DisplayName -eq 'DHCP'} | Select-Object -Property Name,DisplayName,Description,Installed,InstallState | ConvertTo-Json" => cmd.call('get-windows-feature'), + "Get-WindowsFeature | Where-Object {$_.Name -eq 'IIS-WebServer' -or $_.DisplayName -eq 'IIS-WebServer'} | Select-Object -Property Name,DisplayName,Description,Installed,InstallState | ConvertTo-Json" => cmd_exit_1.call('get-windows-feature-iis-webserver'), + 'dism /online /get-featureinfo /featurename:IIS-WebServer' => cmd.call('dism-iis-webserver'), + 'lsmod' => cmd.call('lsmod'), + '/sbin/sysctl -q -n net.ipv4.conf.all.forwarding' => cmd.call('sbin_sysctl'), + '/sbin/sysctl -a' => cmd.call('sbin_sysctl_all'), # ports on windows - "Get-NetTCPConnection -state Listen | Select-Object -Property State, Caption, Description, LocalAddress, LocalPort, RemoteAddress, RemotePort, DisplayName, Status | ConvertTo-Json" => cmd.call("get-net-tcpconnection"), - 'netstat -anbo | Select-String -CaseSensitive -pattern "^\s+UDP|\s+LISTENING\s+\d+$" -context 0,1' => cmd.call("netstat-anbo-pipe-select-string-pattern.utf8"), + 'Get-NetTCPConnection -state Listen | Select-Object -Property State, Caption, Description, LocalAddress, LocalPort, RemoteAddress, RemotePort, DisplayName, Status | ConvertTo-Json' => cmd.call('get-net-tcpconnection'), + 'netstat -anbo | Select-String -CaseSensitive -pattern "^\s+UDP|\s+LISTENING\s+\d+$" -context 0,1' => cmd.call('netstat-anbo-pipe-select-string-pattern.utf8'), # lsof formatted list of ports (should be quite cross platform) - "lsof -nP -i -FpctPn" => cmd.call("lsof-nP-i-FpctPn"), + 'lsof -nP -i -FpctPn' => cmd.call('lsof-nP-i-FpctPn'), # ports on freebsd - "sockstat -46l" => cmd.call("sockstat"), + 'sockstat -46l' => cmd.call('sockstat'), # ports on aix - "netstat -Aan | grep LISTEN" => cmd.call("netstat-aan"), - "rmsock f0000000000000001 tcpcb" => cmd.call("rmsock-f0001"), - "rmsock f0000000000000002 tcpcb" => cmd.call("rmsock-f0002"), + 'netstat -Aan | grep LISTEN' => cmd.call('netstat-aan'), + 'rmsock f0000000000000001 tcpcb' => cmd.call('rmsock-f0001'), + 'rmsock f0000000000000002 tcpcb' => cmd.call('rmsock-f0002'), # packages on windows - "6785190b3df7291a7622b0b75b0217a9a78bd04690bc978df51ae17ec852a282" => cmd.call("get-item-property-package"), + '6785190b3df7291a7622b0b75b0217a9a78bd04690bc978df51ae17ec852a282' => cmd.call('get-item-property-package'), # service status upstart on ubuntu - "initctl status ssh" => cmd.call("initctl-status-ssh"), + 'initctl status ssh' => cmd.call('initctl-status-ssh'), # upstart version on ubuntu - "initctl --version" => cmd.call("initctl--version"), + 'initctl --version' => cmd.call('initctl--version'), # show ssh service Centos 7 - "systemctl show --no-pager --all sshd" => cmd.call("systemctl-show-all-sshd"), - "systemctl show --no-pager --all apache2" => cmd.call("systemctl-show-all-apache2"), - "/path/to/systemctl show --no-pager --all sshd" => cmd.call("systemctl-show-all-sshd"), - "systemctl show --no-pager --all dbus" => cmd.call("systemctl-show-all-dbus"), - "/path/to/systemctl show --no-pager --all dbus" => cmd.call("systemctl-show-all-dbus"), + 'systemctl show --no-pager --all sshd' => cmd.call('systemctl-show-all-sshd'), + 'systemctl show --no-pager --all apache2' => cmd.call('systemctl-show-all-apache2'), + '/path/to/systemctl show --no-pager --all sshd' => cmd.call('systemctl-show-all-sshd'), + 'systemctl show --no-pager --all dbus' => cmd.call('systemctl-show-all-dbus'), + '/path/to/systemctl show --no-pager --all dbus' => cmd.call('systemctl-show-all-dbus'), # services on macos - "launchctl list" => cmd.call("launchctl-list"), + 'launchctl list' => cmd.call('launchctl-list'), # services on freebsd 6+ - "service -e" => cmd.call("service-e"), - "service sendmail onestatus" => cmd.call("service-sendmail-onestatus"), + 'service -e' => cmd.call('service-e'), + 'service sendmail onestatus' => cmd.call('service-sendmail-onestatus'), # mock for FreeBSD10Init info - "service -l" => cmd.call("service-l"), + 'service -l' => cmd.call('service-l'), # service mock for monit - "monit summary" => cmd.call("monit-summary"), - %{sh -c 'type "monit"'} => empty.call, + 'monit summary' => cmd.call('monit-summary'), + %(sh -c 'type "monit"') => empty.call, # services for system 5 e.g. centos6, debian 6 - "service sshd status" => cmd.call("service-sshd-status"), - 'find /etc/rc*.d /etc/init.d/rc*.d -name "S*"' => cmd.call("find-etc-rc-d-name-S"), - "ls -1 /etc/init.d/" => cmd.call("ls-1-etc-init.d"), + 'service sshd status' => cmd.call('service-sshd-status'), + 'find /etc/rc*.d /etc/init.d/rc*.d -name "S*"' => cmd.call('find-etc-rc-d-name-S'), + 'ls -1 /etc/init.d/' => cmd.call('ls-1-etc-init.d'), # user information for linux - "id root" => cmd.call("id-root"), - "getent passwd root" => cmd.call("getent-passwd-root"), - "chage -l root" => cmd.call("chage-l-root"), - "cat ~/.ssh/authorized_keys" => cmd.call("authorized-keys-mock"), - %{sh -c 'type "getent"'} => empty.call, - "getent shadow root" => cmd.call("getent-shadow-mock"), + 'id root' => cmd.call('id-root'), + 'getent passwd root' => cmd.call('getent-passwd-root'), + 'chage -l root' => cmd.call('chage-l-root'), + 'cat ~/.ssh/authorized_keys' => cmd.call('authorized-keys-mock'), + %(sh -c 'type "getent"') => empty.call, + 'getent shadow root' => cmd.call('getent-shadow-mock'), # user information for ldap test - "id jfolmer" => cmd.call("id-jfolmer"), - "getent passwd jfolmer" => cmd.call("getent-passwd-jfolmer"), - "chage -l jfolmer" => cmd.call("chage-l-root"), + 'id jfolmer' => cmd.call('id-jfolmer'), + 'getent passwd jfolmer' => cmd.call('getent-passwd-jfolmer'), + 'chage -l jfolmer' => cmd.call('chage-l-root'), # user info for mac - "id chartmann" => cmd.call("id-chartmann"), - "dscl -q . -read /Users/chartmann NFSHomeDirectory PrimaryGroupID RecordName UniqueID UserShell" => cmd.call("dscl"), + 'id chartmann' => cmd.call('id-chartmann'), + 'dscl -q . -read /Users/chartmann NFSHomeDirectory PrimaryGroupID RecordName UniqueID UserShell' => cmd.call('dscl'), # user info for freebsd - "id fzipi" => cmd.call("id-fzipi"), - "pw usershow fzipi -7" => cmd.call("pw-usershow-fzipi-7"), + 'id fzipi' => cmd.call('id-fzipi'), + 'pw usershow fzipi -7' => cmd.call('pw-usershow-fzipi-7'), # user info for windows (winrm 1.6.0, 1.6.1) - "c603a7d32732390b1ed57ebd56fd176fecdb2035f005d33482de9adb1ddb4447" => cmd.call("adsiusers"), + 'c603a7d32732390b1ed57ebd56fd176fecdb2035f005d33482de9adb1ddb4447' => cmd.call('adsiusers'), # group info for windows - "4020573097e910a573e22e8863c4faa434f52910a45714606cad1fb8b060d9e9" => cmd.call("adsigroups"), + '4020573097e910a573e22e8863c4faa434f52910a45714606cad1fb8b060d9e9' => cmd.call('adsigroups'), # group info for Darwin - "dscacheutil -q group" => cmd.call("dscacheutil-query-group"), + 'dscacheutil -q group' => cmd.call('dscacheutil-query-group'), # network interface - "fddd70e8b8510f5fcc0413cfdc41598c55d6922bb2a0a4075e2118633a0bf422" => cmd.call("find-net-interface"), - "c33821dece09c8b334e03a5bb9daefdf622007f73af4932605e758506584ec3f" => empty.call, - "/sbin/ip -br -4 address show dev eth0" => cmd.call("interface-addresses-4"), - "/sbin/ip -br -6 address show dev eth0" => cmd.call("interface-addresses-6"), - "Get-NetAdapter | Select-Object -Property Name, InterfaceDescription, Status, State, MacAddress, LinkSpeed, ReceiveLinkSpeed, TransmitLinkSpeed, Virtual | ConvertTo-Json" => cmd.call("Get-NetAdapter"), - "Get-NetIPAddress | Select-Object -Property IPv6Address, IPv4Address, InterfaceAlias, PrefixLength | ConvertTo-Json" => cmd.call("Get-NetIPAddress"), - "ifconfig en0" => cmd.call("ifconfig-en0"), + 'fddd70e8b8510f5fcc0413cfdc41598c55d6922bb2a0a4075e2118633a0bf422' => cmd.call('find-net-interface'), + 'c33821dece09c8b334e03a5bb9daefdf622007f73af4932605e758506584ec3f' => empty.call, + '/sbin/ip -br -4 address show dev eth0' => cmd.call('interface-addresses-4'), + '/sbin/ip -br -6 address show dev eth0' => cmd.call('interface-addresses-6'), + 'Get-NetAdapter | Select-Object -Property Name, InterfaceDescription, Status, State, MacAddress, LinkSpeed, ReceiveLinkSpeed, TransmitLinkSpeed, Virtual | ConvertTo-Json' => cmd.call('Get-NetAdapter'), + 'Get-NetIPAddress | Select-Object -Property IPv6Address, IPv4Address, InterfaceAlias, PrefixLength | ConvertTo-Json' => cmd.call('Get-NetIPAddress'), + 'ifconfig en0' => cmd.call('ifconfig-en0'), # network interfaces - "ls /sys/class/net" => cmd.call("ls-sys-class-net"), - "ifconfig -a" => cmd.call("ifconfig-a"), - "ifconfig em0" => cmd.call("ifconfig-em0"), - "ifconfig lo0" => cmd.call("ifconfig-lo0"), - "Get-NetAdapter | Select-Object -Property Name | ConvertTo-Json" => cmd.call("Get-NetAdapter-Name"), + 'ls /sys/class/net' => cmd.call('ls-sys-class-net'), + 'ifconfig -a' => cmd.call('ifconfig-a'), + 'ifconfig em0' => cmd.call('ifconfig-em0'), + 'ifconfig lo0' => cmd.call('ifconfig-lo0'), + 'Get-NetAdapter | Select-Object -Property Name | ConvertTo-Json' => cmd.call('Get-NetAdapter-Name'), # bridge on linux - "ls -1 /sys/class/net/br0/brif/" => cmd.call("ls-sys-class-net-br"), + 'ls -1 /sys/class/net/br0/brif/' => cmd.call('ls-sys-class-net-br'), # bridge on Windows - "Get-NetAdapterBinding -ComponentID ms_bridge | Get-NetAdapter | Select-Object -Property Name, InterfaceDescription | ConvertTo-Json" => cmd.call("get-netadapter-binding-bridge"), + 'Get-NetAdapterBinding -ComponentID ms_bridge | Get-NetAdapter | Select-Object -Property Name, InterfaceDescription | ConvertTo-Json' => cmd.call('get-netadapter-binding-bridge'), # host for Windows - "Resolve-DnsName –Type A microsoft.com | ConvertTo-Json" => cmd.call("Resolve-DnsName"), - "Resolve-DnsName –Type AAAA microsoft.com | ConvertTo-Json" => cmd.call("Resolve-DnsName-ipv6"), - "Test-NetConnection -ComputerName microsoft.com -WarningAction SilentlyContinue| Select-Object -Property ComputerName, TcpTestSucceeded, PingSucceeded | ConvertTo-Json" => cmd.call("Test-NetConnection"), + 'Resolve-DnsName –Type A microsoft.com | ConvertTo-Json' => cmd.call('Resolve-DnsName'), + 'Resolve-DnsName –Type AAAA microsoft.com | ConvertTo-Json' => cmd.call('Resolve-DnsName-ipv6'), + 'Test-NetConnection -ComputerName microsoft.com -WarningAction SilentlyContinue| Select-Object -Property ComputerName, TcpTestSucceeded, PingSucceeded | ConvertTo-Json' => cmd.call('Test-NetConnection'), # host for Linux - "getent ahosts example.com" => cmd.call("getent-ahosts-example.com"), - "ping -w 1 -c 1 example.com" => cmd.call("ping-example.com"), + 'getent ahosts example.com' => cmd.call('getent-ahosts-example.com'), + 'ping -w 1 -c 1 example.com' => cmd.call('ping-example.com'), # host for Darwin - "host -t AAAA example.com" => cmd.call("host-AAAA-example.com"), - "ping -W 1 -c 1 example.com" => cmd.call("ping-example.com"), + 'host -t AAAA example.com' => cmd.call('host-AAAA-example.com'), + 'ping -W 1 -c 1 example.com' => cmd.call('ping-example.com'), # apt - "find /etc/apt/ -name \"*.list\" -exec sh -c 'cat {} || echo -n' \\;" => cmd.call("etc-apt"), + "find /etc/apt/ -name \"*.list\" -exec sh -c 'cat {} || echo -n' \\;" => cmd.call('etc-apt'), # iptables - "/usr/sbin/iptables -S" => cmd.call("iptables-s"), - %{sh -c 'type "/usr/sbin/iptables"'} => empty.call, + '/usr/sbin/iptables -S' => cmd.call('iptables-s'), + %(sh -c 'type "/usr/sbin/iptables"') => empty.call, # ip6tables - "/usr/sbin/ip6tables -S" => cmd.call("ip6tables-s"), - %{sh -c 'type "/usr/sbin/ip6tables"'} => empty.call, + '/usr/sbin/ip6tables -S' => cmd.call('ip6tables-s'), + %(sh -c 'type "/usr/sbin/ip6tables"') => empty.call, # nftables (version) - "/usr/sbin/nft --version" => cmd.call("nftables-version"), + '/usr/sbin/nft --version' => cmd.call('nftables-version'), # nftables (chain with json output) - "/usr/sbin/nft -s -j list chain inet filter INPUT" => cmd.call("nftables-chain-json"), - "/usr/sbin/nft -j list chain inet filter INPUT" => cmd.call("nftables-chain-json"), + '/usr/sbin/nft -s -j list chain inet filter INPUT' => cmd.call('nftables-chain-json'), + '/usr/sbin/nft -j list chain inet filter INPUT' => cmd.call('nftables-chain-json'), # nftables (chain) - "/usr/sbin/nft -s list chain inet filter INPUT" => cmd.call("nftables-chain"), - "/usr/sbin/nft -s -y list chain inet filter INPUT" => cmd.call("nftables-chain"), - "/usr/sbin/nft -s -nn list chain inet filter INPUT" => cmd.call("nftables-chain"), - "/usr/sbin/nft -y list chain inet filter INPUT" => cmd.call("nftables-chain"), - "/usr/sbin/nft list chain inet filter INPUT" => cmd.call("nftables-chain"), + '/usr/sbin/nft -s list chain inet filter INPUT' => cmd.call('nftables-chain'), + '/usr/sbin/nft -s -y list chain inet filter INPUT' => cmd.call('nftables-chain'), + '/usr/sbin/nft -s -nn list chain inet filter INPUT' => cmd.call('nftables-chain'), + '/usr/sbin/nft -y list chain inet filter INPUT' => cmd.call('nftables-chain'), + '/usr/sbin/nft list chain inet filter INPUT' => cmd.call('nftables-chain'), # nftables (set with json output) - "/usr/sbin/nft -s -j list set inet filter OPEN_PORTS" => cmd.call("nftables-set-json"), - "/usr/sbin/nft -j list set inet filter OPEN_PORTS" => cmd.call("nftables-set-json"), + '/usr/sbin/nft -s -j list set inet filter OPEN_PORTS' => cmd.call('nftables-set-json'), + '/usr/sbin/nft -j list set inet filter OPEN_PORTS' => cmd.call('nftables-set-json'), # nftables (set) - "/usr/sbin/nft -s list set inet filter OPEN_PORTS" => cmd.call("nftables-set"), - "/usr/sbin/nft list set inet filter OPEN_PORTS" => cmd.call("nftables-set"), - %{sh -c 'type "/usr/sbin/nft"'} => empty.call, + '/usr/sbin/nft -s list set inet filter OPEN_PORTS' => cmd.call('nftables-set'), + '/usr/sbin/nft list set inet filter OPEN_PORTS' => cmd.call('nftables-set'), + %(sh -c 'type "/usr/sbin/nft"') => empty.call, # ipnat - "/usr/sbin/ipnat -l" => cmd.call("ipnat-l"), - %{type "/usr/sbin/ipnat"} => empty.call, + '/usr/sbin/ipnat -l' => cmd.call('ipnat-l'), + %(type "/usr/sbin/ipnat") => empty.call, # ipfilter - "/usr/sbin/ipfstat -io" => cmd.call("ipfstat-io"), - %{type "/usr/sbin/ipfstat"} => empty.call, + '/usr/sbin/ipfstat -io' => cmd.call('ipfstat-io'), + %(type "/usr/sbin/ipfstat") => empty.call, # lxc - "/usr/sbin/lxc info ubuntu-container" => cmd.call("lxcinfo"), - "/usr/sbin/lxc info my-ubuntu-container-1" => cmd_stderr.call("lxcerror"), - %{sh -c 'type "/usr/sbin/lxc"'} => empty.call, + '/usr/sbin/lxc info ubuntu-container' => cmd.call('lxcinfo'), + '/usr/sbin/lxc info my-ubuntu-container-1' => cmd_stderr.call('lxcerror'), + %(sh -c 'type "/usr/sbin/lxc"') => empty.call, # cgroup - "cgget -n -a carrotking" => cmd.call("cgget-n-a"), - "cgget -n -r cpuset.cpus carrotking" => cmd.call("cgget-n-r"), - "cgget -n -r memory.stat carrotking" => cmd.call("cgget-n-r-stat"), - %{sh -c 'type "cgget"'} => empty.call, + 'cgget -n -a carrotking' => cmd.call('cgget-n-a'), + 'cgget -n -r cpuset.cpus carrotking' => cmd.call('cgget-n-r'), + 'cgget -n -r memory.stat carrotking' => cmd.call('cgget-n-r-stat'), + %(sh -c 'type "cgget"') => empty.call, # mail_alias - "cat /etc/aliases | grep '^daemon:'" => cmd.call("mail-alias"), + "cat /etc/aliases | grep '^daemon:'" => cmd.call('mail-alias'), # php_config - %{sh -c 'type "php"'} => empty.call, + %(sh -c 'type "php"') => empty.call, 'Get-Command "php"' => empty.call, 'type "php"' => empty.call, - "php -r 'echo get_cfg_var(\"default_mimetype\");'" => cmd.call("get-cfg-var"), - "php -c /etc/php/7.4/cli/php.ini -r 'echo get_cfg_var(\"default_mimetype\");'" => cmd.call("get-cfg-var"), + "php -r 'echo get_cfg_var(\"default_mimetype\");'" => cmd.call('get-cfg-var'), + "php -c /etc/php/7.4/cli/php.ini -r 'echo get_cfg_var(\"default_mimetype\");'" => cmd.call('get-cfg-var'), # routing_table - "netstat -rn" => cmd.call("netstat-rn-linux"), - "/usr/sbin/netstat -rn" => cmd.call("netstat-rn-linux"), - %{sh -c 'type "netstat"'} => empty.call, + 'netstat -rn' => cmd.call('netstat-rn-linux'), + '/usr/sbin/netstat -rn' => cmd.call('netstat-rn-linux'), + %(sh -c 'type "netstat"') => empty.call, # mocks for be_immutable matcher for file resource - "lsattr constantfile.txt" => cmd.call("lsattr-output"), - %{sh -c 'type "lsattr"'} => empty.call, + 'lsattr constantfile.txt' => cmd.call('lsattr-output'), + %(sh -c 'type "lsattr"') => empty.call, # linux_audit_system - "/usr/sbin/auditctl -s | grep enabled" => cmd.call("auditctl-s-enabled"), - "/usr/sbin/auditctl -s | grep pid" => cmd.call("auditctl-s-pid"), - "/usr/sbin/auditctl -l" => cmd.call("auditctl-l"), - %{sh -c 'type "/usr/sbin/auditctl"'} => empty.call, + '/usr/sbin/auditctl -s | grep enabled' => cmd.call('auditctl-s-enabled'), + '/usr/sbin/auditctl -s | grep pid' => cmd.call('auditctl-s-pid'), + '/usr/sbin/auditctl -l' => cmd.call('auditctl-l'), + %(sh -c 'type "/usr/sbin/auditctl"') => empty.call, # x509_certificate - %{sh -c 'type "openssl"'} => empty.call, - "openssl x509 -noout -purpose -in test_certificate.rsa.crt.pem" => cmd.call("x509-crt-purpose"), + %(sh -c 'type "openssl"') => empty.call, + 'openssl x509 -noout -purpose -in test_certificate.rsa.crt.pem' => cmd.call('x509-crt-purpose'), # x509_private_key - %{type "openssl"} => empty.call, - "openssl rsa -in /home/openssl_activity/bob_private.pem -check -noout" => empty.call, - "openssl rsa -in /home/openssl_activity/alice_private.pem -check -noout -passin pass:password@123" => empty.call, - "openssl x509 -noout -modulus -in /home/openssl_activity/bob_certificate.crt | openssl md5" => cmd.call("x509-certificate-modulus"), - "openssl rsa -noout -modulus -in /home/openssl_activity/bob_private.pem | openssl md5" => cmd.call("x509-certificate-modulus"), - "openssl x509 -noout -modulus -in /home/openssl_activity/alice_certificate.crt | openssl md5" => cmd.call("x509-certificate-modulus"), - "openssl rsa -noout -modulus -in /home/openssl_activity/alice_private.pem -passin pass:password@123 | openssl md5" => cmd.call("x509-certificate-modulus"), + %(type "openssl") => empty.call, + 'openssl rsa -in /home/openssl_activity/bob_private.pem -check -noout' => empty.call, + 'openssl rsa -in /home/openssl_activity/alice_private.pem -check -noout -passin pass:password@123' => empty.call, + 'openssl x509 -noout -modulus -in /home/openssl_activity/bob_certificate.crt | openssl md5' => cmd.call('x509-certificate-modulus'), + 'openssl rsa -noout -modulus -in /home/openssl_activity/bob_private.pem | openssl md5' => cmd.call('x509-certificate-modulus'), + 'openssl x509 -noout -modulus -in /home/openssl_activity/alice_certificate.crt | openssl md5' => cmd.call('x509-certificate-modulus'), + 'openssl rsa -noout -modulus -in /home/openssl_activity/alice_private.pem -passin pass:password@123 | openssl md5' => cmd.call('x509-certificate-modulus'), # apache_conf - "sh -c 'find /etc/apache2/ports.conf -type f -maxdepth 1'" => cmd.call("find-apache2-ports-conf"), - "sh -c 'find /etc/httpd/conf.d/*.conf -type f -maxdepth 1'" => cmd.call("find-httpd-ssl-conf"), - "sh -c 'find /etc/httpd/mods-enabled/*.conf -type f -maxdepth 1'" => cmd.call("find-httpd-status-conf"), - "sh -c 'find /etc/httpd/conf-enabled/*.conf -type l -maxdepth 1'" => cmd.call("find-httpd-conf-enabled-link"), - "sh -c 'find /etc/apache2/conf-enabled/*.conf -type f -maxdepth 1'" => cmd.call("find-apache2-conf-enabled"), - "sh -c 'find /etc/apache2/conf-enabled/*.conf -type l -maxdepth 1'" => cmd.call("find-apache2-conf-enabled-link"), - "sh -c 'find /etc/nginx/nginx.conf'" => cmd.call("find-nginx-conf"), - "sh -c 'find /etc/nginx/conf/mime.types'" => cmd.call("find-nginx-mime-types"), - "sh -c 'find /etc/nginx/proxy.conf'" => cmd.call("find-nginx-proxy-conf"), - "sh -c 'find /etc/nginx/conf.d/*.conf'" => cmd.call("find-nginx-confd-multiple-conf"), - "sh -c 'find /etc/nginx/quotes.d/*.conf'" => cmd.call("find-nginx-quotesd-example-conf"), + "sh -c 'find /etc/apache2/ports.conf -type f -maxdepth 1'" => cmd.call('find-apache2-ports-conf'), + "sh -c 'find /etc/httpd/conf.d/*.conf -type f -maxdepth 1'" => cmd.call('find-httpd-ssl-conf'), + "sh -c 'find /etc/httpd/mods-enabled/*.conf -type f -maxdepth 1'" => cmd.call('find-httpd-status-conf'), + "sh -c 'find /etc/httpd/conf-enabled/*.conf -type l -maxdepth 1'" => cmd.call('find-httpd-conf-enabled-link'), + "sh -c 'find /etc/apache2/conf-enabled/*.conf -type f -maxdepth 1'" => cmd.call('find-apache2-conf-enabled'), + "sh -c 'find /etc/apache2/conf-enabled/*.conf -type l -maxdepth 1'" => cmd.call('find-apache2-conf-enabled-link'), + "sh -c 'find /etc/nginx/nginx.conf'" => cmd.call('find-nginx-conf'), + "sh -c 'find /etc/nginx/conf/mime.types'" => cmd.call('find-nginx-mime-types'), + "sh -c 'find /etc/nginx/proxy.conf'" => cmd.call('find-nginx-proxy-conf'), + "sh -c 'find /etc/nginx/conf.d/*.conf'" => cmd.call('find-nginx-confd-multiple-conf'), + "sh -c 'find /etc/nginx/quotes.d/*.conf'" => cmd.call('find-nginx-quotesd-example-conf'), # mount - "mount | grep -- ' on /'" => cmd.call("mount"), - "mount | grep -- ' on /mnt/iso-disk'" => cmd.call("mount-multiple"), - "mount | grep -- ' on /mnt/Research & Development'" => cmd.call("mount-whitespaces"), + "mount | grep -- ' on /'" => cmd.call('mount'), + "mount | grep -- ' on /mnt/iso-disk'" => cmd.call('mount-multiple'), + "mount | grep -- ' on /mnt/Research & Development'" => cmd.call('mount-whitespaces'), # solaris 10 package manager - "pkginfo -l SUNWzfsr" => cmd.call("pkginfo-l-SUNWzfsr"), + 'pkginfo -l SUNWzfsr' => cmd.call('pkginfo-l-SUNWzfsr'), # solaris 11 package manager - "pkg info system/file-system/zfs" => cmd.call("pkg-info-system-file-system-zfs"), + 'pkg info system/file-system/zfs' => cmd.call('pkg-info-system-file-system-zfs'), # dpkg-query all packages - "dpkg-query -W -f='${db:Status-Abbrev} ${Package} ${Version} ${Architecture}\\n'" => cmd.call("dpkg-query-W"), + "dpkg-query -W -f='${db:Status-Abbrev} ${Package} ${Version} ${Architecture}\\n'" => cmd.call('dpkg-query-W'), # rpm query all packages - "rpm -qa --queryformat '%{NAME} %{VERSION}-%{RELEASE} %{ARCH}\\n'" => cmd.call("rpm-qa-queryformat"), + "rpm -qa --queryformat '%{NAME} %{VERSION}-%{RELEASE} %{ARCH}\\n'" => cmd.call('rpm-qa-queryformat'), # pkg query all packages - "pkg info vim-console" => cmd.call("pkg-info-vim-console"), - "pkg version -v | grep vim-console" => cmd.call("pkg-version-grep-vim-console"), + 'pkg info vim-console' => cmd.call('pkg-info-vim-console'), + 'pkg version -v | grep vim-console' => cmd.call('pkg-version-grep-vim-console'), # port netstat on solaris 10 & 11 - "netstat -an -f inet -f inet6" => cmd.call("s11-netstat-an-finet-finet6"), + 'netstat -an -f inet -f inet6' => cmd.call('s11-netstat-an-finet-finet6'), # xinetd configuration - "find /etc/xinetd.d -type f" => cmd.call("find-xinetd.d"), + 'find /etc/xinetd.d -type f' => cmd.call('find-xinetd.d'), # wmi test - "cf04ce5615167da0133540398aa9989bf48b3d15a615f08f97eafaeec6e5b2ba" => cmd.call("get-wmiobject"), + 'cf04ce5615167da0133540398aa9989bf48b3d15a615f08f97eafaeec6e5b2ba' => cmd.call('get-wmiobject'), # user info on hpux - "logins -x -l root" => cmd.call("logins-x"), + 'logins -x -l root' => cmd.call('logins-x'), # packages on hpux - "swlist -l product | grep vim" => cmd.call("swlist-l-product"), + 'swlist -l product | grep vim' => cmd.call('swlist-l-product'), # ipv4 ports on hpux - "netstat -an -f inet" => cmd.call("hpux-netstat-inet"), + 'netstat -an -f inet' => cmd.call('hpux-netstat-inet'), # ipv6 ports on hpux - "netstat -an -f inet6" => cmd.call("hpux-netstat-inet6"), + 'netstat -an -f inet6' => cmd.call('hpux-netstat-inet6'), # hostname linux and darwin - "hostname" => cmd.call("hostname"), + 'hostname' => cmd.call('hostname'), # hostname windows - "$env:computername" => cmd.call("$env-computername"), + '$env:computername' => cmd.call('$env-computername'), # Manufacturer linux - "cat /sys/class/dmi/id/sys_vendor" => cmd.call("manufacturer"), + 'cat /sys/class/dmi/id/sys_vendor' => cmd.call('manufacturer'), # Manufacturer windows - "Get-CimInstance -ClassName Win32_ComputerSystem | Select Manufacturer -ExpandProperty Manufacturer" => cmd.call("manufacturer"), + 'Get-CimInstance -ClassName Win32_ComputerSystem | Select Manufacturer -ExpandProperty Manufacturer' => cmd.call('manufacturer'), # Model linux - "cat /sys/class/dmi/id/product_name" => cmd.call("model"), + 'cat /sys/class/dmi/id/product_name' => cmd.call('model'), # Model darwin - "sysctl -n hw.model" => cmd.call("model_darwin"), + 'sysctl -n hw.model' => cmd.call('model_darwin'), # Model windows - "Get-CimInstance -ClassName Win32_ComputerSystem | Select Model -ExpandProperty Model" => cmd.call("model"), + 'Get-CimInstance -ClassName Win32_ComputerSystem | Select Model -ExpandProperty Model' => cmd.call('model'), # windows_hotfix windows - "get-hotfix -id KB4019215" => cmd.call("kb4019215"), + 'get-hotfix -id KB4019215' => cmd.call('kb4019215'), # windows_hotfix windows doesn't exist - "get-hotfix -id KB9999999" => empty.call, + 'get-hotfix -id KB9999999' => empty.call, # windows_task doesnt exist - "schtasks /query /v /fo csv /tn 'does-not-exist' | ConvertFrom-Csv | Select @{N='URI';E={$_.TaskName}},@{N='State';E={$_.Status.ToString()}},'Logon Mode','Last Result','Task To Run','Run As User','Scheduled Task State' | ConvertTo-Json -Compress" => cmd.call("schtasks-error"), + "schtasks /query /v /fo csv /tn 'does-not-exist' | ConvertFrom-Csv | Select @{N='URI';E={$_.TaskName}},@{N='State';E={$_.Status.ToString()}},'Logon Mode','Last Result','Task To Run','Run As User','Scheduled Task State' | ConvertTo-Json -Compress" => cmd.call('schtasks-error'), # windows_task exists and has 1 trigger - "schtasks /query /v /fo csv /tn 'WeLovePizza' | ConvertFrom-Csv | Select @{N='URI';E={$_.TaskName}},@{N='State';E={$_.Status.ToString()}},'Logon Mode','Last Result','Task To Run','Run As User','Scheduled Task State' | ConvertTo-Json -Compress" => cmd.call("schtasks-success-single-trigger"), + "schtasks /query /v /fo csv /tn 'WeLovePizza' | ConvertFrom-Csv | Select @{N='URI';E={$_.TaskName}},@{N='State';E={$_.Status.ToString()}},'Logon Mode','Last Result','Task To Run','Run As User','Scheduled Task State' | ConvertTo-Json -Compress" => cmd.call('schtasks-success-single-trigger'), # windows_task exists and has multiple triggers - "schtasks /query /v /fo csv /tn 'WeLoveMultiplePizzas' | ConvertFrom-Csv | Select @{N='URI';E={$_.TaskName}},@{N='State';E={$_.Status.ToString()}},'Logon Mode','Last Result','Task To Run','Run As User','Scheduled Task State' | ConvertTo-Json -Compress" => cmd.call("schtasks-success-multiple-triggers"), - "modinfo -F version dhcp" => cmd.call("modinfo-f-version-dhcp"), + "schtasks /query /v /fo csv /tn 'WeLoveMultiplePizzas' | ConvertFrom-Csv | Select @{N='URI';E={$_.TaskName}},@{N='State';E={$_.Status.ToString()}},'Logon Mode','Last Result','Task To Run','Run As User','Scheduled Task State' | ConvertTo-Json -Compress" => cmd.call('schtasks-success-multiple-triggers'), + 'modinfo -F version dhcp' => cmd.call('modinfo-f-version-dhcp'), # crontab display for root / current user - "crontab -l" => cmd.call("crontab-root"), + 'crontab -l' => cmd.call('crontab-root'), # crontab display for non-current user - "crontab -l -u foouser" => cmd.call("crontab-foouser"), + 'crontab -l -u foouser' => cmd.call('crontab-foouser'), # crontab display for special time strings - "crontab -l -u special" => cmd.call("crontab-special"), + 'crontab -l -u special' => cmd.call('crontab-special'), # crontab exit status check - "crontab -l -u testuser" => cmd_exit_1.call, + 'crontab -l -u testuser' => cmd_exit_1.call, # zfs output for dataset tank/tmp - "/sbin/zfs get -Hp all tank/tmp" => cmd.call("zfs-get-all-tank-tmp"), + '/sbin/zfs get -Hp all tank/tmp' => cmd.call('zfs-get-all-tank-tmp'), # zfs output for pool tank - "/sbin/zpool get -Hp all tank" => cmd.call("zpool-get-all-tank"), + '/sbin/zpool get -Hp all tank' => cmd.call('zpool-get-all-tank'), # which zfs - "which zfs" => cmd.call("zfs-which"), + 'which zfs' => cmd.call('zfs-which'), # which zpool - "which zpool" => cmd.call("zpool-which"), + 'which zpool' => cmd.call('zpool-which'), # docker - "4f8e24022ea8b7d3b117041ec32e55d9bf08f11f4065c700e7c1dc606c84fd17" => cmd.call("docker-ps-a"), - "b40ed61c006b54f155b28a85dc944dc0352b30222087b47c6279568ec0e59d05" => cmd.call("df-PT"), - "docker version --format '{{ json . }}'" => cmd.call("docker-version"), - "docker info --format '{{ json . }}'" => cmd.call("docker-info"), - "docker inspect 71b5df59442b" => cmd.call("docker-inspec"), - "docker inspect trusting_williams" => cmd.call("docker-inspect"), # inspect container to check for mounted volumes - "docker inspect fried_water" => cmd.call("docker-inspect-e"), # inspect container to check for mounted volumes + '4f8e24022ea8b7d3b117041ec32e55d9bf08f11f4065c700e7c1dc606c84fd17' => cmd.call('docker-ps-a'), + 'b40ed61c006b54f155b28a85dc944dc0352b30222087b47c6279568ec0e59d05' => cmd.call('df-PT'), + "docker version --format '{{ json . }}'" => cmd.call('docker-version'), + "docker info --format '{{ json . }}'" => cmd.call('docker-info'), + 'docker inspect 71b5df59442b' => cmd.call('docker-inspec'), + 'docker inspect trusting_williams' => cmd.call('docker-inspect'), # inspect container to check for mounted volumes + 'docker inspect fried_water' => cmd.call('docker-inspect-e'), # inspect container to check for mounted volumes # docker images - "83c36bfade9375ae1feb91023cd1f7409b786fd992ad4013bf0f2259d33d6406" => cmd.call("docker-images"), - "docker inspect ubuntu:latest" => cmd.call("docker-inspect-image"), + '83c36bfade9375ae1feb91023cd1f7409b786fd992ad4013bf0f2259d33d6406' => cmd.call('docker-images'), + 'docker inspect ubuntu:latest' => cmd.call('docker-inspect-image'), # docker services - %{docker service ls --format '{"ID": {{json .ID}}, "Name": {{json .Name}}, "Mode": {{json .Mode}}, "Replicas": {{json .Replicas}}, "Image": {{json .Image}}, "Ports": {{json .Ports}}}'} => cmd.call("docker-service-ls"), + %(docker service ls --format '{"ID": {{json .ID}}, "Name": {{json .Name}}, "Mode": {{json .Mode}}, "Replicas": {{json .Replicas}}, "Image": {{json .Image}}, "Ports": {{json .Ports}}}') => cmd.call('docker-service-ls'), # docker plugins - %{docker plugin ls --format '{"id": {{json .ID}}, "name": "{{ with split .Name ":"}}{{index . 0}}{{end}}", "version": "{{ with split .Name ":"}}{{index . 1}}{{end}}", "enabled": {{json .Enabled}} }'} => cmd.call("docker-plugin-ls"), + %(docker plugin ls --format '{"id": {{json .ID}}, "name": "{{ with split .Name ":"}}{{index . 0}}{{end}}", "version": "{{ with split .Name ":"}}{{index . 1}}{{end}}", "enabled": {{json .Enabled}} }') => cmd.call('docker-plugin-ls'), # modprobe for kernel_module - "modprobe --showconfig" => cmd.call("modprobe-config"), + 'modprobe --showconfig' => cmd.call('modprobe-config'), # get-process cmdlet for processes resource - '$Proc = Get-Process -IncludeUserName | Select-Object PriorityClass,Id,CPU,PM,VirtualMemorySize,NPM,SessionId,Responding,StartTime,TotalProcessorTime,UserName,Path,ProcessName | ConvertTo-Csv -NoTypeInformation;$Proc.Replace("""","").Replace("`r`n","`n")' => cmd.call("get-process_processes"), + '$Proc = Get-Process -IncludeUserName | Select-Object PriorityClass,Id,CPU,PM,VirtualMemorySize,NPM,SessionId,Responding,StartTime,TotalProcessorTime,UserName,Path,ProcessName | ConvertTo-Csv -NoTypeInformation;$Proc.Replace("""","").Replace("`r`n","`n")' => cmd.call('get-process_processes'), # host resource: TCP/UDP reachability check on linux - %{sh -c 'type "nc"'} => empty.call, - %{sh -c 'type "ncat"'} => empty.call, - %{sh -c 'type "timeout"'} => empty.call, + %(sh -c 'type "nc"') => empty.call, + %(sh -c 'type "ncat"') => empty.call, + %(sh -c 'type "timeout"') => empty.call, %{strings `which bash` | grep -qE '/dev/(tcp|udp)/'} => empty.call, - %{echo | nc -v -w 1 -u example.com 1234} => empty.call, - %{echo | nc -v -w 1 example.com 1234} => empty.call, + %(echo | nc -v -w 1 -u example.com 1234) => empty.call, + %(echo | nc -v -w 1 example.com 1234) => empty.call, 'timeout 1 bash -c "< /dev/tcp/example.com/1234"' => empty.call, 'timeout 1 bash -c "< /dev/udp/example.com/1234"' => empty.call, # host resource: netcat for TCP reachability check on darwin 'type "nc"' => empty.call, 'type "ncat"' => empty.call, 'type "gtimeout"' => empty.call, - "nc -vz -G 1 example.com 1234" => empty.call, + 'nc -vz -G 1 example.com 1234' => empty.call, 'gtimeout 1 bash -c "< /dev/tcp/example.com/1234"' => empty.call, 'gtimeout 1 bash -c "< /dev/udp/example.com/1234"' => empty.call, # host resource: test-netconnection for reachability check on windows - "Test-NetConnection -ComputerName microsoft.com -WarningAction SilentlyContinue -RemotePort 1234| Select-Object -Property ComputerName, TcpTestSucceeded, PingSucceeded | ConvertTo-Json" => cmd.call("Test-NetConnection"), + 'Test-NetConnection -ComputerName microsoft.com -WarningAction SilentlyContinue -RemotePort 1234| Select-Object -Property ComputerName, TcpTestSucceeded, PingSucceeded | ConvertTo-Json' => cmd.call('Test-NetConnection'), # postgres tests - %q{sh -c 'type "psql"'} => cmd.call("sh -c type psql"), - %q(psql --version | awk '{ print $NF }' | awk -F. '{ print $1"."$2 }') => cmd.call("psql-version"), + %q(sh -c 'type "psql"') => cmd.call('sh -c type psql'), + %q(psql --version | awk '{ print $NF }' | awk -F. '{ print $1"."$2 }') => cmd.call('psql-version'), # mssql tests - "sh -c 'type \"sqlcmd\"'" => cmd.call("mssql-sqlcmd"), - "cb0efcd12206e9690c21ac631a72be9dd87678aa048e6dae16b8e9353ab6dd64" => cmd.call("mssql-getdate"), - "7109e5d809058cd3e9cad108e21e91234d2638db4a4f81fadfde21e071a423dc" => cmd.call("mssql-getdate"), - "5c2bc0f0568d11451d6cf83aff02ee3d47211265b52b6c5d45f8e57290b35082" => cmd.call("mssql-getdate"), - "148af1d7706d9cf81097f66d5b891ddfca719445d60fa582befad118f51b9d92" => cmd.call("mssql-getdate"), - "9a1dfd9e403053efb1fd1970a77a241e5c7a9eae34e6f6c56904fa8189bc2e45" => cmd.call("mssql-getdate"), - "e8bece33e9d550af1fc81a5bc1c72b647b3810db3e567ee9f30feb81f4e3b700" => cmd.call("mssql-getdate"), - "53d201ff1cfb8867b79200177b8e2e99dedb700c5fbe15e43820011d7e8b941f" => cmd.call("mssql-getdate"), - "4b550bb227058ac5851aa0bc946be794ee46489610f17842700136cf8bb5a0e9" => cmd.call("mssql-getdate"), - "7d1a7a0f2bd1e7da9a6904e1f28981146ec01a0323623e12a8579d30a3960a79" => cmd.call("mssql-result"), + "sh -c 'type \"sqlcmd\"'" => cmd.call('mssql-sqlcmd'), + 'cb0efcd12206e9690c21ac631a72be9dd87678aa048e6dae16b8e9353ab6dd64' => cmd.call('mssql-getdate'), + '7109e5d809058cd3e9cad108e21e91234d2638db4a4f81fadfde21e071a423dc' => cmd.call('mssql-getdate'), + '5c2bc0f0568d11451d6cf83aff02ee3d47211265b52b6c5d45f8e57290b35082' => cmd.call('mssql-getdate'), + '148af1d7706d9cf81097f66d5b891ddfca719445d60fa582befad118f51b9d92' => cmd.call('mssql-getdate'), + '9a1dfd9e403053efb1fd1970a77a241e5c7a9eae34e6f6c56904fa8189bc2e45' => cmd.call('mssql-getdate'), + 'e8bece33e9d550af1fc81a5bc1c72b647b3810db3e567ee9f30feb81f4e3b700' => cmd.call('mssql-getdate'), + '53d201ff1cfb8867b79200177b8e2e99dedb700c5fbe15e43820011d7e8b941f' => cmd.call('mssql-getdate'), + '4b550bb227058ac5851aa0bc946be794ee46489610f17842700136cf8bb5a0e9' => cmd.call('mssql-getdate'), + '7d1a7a0f2bd1e7da9a6904e1f28981146ec01a0323623e12a8579d30a3960a79' => cmd.call('mssql-result'), # oracle - "sh -c 'type \"sqlplus\"'" => cmd.call("oracle-cmd"), - "1998da5bc0f09bd5258fad51f45447556572b747f631661831d6fcb49269a448" => cmd.call("oracle-result"), - "${Env:ORACLE_HOME}" => cmd.call("fetch-oracle-listener-in-windows"), - "${Env:CASSANDRA_HOME}" => cmd.call("fetch-cassandra-conf-in-windows"), + "sh -c 'type \"sqlplus\"'" => cmd.call('oracle-cmd'), + '1998da5bc0f09bd5258fad51f45447556572b747f631661831d6fcb49269a448' => cmd.call('oracle-result'), + '${Env:ORACLE_HOME}' => cmd.call('fetch-oracle-listener-in-windows'), + '${Env:CASSANDRA_HOME}' => cmd.call('fetch-cassandra-conf-in-windows'), # nginx mock cmd - %{nginx -V 2>&1} => cmd.call("nginx-v"), - %{/usr/sbin/nginx -V 2>&1} => cmd.call("nginx-v"), - %{sh -c 'type "/usr/sbin/nginx"'} => cmd.call("sh-c-type-nginx"), + %(nginx -V 2>&1) => cmd.call('nginx-v'), + %(/usr/sbin/nginx -V 2>&1) => cmd.call('nginx-v'), + %(sh -c 'type "/usr/sbin/nginx"') => cmd.call('sh-c-type-nginx'), # needed for two differnt inspec.command call formats # host resource: dig commands, - "dig +short A example.com" => cmd.call("dig-A-example.com"), - "dig +short AAAA example.com" => cmd.call("dig-AAAA-example.com"), + 'dig +short A example.com' => cmd.call('dig-A-example.com'), + 'dig +short AAAA example.com' => cmd.call('dig-AAAA-example.com'), # firewalld resource - "firewall-cmd --get-zones" => cmd.call("firewall-cmd--get-zones"), - "firewall-cmd --get-default-zone" => cmd.call("firewall-cmd--get-default-zone"), - "firewall-cmd --get-active-zones" => cmd.call("firewall-cmd--get-active-zones"), - "firewall-cmd --state" => cmd.call("firewall-cmd--state"), - "firewall-cmd --permanent --zone=public --query-service=ssh" => cmd.call("firewall-cmd--service-enabled-in-zone"), - "firewall-cmd --permanent --zone=public --query-port=22/udp" => cmd.call("firewall-cmd-has-port-enabled-in-zone"), - "firewall-cmd --permanent --zone=public --query-rich-rule='rule family=ipv4 source address=192.168.0.14 accept'" => cmd.call("firewall-cmd-has-rule-enabled"), - "firewall-cmd --permanent --zone=public --service=ssh --get-ports" => cmd.call("firewall-cmd-service-ports-enabled-in-zone"), - "firewall-cmd --permanent --zone=public --service=ssh --get-protocols" => cmd.call("firewall-cmd-service-protocols-enabled-in-zone"), - "firewall-cmd --permanent --zone=public --list-services" => cmd.call("firewall-cmd-services-bound"), - "firewall-cmd --permanent --zone=default --list-services" => cmd.call("firewall-cmd-services-bound"), - "firewall-cmd --permanent --zone=public --list-sources" => cmd.call("firewall-cmd-sources-bound"), - "firewall-cmd --permanent --zone=default --list-sources" => cmd.call("firewall-cmd-sources-bound"), - "firewall-cmd --permanent --zone=public --get-target" => cmd.call("firewall-cmd-get-target"), - "firewall-cmd --permanent --zone=public --query-icmp-block-inversion" => cmd.call("firewall-cmd-query-icmp-block-inversion"), - "firewall-cmd --permanent --zone=public --list-ports" => cmd.call("firewall-cmd-list-ports"), - "firewall-cmd --permanent --zone=public --list-protocols" => cmd.call("firewall-cmd-list-protocols"), - "firewall-cmd --permanent --zone=public --query-masquerade" => cmd.call("firewall-cmd-query-masquerade"), - "firewall-cmd --permanent --zone=public --list-forward-ports" => cmd.call("firewall-cmd-list-forward-ports"), - "firewall-cmd --permanent --zone=public --list-source-ports" => cmd.call("firewall-cmd-list-source-ports"), - "firewall-cmd --permanent --zone=public --list-icmp-blocks" => cmd.call("firewall-cmd-list-icmp-blocks"), - "firewall-cmd --permanent --zone=public --list-rich-rules" => cmd.call("firewall-cmd-list-rich-rules"), - "firewall-cmd --permanent --zone=public --query-rich-rule=rule family=ipv4 source address=192.168.0.14 accept" => cmd.call("firewall-cmd-has-rule-enabled"), - "sh -c 'type \"firewall-cmd\"'" => cmd.call("firewall-cmd"), - "rpm -qia firewalld" => cmd.call("pkg-info-firewalld"), - "systemctl is-active sshd --quiet" => empty.call, - "systemctl is-active apache2 --quiet" => empty.call, - "systemctl is-enabled sshd --quiet" => empty.call, - "systemctl is-enabled apache2 --quiet" => cmd_exit_1.call("systemctl-is-enabled-apache2-stderr"), - "systemctl is-active dbus --quiet" => empty.call, - "systemctl is-enabled dbus --quiet" => empty.call, - "/path/to/systemctl is-active sshd --quiet" => empty.call, - "/path/to/systemctl is-enabled sshd --quiet" => empty.call, - "/usr/sbin/service sshd status" => empty.call, - "/sbin/service sshd status" => empty.call, - "service apache2 status" => cmd_exit_1.call, + 'firewall-cmd --get-zones' => cmd.call('firewall-cmd--get-zones'), + 'firewall-cmd --get-default-zone' => cmd.call('firewall-cmd--get-default-zone'), + 'firewall-cmd --get-active-zones' => cmd.call('firewall-cmd--get-active-zones'), + 'firewall-cmd --state' => cmd.call('firewall-cmd--state'), + 'firewall-cmd --permanent --zone=public --query-service=ssh' => cmd.call('firewall-cmd--service-enabled-in-zone'), + 'firewall-cmd --permanent --zone=public --query-port=22/udp' => cmd.call('firewall-cmd-has-port-enabled-in-zone'), + "firewall-cmd --permanent --zone=public --query-rich-rule='rule family=ipv4 source address=192.168.0.14 accept'" => cmd.call('firewall-cmd-has-rule-enabled'), + 'firewall-cmd --permanent --zone=public --service=ssh --get-ports' => cmd.call('firewall-cmd-service-ports-enabled-in-zone'), + 'firewall-cmd --permanent --zone=public --service=ssh --get-protocols' => cmd.call('firewall-cmd-service-protocols-enabled-in-zone'), + 'firewall-cmd --permanent --zone=public --list-services' => cmd.call('firewall-cmd-services-bound'), + 'firewall-cmd --permanent --zone=default --list-services' => cmd.call('firewall-cmd-services-bound'), + 'firewall-cmd --permanent --zone=public --list-sources' => cmd.call('firewall-cmd-sources-bound'), + 'firewall-cmd --permanent --zone=default --list-sources' => cmd.call('firewall-cmd-sources-bound'), + 'firewall-cmd --permanent --zone=public --get-target' => cmd.call('firewall-cmd-get-target'), + 'firewall-cmd --permanent --zone=public --query-icmp-block-inversion' => cmd.call('firewall-cmd-query-icmp-block-inversion'), + 'firewall-cmd --permanent --zone=public --list-ports' => cmd.call('firewall-cmd-list-ports'), + 'firewall-cmd --permanent --zone=public --list-protocols' => cmd.call('firewall-cmd-list-protocols'), + 'firewall-cmd --permanent --zone=public --query-masquerade' => cmd.call('firewall-cmd-query-masquerade'), + 'firewall-cmd --permanent --zone=public --list-forward-ports' => cmd.call('firewall-cmd-list-forward-ports'), + 'firewall-cmd --permanent --zone=public --list-source-ports' => cmd.call('firewall-cmd-list-source-ports'), + 'firewall-cmd --permanent --zone=public --list-icmp-blocks' => cmd.call('firewall-cmd-list-icmp-blocks'), + 'firewall-cmd --permanent --zone=public --list-rich-rules' => cmd.call('firewall-cmd-list-rich-rules'), + 'firewall-cmd --permanent --zone=public --query-rich-rule=rule family=ipv4 source address=192.168.0.14 accept' => cmd.call('firewall-cmd-has-rule-enabled'), + "sh -c 'type \"firewall-cmd\"'" => cmd.call('firewall-cmd'), + 'rpm -qia firewalld' => cmd.call('pkg-info-firewalld'), + 'systemctl is-active sshd --quiet' => empty.call, + 'systemctl is-active apache2 --quiet' => empty.call, + 'systemctl is-enabled sshd --quiet' => empty.call, + 'systemctl is-enabled apache2 --quiet' => cmd_exit_1.call('systemctl-is-enabled-apache2-stderr'), + 'systemctl is-active dbus --quiet' => empty.call, + 'systemctl is-enabled dbus --quiet' => empty.call, + '/path/to/systemctl is-active sshd --quiet' => empty.call, + '/path/to/systemctl is-enabled sshd --quiet' => empty.call, + '/usr/sbin/service sshd status' => empty.call, + '/sbin/service sshd status' => empty.call, + 'service apache2 status' => cmd_exit_1.call, 'type "lsof"' => empty.call, - "test -f /etc/mysql/debian.cnf && cat /etc/mysql/debian.cnf" => empty.call, + 'test -f /etc/mysql/debian.cnf && cat /etc/mysql/debian.cnf' => empty.call, # http resource - remote worker' - %{sh -c 'type "curl"'} => cmd.call("sh-c-type-curl"), - "curl -i -X GET --connect-timeout 60 --max-time 120 'http://www.example.com'" => cmd.call("http-remote-no-options"), - "curl -i -X GET --connect-timeout 60 --max-time 120 --location --max-redirs 1 'http://www.example.com'" => cmd.call("http-remote-max-redirs"), - "curl -i -X GET --connect-timeout 60 --max-time 120 --user 'user:pass' 'http://www.example.com'" => cmd.call("http-remote-basic-auth"), - "f77ebcedaf6fbe8f02d2f9d4735a90c12311d2ca4b43ece9efa2f2e396491747" => cmd.call("http-remote-post"), - "curl -i -X GET --connect-timeout 60 --max-time 120 -H 'accept: application/json' -H 'foo: bar' 'http://www.example.com'" => cmd.call("http-remote-headers"), - "curl -i -X GET --connect-timeout 60 --max-time 120 'http://www.example.com?a=b&c=d'" => cmd.call("http-remote-params"), - "curl -i --head --connect-timeout 60 --max-time 120 'http://www.example.com'" => cmd.call("http-remote-head-request"), - "curl -i -X OPTIONS --connect-timeout 60 --max-time 120 -H 'Access-Control-Request-Method: GET' -H 'Access-Control-Request-Headers: origin, x-requested-with' -H 'Origin: http://www.example.com' 'http://www.example.com'" => cmd.call("http-remote-options-request"), + %(sh -c 'type "curl"') => cmd.call('sh-c-type-curl'), + "curl -i -X GET --connect-timeout 60 --max-time 120 'http://www.example.com'" => cmd.call('http-remote-no-options'), + "curl -i -X GET --connect-timeout 60 --max-time 120 --location --max-redirs 1 'http://www.example.com'" => cmd.call('http-remote-max-redirs'), + "curl -i -X GET --connect-timeout 60 --max-time 120 --user 'user:pass' 'http://www.example.com'" => cmd.call('http-remote-basic-auth'), + 'f77ebcedaf6fbe8f02d2f9d4735a90c12311d2ca4b43ece9efa2f2e396491747' => cmd.call('http-remote-post'), + "curl -i -X GET --connect-timeout 60 --max-time 120 -H 'accept: application/json' -H 'foo: bar' 'http://www.example.com'" => cmd.call('http-remote-headers'), + "curl -i -X GET --connect-timeout 60 --max-time 120 'http://www.example.com?a=b&c=d'" => cmd.call('http-remote-params'), + "curl -i --head --connect-timeout 60 --max-time 120 'http://www.example.com'" => cmd.call('http-remote-head-request'), + "curl -i -X OPTIONS --connect-timeout 60 --max-time 120 -H 'Access-Control-Request-Method: GET' -H 'Access-Control-Request-Headers: origin, x-requested-with' -H 'Origin: http://www.example.com' 'http://www.example.com'" => cmd.call('http-remote-options-request'), # http resource - windows - "\n$body = \n $Body = $body | ConvertFrom-Json\n #convert to hashtable\n $HashTable = @{}\n foreach ($property in $Body.PSObject.Properties) {\n $HashTable[$property.Name] = $property.Value\n }\n $response = Invoke-WebRequest -Method HEAD -TimeoutSec 120 'https://www.example.com' -Body $HashTable -UseBasicParsing\n $response | Select-Object -Property * | ConvertTo-json # We use `Select-Object -Property * ` to get around an odd PowerShell error" => cmd.call("http-windows-remote-no-options"), - "\n$body = \n $Body = $body | ConvertFrom-Json\n #convert to hashtable\n $HashTable = @{}\n foreach ($property in $Body.PSObject.Properties) {\n $HashTable[$property.Name] = $property.Value\n }\n $response = Invoke-WebRequest -Method GET -TimeoutSec 120 'https://www.example.com' -Body $HashTable -UseBasicParsing\n $response | Select-Object -Property * | ConvertTo-json # We use `Select-Object -Property * ` to get around an odd PowerShell error" => cmd.call("http-windows-remote-head"), - "\n$body = \n $Body = $body | ConvertFrom-Json\n #convert to hashtable\n $HashTable = @{}\n foreach ($property in $Body.PSObject.Properties) {\n $HashTable[$property.Name] = $property.Value\n }\n $response = Invoke-WebRequest -Method GET -TimeoutSec 120 -Headers @{ 'X-Test-Header' = 'test/value'; 'foo' = 'bar'} 'https://www.example.com' -Body $HashTable -UseBasicParsing\n $response | Select-Object -Property * | ConvertTo-json # We use `Select-Object -Property * ` to get around an odd PowerShell error" => cmd.call("http-windows-remote-get-headers"), - "\n$body = '{ \"a\" : \"1\", \"b\" : \"five\" }'\n $Body = $body | ConvertFrom-Json\n #convert to hashtable\n $HashTable = @{}\n foreach ($property in $Body.PSObject.Properties) {\n $HashTable[$property.Name] = $property.Value\n }\n $response = Invoke-WebRequest -Method POST -TimeoutSec 120 'https://www.example.com' -Body $HashTable -UseBasicParsing\n $response | Select-Object -Property * | ConvertTo-json # We use `Select-Object -Property * ` to get around an odd PowerShell error" => cmd.call("http-windows-remote-head"), + "\n$body = \n $Body = $body | ConvertFrom-Json\n #convert to hashtable\n $HashTable = @{}\n foreach ($property in $Body.PSObject.Properties) {\n $HashTable[$property.Name] = $property.Value\n }\n $response = Invoke-WebRequest -Method HEAD -TimeoutSec 120 'https://www.example.com' -Body $HashTable -UseBasicParsing\n $response | Select-Object -Property * | ConvertTo-json # We use `Select-Object -Property * ` to get around an odd PowerShell error" => cmd.call('http-windows-remote-no-options'), + "\n$body = \n $Body = $body | ConvertFrom-Json\n #convert to hashtable\n $HashTable = @{}\n foreach ($property in $Body.PSObject.Properties) {\n $HashTable[$property.Name] = $property.Value\n }\n $response = Invoke-WebRequest -Method GET -TimeoutSec 120 'https://www.example.com' -Body $HashTable -UseBasicParsing\n $response | Select-Object -Property * | ConvertTo-json # We use `Select-Object -Property * ` to get around an odd PowerShell error" => cmd.call('http-windows-remote-head'), + "\n$body = \n $Body = $body | ConvertFrom-Json\n #convert to hashtable\n $HashTable = @{}\n foreach ($property in $Body.PSObject.Properties) {\n $HashTable[$property.Name] = $property.Value\n }\n $response = Invoke-WebRequest -Method GET -TimeoutSec 120 -Headers @{ 'X-Test-Header' = 'test/value'; 'foo' = 'bar'} 'https://www.example.com' -Body $HashTable -UseBasicParsing\n $response | Select-Object -Property * | ConvertTo-json # We use `Select-Object -Property * ` to get around an odd PowerShell error" => cmd.call('http-windows-remote-get-headers'), + "\n$body = '{ \"a\" : \"1\", \"b\" : \"five\" }'\n $Body = $body | ConvertFrom-Json\n #convert to hashtable\n $HashTable = @{}\n foreach ($property in $Body.PSObject.Properties) {\n $HashTable[$property.Name] = $property.Value\n }\n $response = Invoke-WebRequest -Method POST -TimeoutSec 120 'https://www.example.com' -Body $HashTable -UseBasicParsing\n $response | Select-Object -Property * | ConvertTo-json # We use `Select-Object -Property * ` to get around an odd PowerShell error" => cmd.call('http-windows-remote-head'), # elasticsearch resource - "curl -H 'Content-Type: application/json' http://localhost:9200/_nodes" => cmd.call("elasticsearch-cluster-nodes-default"), - "curl -k -H 'Content-Type: application/json' http://localhost:9200/_nodes" => cmd.call("elasticsearch-cluster-no-ssl"), - "curl -H 'Content-Type: application/json' -u es_admin:password http://localhost:9200/_nodes" => cmd.call("elasticsearch-cluster-auth"), - "curl -H 'Content-Type: application/json' http://elasticsearch.mycompany.biz:1234/_nodes" => cmd.call("elasticsearch-cluster-url"), + "curl -H 'Content-Type: application/json' http://localhost:9200/_nodes" => cmd.call('elasticsearch-cluster-nodes-default'), + "curl -k -H 'Content-Type: application/json' http://localhost:9200/_nodes" => cmd.call('elasticsearch-cluster-no-ssl'), + "curl -H 'Content-Type: application/json' -u es_admin:password http://localhost:9200/_nodes" => cmd.call('elasticsearch-cluster-auth'), + "curl -H 'Content-Type: application/json' http://elasticsearch.mycompany.biz:1234/_nodes" => cmd.call('elasticsearch-cluster-url'), # iis_app_pool resource - "Import-Module WebAdministration\nIf (Test-Path 'IIS:\\AppPools\\DefaultAppPool') {\n Get-Item 'IIS:\\AppPools\\DefaultAppPool' | Select-Object * | ConvertTo-Json -Compress\n} Else {\n Write-Host '{}'\n}\n" => cmd.call("iis-default-app-pool"), + "Import-Module WebAdministration\nIf (Test-Path 'IIS:\\AppPools\\DefaultAppPool') {\n Get-Item 'IIS:\\AppPools\\DefaultAppPool' | Select-Object * | ConvertTo-Json -Compress\n} Else {\n Write-Host '{}'\n}\n" => cmd.call('iis-default-app-pool'), # iis_site resource - "Get-Website 'Default Web Site' | Select-Object -Property Name,State,PhysicalPath,bindings,ApplicationPool | ConvertTo-Json" => cmd.call("iis-default-web-site"), + "Get-Website 'Default Web Site' | Select-Object -Property Name,State,PhysicalPath,bindings,ApplicationPool | ConvertTo-Json" => cmd.call('iis-default-web-site'), # security_policy resource calls - "Get-Content win_secpol-abc123.cfg" => cmd.call("secedit-export"), - "secedit /export /cfg win_secpol-abc123.cfg" => cmd.call("success"), - "Remove-Item win_secpol-abc123.cfg" => cmd.call("success"), - "(New-Object System.Security.Principal.SecurityIdentifier(\"S-1-5-32-544\")).Translate( [System.Security.Principal.NTAccount]).Value" => cmd.call("security-policy-sid-translated"), - "(New-Object System.Security.Principal.SecurityIdentifier(\"S-1-5-32-555\")).Translate( [System.Security.Principal.NTAccount]).Value" => cmd.call("security-policy-sid-untranslated"), + 'Get-Content win_secpol-abc123.cfg' => cmd.call('secedit-export'), + 'secedit /export /cfg win_secpol-abc123.cfg' => cmd.call('success'), + 'Remove-Item win_secpol-abc123.cfg' => cmd.call('success'), + '(New-Object System.Security.Principal.SecurityIdentifier("S-1-5-32-544")).Translate( [System.Security.Principal.NTAccount]).Value' => cmd.call('security-policy-sid-translated'), + '(New-Object System.Security.Principal.SecurityIdentifier("S-1-5-32-555")).Translate( [System.Security.Principal.NTAccount]).Value' => cmd.call('security-policy-sid-untranslated'), # Windows SID calls with CimInstance - "Get-CimInstance -ClassName Win32_Account | Select-Object -Property Domain, Name, SID, SIDType | Where-Object { $_.Name -eq 'Alice' -and $_.SIDType -eq 1 } | ConvertTo-Csv -NoTypeInformation" => cmd.call("security-identifier-alice"), - "Get-CimInstance -ClassName Win32_Account | Select-Object -Property Domain, Name, SID, SIDType | Where-Object { $_.Name -eq 'Bob' -and $_.SIDType -eq 1 } | ConvertTo-Csv -NoTypeInformation" => cmd.call("security-identifier-unknown"), - "Get-CimInstance -ClassName Win32_Account | Select-Object -Property Domain, Name, SID, SIDType | Where-Object { $_.Name -eq 'DontExist' -and $_.SIDType -eq 1 } | ConvertTo-Csv -NoTypeInformation" => cmd.call("security-identifier-unknown"), - "Get-CimInstance -ClassName Win32_Account | Select-Object -Property Domain, Name, SID | Where-Object { $_.Name -eq 'Guests' -and { $_.SIDType -eq 4 -or $_.SIDType -eq 5 } } | ConvertTo-Csv -NoTypeInformation" => cmd.call("security-identifier-guests"), - "Get-CimInstance -ClassName Win32_Account | Select-Object -Property Domain, Name, SID | Where-Object { $_.Name -eq 'DontExist' -and { $_.SIDType -eq 4 -or $_.SIDType -eq 5 } } | ConvertTo-Csv -NoTypeInformation" => cmd.call("security-identifier-unknown"), + "Get-CimInstance -ClassName Win32_Account | Select-Object -Property Domain, Name, SID, SIDType | Where-Object { $_.Name -eq 'Alice' -and $_.SIDType -eq 1 } | ConvertTo-Csv -NoTypeInformation" => cmd.call('security-identifier-alice'), + "Get-CimInstance -ClassName Win32_Account | Select-Object -Property Domain, Name, SID, SIDType | Where-Object { $_.Name -eq 'Bob' -and $_.SIDType -eq 1 } | ConvertTo-Csv -NoTypeInformation" => cmd.call('security-identifier-unknown'), + "Get-CimInstance -ClassName Win32_Account | Select-Object -Property Domain, Name, SID, SIDType | Where-Object { $_.Name -eq 'DontExist' -and $_.SIDType -eq 1 } | ConvertTo-Csv -NoTypeInformation" => cmd.call('security-identifier-unknown'), + "Get-CimInstance -ClassName Win32_Account | Select-Object -Property Domain, Name, SID | Where-Object { $_.Name -eq 'Guests' -and { $_.SIDType -eq 4 -or $_.SIDType -eq 5 } } | ConvertTo-Csv -NoTypeInformation" => cmd.call('security-identifier-guests'), + "Get-CimInstance -ClassName Win32_Account | Select-Object -Property Domain, Name, SID | Where-Object { $_.Name -eq 'DontExist' -and { $_.SIDType -eq 4 -or $_.SIDType -eq 5 } } | ConvertTo-Csv -NoTypeInformation" => cmd.call('security-identifier-unknown'), # alpine package commands - "apk info -vv --no-network | grep git" => cmd.call("apk-info-grep-git"), - "apk list --no-network --installed" => cmd.call("apk-info"), - "apk info git" => cmd.call("apk-info-cmd"), + 'apk info -vv --no-network | grep git' => cmd.call('apk-info-grep-git'), + 'apk list --no-network --installed' => cmd.call('apk-info'), + 'apk info git' => cmd.call('apk-info-cmd'), # filesystem command - "2e7e0d4546342cee799748ec7e2b1c87ca00afbe590fa422a7c27371eefa88f0" => cmd.call("get-wmiobject-filesystem"), - "/usr/sbin/sestatus" => cmd.call("sestatus"), - "sestatus" => cmd.call("sestatus"), - "semodule -lfull" => cmd.call("semodule-lfull"), - "semanage boolean -l -n" => cmd.call("semanage-boolean"), - "Get-ChildItem -Path \"C:\\Program Files\\MongoDB\\Server\" -Name" => cmd.call("mongodb-version"), - "opa eval -i 'input.json' -d 'example.rego' 'data.example.allow'" => cmd.call("opa-result"), - "opa eval -i 'input.json' -d 'example.rego' 'data.example.voilation'" => cmd.call("opa-empty-result"), - "curl -X POST localhost:8181/v1/data/example/violation -d @v1-data-input.json -H 'Content-Type: application/json'" => cmd.call("opa-api-result"), - "curl -X POST localhost:8181/v1/data/example/violation -d @v1-data-input1.json -H 'Content-Type: application/json'" => cmd.call("opa-api-empty-result"), + '2e7e0d4546342cee799748ec7e2b1c87ca00afbe590fa422a7c27371eefa88f0' => cmd.call('get-wmiobject-filesystem'), + '/usr/sbin/sestatus' => cmd.call('sestatus'), + 'sestatus' => cmd.call('sestatus'), + 'semodule -lfull' => cmd.call('semodule-lfull'), + 'semanage boolean -l -n' => cmd.call('semanage-boolean'), + 'Get-ChildItem -Path "C:\\Program Files\\MongoDB\\Server" -Name' => cmd.call('mongodb-version'), + "opa eval -i 'input.json' -d 'example.rego' 'data.example.allow'" => cmd.call('opa-result'), + "opa eval -i 'input.json' -d 'example.rego' 'data.example.voilation'" => cmd.call('opa-empty-result'), + "curl -X POST localhost:8181/v1/data/example/violation -d @v1-data-input.json -H 'Content-Type: application/json'" => cmd.call('opa-api-result'), + "curl -X POST localhost:8181/v1/data/example/violation -d @v1-data-input1.json -H 'Content-Type: application/json'" => cmd.call('opa-api-empty-result'), # ibmdb2 - "/opt/ibm/db2/V11.5/bin/db2 attach to db2inst1; /opt/ibm/db2/V11.5/bin/db2 get database manager configuration" => cmd.call("ibmdb2_conf_output"), - "/opt/ibm/db2/V11.5/bin/db2 attach to db2inst1; /opt/ibm/db2/V11.5/bin/db2 connect to sample; /opt/ibm/db2/V11.5/bin/db2 select rolename from syscat.roleauth;" => cmd.call("ibmdb2_query_output"), - "set-item -path env:DB2CLP -value \"**$$**\"; db2 get database manager configuration" => cmd.call("ibmdb2_conf_output"), - "set-item -path env:DB2CLP -value \"**$$**\"; db2 connect to sample; db2 \"select rolename from syscat.roleauth\";" => cmd.call("ibmdb2_query_output"), + '/opt/ibm/db2/V11.5/bin/db2 attach to db2inst1; /opt/ibm/db2/V11.5/bin/db2 get database manager configuration' => cmd.call('ibmdb2_conf_output'), + '/opt/ibm/db2/V11.5/bin/db2 attach to db2inst1; /opt/ibm/db2/V11.5/bin/db2 connect to sample; /opt/ibm/db2/V11.5/bin/db2 select rolename from syscat.roleauth;' => cmd.call('ibmdb2_query_output'), + 'set-item -path env:DB2CLP -value "**$$**"; db2 get database manager configuration' => cmd.call('ibmdb2_conf_output'), + 'set-item -path env:DB2CLP -value "**$$**"; db2 connect to sample; db2 "select rolename from syscat.roleauth";' => cmd.call('ibmdb2_query_output'), # file resource windows inherit - "(Get-Acl 'C:/ExamlpeFolder').access| Where-Object {$_.IsInherited -eq $true} | measure | % { $_.Count }" => cmd.call("windows_file_inherit_output"), + "(Get-Acl 'C:/ExamlpeFolder').access| Where-Object {$_.IsInherited -eq $true} | measure | % { $_.Count }" => cmd.call('windows_file_inherit_output'), # podman - %{podman ps -a --no-trunc --size --format '{\"ID\": {{json .ID}}, \"Image\": {{json .Image}}, \"ImageID\": {{json .ImageID}}, \"Command\": {{json .Command}}, \"CreatedAt\": {{json .CreatedAt}}, \"RunningFor\": {{json .RunningFor}}, \"Status\": {{json .Status}}, \"Pod\": {{json .Pod}}, \"Ports\": {{json .Ports}}, \"Size\": {{json .Size}}, \"Names\": {{json .Names}}, \"Networks\": {{json .Networks}}, \"Labels\": {{json .Labels}}, \"Mounts\": {{json .Mounts}}}'} => cmd.call("podman-ps-a"), - %{podman images -a --no-trunc --format '{\"ID\": {{json .ID}}, \"Repository\": {{json .Repository}}, \"Tag\": {{json .Tag}}, \"Size\": {{json .Size}}, \"Digest\": {{json .Digest}}, \"CreatedAt\": {{json .CreatedAt}}, \"CreatedSince\": {{json .CreatedSince}}, \"History\": {{json .History}}}'} => cmd.call("podman-images-a"), - %{podman network ls --no-trunc --format '{\"ID\": {{json .ID}}, \"Name\": {{json .Name}}, \"Driver\": {{json .Driver}}, \"Labels\": {{json .Labels}}, \"Options\": {{json .Options}}, \"IPAMOptions\": {{json .IPAMOptions}}, \"Created\": {{json .Created}}, \"Internal\": {{json .Internal}}, \"IPv6Enabled\": {{json .IPv6Enabled}}, \"DNSEnabled\": {{json .DNSEnabled}}, \"NetworkInterface\": {{json .NetworkInterface}}, \"Subnets\": {{json .Subnets}}}'} => cmd.call("podman-network-ls"), - "podman pod ps --no-trunc --format json" => cmd.call("podman-pod-ps"), - "podman info --format json" => cmd.call("podman-info"), - "podman version --format json" => cmd.call("podman-version"), - "podman volume ls --format json" => cmd.call("podman-volume-ls"), - "podman inspect 591270d8d80d --format json" => cmd.call("podman-inspec"), - "podman image inspect docker.io/library/busybox:latest --format '{\"id\": {{json .ID}}, \"repo_tags\": {{json .RepoTags}}, \"size\": {{json .Size}}, \"digest\": {{json .Digest}}, \"created_at\": {{json .Created}}, \"version\": {{json .Version}}, \"names_history\": {{json .NamesHistory}}, \"repo_digests\": {{json .RepoDigests}}, \"architecture\": {{json .Architecture}}, \"os\": {{json .Os}}, \"virtual_size\": {{json .VirtualSize}}}'" => cmd.call("podman-inspect-info"), - "podman image inspect not-exist:latest --format '{\"id\": {{json .ID}}, \"repo_tags\": {{json .RepoTags}}, \"size\": {{json .Size}}, \"digest\": {{json .Digest}}, \"created_at\": {{json .Created}}, \"version\": {{json .Version}}, \"names_history\": {{json .NamesHistory}}, \"repo_digests\": {{json .RepoDigests}}, \"architecture\": {{json .Architecture}}, \"os\": {{json .Os}}, \"virtual_size\": {{json .VirtualSize}}}'" => cmd_stderr.call("podman-errors"), - "podman network inspect minikube --format '{\"id\": {{json .ID}}, \"name\": {{json .Name}}, \"driver\": {{json .Driver}}, \"labels\": {{json .Labels}}, \"options\": {{json .Options}}, \"ipam_options\": {{json .IPAMOptions}}, \"internal\": {{json .Internal}}, \"created\": {{json .Created}}, \"ipv6_enabled\": {{json .IPv6Enabled}}, \"dns_enabled\": {{json .DNSEnabled}}, \"network_interface\": {{json .NetworkInterface}}, \"subnets\": {{json .Subnets}}}'" => cmd.call("podman-network"), - "podman network inspect not-exist --format '{\"id\": {{json .ID}}, \"name\": {{json .Name}}, \"driver\": {{json .Driver}}, \"labels\": {{json .Labels}}, \"options\": {{json .Options}}, \"ipam_options\": {{json .IPAMOptions}}, \"internal\": {{json .Internal}}, \"created\": {{json .Created}}, \"ipv6_enabled\": {{json .IPv6Enabled}}, \"dns_enabled\": {{json .DNSEnabled}}, \"network_interface\": {{json .NetworkInterface}}, \"subnets\": {{json .Subnets}}}'" => cmd_stderr.call("podman-errors"), - "podman version" => empty.call, - "podman volume inspect my_volume --format '{\"name\": {{json .Name}}, \"driver\": {{json .Driver}}, \"mountpoint\": {{json .Mountpoint}}, \"created_at\": {{json .CreatedAt}}, \"labels\": {{json .Labels}}, \"scope\": {{json .Scope}}, \"options\": {{json .Options}}, \"mount_count\": {{json .MountCount}}, \"needs_copy_up\": {{json .NeedsCopyUp}}, \"needs_chown\": {{json .NeedsChown}}}'" => cmd.call("podman-volume-inspect"), - "podman volume inspect non_existing_volume --format '{\"name\": {{json .Name}}, \"driver\": {{json .Driver}}, \"mountpoint\": {{json .Mountpoint}}, \"created_at\": {{json .CreatedAt}}, \"labels\": {{json .Labels}}, \"scope\": {{json .Scope}}, \"options\": {{json .Options}}, \"mount_count\": {{json .MountCount}}, \"needs_copy_up\": {{json .NeedsCopyUp}}, \"needs_chown\": {{json .NeedsChown}}}'" => cmd_stderr.call("podman-errors"), - "podman pod inspect nginx-frontend --format '{\"id\": {{json .ID}}, \"name\": {{json .Name}}, \"created_at\": {{json .Created}}, \"create_command\": {{json .CreateCommand}}, \"state\": {{json .State}}, \"hostname\": {{json .Hostname}}, \"create_cgroup\": {{json .CreateCgroup}}, \"cgroup_parent\": {{json .CgroupParent}}, \"cgroup_path\": {{json .CgroupPath}}, \"create_infra\": {{json .CreateInfra}}, \"infra_container_id\": {{json .InfraContainerID}}, \"infra_config\": {{json .InfraConfig}}, \"shared_namespaces\": {{json .SharedNamespaces}}, \"num_containers\": {{json .NumContainers}}, \"containers\": {{json .Containers}}}'" => cmd.call("podman-pod-inspect"), - "podman pod inspect non_existing_pod --format '{\"id\": {{json .ID}}, \"name\": {{json .Name}}, \"created_at\": {{json .Created}}, \"create_command\": {{json .CreateCommand}}, \"state\": {{json .State}}, \"hostname\": {{json .Hostname}}, \"create_cgroup\": {{json .CreateCgroup}}, \"cgroup_parent\": {{json .CgroupParent}}, \"cgroup_path\": {{json .CgroupPath}}, \"create_infra\": {{json .CreateInfra}}, \"infra_container_id\": {{json .InfraContainerID}}, \"infra_config\": {{json .InfraConfig}}, \"shared_namespaces\": {{json .SharedNamespaces}}, \"num_containers\": {{json .NumContainers}}, \"containers\": {{json .Containers}}}'" => cmd_stderr.call("podman-errors"), + %(podman ps -a --no-trunc --size --format '{\"ID\": {{json .ID}}, \"Image\": {{json .Image}}, \"ImageID\": {{json .ImageID}}, \"Command\": {{json .Command}}, \"CreatedAt\": {{json .CreatedAt}}, \"RunningFor\": {{json .RunningFor}}, \"Status\": {{json .Status}}, \"Pod\": {{json .Pod}}, \"Ports\": {{json .Ports}}, \"Size\": {{json .Size}}, \"Names\": {{json .Names}}, \"Networks\": {{json .Networks}}, \"Labels\": {{json .Labels}}, \"Mounts\": {{json .Mounts}}}') => cmd.call('podman-ps-a'), + %(podman images -a --no-trunc --format '{\"ID\": {{json .ID}}, \"Repository\": {{json .Repository}}, \"Tag\": {{json .Tag}}, \"Size\": {{json .Size}}, \"Digest\": {{json .Digest}}, \"CreatedAt\": {{json .CreatedAt}}, \"CreatedSince\": {{json .CreatedSince}}, \"History\": {{json .History}}}') => cmd.call('podman-images-a'), + %(podman network ls --no-trunc --format '{\"ID\": {{json .ID}}, \"Name\": {{json .Name}}, \"Driver\": {{json .Driver}}, \"Labels\": {{json .Labels}}, \"Options\": {{json .Options}}, \"IPAMOptions\": {{json .IPAMOptions}}, \"Created\": {{json .Created}}, \"Internal\": {{json .Internal}}, \"IPv6Enabled\": {{json .IPv6Enabled}}, \"DNSEnabled\": {{json .DNSEnabled}}, \"NetworkInterface\": {{json .NetworkInterface}}, \"Subnets\": {{json .Subnets}}}') => cmd.call('podman-network-ls'), + 'podman pod ps --no-trunc --format json' => cmd.call('podman-pod-ps'), + 'podman info --format json' => cmd.call('podman-info'), + 'podman version --format json' => cmd.call('podman-version'), + 'podman volume ls --format json' => cmd.call('podman-volume-ls'), + 'podman inspect 591270d8d80d --format json' => cmd.call('podman-inspec'), + "podman image inspect docker.io/library/busybox:latest --format '{\"id\": {{json .ID}}, \"repo_tags\": {{json .RepoTags}}, \"size\": {{json .Size}}, \"digest\": {{json .Digest}}, \"created_at\": {{json .Created}}, \"version\": {{json .Version}}, \"names_history\": {{json .NamesHistory}}, \"repo_digests\": {{json .RepoDigests}}, \"architecture\": {{json .Architecture}}, \"os\": {{json .Os}}, \"virtual_size\": {{json .VirtualSize}}}'" => cmd.call('podman-inspect-info'), + "podman image inspect not-exist:latest --format '{\"id\": {{json .ID}}, \"repo_tags\": {{json .RepoTags}}, \"size\": {{json .Size}}, \"digest\": {{json .Digest}}, \"created_at\": {{json .Created}}, \"version\": {{json .Version}}, \"names_history\": {{json .NamesHistory}}, \"repo_digests\": {{json .RepoDigests}}, \"architecture\": {{json .Architecture}}, \"os\": {{json .Os}}, \"virtual_size\": {{json .VirtualSize}}}'" => cmd_stderr.call('podman-errors'), + "podman network inspect minikube --format '{\"id\": {{json .ID}}, \"name\": {{json .Name}}, \"driver\": {{json .Driver}}, \"labels\": {{json .Labels}}, \"options\": {{json .Options}}, \"ipam_options\": {{json .IPAMOptions}}, \"internal\": {{json .Internal}}, \"created\": {{json .Created}}, \"ipv6_enabled\": {{json .IPv6Enabled}}, \"dns_enabled\": {{json .DNSEnabled}}, \"network_interface\": {{json .NetworkInterface}}, \"subnets\": {{json .Subnets}}}'" => cmd.call('podman-network'), + "podman network inspect not-exist --format '{\"id\": {{json .ID}}, \"name\": {{json .Name}}, \"driver\": {{json .Driver}}, \"labels\": {{json .Labels}}, \"options\": {{json .Options}}, \"ipam_options\": {{json .IPAMOptions}}, \"internal\": {{json .Internal}}, \"created\": {{json .Created}}, \"ipv6_enabled\": {{json .IPv6Enabled}}, \"dns_enabled\": {{json .DNSEnabled}}, \"network_interface\": {{json .NetworkInterface}}, \"subnets\": {{json .Subnets}}}'" => cmd_stderr.call('podman-errors'), + 'podman version' => empty.call, + "podman volume inspect my_volume --format '{\"name\": {{json .Name}}, \"driver\": {{json .Driver}}, \"mountpoint\": {{json .Mountpoint}}, \"created_at\": {{json .CreatedAt}}, \"labels\": {{json .Labels}}, \"scope\": {{json .Scope}}, \"options\": {{json .Options}}, \"mount_count\": {{json .MountCount}}, \"needs_copy_up\": {{json .NeedsCopyUp}}, \"needs_chown\": {{json .NeedsChown}}}'" => cmd.call('podman-volume-inspect'), + "podman volume inspect non_existing_volume --format '{\"name\": {{json .Name}}, \"driver\": {{json .Driver}}, \"mountpoint\": {{json .Mountpoint}}, \"created_at\": {{json .CreatedAt}}, \"labels\": {{json .Labels}}, \"scope\": {{json .Scope}}, \"options\": {{json .Options}}, \"mount_count\": {{json .MountCount}}, \"needs_copy_up\": {{json .NeedsCopyUp}}, \"needs_chown\": {{json .NeedsChown}}}'" => cmd_stderr.call('podman-errors'), + "podman pod inspect nginx-frontend --format '{\"id\": {{json .ID}}, \"name\": {{json .Name}}, \"created_at\": {{json .Created}}, \"create_command\": {{json .CreateCommand}}, \"state\": {{json .State}}, \"hostname\": {{json .Hostname}}, \"create_cgroup\": {{json .CreateCgroup}}, \"cgroup_parent\": {{json .CgroupParent}}, \"cgroup_path\": {{json .CgroupPath}}, \"create_infra\": {{json .CreateInfra}}, \"infra_container_id\": {{json .InfraContainerID}}, \"infra_config\": {{json .InfraConfig}}, \"shared_namespaces\": {{json .SharedNamespaces}}, \"num_containers\": {{json .NumContainers}}, \"containers\": {{json .Containers}}}'" => cmd.call('podman-pod-inspect'), + "podman pod inspect non_existing_pod --format '{\"id\": {{json .ID}}, \"name\": {{json .Name}}, \"created_at\": {{json .Created}}, \"create_command\": {{json .CreateCommand}}, \"state\": {{json .State}}, \"hostname\": {{json .Hostname}}, \"create_cgroup\": {{json .CreateCgroup}}, \"cgroup_parent\": {{json .CgroupParent}}, \"cgroup_path\": {{json .CgroupPath}}, \"create_infra\": {{json .CreateInfra}}, \"infra_container_id\": {{json .InfraContainerID}}, \"infra_config\": {{json .InfraConfig}}, \"shared_namespaces\": {{json .SharedNamespaces}}, \"num_containers\": {{json .NumContainers}}, \"containers\": {{json .Containers}}}'" => cmd_stderr.call('podman-errors') } - if @platform && (@platform[:name] == "windows" || @platform[:name] == "freebsd") + if @platform && (@platform[:name] == 'windows' || @platform[:name] == 'freebsd') mock_cmds.merge!( - "sestatus" => empty.call, - "semodule -lfull" => empty.call, - "semanage boolean -l -n" => empty.call + 'sestatus' => empty.call, + 'semodule -lfull' => empty.call, + 'semanage boolean -l -n' => empty.call ) end # ports on linux # allow the ss and/or netstat commands to exist so the later mock is called - if @platform && @platform[:name] == "alpine" + if @platform && @platform[:name] == 'alpine' mock_cmds.merge!( - "ps --help" => cmd_stderr.call("ps-help-busybox"), - %{sh -c 'type "netstat"'} => cmd_exit_1.call, - %{sh -c 'type "ss"'} => cmd_exit_1.call, - %{which "ss"} => cmd_exit_1.call, - %{which "netstat"} => empty.call, - "netstat -tulpen" => cmd.call("netstat-tulpen-busybox") + 'ps --help' => cmd_stderr.call('ps-help-busybox'), + %(sh -c 'type "netstat"') => cmd_exit_1.call, + %(sh -c 'type "ss"') => cmd_exit_1.call, + %(which "ss") => cmd_exit_1.call, + %(which "netstat") => empty.call, + 'netstat -tulpen' => cmd.call('netstat-tulpen-busybox') ) else mock_cmds.merge!( - "ps --help" => empty.call, - %{sh -c 'type "ss"'} => empty.call, - %{sh -c 'type "netstat"'} => empty.call, - "ss -tulpen" => cmd.call("ss-tulpen"), - "ss -tulpen '( dport = 22 or sport = 22 )'" => cmd.call("ss-tulpen"), - "ss -tulpen '( dport = 68 or sport = 68 )'" => cmd.call("ss-tulpen"), - "ss -tulpen '( dport = 9200 or sport = 9200 )'" => cmd.call("ss-tulpen"), - "ss -tulpen '( dport = 80 or sport = 80 )'" => cmd.call("ss-tulpen"), - "netstat -tulpen" => cmd.call("netstat-tulpen") + 'ps --help' => empty.call, + %(sh -c 'type "ss"') => empty.call, + %(sh -c 'type "netstat"') => empty.call, + 'ss -tulpen' => cmd.call('ss-tulpen'), + "ss -tulpen '( dport = 22 or sport = 22 )'" => cmd.call('ss-tulpen'), + "ss -tulpen '( dport = 68 or sport = 68 )'" => cmd.call('ss-tulpen'), + "ss -tulpen '( dport = 9200 or sport = 9200 )'" => cmd.call('ss-tulpen'), + "ss -tulpen '( dport = 80 or sport = 80 )'" => cmd.call('ss-tulpen'), + 'netstat -tulpen' => cmd.call('netstat-tulpen') ) end # zfs dynamic commands - if @platform && %w{centos debian ubuntu amazon}.include?(@platform[:name]) + if @platform && %w[centos debian ubuntu amazon].include?(@platform[:name]) mock_cmds.merge!( # zfs output for dataset tank/tmp - %{`which zfs` get -Hp all tank/tmp} => cmd.call("zfs-get-all-tank-tmp"), + %(`which zfs` get -Hp all tank/tmp) => cmd.call('zfs-get-all-tank-tmp'), # zfs output for pool tank - %{`which zpool` get -Hp all tank} => cmd.call("zpool-get-all-tank") + %(`which zpool` get -Hp all tank) => cmd.call('zpool-get-all-tank') ) end - if @platform && ! %w{centos cloudlinux coreos debian freebsd ubuntu amazon}.include?(@platform[:name]) - mock_cmds.delete("/sbin/zfs get -Hp all tank/tmp") - mock_cmds.delete("/sbin/zpool get -Hp all tank") - mock_cmds.delete("which zfs") - mock_cmds.delete("which zpool") + if @platform && !%w[centos cloudlinux coreos debian freebsd ubuntu amazon].include?(@platform[:name]) + mock_cmds.delete('/sbin/zfs get -Hp all tank/tmp') + mock_cmds.delete('/sbin/zpool get -Hp all tank') + mock_cmds.delete('which zfs') + mock_cmds.delete('which zpool') end - if @platform && (@platform[:name] == "freebsd" && @platform[:release].to_f >= 10) + if @platform && (@platform[:name] == 'freebsd' && @platform[:release].to_f >= 10) mock_cmds.merge!( - "service sendmail enabled" => cmd.call("service-sendmail-enabled") + 'service sendmail enabled' => cmd.call('service-sendmail-enabled') ) end @@ -785,27 +792,30 @@ def md.directory? end # loads a resource class and instantiates the class with the given arguments - def load_resource(resource, *args) + def load_resource(res, *args) + # If a platform override is passed, set @platform accordingly + @platform = OPERATING_SYSTEMS[ args[0][:os] ] || @platform if args[0].is_a?(Hash) && args[0][:os] + # initialize resource with backend and parameters - @resource_class = Inspec::Resource.registry[resource] - raise ArgumentError, "No resource #{resource}" unless @resource_class + @resource_class = Inspec::Resource.registry[res] + raise ArgumentError, "No resource #{res}" unless @resource_class - @resource = @resource_class.new(backend, resource, *args) + @resource = @resource_class.new(backend, res, *args) end def self.mock_os(resource, name) osinfo = OPERATING_SYSTEMS[name] || - raise("Can't find operating system to mock: #{name}") + raise("Can't find operating system to mock: #{name}") resource.inspec.backend.mock_os(osinfo) end def self.mock_command(resource, cmd, res = {}) resource.inspec.backend - .mock_command(cmd, res[:stdout], res[:stderr], res[:exit_status]) + .mock_command(cmd, res[:stdout], res[:stderr], res[:exit_status]) end def self.home # "home" of the repo (not test!)... I really dislike this name - File.expand_path "../..", __dir__ + File.expand_path '../..', __dir__ end def self.profile_path(name) @@ -816,36 +826,36 @@ def self.profile_path(name) end def self.load_profile(name, opts = {}) - require "inspec/profile" + require 'inspec/profile' opts[:test_collector] = Inspec::RunnerMock.new opts[:backend] = Inspec::Backend.create(Inspec::Config.mock(opts)) Inspec::Profile.for_target(profile_path(name), opts) end def self.profile_tgz(name) - path = File.join(home, "test", "fixtures", "profiles", name) # TODO: refactor these paths + path = File.join(home, 'test', 'fixtures', 'profiles', name) # TODO: refactor these paths dst = File.join(Dir.mktmpdir, "#{name}.tar.gz") # generate relative paths files = Dir.glob("#{path}/**/*") relatives = files.map { |e| Pathname.new(e).relative_path_from(Pathname.new(path)).to_s } - require "inspec/archive/tar" + require 'inspec/archive/tar' tag = Inspec::Archive::TarArchiveGenerator.new tag.archive(path, relatives, dst) dst end - def self.profile_zip(name, opts = {}) - path = File.join(home, "test", "fixtures", "profiles", name) + def self.profile_zip(name, _opts = {}) + path = File.join(home, 'test', 'fixtures', 'profiles', name) dst = File.join(Dir.mktmpdir, "#{name}.zip") # rubyzip only works relative paths files = Dir.glob("#{path}/**/*") relatives = files.map { |e| Pathname.new(e).relative_path_from(Pathname.new(path)).to_s } - require "inspec/archive/zip" + require 'inspec/archive/zip' zag = Inspec::Archive::ZipArchiveGenerator.new zag.archive(path, relatives, dst) diff --git a/test/unit/matchers/matchers_test.rb b/test/unit/matchers/matchers_test.rb index f584ccae15..464e18b588 100644 --- a/test/unit/matchers/matchers_test.rb +++ b/test/unit/matchers/matchers_test.rb @@ -1,12 +1,12 @@ -require "minitest/autorun" -require "rspec/matchers" -require "rspec/expectations" -require "matchers/matchers" - -require "pry" - -describe "inspec matchers" do - describe "cmp matcher" do +require 'minitest/autorun' +require 'rspec/matchers' +require 'rspec/expectations' +require 'matchers/matchers' +require 'pry' +require_relative '../../helpers/mock_loader' # Ensure MockLoader is required + +describe 'inspec matchers' do + describe 'cmp matcher' do include RSpec::Matchers ## @@ -51,104 +51,143 @@ def refute_cmp(expect, actual) end end - it "String cmp String" do - assert_cmp "happy", "happy" - assert_cmp "HAPPY", "happy" # case insensitive - refute_cmp "happy", "unhappy" - refute_cmp "happy", nil - end + # Explicitly mark which tests are meant to be skipped + describe 'test execution' do + # Enable verbose test names in output + def self.test_order + :alpha + end - it "String cmp String w/o ==" do - # String, String, op!==, normal op call? - skip "TODO: how to test w/ other ops?" - end + before do + @known_skips = ['test_0002_String cmp String w/o ==', 'test_0016_should test XXX'] + end - it "String cmp String w/ versions " do - assert_cmp "1.0", "1.0" - refute_cmp "1.0.0", "1.0" - refute_cmp "1.0", nil - end + it 'String cmp String' do + assert_cmp 'happy', 'happy' + assert_cmp 'HAPPY', 'happy' # case insensitive + refute_cmp 'happy', 'unhappy' + refute_cmp 'happy', nil + end - it "Regexp cmp String" do - assert_cmp(/abc/, "xxx abc zzz") - refute_cmp(/yyy/, "xxx abc zzz") - refute_cmp(/yyy/, nil) - end + it 'String cmp String w/o ==' do + skip 'TODO: how to test w/ other ops?' + end - it "Regexp cmp Int" do - assert_cmp(/42/, 42) - refute_cmp(/yyy/, 42) - refute_cmp(/yyy/, nil) - end + it 'String cmp String w/ versions ' do + assert_cmp '1.0', '1.0' + refute_cmp '1.0.0', '1.0' + refute_cmp '1.0', nil + end - it "String (int) cmp Integer" do - assert_cmp "42", 42 - refute_cmp "42", 420 - refute_cmp "42", nil - end + it 'Regexp cmp String' do + assert_cmp(/abc/, 'xxx abc zzz') + refute_cmp(/yyy/, 'xxx abc zzz') + refute_cmp(/yyy/, nil) + end - it "String (bool) cmp Bool" do - assert_cmp "true", true - assert_cmp "TRUE", true - refute_cmp "true", false - assert_cmp "false", false - assert_cmp "FALSE", false - refute_cmp "false", true - refute_cmp "false", nil - assert_cmp true, "true" - refute_cmp false, "true" - refute_cmp false, nil - end + it 'Regexp cmp Int' do + assert_cmp(/42/, 42) + refute_cmp(/yyy/, 42) + refute_cmp(/yyy/, nil) + end - it "Int cmp String(int)" do - assert_cmp 42, "42" - refute_cmp 420, "42" - refute_cmp 420, nil - end + it 'String (int) cmp Integer' do + assert_cmp '42', 42 + refute_cmp '42', 420 + refute_cmp '42', nil + end - it "Int cmp String(!int)" do - refute_cmp 42, :not_int - refute_cmp 42, nil - end + it 'String (bool) cmp Bool' do + assert_cmp 'true', true + assert_cmp 'TRUE', true + refute_cmp 'true', false + assert_cmp 'false', false + assert_cmp 'FALSE', false + refute_cmp 'false', true + refute_cmp 'false', nil + assert_cmp true, 'true' + refute_cmp false, 'true' + refute_cmp false, nil + end - it "Float cmp Float" do - assert_cmp 3.14159, 3.14159 - refute_cmp 3.14159, 42.0 - refute_cmp 3.14159, nil - end + it 'Int cmp String(int)' do + assert_cmp 42, '42' + refute_cmp 420, '42' + refute_cmp 420, nil + end - it "Float cmp String(float)" do - assert_cmp 3.14159, "3.14159" - refute_cmp 3.14159, "3.1415926" - refute_cmp 3.14159, nil - end + it 'Int cmp String(!int)' do + refute_cmp 42, :not_int + refute_cmp 42, nil + end - it "Float cmp String(!float)" do - refute_cmp 3.14159, :not_float - refute_cmp 3.14159, nil - end + it 'Float cmp Float' do + assert_cmp 3.14159, 3.14159 + refute_cmp 3.14159, 42.0 + refute_cmp 3.14159, nil + end - it "String cmp Symbol" do - assert_cmp "abc", :abc - assert_cmp "abc", :ABC - refute_cmp "abc", nil - end + it 'Float cmp String(float)' do + assert_cmp 3.14159, '3.14159' + refute_cmp 3.14159, '3.1415926' + refute_cmp 3.14159, nil + end + + it 'Float cmp String(!float)' do + refute_cmp 3.14159, :not_float + refute_cmp 3.14159, nil + end + + it 'String cmp Symbol' do + assert_cmp 'symbol', :symbol + refute_cmp 'symbol', :other_symbol + refute_cmp 'symbol', nil + end - it "String(oct) cmp Int" do - assert_cmp "0777", 0777 - refute_cmp "0777", 0777 + 1 - refute_cmp "0999", 0 # bad octal regexp - refute_cmp "0777", nil + it 'String(oct) cmp Int' do + assert_cmp '052', 42 # Octal 52 is decimal 42 + refute_cmp '052', 43 + refute_cmp '052', nil + end + + it 'String(!oct) cmp Int' do + refute_cmp 'not_oct', 42 + refute_cmp 'not_oct', nil + end + + it 'should test XXX' do + skip 'TODO: Implement XXX tests' + end + + it 'version comparison with segments' do + assert_cmp '1.2.3', '1.2.3' + refute_cmp '1.2.3', '1.2.4' + end + + it 'version comparison with loose matching' do + assert_cmp '1.2.*', '1.2.3' + refute_cmp '1.3.*', '1.2.3' + end + + it 'version comparison failure cases' do + refute_cmp '1.a.3', '1.2.3' + refute_cmp '1.2.3', '1.2.a' + end end + end - it "String(!oct) cmp Int" do - obj = Object.new - refute_cmp obj, 0x42 - refute_cmp obj, nil + describe 'Custom Matchers' do + let(:ubuntu_resource) { MockLoader.new(:ubuntu).load_resource('platform') } + let(:windows_resource) { MockLoader.new(:windows_server_2016_datacenter).load_resource('platform') } + + it 'checks if ubuntu is readable' do + _(ubuntu_resource).must_be :readable? end - it "should test XXX" do - skip "TODO?" + it 'checks if windows is writable' do + _(windows_resource).must_be :writable? end + + # ...additional matcher tests... end end diff --git a/test/unit/resources/os_test.rb b/test/unit/resources/os_test.rb index 055f3e5616..6913099630 100644 --- a/test/unit/resources/os_test.rb +++ b/test/unit/resources/os_test.rb @@ -2,8 +2,14 @@ require "inspec/resource" require "inspec/resources/os" +# rubocop:disable Metrics/BlockLength describe "Inspec::Resources::Os" do + before do + Inspec::Resources::PlatformResource.reset_shared_platform + end + it "verify os parsing on CentOS" do + Inspec::Resources::PlatformResource.reset_shared_platform resource = MockLoader.new(:centos7).load_resource("os") _(resource.resource_id).must_equal "centos" _(resource.name).must_equal "centos" @@ -13,6 +19,7 @@ end it "read env variable on Windows" do + Inspec::Resources::PlatformResource.reset_shared_platform resource = MockLoader.new(:windows).load_resource("os") _(resource.resource_id).must_equal "windows" _(resource.name).must_equal "windows" @@ -22,6 +29,7 @@ end it "verify os parsing on Debian" do + Inspec::Resources::PlatformResource.reset_shared_platform resource = MockLoader.new(:debian8).load_resource("os") _(resource.resource_id).must_equal "debian" _(resource.name).must_equal "debian" @@ -31,6 +39,7 @@ end it "verify os parsing on Ubuntu" do + Inspec::Resources::PlatformResource.reset_shared_platform resource = MockLoader.new(:ubuntu).load_resource("os") _(resource.name).must_equal "ubuntu" _(resource.family).must_equal "debian" @@ -39,6 +48,7 @@ end it "verify os parsing on Mint" do + Inspec::Resources::PlatformResource.reset_shared_platform resource = MockLoader.new(:mint18).load_resource("os") _(resource.name).must_equal "linuxmint" _(resource.family).must_equal "debian" diff --git a/test/unit/resources/platform_test.rb b/test/unit/resources/platform_test.rb index ca1c38bc75..62c62311dc 100644 --- a/test/unit/resources/platform_test.rb +++ b/test/unit/resources/platform_test.rb @@ -1,128 +1,133 @@ -require "helper" -require "inspec/resource" -require "inspec/resources/platform" +require 'helper' +require 'inspec/resource' +require 'inspec/resources/platform' -describe "Inspec::Resources::Platform" do - let(:resource) { MockLoader.new(:ubuntu).load_resource("platform") } +describe 'Inspec::Resources::Platform' do + before do + Inspec::Resources::PlatformResource.reset_shared_platform + end + + let(:resource) { MockLoader.new(:ubuntu).load_resource('platform') } - it "generates the resource_id for the current resource" do - _(resource.resource_id).must_equal "ubuntu" + it 'generates the resource_id for the current resource' do + _(resource.resource_id).must_equal 'ubuntu' end - it "verify platform parsing on Ubuntu" do - _(resource.name).must_equal "ubuntu" - _(resource.family).must_equal "debian" - _(resource.release).must_equal "22.04" - _(resource.arch).must_equal "x86_64" + it 'verify platform parsing on Ubuntu' do + _(resource.name).must_equal 'ubuntu' + _(resource.family).must_equal 'debian' + _(resource.release).must_equal '22.04' + _(resource.arch).must_equal 'x86_64' end - it "verify platform hash parsing on Ubuntu" do - _(resource[:name]).must_equal "ubuntu" - _(resource[:family]).must_equal "debian" - _(resource[:release]).must_equal "22.04" - _(resource[:arch]).must_equal "x86_64" + it 'verify platform hash parsing on Ubuntu' do + _(resource[:name]).must_equal 'ubuntu' + _(resource[:family]).must_equal 'debian' + _(resource[:release]).must_equal '22.04' + _(resource[:arch]).must_equal 'x86_64' end - it "verify platform families" do - expect = %w{debian linux unix os} + it 'verify platform families' do + expect = %w[debian linux unix os] _(resource.families).must_equal expect end - it "verify platform? responds correctly" do - _(resource.platform?("windows")).must_equal false - _(resource.platform?("unix")).must_equal true - _(resource.platform?("ubuntu")).must_equal true - _(resource.platform?("mac_os_x")).must_equal false + it 'verify platform? responds correctly' do + _(resource.platform?('windows')).must_equal false + _(resource.platform?('unix')).must_equal true + _(resource.platform?('ubuntu')).must_equal true + _(resource.platform?('mac_os_x')).must_equal false end - it "verify family? responds correctly" do - _(resource.in_family?("windows")).must_equal false - _(resource.in_family?("unix")).must_equal true - _(resource.in_family?("ubuntu")).must_equal false - _(resource.in_family?("mac_os_x")).must_equal false + it 'verify in_family? responds correctly' do + _(resource.in_family?('windows')).must_equal false + _(resource.in_family?('unix')).must_equal true + _(resource.in_family?('ubuntu')).must_equal false + _(resource.in_family?('mac_os_x')).must_equal false end - it "accept an empty supports collection" do + it 'accept an empty supports collection' do supports = [] _(resource).must_be :supported?, supports end - it "verify supported? with multiple families" do + it 'verify supported? with multiple families' do supports = [ - { os_family: "windows" }, - { os_family: "unix" }, + { os_family: 'windows' }, + { os_family: 'unix' } ] _(resource).must_be :supported?, supports end - it "loads a profile which supports multiple names" do + it 'loads a profile which supports multiple names' do supports = [ - { 'os-family': "windows", 'os-name': "windows_2000" }, - { 'os-family': "unix", 'os-name': "ubuntu" }, + { 'os-family': 'windows', 'os-name': 'windows_2000' }, + { 'os-family': 'unix', 'os-name': 'ubuntu' } ] _(resource).must_be :supported?, supports end - it "reject a profile which supports multiple families" do + it 'reject a profile which supports multiple families' do supports = [ - { os_family: "windows" }, - { os_family: "redhat" }, + { os_family: 'windows' }, + { os_family: 'redhat' } ] _(resource).wont_be :supported?, supports end - it "loads a profile which supports release 22.04" do + it 'loads a profile which supports release 22.04' do supports = [ - { 'os-family': "windows", 'os-name': "windows_2000" }, - { 'os-name': "ubuntu", 'release': "22.04" }, + { 'os-family': 'windows', 'os-name': 'windows_2000' }, + { 'os-name': 'ubuntu', 'release': '22.04' } ] _(resource).must_be :supported?, supports end - it "loads a profile which supports release 22.*" do + it 'loads a profile which supports release 22.*' do supports = [ - { 'os-family': "windows", 'os-name': "windows_2000" }, - { 'os-name': "ubuntu", 'release': "22.*" }, + { 'os-family': 'windows', 'os-name': 'windows_2000' }, + { 'os-name': 'ubuntu', 'release': '22.*' } ] _(resource).must_be :supported?, supports end - it "loads a profile which supports release *.04" do + it 'loads a profile which supports release *.04' do supports = [ - { 'os-family': "windows", 'os-name': "windows_2000" }, - { 'os-name': "ubuntu", 'release': "*.04" }, + { 'os-family': 'windows', 'os-name': 'windows_2000' }, + { 'os-name': 'ubuntu', 'release': '*.04' } ] _(resource).must_be :supported?, supports end - it "reject a profile which supports release 12.*" do + it 'reject a profile which supports release 12.*' do supports = [ - { 'os-family': "windows", 'os-name': "windows_2000" }, - { 'os-name': "ubuntu", 'release': "12.*" }, + { 'os-family': 'windows', 'os-name': 'windows_2000' }, + { 'os-name': 'ubuntu', 'release': '12.*' } ] _(resource).wont_be :supported?, supports end - let(:resource2) { MockLoader.new(:windows2016).load_resource("platform") } - it "loads a profile which supports platform-name windows_server_2016*" do - supports = [ - { 'platform-name': "windows_server_2016*" }, - ] - _(resource2).must_be :supported?, supports - end + # Create a separate windows-specific context + describe 'Windows platform detection' do + before do + Inspec::Resources::PlatformResource.reset_shared_platform + end - it "loads a profile which supports platform-name windows_server_2016*" do - supports = [ - { 'platform-name': "*2016*" }, - ] - _(resource2).must_be :supported?, supports - end + let(:windows_resource) { MockLoader.new(:windows_server_2016_datacenter).load_resource('platform') } - it "reject a profile which supports platform-name not matching regex windows_server_2016*" do - supports = [ - { 'platform-name': "*2019*" }, - ] - _(resource2).wont_be :supported?, supports - end + it 'loads a profile which supports platform-name windows_server_2016*' do + supports = [{ 'platform-name' => 'windows_server_2016*' }] + _(windows_resource).must_be :supported?, supports + end + + it 'loads a profile which supports platform-name *2016*' do + supports = [{ 'platform-name' => '*2016*' }] + _(windows_resource).must_be :supported?, supports + end + it 'reject a profile which supports platform-name not matching regex windows_server_2016*' do + supports = [{ 'platform-name' => '*2019*' }] + _(windows_resource).wont_be :supported?, supports + end + end end