lib/cucumber/chef/providers/aws.rb in cucumber-chef-2.1.0.rc.2 vs lib/cucumber/chef/providers/aws.rb in cucumber-chef-2.1.0.rc.3
- old
+ new
@@ -23,239 +23,208 @@
class Provider
class AWSError < Error; end
class AWS
- attr_accessor :stdout, :stderr, :stdin, :logger
+ attr_accessor :connection, :server, :stdout, :stderr, :stdin, :logger
- INVALID_STATES = %w( terminated pending )
- RUNNING_STATES = %w( running starting-up )
- SHUTDOWN_STATES = %w( shutdown stopping stopped shutting-down )
+ INVALID_STATES = %w(terminated pending).map(&:to_sym)
+ RUNNING_STATES = %w(running starting-up).map(&:to_sym)
+ SHUTDOWN_STATES = %w(shutdown stopping stopped shutting-down).map(&:to_sym)
VALID_STATES = RUNNING_STATES+SHUTDOWN_STATES
################################################################################
def initialize(stdout=STDOUT, stderr=STDERR, stdin=STDIN, logger=$logger)
@stdout, @stderr, @stdin, @logger = stdout, stderr, stdin, logger
@stdout.sync = true if @stdout.respond_to?(:sync=)
@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]
+ :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
################################################################################
+# CREATE
+################################################################################
def create
- if (lab_exists? && (@server = labs_running.first))
- @stdout.puts("A test lab already exists using the AWS credentials you have supplied; attempting to reprovision it.")
+ if (exists? && alive?)
+ @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]
+ :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))
- @stdout.puts("Provisioning cucumber-chef test lab platform.")
- @stdout.print("Waiting for instance...")
- Cucumber::Chef.spinner do
+ if (@server = @connection.servers.create(server_definition))
+ ZTK::Benchmark.bench(:message => "Creating #{Cucumber::Chef::Config.provider.upcase} instance", :mark => "completed in %0.4f seconds.", :stdout => @stdout) do
@server.wait_for { ready? }
+ tag_server
+ ZTK::TCPSocketCheck.new(:host => self.ip, :port => self.port, :wait => 120).wait
end
- @stdout.puts("done.\n")
-
- tag_server
-
- @stdout.print("Waiting for 20 seconds...")
- Cucumber::Chef.spinner do
- sleep(20)
- end
- @stdout.print("done.\n")
end
end
- if @server
- @stdout.print("Waiting for SSHD...")
- Cucumber::Chef.spinner do
- ZTK::TCPSocketCheck.new(:host => @server.public_ip_address, :port => 22, :wait => 120).wait
- end
- @stdout.puts("done.\n")
- end
-
self
rescue Exception => e
Cucumber::Chef.logger.fatal { e.message }
Cucumber::Chef.logger.fatal { "Backtrace:\n#{e.backtrace.join("\n")}" }
raise AWSError, e.message
end
################################################################################
+# DESTROY
+################################################################################
def destroy
- if ((l = labs).count > 0)
- @stdout.puts("Destroying Servers:")
- l.each do |server|
- @stdout.puts(" * #{server.public_ip_address}")
- server.destroy
- end
+ if exists?
+ @server.destroy
else
- @stdout.puts("There are no cucumber-chef test labs to destroy!")
+ raise AWSError, "We could not find a test lab!"
end
rescue Exception => e
Cucumber::Chef.logger.fatal { e.message }
Cucumber::Chef.logger.fatal { e.backtrace.join("\n") }
raise AWSError, e.message
end
################################################################################
+# UP
+################################################################################
def up
- if (lab_exists? && (@server = labs_shutdown.first))
+ 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
- @stdout.print("Waiting for instance...")
- Cucumber::Chef.spinner do
- @server.wait_for { ready? }
- end
- @stdout.puts("done.\n")
+ rescue Exception => e
+ Cucumber::Chef.logger.fatal { e.message }
+ Cucumber::Chef.logger.fatal { e.backtrace.join("\n") }
+ raise AWSError, e.message
+ end
- @stdout.print("Waiting for SSHD...")
- Cucumber::Chef.spinner do
- ZTK::TCPSocketCheck.new(:host => @server.public_ip_address, :port => 22, :wait => 120).wait
- end
- @stdout.puts("done.\n")
+################################################################################
+# HALT
+################################################################################
- @stdout.puts("Successfully started up cucumber-chef test lab!")
-
- info
- else
- @stdout.puts("Failed to start up cucumber-chef test lab!")
+ def halt
+ if (exists? && alive?)
+ if !@server.stop
+ raise AWSError, "Failed to halt the test lab!"
end
else
- @stdout.puts("There are no available cucumber-chef test labs to start up!")
+ raise AWSError, "We could not find a running test lab."
end
rescue Exception => e
Cucumber::Chef.logger.fatal { e.message }
Cucumber::Chef.logger.fatal { e.backtrace.join("\n") }
raise AWSError, e.message
end
################################################################################
+# RELOAD
+################################################################################
- def down
- if (lab_exists? && (@server = labs_running.first))
- if @server.stop
- @stdout.puts("Successfully shutdown cucumber-chef test lab!")
- else
- @stdout.puts("Failed to shutdown cucumber-chef test lab!")
+ def reload
+ if (exists? && alive?)
+ if !@server.restart
+ raise AWSError, "Failed to reload the test lab!"
end
else
- @stdout.puts("There are no available cucumber-chef test labs top shutdown!")
+ raise AWSError, "We could not find a running test lab."
end
rescue Exception => e
Cucumber::Chef.logger.fatal { e.message }
Cucumber::Chef.logger.fatal { e.backtrace.join("\n") }
raise AWSError, e.message
end
################################################################################
+ def exists?
+ !!@server
+ end
+
+ def alive?
+ (exists? && RUNNING_STATES.include?(self.state))
+ end
+
+ def dead?
+ (exists? && SHUTDOWN_STATES.include?(self.state))
+ end
+
+################################################################################
+
def id
- labs_running.first.id
+ @server.id
end
def state
- labs_running.first.state
+ @server.state.to_sym
end
def username
- labs_running.first.username
+ @server.username
end
def ip
- labs_running.first.public_ip_address
+ @server.public_ip_address
end
def port
22
end
-################################################################################
- def lab_exists?
- (labs.size > 0)
- end
-
################################################################################
-
- def labs
- @servers ||= @connection.servers
- results = @servers.select do |server|
- Cucumber::Chef.logger.debug("candidate") { "ID=#{server.id}, state='#{server.state}'" }
- ( server.tags['cucumber-chef-mode'] == Cucumber::Chef::Config[:mode].to_s &&
- server.tags['cucumber-chef-user'] == Cucumber::Chef::Config[:user].to_s &&
- VALID_STATES.any?{ |state| state == server.state } )
- end
- results.each do |server|
- Cucumber::Chef.logger.debug("results") { "ID=#{server.id}, state='#{server.state}'" }
- end
- results
- end
-
+ private
################################################################################
- def labs_running
- @servers ||= @connection.servers
- results = @servers.select do |server|
- Cucumber::Chef.logger.debug("candidate") { "ID=#{server.id}, state='#{server.state}'" }
- ( server.tags['cucumber-chef-mode'] == Cucumber::Chef::Config[:mode].to_s &&
- server.tags['cucumber-chef-user'] == Cucumber::Chef::Config[:user].to_s &&
- RUNNING_STATES.any?{ |state| state == server.state } )
- end
- results.each do |server|
- Cucumber::Chef.logger.debug("results") { "ID=#{server.id}, state='#{server.state}'" }
- end
- results
- end
+ def filter_servers(servers, states=VALID_STATES)
+ Cucumber::Chef.logger.debug("states") { states.collect{ |s| s.inspect }.join(", ") }
+ results = servers.select do |server|
+ Cucumber::Chef.logger.debug("candidate") { "id=#{server.id.inspect}, state=#{server.state.inspect}, tags=#{server.tags.inspect}" }
-################################################################################
-
- def labs_shutdown
- @servers ||= @connection.servers
- results = @servers.select do |server|
- Cucumber::Chef.logger.debug("candidate") { "ID=#{server.id}, state='#{server.state}'" }
- ( server.tags['cucumber-chef-mode'] == Cucumber::Chef::Config[:mode].to_s &&
- server.tags['cucumber-chef-user'] == Cucumber::Chef::Config[:user].to_s &&
- SHUTDOWN_STATES.any?{ |state| state == server.state } )
+ ( 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|
- Cucumber::Chef.logger.debug("results") { "ID=#{server.id}, state='#{server.state}'" }
+ Cucumber::Chef.logger.debug("results") { "id=#{server.id.inspect}, state=#{server.state.inspect}" }
end
- results
+ results.first
end
-
################################################################################
- private
-################################################################################
def tag_server
{
- "cucumber-chef-mode" => Cucumber::Chef::Config[:mode],
- "cucumber-chef-user" => Cucumber::Chef::Config[:user],
+ "cucumber-chef-mode" => Cucumber::Chef::Config.mode,
+ "cucumber-chef-user" => 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
@@ -264,10 +233,10 @@
end
################################################################################
def ensure_security_group
- security_group_name = Cucumber::Chef::Config[:aws][:aws_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(4000..4000) if port_ranges.none?{ |port_range| port_range === 4000 }
security_group.authorize_port_range(4040..4040) if port_ranges.none?{ |port_range| port_range === 4040 }