class Stemcell::OptionParser

Constants

OPTION_DEFINITIONS

Attributes

banner[R]
defaults[R]
options[R]
override_help[R]
version[R]

Public Class Methods

new(config={}) click to toggle source
# File lib/stemcell/option_parser.rb, line 311
def initialize(config={})
  @defaults = config[:defaults] || {}
  @version = config[:version]
  @banner = config[:banner]
  @override_help = config[:override_help]
end

Public Instance Methods

parse!(args) click to toggle source
# File lib/stemcell/option_parser.rb, line 318
def parse!(args)
  # The block passed to Trollop#options is evaluated in the binding of the
  # trollop parser itself, it doesn't have access to the this instance.
  # So use a value that can be captured instead!
  _this = self
  _defns = OPTION_DEFINITIONS

  @options = Trollop::options(args) do
    version _this.version if _this.version
    banner  _this.banner  if _this.banner

    _defns.each do |defn|
      # Prioritize the environment variable, then the given default
      if defn[:hide]
        default = "<hidden>"
      else
        default = ENV[defn[:env]] || _this.defaults[defn[:name]]
      end

      opt(
        defn[:name],
        defn[:desc],
          :type    => defn[:type],
          :short   => defn[:short],
          :default => default)
    end

    # Prevent trollop from showing its help screen
    opt('help', 'help', :short => :l) if _this.override_help
  end

  # Populate the hidden defaults. Some (like aws secret key) is :hidden so that Trollop wont print that into stdout
  _defns.each do |defn|
    if defn[:hide] && options[defn[:name]] == "<hidden>"
      options[defn[:name]] = ENV[defn[:env]] || _this.defaults[defn[:name]]
    end
  end

  # convert tags from string to ruby hash
  if options['tags']
    tags = {}
    options['tags'].split(',').each do |tag_set|
      key, value = tag_set.split('=')
      tags[key] = value
    end
    options['tags'] = tags
  end

  # parse block_device_mappings to convert it from the standard CLI format
  # to the EC2 Ruby API format.
  # All of this is a bit hard to find so here are some docs links to
  # understand

  # CLI This format is documented by typing
  # ec2-run-instances --help and looking at the -b option
  # Basically, it's either

  # none
  # ephemeral<number>
  # '[<snapshot-id>][:<size>[:<delete-on-termination>][:<type>[:<iops>]]]'

  # Ruby API (that does call to the native API)
  # gems/aws-sdk-1.17.0/lib/aws/ec2/instance_collection.rb
  # line 91 + example line 57

  if options['block_device_mappings']
    block_device_mappings = []
    options['block_device_mappings'].split(',').each do |device_set|
      device,devparam = device_set.split('=')

      mapping = {}

      if devparam == 'none'
        mapping = { :no_device => device }
      else
        mapping = { :device_name => device }
        if devparam =~ /^ephemeral[0-3]/
          mapping[:virtual_name] = devparam
        else
          # we have a more complex 'ebs' parameter
          #'[<snapshot-id>][:<size>[:<delete-on-termination>][:<type>[:<iops>]]]'

          mapping[:ebs] = {}

          devparam = devparam.split ':'

          # a bit ugly but short and won't change
          # notice the to_i on volume_size parameter
          mapping[:ebs][:snapshot_id] = devparam[0] unless (devparam[0].nil? || devparam[0].empty?)
          mapping[:ebs][:volume_size] = devparam[1].to_i

          # defaults to true - except if we have the exact string "false"
          mapping[:ebs][:delete_on_termination] = (devparam[2] != "false")

          # optional. notice the to_i on iops parameter
          mapping[:ebs][:volume_type] = devparam[3] unless (devparam[3].nil? || devparam[3].empty?)
          mapping[:ebs][:iops] = devparam[4].to_i unless (devparam[4].nil? || devparam[4].empty?)

        end
      end

      block_device_mappings.push mapping
    end

    options['block_device_mappings'] = block_device_mappings
  end

  # convert security_groups from comma separated string to ruby array
  options['security_groups'] &&= options['security_groups'].split(',')
  options['security_group_ids'] &&= options['security_group_ids'].split(',')
  # convert ephemeral_devices from comma separated string to ruby array
  options['ephemeral_devices'] &&= options['ephemeral_devices'].split(',')
  # convert chef_cookbook_attributes from comma separated string to ruby array
  options['chef_cookbook_attributes'] &&= options['chef_cookbook_attributes'].split(',')

  # format the classic link options
  if options['classic_link_vpc_id']
    options['classic_link']['vpc_id'] = options['classic_link_vpc_id']
  end
  if options['classic_link_security_group_ids']
    options['classic_link']['security_group_ids'] = options['classic_link_security_group_ids'].split(',')
  end
  if options['classic_link_security_groups']
    options['classic_link']['security_groups'] = options['classic_link_security_groups'].split(',')
  end

  options
end