class Cucumber::Chef::Provider::AWS

Constants

INVALID_STATES
RUNNING_STATES
SHUTDOWN_STATES
VALID_STATES

Attributes

connection[RW]
server[RW]

Public Class Methods

new(ui=ZTK::UI.new) click to toggle source
# File lib/cucumber/chef/providers/aws.rb, line 37
def initialize(ui=ZTK::UI.new)
  @ui = ui

  @connection = Fog::Compute.new(
    :provider => 'AWS',
    :aws_access_key_id => Cucumber::Chef::Config.aws[:aws_access_key_id],
    :aws_secret_access_key => Cucumber::Chef::Config.aws[:aws_secret_access_key],
    :region => Cucumber::Chef::Config.aws[:region]
  )
  ensure_security_group

  @server = filter_servers(@connection.servers, VALID_STATES)
end

Public Instance Methods

alive?() click to toggle source
# File lib/cucumber/chef/providers/aws.rb, line 169
def alive?
  (exists? && RUNNING_STATES.include?(self.state))
end
create() click to toggle source

CREATE

# File lib/cucumber/chef/providers/aws.rb, line 55
def create
  if (exists? && alive?)
    @ui.stdout.puts("A test lab already exists using the #{Cucumber::Chef::Config.provider.upcase} credentials you have supplied; attempting to reprovision it.")
  else
    server_definition = {
      :image_id => Cucumber::Chef::Config.aws_image_id,
      :groups => Cucumber::Chef::Config.aws[:aws_security_group],
      :flavor_id => Cucumber::Chef::Config.aws[:aws_instance_type],
      :key_name => Cucumber::Chef::Config.aws[:aws_ssh_key_id],
      :availability_zone => Cucumber::Chef::Config.aws[:availability_zone],
      :tags => { "purpose" => "cucumber-chef", "cucumber-chef-mode" => Cucumber::Chef::Config.mode },
      :identity_file => Cucumber::Chef::Config.aws[:identity_file]
    }

    if (@server = @connection.servers.create(server_definition))
      ZTK::Benchmark.bench(:message => "Creating #{Cucumber::Chef::Config.provider.upcase} instance", :mark => "completed in %0.4f seconds.", :ui => @ui) do
        @server.wait_for { ready? }
        tag_server
        ZTK::TCPSocketCheck.new(:host => self.ip, :port => self.port, :wait => 120).wait
      end
    end
  end

  self

rescue Exception => e
  @ui.logger.fatal { e.message }
  @ui.logger.fatal { "Backtrace:\n#{e.backtrace.join("\n")}" }
  raise AWSError, e.message
end
dead?() click to toggle source
# File lib/cucumber/chef/providers/aws.rb, line 173
def dead?
  (exists? && SHUTDOWN_STATES.include?(self.state))
end
destroy() click to toggle source

DESTROY

# File lib/cucumber/chef/providers/aws.rb, line 90
def destroy
  if exists?
    @server.destroy
  else
    raise AWSError, "We could not find a test lab!"
  end

rescue Exception => e
  @ui.logger.fatal { e.message }
  @ui.logger.fatal { e.backtrace.join("\n") }
  raise AWSError, e.message
end
down() click to toggle source

HALT

# File lib/cucumber/chef/providers/aws.rb, line 129
def down
  if (exists? && alive?)
    if !@server.stop
      raise AWSError, "Failed to halt the test lab!"
    end
  else
    raise AWSError, "We could not find a running test lab."
  end

rescue Exception => e
  @ui.logger.fatal { e.message }
  @ui.logger.fatal { e.backtrace.join("\n") }
  raise AWSError, e.message
end
exists?() click to toggle source
# File lib/cucumber/chef/providers/aws.rb, line 165
def exists?
  !!@server
end
id() click to toggle source
# File lib/cucumber/chef/providers/aws.rb, line 179
def id
  @server.id
end
ip() click to toggle source
# File lib/cucumber/chef/providers/aws.rb, line 191
def ip
  @server.public_ip_address
end
port() click to toggle source
# File lib/cucumber/chef/providers/aws.rb, line 195
def port
  22
end
reload() click to toggle source

RELOAD

# File lib/cucumber/chef/providers/aws.rb, line 148
def reload
  if (exists? && alive?)
    if !@server.restart
      raise AWSError, "Failed to reload the test lab!"
    end
  else
    raise AWSError, "We could not find a running test lab."
  end

rescue Exception => e
  @ui.logger.fatal { e.message }
  @ui.logger.fatal { e.backtrace.join("\n") }
  raise AWSError, e.message
end
state() click to toggle source
# File lib/cucumber/chef/providers/aws.rb, line 183
def state
  @server.state.to_sym
end
up() click to toggle source

UP

# File lib/cucumber/chef/providers/aws.rb, line 107
def up
  if (exists? && dead?)
    if @server.start
      @server.wait_for { ready? }
      ZTK::TCPSocketCheck.new(:host => self.ip, :port => self.port, :wait => 120).wait
    else
      raise AWSError, "Failed to boot the test lab!"
    end
  else
    raise AWSError, "We could not find a powered off test lab."
  end

rescue Exception => e
  @ui.logger.fatal { e.message }
  @ui.logger.fatal { e.backtrace.join("\n") }
  raise AWSError, e.message
end
username() click to toggle source
# File lib/cucumber/chef/providers/aws.rb, line 187
def username
  @server.username
end

Private Instance Methods

ensure_security_group() click to toggle source
# File lib/cucumber/chef/providers/aws.rb, line 237
def ensure_security_group
  security_group_name = Cucumber::Chef::Config.aws[:aws_security_group]
  if (security_group = @connection.security_groups.get(security_group_name))
    port_ranges = security_group.ip_permissions.collect{ |entry| entry["fromPort"]..entry["toPort"] }
    security_group.authorize_port_range(22..22) if port_ranges.none?{ |port_range| port_range === 22 }
    security_group.authorize_port_range(443..443) if port_ranges.none?{ |port_range| port_range === 443 }
    security_group.authorize_port_range(444..444) if port_ranges.none?{ |port_range| port_range === 444 }
  elsif (security_group = @connection.security_groups.new(:name => security_group_name, :description => "cucumber-chef test lab")).save
    security_group.authorize_port_range(22..22)
    security_group.authorize_port_range(443..443)
    security_group.authorize_port_range(444..444)
  else
    raise AWSError, "Could not find an existing or create a new AWS security group."
  end
end
filter_servers(servers, states=VALID_STATES) click to toggle source
# File lib/cucumber/chef/providers/aws.rb, line 204
def filter_servers(servers, states=VALID_STATES)
  @ui.logger.debug("states") { states.collect{ |s| s.inspect }.join(", ") }
  results = servers.select do |server|
    @ui.logger.debug("candidate") { "id=#{server.id.inspect}, state=#{server.state.inspect}, tags=#{server.tags.inspect}" }

    ( server.tags['cucumber-chef-mode'] == Cucumber::Chef::Config.mode.to_s &&
      server.tags['cucumber-chef-user'] == Cucumber::Chef::Config.user.to_s &&
      states.any?{ |state| state.to_s == server.state } )
  end
  results.each do |server|
    @ui.logger.debug("results") { "id=#{server.id.inspect}, state=#{server.state.inspect}" }
  end
  results.first
end
tag_server() click to toggle source
# File lib/cucumber/chef/providers/aws.rb, line 221
def tag_server
  {
    "cucumber-chef-mode" => Cucumber::Chef::Config.mode,
    "cucumber-chef-user" => Cucumber::Chef::Config.user,
    "Name" => "cucumber-chef-#{Cucumber::Chef::Config.user}",
    "purpose" => "cucumber-chef"
  }.each do |k, v|
    tag = @connection.tags.new
    tag.resource_id = @server.id
    tag.key, tag.value = k, v
    tag.save
  end
end