Merge pull request #1321 from chef/ap/check-vendor-cache

inspec check and json to use vendored dependencies
This commit is contained in:
Christoph Hartmann 2016-11-29 23:46:32 +01:00 committed by GitHub
commit 45ef79b098
4 changed files with 69 additions and 10 deletions

View file

@ -8,6 +8,6 @@ summary: InSpec Profile that is only consuming dependencies
version: 0.2.0 version: 0.2.0
depends: depends:
- name: hardening/ssh-hardening # defaults to supermarket - name: hardening/ssh-hardening # defaults to supermarket
- git: https://github.com/dev-sec/ssl-benchmark.git - url: https://github.com/dev-sec/ssl-benchmark
- name: windows-patch-benchmark - name: windows-patch-benchmark
git: https://github.com/chris-rock/windows-patch-benchmark.git url: https://github.com/chris-rock/windows-patch-benchmark

View file

@ -33,6 +33,7 @@ class Inspec::InspecCLI < Inspec::BaseCLI # rubocop:disable Metrics/ClassLength
def json(target) def json(target)
diagnose diagnose
o = opts.dup o = opts.dup
configure_logger(o)
o[:ignore_supports] = true o[:ignore_supports] = true
o[:backend] = Inspec::Backend.create(target: 'mock://') o[:backend] = Inspec::Backend.create(target: 'mock://')
@ -59,7 +60,7 @@ class Inspec::InspecCLI < Inspec::BaseCLI # rubocop:disable Metrics/ClassLength
def check(path) # rubocop:disable Metrics/AbcSize def check(path) # rubocop:disable Metrics/AbcSize
diagnose diagnose
o = opts.dup o = opts.dup
# configure_logger(o) # we do not need a logger for check yet configure_logger(o)
o[:ignore_supports] = true # we check for integrity only o[:ignore_supports] = true # we check for integrity only
o[:backend] = Inspec::Backend.create(target: 'mock://') o[:backend] = Inspec::Backend.create(target: 'mock://')

View file

@ -21,10 +21,9 @@ module Inspec
class Profile # rubocop:disable Metrics/ClassLength class Profile # rubocop:disable Metrics/ClassLength
extend Forwardable extend Forwardable
def self.resolve_target(target, cache = nil) def self.resolve_target(target, cache)
c = cache || Cache.new Inspec::Log.debug "Resolve #{target} into cache #{cache.path}"
Inspec::Log.debug "Resolve #{target} into cache #{c.path}" Inspec::CachedFetcher.new(target, cache)
Inspec::CachedFetcher.new(target, cache || Cache.new)
end end
# Check if the profile contains a vendored cache, move content into global cache # Check if the profile contains a vendored cache, move content into global cache
@ -65,11 +64,13 @@ module Inspec
end end
def self.for_fetcher(fetcher, opts) def self.for_fetcher(fetcher, opts)
opts[:cache] = opts[:cache] || Cache.new
path, writable = fetcher.fetch path, writable = fetcher.fetch
for_path(path, opts.merge(target: fetcher.target, writable: writable)) for_path(path, opts.merge(target: fetcher.target, writable: writable))
end end
def self.for_target(target, opts = {}) def self.for_target(target, opts = {})
opts[:cache] = opts[:cache] || Cache.new
fetcher = resolve_target(target, opts[:cache]) fetcher = resolve_target(target, opts[:cache])
for_fetcher(fetcher, opts) for_fetcher(fetcher, opts)
end end

View file

@ -21,6 +21,10 @@ describe 'example inheritance profile' do
end end
it 'can vendor profile dependencies from the profile path' do it 'can vendor profile dependencies from the profile path' do
# clean existing vendor directory
FileUtils.rm_r ("#{inheritance_path}/vendor")
# vendor all dependencies
out = inspec('vendor --overwrite', "cd #{inheritance_path} &&") out = inspec('vendor --overwrite', "cd #{inheritance_path} &&")
out.stdout.force_encoding(Encoding::UTF_8).must_include "Vendor dependencies of #{inheritance_path} into #{inheritance_path}/vendor" out.stdout.force_encoding(Encoding::UTF_8).must_include "Vendor dependencies of #{inheritance_path} into #{inheritance_path}/vendor"
out.stderr.must_equal '' out.stderr.must_equal ''
@ -34,6 +38,10 @@ describe 'example inheritance profile' do
end end
it 'ensure nothing is loaded from external source if vendored profile is used' do it 'ensure nothing is loaded from external source if vendored profile is used' do
# clean existing vendor directory
FileUtils.rm_r ("#{meta_path}/vendor")
# vendor all dependencies
out = inspec('vendor ' + meta_path + ' --overwrite') out = inspec('vendor ' + meta_path + ' --overwrite')
out.exit_status.must_equal 0 out.exit_status.must_equal 0
@ -44,19 +52,68 @@ describe 'example inheritance profile' do
File.exist?(lockfile).must_equal true File.exist?(lockfile).must_equal true
out = inspec('exec ' + meta_path + ' -l debug --no-create-lockfile') out = inspec('exec ' + meta_path + ' -l debug --no-create-lockfile')
out.stdout.force_encoding(Encoding::UTF_8).must_include 'Using cached dependency for {:url=>"https://github.com/dev-sec/tests-ssh-hardening/archive/master.tar.gz", :sha256=>"01414bd307ea2f7d4dc8cd141085ba7ad61d4c3b2606d57b2dae987c1c3954cb"' out.stdout.force_encoding(Encoding::UTF_8).must_include 'Using cached dependency for {:url=>"https://github.com/dev-sec/tests-ssh-hardening/archive/master.tar.gz"'
out.stdout.force_encoding(Encoding::UTF_8).must_include 'Using cached dependency for {:git=>"https://github.com/dev-sec/ssl-benchmark.git", :ref=>"e17486c864434c818f96ca13edd2c5a420100a45"' out.stdout.force_encoding(Encoding::UTF_8).must_include 'Using cached dependency for {:url=>"https://github.com/dev-sec/ssl-benchmark/archive/master.tar.gz"'
out.stdout.force_encoding(Encoding::UTF_8).must_include 'Using cached dependency for {:git=>"https://github.com/chris-rock/windows-patch-benchmark.git", :ref=>"c183d08eb25638e7f5eac97e521640ea314c8e3d"' out.stdout.force_encoding(Encoding::UTF_8).must_include 'Using cached dependency for {:url=>"https://github.com/chris-rock/windows-patch-benchmark/archive/master.tar.gz"'
out.stdout.force_encoding(Encoding::UTF_8).index('Fetching URL:').must_be_nil out.stdout.force_encoding(Encoding::UTF_8).index('Fetching URL:').must_be_nil
out.stdout.force_encoding(Encoding::UTF_8).index('Fetched archive moved to:').must_be_nil out.stdout.force_encoding(Encoding::UTF_8).index('Fetched archive moved to:').must_be_nil
out.stderr.must_equal '' out.stderr.must_equal ''
end end
it 'ensure json command is not fetching remote profiles if vendored' do
# ensure the profile is vendored
out = inspec('vendor ' + meta_path + ' --overwrite')
# clean cache directory
FileUtils.rm_rf "#{Dir.home}/.inspec/cache"
# execute json command
out = inspec('json ' + meta_path + ' -l debug')
out.exit_status.must_equal 0
copies = out.stdout.scan(/Copy .* to cache directory/).length
copies.must_equal 3
length = out.stdout.scan(/Dependency does not exist in the cache/).length
length.must_equal 1
end
it 'ensure check command is not fetching remote profiles if vendored' do
# ensure the profile is vendored
out = inspec('vendor ' + meta_path + ' --overwrite')
# clean cache directory
FileUtils.rm_rf "#{Dir.home}/.inspec/cache"
# execute check command
out = inspec('check ' + meta_path + ' -l debug')
out.exit_status.must_equal 0
copies = out.stdout.scan(/Copy .* to cache directory/).length
copies.must_equal 3
length = out.stdout.scan(/Dependency does not exist in the cache/).length
length.must_equal 1
end
it 'ensure json command works for vendored profile' do it 'ensure json command works for vendored profile' do
out = inspec('json ' + meta_path + ' --output ' + dst.path) out = inspec('json ' + meta_path + ' --output ' + dst.path)
hm = JSON.load(File.read(dst.path)) hm = JSON.load(File.read(dst.path))
hm['name'].must_equal 'meta-profile' hm['name'].must_equal 'meta-profile'
hm['controls'].length.must_equal 79 hm['controls'].length.must_equal 79
end end
it 'can vendor profile dependencies from the profile path' do
out = inspec('vendor --overwrite', "cd #{inheritance_path} &&")
out.stdout.force_encoding(Encoding::UTF_8).must_include "Vendor dependencies of #{inheritance_path} into #{inheritance_path}/vendor"
out.stderr.must_equal ''
out.exit_status.must_equal 0
vendor_dir = File.join(inheritance_path, 'vendor')
File.exist?(vendor_dir).must_equal true
lockfile = File.join(inheritance_path, 'inspec.lock')
File.exist?(lockfile).must_equal true
end
end end