class ChefCLI::Policyfile::ChefServerLockFetcher

A policyfile lock fetcher that can read a lock from a chef server

def apply_locked_source_options(options_from_lock)

Parameters:
  • options_from_lock (Hash) -- The source options loaded from a policyfile lock
def apply_locked_source_options(options_from_lock)
  options = options_from_lock.inject({}) do |acc, (key, value)|
    acc[key.to_sym] = value
    acc
  end
  source_options.merge!(options)
  raise ChefCLI::InvalidLockfile, "Invalid source_options provided from lock data: #{options_from_lock_file.inspect}" unless valid?
end

def errors

Returns:
  • (Array) - A list of errors found
def errors
  error_messages = []
  %i{server policy_name}.each do |key|
    error_messages << "include_policy for #{name} is missing key #{key}" unless source_options[key]
  end
  if %i{policy_revision_id policy_group}.all? { |key| source_options[key].nil? }
    error_messages << "include_policy for #{name} must specify policy_revision_id or policy_group"
  end
  error_messages
end

def fetch_lock_data

def fetch_lock_data
  if revision
    http_client.get("policies/#{policy_name}/revisions/#{revision}")
  elsif policy_group
    http_client.get("policy_groups/#{policy_group}/policies/#{policy_name}")
  else
    raise ChefCLI::BUG.new("The source_options should have been validated: #{source_options.inspect}")
  end
rescue Net::ProtocolError => e
  if e.respond_to?(:response) && e.response.code.to_s == "404"
    raise ChefCLI::PolicyfileLockDownloadError.new("No Policyfile lock named '#{policy_name}' found with revision '#{revision}' at #{http_client.url}") if revision
    raise ChefCLI::PolicyfileLockDownloadError.new("No Policyfile lock named '#{policy_name}' found with policy group '#{policy_group}' at #{http_client.url}") if policy_group
  else
    raise ChefCLI::PolicyfileLockDownloadError.new("HTTP error attempting to fetch policyfile lock from #{http_client.url}")
  end
rescue => e
  raise e
end

def http_client

Returns:
  • (Hash) - Returns a parsed JSON object... I think.

Other tags:
    See: Chef::HTTP::JSONInput#get -
    See: Chef:ServerAPI -
def http_client
  @http_client ||= Chef::ServerAPI.new(source_options[:server],
    signing_key_filename: chef_config.client_key,
    client_name: chef_config.node_name)
end

def initialize(name, source_options, chef_config)

Other tags:
    Example: ChefServerLockFetcher for a policyfile with the latest revision_id for a policy group -
    Example: ChefServerLockFetcher for a policyfile with a specific revision id -

Parameters:
  • chef_config (Chef::Config, ChefConfig::Config) --
  • source_options (Hash) -- A hash with a :server key pointing at the chef server,
  • name (String) -- The name of the policyfile
def initialize(name, source_options, chef_config)
  @name = name
  @source_options = source_options
  @chef_config = chef_config
  @source_options[:policy_name] ||= name
end

def lock_data

Returns:
  • (String) - of the policyfile lock data
def lock_data
  @lock_data ||= fetch_lock_data.tap do |data|
    data["cookbook_locks"].each do |cookbook_name, cookbook_lock|
      cookbook_lock["source_options"] = {
        "chef_server_artifact" => server,
        "identifier" => cookbook_lock["identifier"],
      }
    end
  end
end

def policy_group

def policy_group
  source_options[:policy_group]
end

def policy_name

def policy_name
  source_options[:policy_name]
end

def revision

def revision
  source_options[:policy_revision_id]
end

def server

def server
  source_options[:server]
end

def source_options_for_lock

Returns:
  • (Hash) - The source_options that describe how to fetch this exact lock again
def source_options_for_lock
  source_options.merge({
    policy_revision_id: lock_data["revision_id"],
  })
end

def valid?

Returns:
  • (False) - if there were errors with the provided source_options
  • (True) - if there were no errors with the provided source_options
def valid?
  errors.empty?
end