Skip to content

Commit

Permalink
Merge pull request #227 from chef-cookbooks/chris-rock/automate-fetcher
Browse files Browse the repository at this point in the history
add automate fetcher for chef solo
  • Loading branch information
alexpop authored May 19, 2017
2 parents e74839d + 8966e93 commit b355449
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 3 deletions.
13 changes: 11 additions & 2 deletions files/default/handler/audit_report.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ def report
interval_time = node['audit']['interval']['time']
profiles = node['audit']['profiles']
quiet = node['audit']['quiet']
fetcher = node['audit']['fetcher']

# load inspec, supermarket bundle and compliance bundle
load_needed_dependencies
Expand All @@ -36,7 +37,9 @@ def report
reporters.include?('chef-server-compliance') ||
reporters.include?('chef-server-visibility') ||
reporters.include?('chef-server-automate') ||
node['audit']['fetcher'] == 'chef-server'
%w{chef-server chef-server-compliance chef-server-visibility chef-server-automate}.include?(fetcher)

load_automate_fetcher if fetcher == 'chef-automate'

# ensure authentication for Chef Compliance is in place, see libraries/compliance.rb
login_to_compliance(server, user, token, refresh_token) if reporters.include?('chef-compliance')
Expand Down Expand Up @@ -95,11 +98,17 @@ def load_needed_dependencies

# we expect inspec to be loaded before
def load_chef_fetcher
Chef::Log.debug "Load vendored ruby files from: #{cookbook_vendor_path}"
Chef::Log.debug "Load Chef Server fetcher from: #{cookbook_vendor_path}"
$LOAD_PATH.unshift(cookbook_vendor_path)
require 'chef-server/fetcher'
end

def load_automate_fetcher
Chef::Log.debug "Load Chef Automate fetcher from: #{cookbook_vendor_path}"
$LOAD_PATH.unshift(cookbook_vendor_path)
require 'chef-automate/fetcher'
end

# sets format to json-min when chef-compliance, json when chef-automate
def get_opts(format, quiet)
output = quiet ? ::File::NULL : $stdout
Expand Down
69 changes: 69 additions & 0 deletions files/default/vendor/chef-automate/fetcher.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
module ChefAutomate
class Fetcher < Compliance::Fetcher
name 'chef-automate'

# it positions itself before `compliance` fetcher
# only load it, if you want to use audit cookbook in Chef Solo with Chef Automate
priority 502

def self.resolve(target)
uri = if target.is_a?(String) && URI(target).scheme == 'compliance'
URI(target)
elsif target.respond_to?(:key?) && target.key?(:compliance)
URI("compliance://#{target[:compliance]}")
end

return nil if uri.nil?

# we have detailed information available in our lockfile, no need to ask the server
if target.respond_to?(:key?) && target.key?(:url)
profile_fetch_url = target[:url]
config = {}
else
# verifies that the target e.g base/ssh exists
profile = sanitize_profile_name(uri)
owner, id = profile.split('/')
profile_path = "/compliance/profiles/#{owner}/#{id}/tar"
dc = Chef::Config[:data_collector]
url = URI(dc[:server_url])
url.path = profile_path
profile_fetch_url = url.to_s
config = {
'token' => dc[:token],
}
end

new(profile_fetch_url, config)
rescue URI::Error => _e
nil
end

# returns a parsed url for `admin/profile` or `compliance://admin/profile`
# TODO: remove in future, copied from inspec to support older versions of inspec
def self.sanitize_profile_name(profile)
if URI(profile).scheme == 'compliance'
uri = URI(profile)
else
uri = URI("compliance://#{profile}")
end
uri.to_s.sub(%r{^compliance:\/\/}, '')
end

def initialize(url, opts)
options = {
'insecure' => true,
'token' => opts['token'],
'server_type' => 'automate',
'automate' => {
'ent' => '',
'token_type' => 'dctoken',
},
}
super(url, options)
end

def to_s
'Chef Automate for Chef Solo Fetcher'
end
end
end
2 changes: 1 addition & 1 deletion libraries/compliance.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def upload_profile(config, owner, profile_name, path)
Compliance::API.upload(config, owner, profile_name, path)
end

# TODO: temporary, we should not use this
# TODO: temporary, we should use a stateless approach
# TODO: harmonize with CLI login_refreshtoken method
def login_to_compliance(server, user, access_token, refresh_token)
if !refresh_token.nil?
Expand Down

0 comments on commit b355449

Please sign in to comment.