2016-02-21 01:02:39 +00:00
|
|
|
# encoding: utf-8
|
|
|
|
# author: Dominik Richter
|
|
|
|
# author: Christoph Hartmann
|
|
|
|
|
2017-06-03 00:14:55 +00:00
|
|
|
require 'openssl'
|
|
|
|
|
2016-02-21 01:02:39 +00:00
|
|
|
module Fetchers
|
|
|
|
class Local < Inspec.fetcher(1)
|
|
|
|
name 'local'
|
|
|
|
priority 0
|
|
|
|
|
|
|
|
def self.resolve(target)
|
2018-09-07 03:28:08 +00:00
|
|
|
if target.is_a?(String)
|
|
|
|
local_path = resolve_from_string(target)
|
|
|
|
new(local_path) if local_path
|
|
|
|
elsif target.is_a?(Hash)
|
|
|
|
local_path = resolve_from_hash(target)
|
|
|
|
new(local_path, target) if local_path
|
|
|
|
end
|
2016-09-08 09:11:44 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def self.resolve_from_hash(target)
|
2017-11-21 07:49:41 +00:00
|
|
|
return unless target.key?(:path)
|
|
|
|
|
2018-09-07 03:28:08 +00:00
|
|
|
if target.key?(:cwd)
|
|
|
|
File.expand_path(target[:path], target[:cwd])
|
|
|
|
else
|
|
|
|
target[:path]
|
|
|
|
end
|
2016-09-08 09:11:44 +00:00
|
|
|
end
|
2016-08-19 14:21:04 +00:00
|
|
|
|
2016-09-08 09:11:44 +00:00
|
|
|
def self.resolve_from_string(target)
|
2016-08-19 14:21:04 +00:00
|
|
|
# Support "urls" in the form of file://
|
|
|
|
if target.start_with?('file://')
|
|
|
|
target = target.gsub(%r{^file://}, '')
|
2016-06-30 03:18:30 +00:00
|
|
|
else
|
|
|
|
# support for windows paths
|
2016-08-24 14:06:12 +00:00
|
|
|
target = target.tr('\\', '/')
|
2016-08-19 14:21:04 +00:00
|
|
|
end
|
|
|
|
|
2018-09-14 00:19:02 +00:00
|
|
|
target if File.exist?(File.expand_path(target))
|
2016-02-21 01:02:39 +00:00
|
|
|
end
|
|
|
|
|
2018-09-07 03:28:08 +00:00
|
|
|
def initialize(target, opts = {})
|
2016-08-19 14:21:04 +00:00
|
|
|
@target = target
|
2018-09-07 03:28:08 +00:00
|
|
|
@backend = opts[:backend]
|
|
|
|
@archive_shasum = nil
|
2016-02-21 01:02:39 +00:00
|
|
|
end
|
|
|
|
|
2018-09-07 03:28:08 +00:00
|
|
|
def fetch(path)
|
|
|
|
# If `inspec exec` is used then we should not vendor/fetch. This makes
|
|
|
|
# local development easier and more predictable.
|
|
|
|
return @target if Inspec::BaseCLI.inspec_cli_command == :exec
|
|
|
|
|
|
|
|
# Skip vendoring if @backend is not set (example: ad hoc runners)
|
|
|
|
return @target unless @backend
|
|
|
|
|
|
|
|
if File.directory?(@target)
|
|
|
|
# Create an archive, checksum, and move to the vendor directory
|
|
|
|
Dir.mktmpdir do |tmpdir|
|
2018-09-14 00:19:02 +00:00
|
|
|
temp_archive = File.join(tmpdir, "#{File.basename(@target)}.tar.gz")
|
2018-09-07 03:28:08 +00:00
|
|
|
opts = {
|
|
|
|
backend: @backend,
|
2018-09-14 00:19:02 +00:00
|
|
|
output: temp_archive,
|
2018-09-07 03:28:08 +00:00
|
|
|
}
|
2018-09-14 00:19:02 +00:00
|
|
|
|
|
|
|
# Create a temporary archive at `opts[:output]`
|
2018-09-07 03:28:08 +00:00
|
|
|
Inspec::Profile.for_target(@target, opts).archive(opts)
|
2018-09-14 00:19:02 +00:00
|
|
|
|
|
|
|
checksum = perform_shasum(temp_archive)
|
|
|
|
final_path = File.join(path, checksum)
|
|
|
|
FileUtils.mkdir_p(final_path)
|
|
|
|
Inspec::FileProvider.for_path(temp_archive).extract(final_path)
|
2018-09-07 03:28:08 +00:00
|
|
|
end
|
|
|
|
else
|
|
|
|
# Verify profile (archive) is valid and extract to vendor directory
|
|
|
|
opts = { backend: @backend }
|
|
|
|
Inspec::Profile.for_target(@target, opts).check
|
|
|
|
Inspec::FileProvider.for_path(@target).extract(path)
|
|
|
|
end
|
|
|
|
|
|
|
|
@target
|
2016-09-08 09:11:44 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def archive_path
|
|
|
|
@target
|
|
|
|
end
|
|
|
|
|
2016-09-21 12:09:57 +00:00
|
|
|
def writable?
|
|
|
|
File.directory?(@target)
|
|
|
|
end
|
|
|
|
|
2016-09-20 10:36:23 +00:00
|
|
|
def cache_key
|
2016-09-21 09:15:00 +00:00
|
|
|
sha256.to_s
|
2016-09-20 10:36:23 +00:00
|
|
|
end
|
|
|
|
|
2016-09-21 09:15:00 +00:00
|
|
|
def sha256
|
2018-09-07 03:28:08 +00:00
|
|
|
if !@archive_shasum.nil?
|
|
|
|
@archive_shasum
|
|
|
|
elsif File.directory?(@target)
|
|
|
|
nil
|
|
|
|
else
|
|
|
|
perform_shasum(@target)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def perform_shasum(target)
|
|
|
|
@archive_shasum ||= OpenSSL::Digest::SHA256.digest(File.read(target)).unpack('H*')[0]
|
2016-09-20 10:36:23 +00:00
|
|
|
end
|
|
|
|
|
2016-09-08 09:11:44 +00:00
|
|
|
def resolved_source
|
2016-09-20 10:36:23 +00:00
|
|
|
h = { path: @target }
|
2016-09-21 09:15:00 +00:00
|
|
|
h[:sha256] = sha256 if sha256
|
2016-09-20 10:36:23 +00:00
|
|
|
h
|
2016-02-21 01:02:39 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|