class Spiceweasel::CLI

parse and execute cli options

Constants

MANIFEST_OPTIONS

Public Class Methods

new(_argv = []) click to toggle source
Calls superclass method
# File lib/spiceweasel/cli.rb, line 245
def initialize(_argv = [])
  super()
  parse_and_validate_options
  Config.merge!(@config)
  configure_logging
  Spiceweasel::Log.debug('Validation of the manifest has been turned off.') if Spiceweasel::Config[:novalidation]
end

Public Instance Methods

configure_logging() click to toggle source
# File lib/spiceweasel/cli.rb, line 286
def configure_logging
  [Spiceweasel::Log, Chef::Log].each do |log_klass|
    log_klass.init(Spiceweasel::Config[:log_location])
    log_klass.level = Spiceweasel::Config[:log_level]
    log_klass.level = :debug if Spiceweasel::Config[:debug]
  end
end
do_config_execute_delete(delete) click to toggle source
# File lib/spiceweasel/cli.rb, line 237
def do_config_execute_delete(delete)
  if Spiceweasel::Config[:execute]
    Execute.new(delete)
  else
    puts delete unless delete.empty?
  end
end
do_execute_rebuild(create, delete) click to toggle source
# File lib/spiceweasel/cli.rb, line 227
def do_execute_rebuild(create, delete)
  if Spiceweasel::Config[:execute]
    Execute.new(delete)
    Execute.new(create)
  else
    puts delete unless delete.empty?
    puts create unless create.empty?
  end
end
evaluate_configuration(create, delete, manifest) click to toggle source
# File lib/spiceweasel/cli.rb, line 208
def evaluate_configuration(create, delete, manifest)
  case
  when Spiceweasel::Config[:extractjson]
    puts JSON.pretty_generate(manifest)
  when Spiceweasel::Config[:extractyaml]
    puts manifest.to_yaml unless manifest.empty?
  when Spiceweasel::Config[:delete]
    do_config_execute_delete(delete)
  when Spiceweasel::Config[:rebuild]
    do_execute_rebuild(create, delete)
  else
    if Spiceweasel::Config[:execute]
      Execute.new(create)
    else
      puts create unless create.empty?
    end
  end
end
find_knife_commands() click to toggle source
# File lib/spiceweasel/cli.rb, line 390
def find_knife_commands
  require 'mixlib/shellout'
  allknifes = Mixlib::ShellOut.new('knife -h').run_command.stdout.split(/\n/)
  allknifes.keep_if { |x| x.start_with?('knife') }
  Spiceweasel::Log.debug(allknifes)
  allknifes
end
find_manifest() click to toggle source

find the .rb/.json/.yml file from the ARGV that isn't the clusterfile

# File lib/spiceweasel/cli.rb, line 332
def find_manifest
  ARGV.each do |arg|
    if arg =~ /\.json$|\.rb$|\.yml$/
      return arg unless ARGV[ARGV.find_index(arg) - 1].eql?('--cluster-file')
    end
  end
end
parse_and_validate_input(file) click to toggle source
# File lib/spiceweasel/cli.rb, line 294
def parse_and_validate_input(file) # rubocop:disable CyclomaticComplexity
  begin
    Spiceweasel::Log.debug("file: #{file}")
    unless File.file?(file)
      STDERR.puts "ERROR: #{file} is an invalid manifest file, please check your path."
      exit(-1)
    end
    output = nil
    if file.end_with?('.yml')
      output = YAML.load_file(file)
    elsif file.end_with?('.json')
      output = JSON.parse(File.read(file))
    elsif file.end_with?('.rb')
      output = instance_eval(IO.read(file), file, 1)
      output = JSON.parse(JSON.dump(output))
    else
      STDERR.puts "ERROR: #{file} is an unknown file type, please use a file ending with '.rb', '.json' or '.yml'."
      exit(-1)
    end
  rescue Psych::SyntaxError => e
    STDERR.puts e.message
    STDERR.puts "ERROR: Parsing error in #{file}."
    exit(-1)
  rescue JSON::ParserError => e
    STDERR.puts e.message
    STDERR.puts "ERROR: Parsing error in #{file}."
    exit(-1)
  rescue Exception => e # rubocop:disable RescueException
    STDERR.puts 'ERROR: Invalid or missing  manifest .json, .rb, or .yml file provided.'
    if Spiceweasel::Config[:log_level].to_s == 'debug'
      STDERR.puts "ERROR: #{e}\n#{e.backtrace.join("\n")}"
    end
    exit(-1)
  end
  output
end
parse_and_validate_options() click to toggle source
# File lib/spiceweasel/cli.rb, line 253
def parse_and_validate_options
  ARGV << '-h' if ARGV.empty?
  begin
    parse_options
    # Load knife configuration if using knife config
    require 'chef/knife'
    knife = Chef::Knife.new
    # Only log on error during startup
    Chef::Config[:verbosity] = 0
    Chef::Config[:log_level] = :error
    if @config[:knifeconfig]
      # 11.8 and later
      fetcher = Chef::ConfigFetcher.new(@config[:knifeconfig], Chef::Config.config_file_jail)
      knife.read_config(fetcher.read_config, @config[:knifeconfig])
      Spiceweasel::Config[:knife_options] = " -c #{@config[:knifeconfig]} "
    else
      knife.configure_chef
    end
    if @config[:timeout]
      Spiceweasel::Config[:cmd_timeout] = @config[:timeout].to_i
    end
    if @config[:serverurl]
      Spiceweasel::Config[:knife_options] += "--server-url #{@config[:serverurl]} "
    end
    # NOTE: Only set cookbook path via config if path unset
    Spiceweasel::Config[:cookbook_dir] ||= Chef::Config[:cookbook_path]
  rescue OptionParser::InvalidOption => e
    STDERR.puts e.message
    puts opt_parser.to_s
    exit(-1)
  end
end
process_manifest(manifest) click to toggle source
# File lib/spiceweasel/cli.rb, line 356
def process_manifest(manifest)
  do_not_validate = Spiceweasel::Config[:novalidation]
  berksfile = nil
  berksfile = Berksfile.new(manifest['berksfile']) if manifest.include?('berksfile')
  if berksfile
    cookbooks = Cookbooks.new(manifest['cookbooks'], berksfile.cookbook_list)
    create = berksfile.create + cookbooks.create
    delete = berksfile.delete + cookbooks.delete
  else
    cookbooks = Cookbooks.new(manifest['cookbooks'])
    create = cookbooks.create
    delete = cookbooks.delete
  end
  environments = Environments.new(manifest['environments'], cookbooks)
  roles = Roles.new(manifest['roles'], environments, cookbooks)
  data_bags = DataBags.new(manifest['data bags'])
  knifecommands = nil
  knifecommands = find_knife_commands unless do_not_validate
  options = manifest['options']
  nodes = Nodes.new(manifest['nodes'], cookbooks, environments, roles, knifecommands, options)
  clusters = Clusters.new(manifest['clusters'], cookbooks, environments, roles, knifecommands, options)
  knife = Knife.new(manifest['knife'], knifecommands)

  create += environments.create + roles.create + data_bags.create + nodes.create + clusters.create + knife.create
  delete += environments.delete + roles.delete + data_bags.delete + nodes.delete + clusters.delete

  # --chef-client only runs on nodes
  if Spiceweasel::Config[:chefclient]
    create = nodes.create + clusters.create
    delete = []
  end
  [create, delete]
end
process_only(manifest) click to toggle source

the –only options

# File lib/spiceweasel/cli.rb, line 341
def process_only(manifest)
  only_list = Spiceweasel::Config[:only]
  return manifest if only_list.empty?
  only_list.each do |key|
    unless MANIFEST_OPTIONS.member?(key)
      STDERR.puts "ERROR: '--only #{key}' is an invalid option."
      STDERR.puts "ERROR: Valid options are #{MANIFEST_OPTIONS}."
      exit(-1)
    end
  end
  only_list.push('berksfile') if only_list.member?('cookbooks')
  only_list.push('data bags') if only_list.delete('data_bags')
  manifest.keep_if { |key, val| only_list.member?(key) }
end
run() click to toggle source
# File lib/spiceweasel/cli.rb, line 185
def run # rubocop:disable CyclomaticComplexity
  if Spiceweasel::Config[:extractlocal] || Spiceweasel::Config[:extractjson] || Spiceweasel::Config[:extractyaml]
    manifest = Spiceweasel::ExtractLocal.parse_objects
  else
    manifest = parse_and_validate_input(find_manifest)
    if Spiceweasel::Config[:clusterfile]
      # if we have a cluster file, override any nodes or clusters in the original manifest
      manifest['nodes'] = manifest['clusters'] = {}
      manifest.merge!(parse_and_validate_input(Spiceweasel::Config[:clusterfile]))
    end
  end

  Spiceweasel::Log.debug("file manifest: #{manifest}")

  manifest = process_only(manifest)

  create, delete = process_manifest(manifest)

  evaluate_configuration(create, delete, manifest)

  exit 0
end