roark 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +19 -0
- data/.travis.yml +5 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +75 -0
- data/Rakefile +8 -0
- data/bin/roark +6 -0
- data/examples/example.json +52 -0
- data/lib/roark/ami.rb +148 -0
- data/lib/roark/ami_create_workflow.rb +50 -0
- data/lib/roark/aws/cloud_formation/create_stack.rb +35 -0
- data/lib/roark/aws/cloud_formation/destroy_stack.rb +17 -0
- data/lib/roark/aws/cloud_formation/stack_outputs.rb +17 -0
- data/lib/roark/aws/cloud_formation/stack_status.rb +21 -0
- data/lib/roark/aws/cloud_formation.rb +4 -0
- data/lib/roark/aws/connection.rb +27 -0
- data/lib/roark/aws/ec2/ami_state.rb +19 -0
- data/lib/roark/aws/ec2/create_ami.rb +20 -0
- data/lib/roark/aws/ec2/destroy_ami.rb +34 -0
- data/lib/roark/aws/ec2/instance_status.rb +15 -0
- data/lib/roark/aws/ec2/stop_instance.rb +15 -0
- data/lib/roark/aws/ec2.rb +5 -0
- data/lib/roark/aws.rb +5 -0
- data/lib/roark/cli/create.rb +76 -0
- data/lib/roark/cli/destroy.rb +53 -0
- data/lib/roark/cli/shared.rb +28 -0
- data/lib/roark/cli.rb +66 -0
- data/lib/roark/instance.rb +56 -0
- data/lib/roark/response.rb +15 -0
- data/lib/roark/stack.rb +63 -0
- data/lib/roark/version.rb +3 -0
- data/lib/roark.rb +17 -0
- data/roark.gemspec +26 -0
- data/spec/ami_create_workflow_spec.rb +34 -0
- data/spec/ami_spec.rb +217 -0
- data/spec/aws/cloud_formation/create_stack_spec.rb +20 -0
- data/spec/aws/connection_spec.rb +26 -0
- data/spec/aws/ec2/ami_state_spec.rb +11 -0
- data/spec/aws/ec2/create_ami_spec.rb +17 -0
- data/spec/aws/ec2/destroy_ami_spec.rb +32 -0
- data/spec/create_stack_spec.rb +20 -0
- data/spec/instance_spec.rb +80 -0
- data/spec/response_spec.rb +21 -0
- data/spec/spec_helper.rb +4 -0
- data/spec/stack_spec.rb +99 -0
- metadata +155 -0
@@ -0,0 +1,76 @@
|
|
1
|
+
module Roark
|
2
|
+
module CLI
|
3
|
+
class Create
|
4
|
+
|
5
|
+
include Shared
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@options = { :parameters => {}, :region => 'us-east-1' }
|
9
|
+
@logger = Roark.logger
|
10
|
+
end
|
11
|
+
|
12
|
+
def create
|
13
|
+
option_parser.parse!
|
14
|
+
|
15
|
+
validate_required_options [:name, :template]
|
16
|
+
|
17
|
+
unless File.exists? @options[:template]
|
18
|
+
@logger.error "Template #{@options[:template]} does not exist."
|
19
|
+
exit 1
|
20
|
+
end
|
21
|
+
|
22
|
+
template = File.read @options[:template]
|
23
|
+
|
24
|
+
ami = Roark::Ami.new :aws => aws, :name => @options[:name]
|
25
|
+
|
26
|
+
ami_create_workflow = Roark::AmiCreateWorkflow.new :ami => ami,
|
27
|
+
:template => template,
|
28
|
+
:parameters => @options[:parameters]
|
29
|
+
response = ami_create_workflow.execute
|
30
|
+
|
31
|
+
unless response.success?
|
32
|
+
@logger.error response.message
|
33
|
+
exit 1
|
34
|
+
end
|
35
|
+
|
36
|
+
@logger.info response.message
|
37
|
+
end
|
38
|
+
|
39
|
+
def option_parser
|
40
|
+
OptionParser.new do |opts|
|
41
|
+
opts.banner = "Usage: roark create [options]"
|
42
|
+
|
43
|
+
opts.on("-n", "--name [NAME]", "Name of AMI") do |o|
|
44
|
+
@options[:name] = o
|
45
|
+
end
|
46
|
+
|
47
|
+
opts.on("-p", "--parameters [PARAMETERS]", "Parameter name and it's value separated by '=' to pass to Cloud Formation. Can be specified multiple times.") do |o|
|
48
|
+
data = o.split('=')
|
49
|
+
@options[:parameters].merge!({ data.first => data[1] })
|
50
|
+
end
|
51
|
+
|
52
|
+
opts.on("-r", "--region [REGION]", "Region to build AMI") do |o|
|
53
|
+
@options[:region] = o
|
54
|
+
end
|
55
|
+
|
56
|
+
opts.on("-t", "--template [TEMPLATE]", "Path to Cloud Formation template") do |o|
|
57
|
+
@options[:template] = o
|
58
|
+
end
|
59
|
+
|
60
|
+
opts.on("--aws-access-key [KEY]", "AWS Access Key") do |o|
|
61
|
+
@options[:aws_access_key] = o
|
62
|
+
end
|
63
|
+
|
64
|
+
opts.on("--aws-secret-key [KEY]", "AWS Secret Key") do |o|
|
65
|
+
@options[:aws_secret_key] = o
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def command_summary
|
71
|
+
'Creates an AMI'
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Roark
|
2
|
+
module CLI
|
3
|
+
class Destroy
|
4
|
+
|
5
|
+
include Shared
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@options = { :region => 'us-east-1' }
|
9
|
+
end
|
10
|
+
|
11
|
+
def destroy
|
12
|
+
option_parser.parse!
|
13
|
+
|
14
|
+
validate_required_options [:ami_id]
|
15
|
+
|
16
|
+
ami = Roark::Ami.new :aws => aws, :ami_id => @options[:ami_id]
|
17
|
+
|
18
|
+
response = ami.destroy
|
19
|
+
unless response.success?
|
20
|
+
Roark.logger.error response.message
|
21
|
+
exit 1
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def option_parser
|
26
|
+
OptionParser.new do |opts|
|
27
|
+
opts.banner = "Usage: roark destroy [options]"
|
28
|
+
|
29
|
+
opts.on("-i", "--ami-id [AMI_ID]", "ID of AMI to destroy") do |o|
|
30
|
+
@options[:ami_id] = o
|
31
|
+
end
|
32
|
+
|
33
|
+
opts.on("-r", "--region [REGION]", "Region to build AMI") do |o|
|
34
|
+
@options[:region] = o
|
35
|
+
end
|
36
|
+
|
37
|
+
opts.on("--aws-access-key [KEY]", "AWS Access Key") do |o|
|
38
|
+
@options[:aws_access_key] = o
|
39
|
+
end
|
40
|
+
|
41
|
+
opts.on("--aws-secret-key [KEY]", "AWS Secret Key") do |o|
|
42
|
+
@options[:aws_secret_key] = o
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def command_summary
|
48
|
+
'Destroys an AMI'
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Roark
|
2
|
+
module CLI
|
3
|
+
module Shared
|
4
|
+
def validate_required_options(options)
|
5
|
+
options.each do |o|
|
6
|
+
unless @options[o]
|
7
|
+
@logger.error "Option '#{o.to_s}' required."
|
8
|
+
exit 1
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def command_name
|
14
|
+
self.class.name.split('::').last.downcase
|
15
|
+
end
|
16
|
+
|
17
|
+
def help
|
18
|
+
puts option_parser.help
|
19
|
+
end
|
20
|
+
|
21
|
+
def aws
|
22
|
+
Roark::Aws::Connection.new :access_key_id => @options[:access_key_id],
|
23
|
+
:aws_secret_key => @options[:secret_access_key],
|
24
|
+
:region => @options[:region]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/roark/cli.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
|
3
|
+
require 'roark/cli/shared'
|
4
|
+
|
5
|
+
require 'roark/cli/create'
|
6
|
+
require 'roark/cli/destroy'
|
7
|
+
|
8
|
+
module Roark
|
9
|
+
module CLI
|
10
|
+
|
11
|
+
def self.start
|
12
|
+
cmd = ARGV.shift
|
13
|
+
|
14
|
+
case cmd
|
15
|
+
when 'create'
|
16
|
+
begin
|
17
|
+
CLI::Create.new.create
|
18
|
+
rescue OptionParser::MissingArgument => e
|
19
|
+
puts e.message
|
20
|
+
exit 1
|
21
|
+
end
|
22
|
+
when 'destroy'
|
23
|
+
begin
|
24
|
+
CLI::Destroy.new.destroy
|
25
|
+
rescue OptionParser::MissingArgument => e
|
26
|
+
puts e.message
|
27
|
+
exit 1
|
28
|
+
end
|
29
|
+
when '-h'
|
30
|
+
usage
|
31
|
+
when '-v'
|
32
|
+
puts Roark::VERSION
|
33
|
+
else
|
34
|
+
puts "Unknown command: '#{cmd}'."
|
35
|
+
puts ''
|
36
|
+
usage
|
37
|
+
exit 1
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.usage
|
42
|
+
puts 'Usage: roark command'
|
43
|
+
puts ''
|
44
|
+
puts 'Append -h for help on specific subcommand.'
|
45
|
+
puts ''
|
46
|
+
|
47
|
+
puts 'Commands:'
|
48
|
+
commands.each do |cmd|
|
49
|
+
$stdout.printf " %-#{length_of_longest_command}s %s\n",
|
50
|
+
cmd.command_name,
|
51
|
+
cmd.command_summary
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.commands
|
56
|
+
return @commands if @commands
|
57
|
+
klasses = Roark::CLI.constants.reject {|c| [:Shared].include? c}
|
58
|
+
@commands = klasses.map { |klass| Roark::CLI.const_get(klass).new }
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.length_of_longest_command
|
62
|
+
commands.map { |c| c.command_name.length }.max
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Roark
|
2
|
+
class Instance
|
3
|
+
|
4
|
+
require "forwardable"
|
5
|
+
|
6
|
+
extend Forwardable
|
7
|
+
|
8
|
+
def_delegators :stack, :destroy, :exists?, :in_progress?, :instance_id, :success?
|
9
|
+
|
10
|
+
def initialize(args)
|
11
|
+
@aws = args[:aws]
|
12
|
+
@name = args[:name]
|
13
|
+
@logger = Roark.logger
|
14
|
+
end
|
15
|
+
|
16
|
+
def create(args)
|
17
|
+
parameters = args[:parameters]
|
18
|
+
template = args[:template]
|
19
|
+
|
20
|
+
stack.create :name => @name,
|
21
|
+
:parameters => parameters,
|
22
|
+
:template => template
|
23
|
+
end
|
24
|
+
|
25
|
+
def create_ami_from_instance
|
26
|
+
create_ami.create :name => @name,
|
27
|
+
:instance_id => instance_id
|
28
|
+
end
|
29
|
+
|
30
|
+
def stop
|
31
|
+
stop_instance.stop instance_id
|
32
|
+
end
|
33
|
+
|
34
|
+
def status
|
35
|
+
instance_status.status instance_id
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def stack
|
41
|
+
@stack ||= Stack.new :aws => @aws, :name => @name
|
42
|
+
end
|
43
|
+
|
44
|
+
def create_ami
|
45
|
+
@create_ami ||= Roark::Aws::Ec2::CreateAmi.new @aws
|
46
|
+
end
|
47
|
+
|
48
|
+
def stop_instance
|
49
|
+
@stop_instance ||= Roark::Aws::Ec2::StopInstance.new @aws
|
50
|
+
end
|
51
|
+
|
52
|
+
def instance_status
|
53
|
+
@instance_status ||= Roark::Aws::Ec2::InstanceStatus.new @aws
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
data/lib/roark/stack.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
class Stack
|
2
|
+
|
3
|
+
def initialize(args)
|
4
|
+
@aws = args[:aws]
|
5
|
+
@name = args[:name]
|
6
|
+
@region = @aws.region
|
7
|
+
@logger = Roark.logger
|
8
|
+
end
|
9
|
+
|
10
|
+
def create(args)
|
11
|
+
@logger.info "Creating Cloud Formation stack '#{@name}' in '#{@region}'."
|
12
|
+
create_stack.create :name => @name,
|
13
|
+
:parameters => args[:parameters],
|
14
|
+
:template => args[:template]
|
15
|
+
end
|
16
|
+
|
17
|
+
def destroy
|
18
|
+
@logger.info "Destroying Cloud Formation stack '#{@name}'."
|
19
|
+
destroy_stack.destroy @name
|
20
|
+
end
|
21
|
+
|
22
|
+
def exists?
|
23
|
+
stack_status.exists? @name
|
24
|
+
end
|
25
|
+
|
26
|
+
def in_progress?
|
27
|
+
status =~ /^CREATE_IN_PROGRESS$/
|
28
|
+
end
|
29
|
+
|
30
|
+
def success?
|
31
|
+
status =~ /^CREATE_COMPLETE$/
|
32
|
+
end
|
33
|
+
|
34
|
+
def instance_id
|
35
|
+
outputs.find {|o| o.key == 'InstanceId'}.value
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def status
|
41
|
+
stack_status.status @name
|
42
|
+
end
|
43
|
+
|
44
|
+
def outputs
|
45
|
+
stack_outputs.outputs @name
|
46
|
+
end
|
47
|
+
|
48
|
+
def create_stack
|
49
|
+
@create_stack ||= Roark::Aws::CloudFormation::CreateStack.new @aws
|
50
|
+
end
|
51
|
+
|
52
|
+
def destroy_stack
|
53
|
+
@destroy_stack ||= Roark::Aws::CloudFormation::DestroyStack.new @aws
|
54
|
+
end
|
55
|
+
|
56
|
+
def stack_outputs
|
57
|
+
@stack_outputs ||= Roark::Aws::CloudFormation::StackOutputs.new @aws
|
58
|
+
end
|
59
|
+
|
60
|
+
def stack_status
|
61
|
+
@stack_status ||= Roark::Aws::CloudFormation::StackStatus.new @aws
|
62
|
+
end
|
63
|
+
end
|
data/lib/roark.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require "roark/aws"
|
2
|
+
require "roark/ami"
|
3
|
+
require "roark/ami_create_workflow"
|
4
|
+
require "roark/instance"
|
5
|
+
require "roark/response"
|
6
|
+
require "roark/stack"
|
7
|
+
require "roark/version"
|
8
|
+
|
9
|
+
require "logger"
|
10
|
+
|
11
|
+
module Roark
|
12
|
+
module_function
|
13
|
+
|
14
|
+
def logger(logger=nil)
|
15
|
+
@logger ||= logger ? logger : Logger.new(STDOUT)
|
16
|
+
end
|
17
|
+
end
|
data/roark.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'roark/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "roark"
|
8
|
+
spec.version = Roark::VERSION
|
9
|
+
spec.authors = ["Brett Weaver"]
|
10
|
+
spec.email = ["brett@weav.net"]
|
11
|
+
spec.description = %q{Library and CLI to build AMIs from Instances created via Cloud Formation.}
|
12
|
+
spec.summary = %q{Howard Roark, master architect and builder of AMIs.}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency "rspec"
|
24
|
+
|
25
|
+
spec.add_runtime_dependency "aws-sdk", "1.11.2"
|
26
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Roark::AmiCreateWorkflow do
|
4
|
+
before do
|
5
|
+
logger_stub = stub 'logger'
|
6
|
+
@response_stub = mock 'response'
|
7
|
+
Roark.logger logger_stub
|
8
|
+
Roark.logger.stub :info => true
|
9
|
+
@ami_mock = mock 'ami mock'
|
10
|
+
@ami_create_workflow = Roark::AmiCreateWorkflow.new :ami => @ami_mock,
|
11
|
+
:parameters => { 'key' => 'val' },
|
12
|
+
:template => 'template'
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should create and execute a new workflow" do
|
16
|
+
@response_stub.stub :success? => true
|
17
|
+
@ami_mock.should_receive(:create_instance).with(:parameters => { 'key' => 'val' },
|
18
|
+
:template => 'template').and_return @response_stub
|
19
|
+
@ami_mock.should_receive(:wait_for_instance).and_return @response_stub
|
20
|
+
@ami_mock.should_receive(:stop_instance).and_return @response_stub
|
21
|
+
@ami_mock.should_receive(:wait_for_instance_to_stop).and_return @response_stub
|
22
|
+
@ami_mock.should_receive(:create_ami).and_return @response_stub
|
23
|
+
@ami_mock.should_receive(:wait_for_ami).and_return @response_stub
|
24
|
+
@ami_mock.should_receive(:destroy_instance).and_return @response_stub
|
25
|
+
expect(@ami_create_workflow.execute.success?).to be_true
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should raise AmiCreateWorkflowError exception" do
|
29
|
+
@response_stub.stub :success? => false, :message => 'error'
|
30
|
+
@ami_mock.should_receive(:create_instance).with(:parameters => { 'key' => 'val' },
|
31
|
+
:template => 'template').and_return @response_stub
|
32
|
+
expect(@ami_create_workflow.execute.success?).to be_false
|
33
|
+
end
|
34
|
+
end
|
data/spec/ami_spec.rb
ADDED
@@ -0,0 +1,217 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Roark::Ami do
|
4
|
+
before do
|
5
|
+
logger_stub = stub 'logger stub'
|
6
|
+
Roark.logger.stub :info => true
|
7
|
+
|
8
|
+
@aws_mock = mock "aws connection mock"
|
9
|
+
@aws_mock.stub :region => 'us-west-1'
|
10
|
+
init_args = { :aws => @aws_mock,
|
11
|
+
:name => 'test-ami' }
|
12
|
+
|
13
|
+
@ami = Roark::Ami.new init_args
|
14
|
+
end
|
15
|
+
|
16
|
+
context "testing instance methods" do
|
17
|
+
before do
|
18
|
+
@instance_mock = mock 'instance mock'
|
19
|
+
Roark::Instance.should_receive(:new).
|
20
|
+
with(:aws => @aws_mock,
|
21
|
+
:name => 'test-ami').
|
22
|
+
and_return @instance_mock
|
23
|
+
@instance_mock.stub :instance_id => 'i-1234abcd'
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "#create_instance" do
|
27
|
+
it "should create on instance" do
|
28
|
+
args = { :parameters => 'parameters',
|
29
|
+
:template => 'template' }
|
30
|
+
@instance_mock.should_receive(:create).with args
|
31
|
+
expect(@ami.create_instance(args).success?).to be_true
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should return unsuccesful if an AWS exception is raised" do
|
35
|
+
args = { :parameters => 'parameters',
|
36
|
+
:template => 'template' }
|
37
|
+
@instance_mock.should_receive(:create).and_raise AWS::Errors::Base.new "error"
|
38
|
+
expect(@ami.create_instance(args).success?).to be_false
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "#create_ami" do
|
43
|
+
it "should call create_ami_from_instance on instance and return ami" do
|
44
|
+
ami_mock = mock 'ami'
|
45
|
+
@instance_mock.stub :create_ami_from_instance => ami_mock
|
46
|
+
ami_mock.stub :id => 'ami-12345678'
|
47
|
+
expect(@ami.create_ami.success?).to be_true
|
48
|
+
expect(@ami.ami_id).to eq('ami-12345678')
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should return unsuccesful if an AWS exception is raised" do
|
52
|
+
ami_mock = mock 'ami'
|
53
|
+
@instance_mock.should_receive(:create_ami_from_instance).
|
54
|
+
and_raise AWS::Errors::Base.new "error"
|
55
|
+
expect(@ami.create_ami.success?).to be_false
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "#stop_instance" do
|
60
|
+
it "should call stop on instance" do
|
61
|
+
@instance_mock.should_receive(:stop)
|
62
|
+
expect(@ami.stop_instance.success?).to be_true
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should return unsuccesful if an AWS exception is raised" do
|
66
|
+
@instance_mock.should_receive(:stop).
|
67
|
+
and_raise AWS::Errors::Base.new "error"
|
68
|
+
expect(@ami.stop_instance.success?).to be_false
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe "#destroy_instance" do
|
73
|
+
it "should call destroy on instance" do
|
74
|
+
@instance_mock.should_receive(:destroy)
|
75
|
+
expect(@ami.destroy_instance.success?).to be_true
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should return unsuccesful if an AWS exception is raised" do
|
79
|
+
@instance_mock.should_receive(:destroy).
|
80
|
+
and_raise AWS::Errors::Base.new "error"
|
81
|
+
expect(@ami.destroy_instance.success?).to be_false
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe "#wait_for_instance_to_stop" do
|
86
|
+
it "should sleep until instance is stopped" do
|
87
|
+
@instance_mock.stub(:status).and_return(:available, :stopped)
|
88
|
+
@ami.should_receive(:sleep).with(15)
|
89
|
+
expect(@ami.wait_for_instance_to_stop.success?).to be_true
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe "#wait_for_instance" do
|
94
|
+
it "should sleep until the instance is not in state in_progress" do
|
95
|
+
@instance_mock.stub(:in_progress?).and_return(true, false)
|
96
|
+
@instance_mock.stub :exists? => true
|
97
|
+
@ami.should_receive(:sleep).with(60)
|
98
|
+
@instance_mock.stub :success? => true
|
99
|
+
expect(@ami.wait_for_instance.success?).to be_true
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe "#wait_for_instance" do
|
104
|
+
it "should sleep until the instance exists" do
|
105
|
+
@instance_mock.stub :in_progress? => false
|
106
|
+
@instance_mock.stub(:exists?).and_return(false, true)
|
107
|
+
@ami.should_receive(:sleep).with(60)
|
108
|
+
@instance_mock.stub :success? => true
|
109
|
+
expect(@ami.wait_for_instance.success?).to be_true
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
describe "#wait_for_instance" do
|
114
|
+
it "should return false if instance create was not succesful" do
|
115
|
+
@instance_mock.stub :in_progress? => false
|
116
|
+
@instance_mock.stub :exists? => true
|
117
|
+
@instance_mock.stub :success? => false
|
118
|
+
expect(@ami.wait_for_instance.success?).to be_false
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
describe "#instance_id" do
|
123
|
+
it "should call instance_id on instance" do
|
124
|
+
@instance_mock.stub :instance_id => 'i-12345678'
|
125
|
+
expect(@ami.instance_id).to eq('i-12345678')
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
context "testing state methods" do
|
131
|
+
before do
|
132
|
+
@ec2_ami_state_mock = mock 'ec2 ami state'
|
133
|
+
Roark::Aws::Ec2::AmiState.should_receive(:new).
|
134
|
+
with(@aws_mock).
|
135
|
+
and_return @ec2_ami_state_mock
|
136
|
+
end
|
137
|
+
|
138
|
+
describe "#available?" do
|
139
|
+
it "should return true if the ami is in state available" do
|
140
|
+
@ec2_ami_state_mock.stub :state => :available
|
141
|
+
expect(@ami.available?).to be_true
|
142
|
+
end
|
143
|
+
|
144
|
+
it "should return false if the ami is not in state available" do
|
145
|
+
@ec2_ami_state_mock.stub :state => :pending
|
146
|
+
expect(@ami.available?).to be_false
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
describe "#pending?" do
|
151
|
+
it "should return true if the ami is in state pending" do
|
152
|
+
@ec2_ami_state_mock.stub :state => :pending
|
153
|
+
expect(@ami.pending?).to be_true
|
154
|
+
end
|
155
|
+
|
156
|
+
it "should return false if the ami is not in state pending" do
|
157
|
+
@ec2_ami_state_mock.stub :state => :stopped
|
158
|
+
expect(@ami.pending?).to be_false
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
describe "#exists?" do
|
163
|
+
it "should return true if the ami exists" do
|
164
|
+
@ec2_ami_state_mock.stub :exists? => true
|
165
|
+
expect(@ami.exists?).to be_true
|
166
|
+
end
|
167
|
+
|
168
|
+
it "should return false if the ami does not exist" do
|
169
|
+
@ec2_ami_state_mock.stub :exists? => false
|
170
|
+
expect(@ami.exists?).to be_false
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
describe "#state" do
|
175
|
+
it "should call Ec2::AmiState for ami state" do
|
176
|
+
@ec2_ami_state_mock.stub :state => :available
|
177
|
+
expect(@ami.state).to eq(:available)
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
describe "#wait_for_ami" do
|
182
|
+
it "should wait for the ami to not be in state pending" do
|
183
|
+
@ec2_ami_state_mock.stub(:state).and_return(:pending, :available)
|
184
|
+
@ec2_ami_state_mock.stub :exists? => true
|
185
|
+
@ami.should_receive(:sleep).with(15)
|
186
|
+
expect(@ami.wait_for_ami.success?).to be_true
|
187
|
+
end
|
188
|
+
|
189
|
+
it "should wait for the ami if it does not yet exists" do
|
190
|
+
@ec2_ami_state_mock.stub(:exists?).and_return(false, true)
|
191
|
+
@ec2_ami_state_mock.stub :state => :available
|
192
|
+
@ami.should_receive(:sleep).with(15)
|
193
|
+
expect(@ami.wait_for_ami.success?).to be_true
|
194
|
+
end
|
195
|
+
|
196
|
+
it "should return false if the ami is not in state available" do
|
197
|
+
@ec2_ami_state_mock.stub :state => :failed, :exists? => true
|
198
|
+
expect(@ami.wait_for_ami.success?).to be_false
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
context "testing ami methods" do
|
204
|
+
describe "#destroy" do
|
205
|
+
it "should call destroy on Ec2::DestroyAmi" do
|
206
|
+
@ami.ami_id = 'ami-12345678'
|
207
|
+
ec2_destroy_ami_mock = mock 'aws_destroy_ami'
|
208
|
+
Roark::Aws::Ec2::DestroyAmi.should_receive(:new).
|
209
|
+
with(@aws_mock).
|
210
|
+
and_return ec2_destroy_ami_mock
|
211
|
+
ec2_destroy_ami_mock.should_receive(:destroy).with('ami-12345678')
|
212
|
+
expect(@ami.destroy.success?).to be_true
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Roark::Aws::CloudFormation::CreateStack do
|
4
|
+
describe "#create" do
|
5
|
+
it "should create the requestd stack" do
|
6
|
+
stacks_mock = mock 'stacks'
|
7
|
+
cf_stub = stub 'cf', :stacks => stacks_mock
|
8
|
+
connection_stub = stub 'connection', :cf => cf_stub
|
9
|
+
create_stack = Roark::Aws::CloudFormation::CreateStack.new connection_stub
|
10
|
+
stacks_mock.should_receive(:create).
|
11
|
+
with("test123", "{\"some\":\"json\"}",
|
12
|
+
{ :capabilities => ["CAPABILITY_IAM"],
|
13
|
+
:parameters => [{ :parameter_key => "key",
|
14
|
+
:parameter_value => "val"}]})
|
15
|
+
create_stack.create :name => 'test123',
|
16
|
+
:parameters => { 'key' => 'val' },
|
17
|
+
:template => "{\"some\":\"json\"}"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|