diff --git a/lib/inspec/control_eval_context.rb b/lib/inspec/control_eval_context.rb index 5fe9b60ae..c0fd8fa50 100644 --- a/lib/inspec/control_eval_context.rb +++ b/lib/inspec/control_eval_context.rb @@ -107,7 +107,9 @@ module Inspec end define_method :register_control do |control, &block| - ::Inspec::Rule.set_skip_rule(control, true) if @skip_profile + if @skip_profile || !profile_context_owner.profile_supports_os? + ::Inspec::Rule.set_skip_rule(control, true) + end profile_context_owner.register_rule(control, &block) unless control.nil? end diff --git a/lib/inspec/dependencies/requirement.rb b/lib/inspec/dependencies/requirement.rb index 3cccb34af..379274cbb 100644 --- a/lib/inspec/dependencies/requirement.rb +++ b/lib/inspec/dependencies/requirement.rb @@ -29,7 +29,7 @@ module Inspec req end - attr_reader :name, :cwd, :opts, :required_version + attr_reader :cwd, :opts, :required_version def initialize(name, version_constraints, vendor_index, cwd, opts) @name = name @required_version = Gem::Requirement.new(Array(version_constraints)) @@ -39,6 +39,14 @@ module Inspec @cwd = cwd end + # + # A dependency can be renamed in inspec.yml/inspec.lock. Prefer + # the name the user gave this dependency over the profile name. + # + def name + @name || profile.name + end + def source_version profile.version end diff --git a/lib/inspec/profile.rb b/lib/inspec/profile.rb index 8902a1878..9114b2e93 100644 --- a/lib/inspec/profile.rb +++ b/lib/inspec/profile.rb @@ -51,8 +51,7 @@ module Inspec for_path(resolve_target(target, opts[:cache]), opts.merge(target: target)) end - attr_reader :source_reader - attr_accessor :runner_context + attr_reader :source_reader, :backend, :runner_context def_delegator :@source_reader, :tests def_delegator :@source_reader, :libraries def_delegator :@source_reader, :metadata @@ -81,6 +80,24 @@ module Inspec metadata.params[:version] end + # + # Is this profile is supported on the current platform of the + # backend machine and the current inspec version. + # + # @returns [TrueClass, FalseClass] + # + def supported? + supports_os? && supports_runtime? + end + + def supports_os? + metadata.supports_transport?(@backend) + end + + def supports_runtime? + metadata.supports_runtime? + end + def params @params ||= load_params end diff --git a/lib/inspec/profile_context.rb b/lib/inspec/profile_context.rb index 6d2a62bb0..d711b11a1 100644 --- a/lib/inspec/profile_context.rb +++ b/lib/inspec/profile_context.rb @@ -59,6 +59,12 @@ module Inspec @control_eval_context = nil end + def profile_supports_os? + return true if @conf['profile'].nil? + + @conf['profile'].supports_os? + end + def all_rules ret = @rules.values ret += @subcontexts.map(&:all_rules).flatten diff --git a/lib/inspec/runner.rb b/lib/inspec/runner.rb index 6ce7e98ff..a08d18824 100644 --- a/lib/inspec/runner.rb +++ b/lib/inspec/runner.rb @@ -66,7 +66,6 @@ module Inspec def run(with = nil) Inspec::Log.debug "Starting run with targets: #{@target_profiles.map(&:to_s)}" - Inspec::Log.debug "Backend is #{@backend}" all_controls = [] @target_profiles.each do |profile| @@ -149,17 +148,16 @@ module Inspec end def supports_profile?(profile) - return true if profile.metadata.nil? || @ignore_supports + return true if @ignore_supports - if !profile.metadata.supports_runtime? + if !profile.supports_runtime? fail 'This profile requires InSpec version '\ "#{profile.metadata.inspec_requirement}. You are running "\ "InSpec v#{Inspec::VERSION}.\n" end - if !profile.metadata.supports_transport?(@backend) - os_info = @backend.os[:name].to_s - fail "This OS/platform (#{os_info}) is not supported by this profile." + if !profile.supports_os? + fail "This OS/platform (#{@backend.os[:name]}) is not supported by this profile." end true diff --git a/test/functional/inspec_exec_test.rb b/test/functional/inspec_exec_test.rb index ca3a56359..7d4ddb207 100644 --- a/test/functional/inspec_exec_test.rb +++ b/test/functional/inspec_exec_test.rb @@ -184,4 +184,11 @@ Summary: \e[32m2 successful\e[0m, \e[31m0 failures\e[0m, \e[37m0 skipped\e[0m out.stdout.force_encoding(Encoding::UTF_8).must_include "Summary: \e[32m2 successful\e[0m, \e[31m0 failures\e[0m, \e[37m0 skipped\e[0m\n" end end + + describe 'when a dependency does not support our backend platform' do + it 'skips the controls from that profile' do + out = inspec("exec #{File.join(profile_path, 'profile-support-skip')}") + out.stdout.force_encoding(Encoding::UTF_8).must_include "Summary: \e[32m0 successful\e[0m, \e[31m0 failures\e[0m, \e[37m2 skipped\e[0m\n" + end + end end diff --git a/test/unit/mock/profiles/profile-support-skip/controls/example.rb b/test/unit/mock/profiles/profile-support-skip/controls/example.rb new file mode 100644 index 000000000..4aec8958a --- /dev/null +++ b/test/unit/mock/profiles/profile-support-skip/controls/example.rb @@ -0,0 +1,5 @@ +# encoding: utf-8 +# copyright: 2015, The Authors +# license: All rights reserved + +include_controls 'windows-only' diff --git a/test/unit/mock/profiles/profile-support-skip/inspec.yml b/test/unit/mock/profiles/profile-support-skip/inspec.yml new file mode 100644 index 000000000..0a5c2e7b4 --- /dev/null +++ b/test/unit/mock/profiles/profile-support-skip/inspec.yml @@ -0,0 +1,11 @@ +name: profile-support-skip +title: InSpec Profile +maintainer: The Authors +copyright: The Authors +copyright_email: you@example.com +license: All Rights Reserved +summary: An InSpec Compliance Profile +version: 0.1.0 +depends: + - name: windows-only + path: '../windows-only' diff --git a/test/unit/mock/profiles/windows-only/controls/example.rb b/test/unit/mock/profiles/windows-only/controls/example.rb new file mode 100644 index 000000000..18419cae8 --- /dev/null +++ b/test/unit/mock/profiles/windows-only/controls/example.rb @@ -0,0 +1,17 @@ +# encoding: utf-8 +# copyright: 2015, The Authors +# license: All rights reserved + +control 'dhcp-disabled' do + title 'DHCP is disabled' + describe windows_feature('dhcp') do + it { should be_installed } + end +end + +control 'cdrive' do + title 'Has a C://' + describe file("C://") do + it { should be_directory } + end +end diff --git a/test/unit/mock/profiles/windows-only/inspec.yml b/test/unit/mock/profiles/windows-only/inspec.yml new file mode 100644 index 000000000..6a260f212 --- /dev/null +++ b/test/unit/mock/profiles/windows-only/inspec.yml @@ -0,0 +1,10 @@ +name: windows-only +title: InSpec Profile +maintainer: The Authors +copyright: The Authors +copyright_email: you@example.com +license: All Rights Reserved +summary: An InSpec Compliance Profile +version: 0.1.0 +supports: + - windows