roark 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/.gitignore +19 -0
  2. data/.travis.yml +5 -0
  3. data/CHANGELOG.md +3 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +75 -0
  7. data/Rakefile +8 -0
  8. data/bin/roark +6 -0
  9. data/examples/example.json +52 -0
  10. data/lib/roark/ami.rb +148 -0
  11. data/lib/roark/ami_create_workflow.rb +50 -0
  12. data/lib/roark/aws/cloud_formation/create_stack.rb +35 -0
  13. data/lib/roark/aws/cloud_formation/destroy_stack.rb +17 -0
  14. data/lib/roark/aws/cloud_formation/stack_outputs.rb +17 -0
  15. data/lib/roark/aws/cloud_formation/stack_status.rb +21 -0
  16. data/lib/roark/aws/cloud_formation.rb +4 -0
  17. data/lib/roark/aws/connection.rb +27 -0
  18. data/lib/roark/aws/ec2/ami_state.rb +19 -0
  19. data/lib/roark/aws/ec2/create_ami.rb +20 -0
  20. data/lib/roark/aws/ec2/destroy_ami.rb +34 -0
  21. data/lib/roark/aws/ec2/instance_status.rb +15 -0
  22. data/lib/roark/aws/ec2/stop_instance.rb +15 -0
  23. data/lib/roark/aws/ec2.rb +5 -0
  24. data/lib/roark/aws.rb +5 -0
  25. data/lib/roark/cli/create.rb +76 -0
  26. data/lib/roark/cli/destroy.rb +53 -0
  27. data/lib/roark/cli/shared.rb +28 -0
  28. data/lib/roark/cli.rb +66 -0
  29. data/lib/roark/instance.rb +56 -0
  30. data/lib/roark/response.rb +15 -0
  31. data/lib/roark/stack.rb +63 -0
  32. data/lib/roark/version.rb +3 -0
  33. data/lib/roark.rb +17 -0
  34. data/roark.gemspec +26 -0
  35. data/spec/ami_create_workflow_spec.rb +34 -0
  36. data/spec/ami_spec.rb +217 -0
  37. data/spec/aws/cloud_formation/create_stack_spec.rb +20 -0
  38. data/spec/aws/connection_spec.rb +26 -0
  39. data/spec/aws/ec2/ami_state_spec.rb +11 -0
  40. data/spec/aws/ec2/create_ami_spec.rb +17 -0
  41. data/spec/aws/ec2/destroy_ami_spec.rb +32 -0
  42. data/spec/create_stack_spec.rb +20 -0
  43. data/spec/instance_spec.rb +80 -0
  44. data/spec/response_spec.rb +21 -0
  45. data/spec/spec_helper.rb +4 -0
  46. data/spec/stack_spec.rb +99 -0
  47. 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
@@ -0,0 +1,15 @@
1
+ module Roark
2
+ class Response
3
+ attr_accessor :code, :message
4
+
5
+ def initialize(args={})
6
+ @code = args.fetch :code, 1
7
+ @message = args.fetch :message, ''
8
+ end
9
+
10
+ def success?
11
+ @code == 0
12
+ end
13
+
14
+ end
15
+ end
@@ -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
@@ -0,0 +1,3 @@
1
+ module Roark
2
+ VERSION = "0.0.1"
3
+ 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