simple_deploy 0.7.2 → 0.7.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/CHANGELOG.md +6 -0
- data/lib/simple_deploy/aws/cloud_formation/error.rb +32 -0
- data/lib/simple_deploy/aws/cloud_formation.rb +76 -0
- data/lib/simple_deploy/aws/instance_reader.rb +59 -0
- data/lib/simple_deploy/aws/simpledb.rb +52 -0
- data/lib/simple_deploy/aws.rb +4 -0
- data/lib/simple_deploy/cli/attributes.rb +7 -18
- data/lib/simple_deploy/cli/clone.rb +9 -19
- data/lib/simple_deploy/cli/create.rb +5 -14
- data/lib/simple_deploy/cli/deploy.rb +8 -11
- data/lib/simple_deploy/cli/destroy.rb +4 -10
- data/lib/simple_deploy/cli/environments.rb +1 -1
- data/lib/simple_deploy/cli/events.rb +5 -11
- data/lib/simple_deploy/cli/execute.rb +6 -9
- data/lib/simple_deploy/cli/instances.rb +4 -9
- data/lib/simple_deploy/cli/list.rb +5 -10
- data/lib/simple_deploy/cli/outputs.rb +5 -11
- data/lib/simple_deploy/cli/parameters.rb +5 -11
- data/lib/simple_deploy/cli/protect.rb +5 -10
- data/lib/simple_deploy/cli/resources.rb +5 -11
- data/lib/simple_deploy/cli/shared.rb +6 -6
- data/lib/simple_deploy/cli/status.rb +5 -11
- data/lib/simple_deploy/cli/template.rb +8 -13
- data/lib/simple_deploy/cli/update.rb +6 -10
- data/lib/simple_deploy/configuration.rb +102 -0
- data/lib/simple_deploy/entry.rb +71 -0
- data/lib/simple_deploy/entry_lister.rb +30 -0
- data/lib/simple_deploy/exceptions.rb +8 -0
- data/lib/simple_deploy/misc/attribute_merger.rb +2 -5
- data/lib/simple_deploy/notifier/campfire.rb +15 -12
- data/lib/simple_deploy/notifier.rb +6 -11
- data/lib/simple_deploy/stack/deployment/status.rb +5 -3
- data/lib/simple_deploy/stack/deployment.rb +8 -10
- data/lib/simple_deploy/stack/execute.rb +2 -3
- data/lib/simple_deploy/stack/output_mapper.rb +1 -4
- data/lib/simple_deploy/stack/ssh.rb +4 -4
- data/lib/simple_deploy/stack/{stack_attribute_formater.rb → stack_attribute_formatter.rb} +4 -6
- data/lib/simple_deploy/stack/stack_creator.rb +46 -0
- data/lib/simple_deploy/stack/stack_destroyer.rb +19 -0
- data/lib/simple_deploy/stack/stack_formatter.rb +25 -0
- data/lib/simple_deploy/stack/stack_lister.rb +18 -0
- data/lib/simple_deploy/stack/stack_reader.rb +56 -0
- data/lib/simple_deploy/stack/stack_updater.rb +67 -0
- data/lib/simple_deploy/stack/status.rb +53 -0
- data/lib/simple_deploy/stack.rb +89 -37
- data/lib/simple_deploy/version.rb +1 -1
- data/lib/simple_deploy.rb +31 -1
- data/simple_deploy.gemspec +6 -3
- data/spec/aws/cloud_formation/error_spec.rb +50 -0
- data/spec/aws/cloud_formation_spec.rb +207 -0
- data/spec/aws/instance_reader_spec.rb +96 -0
- data/spec/aws/simpledb_spec.rb +89 -0
- data/spec/cli/attributes_spec.rb +5 -15
- data/spec/cli/clone_spec.rb +14 -27
- data/spec/cli/create_spec.rb +11 -18
- data/spec/cli/deploy_spec.rb +24 -63
- data/spec/cli/destroy_spec.rb +7 -25
- data/spec/cli/outputs_spec.rb +12 -17
- data/spec/cli/protect_spec.rb +68 -106
- data/spec/cli/shared_spec.rb +12 -15
- data/spec/cli/update_spec.rb +9 -27
- data/spec/config_spec.rb +47 -14
- data/spec/contexts/config_contexts.rb +28 -0
- data/spec/contexts/logger_contexts.rb +9 -0
- data/spec/contexts/stack_contexts.rb +40 -0
- data/spec/entry_lister_spec.rb +31 -0
- data/spec/entry_spec.rb +86 -0
- data/spec/misc/attribute_merger_spec.rb +3 -8
- data/spec/notifier/campfire_spec.rb +21 -61
- data/spec/notifier_spec.rb +18 -40
- data/spec/spec_helper.rb +10 -0
- data/spec/stack/deployment/status_spec.rb +13 -13
- data/spec/stack/deployment_spec.rb +26 -21
- data/spec/stack/execute_spec.rb +7 -3
- data/spec/stack/output_mapper_spec.rb +3 -15
- data/spec/stack/ssh_spec.rb +14 -13
- data/spec/stack/{stack_attribute_formater_spec.rb → stack_attribute_formatter_spec.rb} +19 -16
- data/spec/stack/stack_creator_spec.rb +46 -0
- data/spec/stack/stack_destroyer_spec.rb +18 -0
- data/spec/stack/stack_formatter_spec.rb +37 -0
- data/spec/stack/stack_lister_spec.rb +17 -0
- data/spec/stack/stack_reader_spec.rb +81 -0
- data/spec/stack/stack_updater_spec.rb +79 -0
- data/spec/stack/status_spec.rb +106 -0
- data/spec/stack_spec.rb +160 -133
- metadata +112 -19
- data/.rvmrc +0 -1
- data/lib/simple_deploy/config.rb +0 -87
data/lib/simple_deploy.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
|
+
require 'simple_deploy/aws'
|
1
2
|
require 'simple_deploy/env'
|
3
|
+
require 'simple_deploy/entry'
|
4
|
+
require 'simple_deploy/entry_lister'
|
2
5
|
require 'simple_deploy/exceptions'
|
3
|
-
require 'simple_deploy/
|
6
|
+
require 'simple_deploy/configuration'
|
4
7
|
require 'simple_deploy/artifact'
|
5
8
|
require 'simple_deploy/stack'
|
6
9
|
require 'simple_deploy/misc'
|
@@ -9,3 +12,30 @@ require 'simple_deploy/notifier'
|
|
9
12
|
require 'simple_deploy/logger'
|
10
13
|
require 'simple_deploy/version'
|
11
14
|
require 'simple_deploy/backoff'
|
15
|
+
|
16
|
+
module SimpleDeploy
|
17
|
+
module_function
|
18
|
+
|
19
|
+
def create_config(environment, custom_config = {})
|
20
|
+
raise SimpleDeploy::Exceptions::IllegalStateException.new(
|
21
|
+
'environment is not defined') unless environment
|
22
|
+
|
23
|
+
@config = SimpleDeploy::Configuration.configure environment, custom_config
|
24
|
+
end
|
25
|
+
|
26
|
+
def config
|
27
|
+
@config
|
28
|
+
end
|
29
|
+
|
30
|
+
def release_config
|
31
|
+
@config = nil
|
32
|
+
end
|
33
|
+
|
34
|
+
def environments(custom_config = {})
|
35
|
+
SimpleDeploy::Configuration.environments custom_config
|
36
|
+
end
|
37
|
+
|
38
|
+
def logger(log_level = 'info')
|
39
|
+
@logger ||= SimpleDeployLogger.new :log_level => log_level
|
40
|
+
end
|
41
|
+
end
|
data/simple_deploy.gemspec
CHANGED
@@ -20,10 +20,13 @@ Gem::Specification.new do |s|
|
|
20
20
|
|
21
21
|
s.add_development_dependency "fakefs", "~> 0.4.2"
|
22
22
|
s.add_development_dependency "rake"
|
23
|
-
s.add_development_dependency "rspec", "~> 2.
|
23
|
+
s.add_development_dependency "rspec", "~> 2.13.0"
|
24
|
+
s.add_development_dependency "simplecov", "~> 0.7.1"
|
25
|
+
s.add_development_dependency "timecop", "~> 0.6.1"
|
24
26
|
|
25
27
|
s.add_runtime_dependency "capistrano", "= 2.13.5"
|
26
|
-
s.add_runtime_dependency "
|
27
|
-
s.add_runtime_dependency "tinder", "= 1.8.0"
|
28
|
+
s.add_runtime_dependency "esbit", "~> 0.0.4"
|
28
29
|
s.add_runtime_dependency "trollop", "= 2.0"
|
30
|
+
s.add_runtime_dependency "fog", "= 1.10.0"
|
31
|
+
s.add_runtime_dependency "xml-simple", "= 1.1.2"
|
29
32
|
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SimpleDeploy::AWS::CloudFormation::Error do
|
4
|
+
include_context 'double stubbed config', :access_key => 'key',
|
5
|
+
:secret_key => 'XXX',
|
6
|
+
:region => 'us-west-1'
|
7
|
+
include_context 'double stubbed logger'
|
8
|
+
|
9
|
+
before do
|
10
|
+
@exception_stub1 = stub 'Excon::Response'
|
11
|
+
@exception_stub1.stub(:response).and_return(@exception_stub1)
|
12
|
+
@exception_stub1.stub(:body).and_return('<opt><Error><Message>No updates are to be performed.</Message></Error></opt>')
|
13
|
+
|
14
|
+
@exception_stub2 = stub 'Excon::Response'
|
15
|
+
@exception_stub2.stub(:response).and_return(@exception_stub2)
|
16
|
+
@exception_stub2.stub(:body).and_return('<opt><Error><Message>Oops.</Message></Error></opt>')
|
17
|
+
|
18
|
+
@exception_stub3 = stub 'Excon::Response'
|
19
|
+
@exception_stub3.stub(:response).and_return(@exception_stub3)
|
20
|
+
@exception_stub3.stub(:body).and_return('<opt><Error><Message>Stack:test does not exist</Message></Error></opt>')
|
21
|
+
end
|
22
|
+
|
23
|
+
describe 'process' do
|
24
|
+
it 'should process no update messages' do
|
25
|
+
error = SimpleDeploy::AWS::CloudFormation::Error.new :exception => @exception_stub1
|
26
|
+
expect { error.process }.to_not raise_error SimpleDeploy::Exceptions::CloudFormationError
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should re-raise unkonwn errors as SimpleDeploy::CloudFormationError' do
|
30
|
+
error = SimpleDeploy::AWS::CloudFormation::Error.new :exception => @exception_stub2
|
31
|
+
|
32
|
+
lambda { error.process }.should raise_error SimpleDeploy::Exceptions::CloudFormationError
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should re-raise unkonwn errors as SimpleDeploy::CloudFormationError and set mesg' do
|
36
|
+
error = SimpleDeploy::AWS::CloudFormation::Error.new :exception => @exception_stub2
|
37
|
+
begin
|
38
|
+
error.process
|
39
|
+
rescue SimpleDeploy::Exceptions::CloudFormationError => e
|
40
|
+
e.message.should == "Oops."
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should reaise stck unkown messages as SimpleDeploy::UnknownStack' do
|
45
|
+
error = SimpleDeploy::AWS::CloudFormation::Error.new :exception => @exception_stub3
|
46
|
+
lambda { error.process }.should raise_error SimpleDeploy::Exceptions::UnknownStack
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,207 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SimpleDeploy::AWS::CloudFormation do
|
4
|
+
include_context 'double stubbed config', :access_key => 'key',
|
5
|
+
:secret_key => 'XXX',
|
6
|
+
:region => 'us-west-1'
|
7
|
+
include_context 'double stubbed logger'
|
8
|
+
|
9
|
+
before do
|
10
|
+
@error_stub = stub 'Error', :process => 'Processed Error'
|
11
|
+
@response_stub = stub 'Excon::Response', :body => {
|
12
|
+
'Stacks' => [{'StackStatus' => 'green', 'Outputs' => [{'key' => 'value'}]}],
|
13
|
+
'StackResources' => [{'StackName' => 'my_stack'}],
|
14
|
+
'StackEvents' => ['event1', 'event2'],
|
15
|
+
'TemplateBody' => '{EIP: "string"}'
|
16
|
+
}
|
17
|
+
|
18
|
+
@cf_mock = mock 'CloudFormation'
|
19
|
+
Fog::AWS::CloudFormation.stub(:new).and_return(@cf_mock)
|
20
|
+
|
21
|
+
@args = {
|
22
|
+
:parameters => { 'parameter1' => 'my_param' },
|
23
|
+
:name => 'my_stack',
|
24
|
+
:template => 'my_template'
|
25
|
+
}
|
26
|
+
|
27
|
+
@exception = Exception.new('Failed')
|
28
|
+
|
29
|
+
@cf = SimpleDeploy::AWS::CloudFormation.new
|
30
|
+
end
|
31
|
+
|
32
|
+
after do
|
33
|
+
SimpleDeploy.release_config
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "create" do
|
37
|
+
it "should create the stack on Cloud Formation" do
|
38
|
+
@cf_mock.should_receive(:create_stack).with('my_stack',
|
39
|
+
{ 'Capabilities' => ['CAPABILITY_IAM'],
|
40
|
+
'TemplateBody' => 'my_template',
|
41
|
+
'Parameters' => { 'parameter1' => 'my_param' }
|
42
|
+
})
|
43
|
+
|
44
|
+
@cf.create(@args)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should trap and re-raise exceptions as SimpleDeploy::Exceptions::CloudFormationError" do
|
48
|
+
@cf_mock.should_receive(:create_stack).with('my_stack',
|
49
|
+
{ 'Capabilities' => ['CAPABILITY_IAM'],
|
50
|
+
'TemplateBody' => 'my_template',
|
51
|
+
'Parameters' => { 'parameter1' => 'my_param' }
|
52
|
+
}).and_raise(@exception)
|
53
|
+
|
54
|
+
SimpleDeploy::AWS::CloudFormation::Error.should_receive(:new).
|
55
|
+
with(:exception => @exception).
|
56
|
+
and_raise SimpleDeploy::Exceptions::CloudFormationError.new('failed')
|
57
|
+
|
58
|
+
lambda { @cf.create @args }.
|
59
|
+
should raise_error SimpleDeploy::Exceptions::CloudFormationError
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe "update" do
|
64
|
+
it "should update the stack on Cloud Formation" do
|
65
|
+
@cf_mock.should_receive(:update_stack).with('my_stack',
|
66
|
+
{ 'Capabilities' => ['CAPABILITY_IAM'],
|
67
|
+
'TemplateBody' => 'my_template',
|
68
|
+
'Parameters' => { 'parameter1' => 'my_param' }
|
69
|
+
})
|
70
|
+
|
71
|
+
@cf.update(@args)
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should trap and re-raise exceptions as SimpleDeploy::Exceptions::CloudFormationError" do
|
75
|
+
@cf_mock.should_receive(:update_stack).with('my_stack',
|
76
|
+
{ 'Capabilities' => ['CAPABILITY_IAM'],
|
77
|
+
'TemplateBody' => 'my_template',
|
78
|
+
'Parameters' => { 'parameter1' => 'my_param' }
|
79
|
+
}).and_raise(@exception)
|
80
|
+
SimpleDeploy::AWS::CloudFormation::Error.should_receive(:new).
|
81
|
+
with(:exception => @exception).
|
82
|
+
and_raise SimpleDeploy::Exceptions::CloudFormationError.new('failed')
|
83
|
+
|
84
|
+
lambda { @cf.update(@args) }.
|
85
|
+
should raise_error SimpleDeploy::Exceptions::CloudFormationError
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
describe 'destroy' do
|
91
|
+
it "should delete the stack on Cloud Formation" do
|
92
|
+
@cf_mock.should_receive(:delete_stack).with('my_stack')
|
93
|
+
|
94
|
+
@cf.destroy('my_stack')
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should trap and re-raise exceptions as SimpleDeploy::Exceptions::CloudFormationError" do
|
98
|
+
@cf_mock.should_receive(:delete_stack).
|
99
|
+
with('my_stack').
|
100
|
+
and_raise @exception
|
101
|
+
SimpleDeploy::AWS::CloudFormation::Error.should_receive(:new).
|
102
|
+
with(:exception => @exception).
|
103
|
+
and_raise SimpleDeploy::Exceptions::CloudFormationError.new('failed')
|
104
|
+
|
105
|
+
lambda { @cf.destroy('my_stack') }.
|
106
|
+
should raise_error SimpleDeploy::Exceptions::CloudFormationError
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
|
111
|
+
describe 'describe_stack' do
|
112
|
+
it "should return the Cloud Formation description of the stack" do
|
113
|
+
@cf_mock.should_receive(:describe_stacks).with('StackName' => 'my_stack').and_return(@response_stub)
|
114
|
+
|
115
|
+
@cf.describe_stack('my_stack').should == [{'StackStatus' => 'green', 'Outputs' => [{'key' => 'value'}]}]
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should trap and re-raise exceptions as SimpleDeploy::Exceptions::CloudFormationError" do
|
119
|
+
@cf_mock.should_receive(:describe_stacks).
|
120
|
+
with('StackName' => 'my_stack').
|
121
|
+
and_raise @exception
|
122
|
+
SimpleDeploy::AWS::CloudFormation::Error.should_receive(:new).
|
123
|
+
with(:exception => @exception).
|
124
|
+
and_raise SimpleDeploy::Exceptions::CloudFormationError.new('failed')
|
125
|
+
|
126
|
+
lambda { @cf.describe_stack('my_stack') }.
|
127
|
+
should raise_error SimpleDeploy::Exceptions::CloudFormationError
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
describe "stack_resources" do
|
132
|
+
it "should return the Cloud Formation description of the stack resources" do
|
133
|
+
@cf_mock.should_receive(:describe_stack_resources).with('StackName' => 'my_stack').and_return(@response_stub)
|
134
|
+
|
135
|
+
@cf.stack_resources('my_stack').should == [{'StackName' => 'my_stack'}]
|
136
|
+
end
|
137
|
+
|
138
|
+
it "should trap and re-raise exceptions as SimpleDeploy::Exceptions::CloudFormationError" do
|
139
|
+
@cf_mock.should_receive(:describe_stack_resources).
|
140
|
+
with('StackName' => 'my_stack').
|
141
|
+
and_raise @exception
|
142
|
+
SimpleDeploy::AWS::CloudFormation::Error.should_receive(:new).
|
143
|
+
with(:exception => @exception).
|
144
|
+
and_raise SimpleDeploy::Exceptions::CloudFormationError.new('failed')
|
145
|
+
|
146
|
+
lambda { @cf.stack_resources('my_stack') }.
|
147
|
+
should raise_error SimpleDeploy::Exceptions::CloudFormationError
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
describe "stack_events" do
|
152
|
+
it "should return the Cloud Formation description of the stack events" do
|
153
|
+
@cf_mock.should_receive(:describe_stack_events).with('my_stack').and_return(@response_stub)
|
154
|
+
|
155
|
+
@cf.stack_events('my_stack', 2).should == ['event1', 'event2']
|
156
|
+
end
|
157
|
+
|
158
|
+
it "should trap and re-raise exceptions as SimpleDeploy::Exceptions::CloudFormationError" do
|
159
|
+
@cf_mock.should_receive(:describe_stack_events).
|
160
|
+
with('my_stack').
|
161
|
+
and_raise @exception
|
162
|
+
|
163
|
+
SimpleDeploy::AWS::CloudFormation::Error.should_receive(:new).
|
164
|
+
with(:exception => @exception).
|
165
|
+
and_raise SimpleDeploy::Exceptions::CloudFormationError.new('failed')
|
166
|
+
|
167
|
+
lambda { @cf.stack_events('my_stack', 2) }.
|
168
|
+
should raise_error SimpleDeploy::Exceptions::CloudFormationError
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
describe "stack_status" do
|
173
|
+
it "should return the Cloud Formation status of the stack" do
|
174
|
+
@cf_mock.should_receive(:describe_stacks).with('StackName' => 'my_stack').and_return(@response_stub)
|
175
|
+
|
176
|
+
@cf.stack_status('my_stack').should == 'green'
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
describe "stack_outputs" do
|
181
|
+
it "should return the Cloud Formation outputs for the stack" do
|
182
|
+
@cf_mock.should_receive(:describe_stacks).with('StackName' => 'my_stack').and_return(@response_stub)
|
183
|
+
|
184
|
+
@cf.stack_outputs('my_stack').should == [{'key' => 'value'}]
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
describe "template" do
|
189
|
+
it "should return the Cloud Formation template for the stack" do
|
190
|
+
@cf_mock.should_receive(:get_template).with('my_stack').and_return(@response_stub)
|
191
|
+
|
192
|
+
@cf.template('my_stack').should == '{EIP: "string"}'
|
193
|
+
end
|
194
|
+
|
195
|
+
it "should trap and re-raise exceptions as SimpleDeploy::Exceptions::CloudFormationError" do
|
196
|
+
@cf_mock.should_receive(:get_template).
|
197
|
+
with('my_stack').
|
198
|
+
and_raise @exception
|
199
|
+
SimpleDeploy::AWS::CloudFormation::Error.should_receive(:new).
|
200
|
+
with(:exception => @exception).
|
201
|
+
and_raise SimpleDeploy::Exceptions::CloudFormationError.new('failed')
|
202
|
+
|
203
|
+
lambda { @cf.template('my_stack') }.
|
204
|
+
should raise_error SimpleDeploy::Exceptions::CloudFormationError
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SimpleDeploy::AWS::InstanceReader do
|
4
|
+
include_context 'double stubbed logger'
|
5
|
+
include_context 'double stubbed config', :access_key => 'key',
|
6
|
+
:secret_key => 'XXX',
|
7
|
+
:region => 'us-west-1'
|
8
|
+
|
9
|
+
describe "list_stack_instances" do
|
10
|
+
before do
|
11
|
+
@cloud_formation_mock = mock 'cloud formation'
|
12
|
+
@auto_scaling_groups_mock = mock 'auto scaling'
|
13
|
+
@ec2_mock = mock 'ec2'
|
14
|
+
|
15
|
+
instances = ['first',{ 'Instances' => [{ 'InstanceId' => 'i-000001' },
|
16
|
+
{ 'InstanceId' => 'i-000002' }] }]
|
17
|
+
body = { 'DescribeAutoScalingGroupsResult' => { 'AutoScalingGroups' => instances } }
|
18
|
+
@list_response = stub 'Fog::Response', :body => body, :any? => true
|
19
|
+
|
20
|
+
empty_body = { 'DescribeAutoScalingGroupsResult' => { 'AutoScalingGroups' => [] } }
|
21
|
+
@empty_response = stub 'Fog::Response', :body => empty_body
|
22
|
+
|
23
|
+
@describe_response = stub 'Excon::Response', :body => {
|
24
|
+
'reservationSet' => [{
|
25
|
+
'instanceSet' => [{'instanceState' => {'name' => 'running'}},
|
26
|
+
{'ipAddress' => '54.10.10.1'},
|
27
|
+
{'instanceId' => 'i-123456'},
|
28
|
+
{'privateIpAddress' => '192.168.1.1'}]}]
|
29
|
+
}
|
30
|
+
|
31
|
+
SimpleDeploy::AWS::CloudFormation.stub(:new).
|
32
|
+
and_return @cloud_formation_mock
|
33
|
+
end
|
34
|
+
|
35
|
+
context "with no ASGs" do
|
36
|
+
before do
|
37
|
+
@cloud_formation_mock.should_receive(:stack_resources).
|
38
|
+
with('stack').
|
39
|
+
and_return []
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should return an empty array" do
|
43
|
+
instance_reader = SimpleDeploy::AWS::InstanceReader.new
|
44
|
+
instance_reader.list_stack_instances('stack').should == []
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context "with an ASG" do
|
49
|
+
before do
|
50
|
+
stack_resource_results = [{'StackName' => 'stack',
|
51
|
+
'ResourceType' => 'AWS::AutoScaling::AutoScalingGroup',
|
52
|
+
'PhysicalResourceId' => 'asg1'}]
|
53
|
+
|
54
|
+
@cloud_formation_mock.should_receive(:stack_resources).
|
55
|
+
with('stack').
|
56
|
+
and_return stack_resource_results
|
57
|
+
|
58
|
+
Fog::AWS::AutoScaling.stub(:new).
|
59
|
+
and_return @auto_scaling_groups_mock
|
60
|
+
end
|
61
|
+
|
62
|
+
context "with no running instances" do
|
63
|
+
it "should return empty array" do
|
64
|
+
@auto_scaling_groups_mock.should_receive(:describe_auto_scaling_groups).
|
65
|
+
with('AutoScalingGroupNames' => ['asg1']).
|
66
|
+
and_return(@empty_response)
|
67
|
+
|
68
|
+
instance_reader = SimpleDeploy::AWS::InstanceReader.new
|
69
|
+
instance_reader.list_stack_instances('stack').should == []
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context "with running instances" do
|
74
|
+
it "should return the reservation set for each running instance" do
|
75
|
+
@auto_scaling_groups_mock.should_receive(:describe_auto_scaling_groups).
|
76
|
+
with('AutoScalingGroupNames' => ['asg1']).
|
77
|
+
and_return(@list_response)
|
78
|
+
|
79
|
+
Fog::Compute::AWS.stub(:new).
|
80
|
+
and_return @ec2_mock
|
81
|
+
@ec2_mock.should_receive(:describe_instances).
|
82
|
+
with('instance-state-name' => 'running',
|
83
|
+
'instance-id' => ['i-000001', 'i-000002']).
|
84
|
+
and_return @describe_response
|
85
|
+
|
86
|
+
instance_reader = SimpleDeploy::AWS::InstanceReader.new
|
87
|
+
instance_reader.list_stack_instances('stack').should == [{
|
88
|
+
'instanceSet' => [{'instanceState' => {'name' => 'running'}},
|
89
|
+
{'ipAddress' => '54.10.10.1'},
|
90
|
+
{'instanceId' => 'i-123456'},
|
91
|
+
{'privateIpAddress' => '192.168.1.1'}]}]
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SimpleDeploy::AWS::SimpleDB do
|
4
|
+
include_context 'double stubbed config', :access_key => 'key',
|
5
|
+
:secret_key => 'XXX',
|
6
|
+
:region => 'us-west-1'
|
7
|
+
|
8
|
+
before do
|
9
|
+
@response_stub = stub 'Excon::Response', :body => {
|
10
|
+
'RequestId' => 'rid',
|
11
|
+
'Domains' => ['domain1', 'domain2'],
|
12
|
+
'Items' => { 'item1' => { 'key' => ['value'] } },
|
13
|
+
'NextToken' => nil
|
14
|
+
}
|
15
|
+
@multi_response_stub = stub 'Excon::Response', :body => {
|
16
|
+
'RequestId' => 'rid',
|
17
|
+
'Domains' => ['domain1', 'domain2'],
|
18
|
+
'Items' => { 'item1-2' => { 'key' => ['value'] } },
|
19
|
+
'NextToken' => 'Chunk2'
|
20
|
+
}
|
21
|
+
|
22
|
+
@db_mock = mock 'SimpleDB'
|
23
|
+
Fog::AWS::SimpleDB.stub(:new).and_return(@db_mock)
|
24
|
+
@db_mock.stub(:list_domains).and_return(@response_stub)
|
25
|
+
|
26
|
+
@db = SimpleDeploy::AWS::SimpleDB.new
|
27
|
+
end
|
28
|
+
|
29
|
+
describe 'domains' do
|
30
|
+
it 'should return a list of domains' do
|
31
|
+
@db.domains.should == ['domain1', 'domain2']
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe 'domain_exists?' do
|
36
|
+
it 'should return true for existing domains' do
|
37
|
+
@db.domain_exists?('domain1').should be_true
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should return false for non-existent domains' do
|
41
|
+
@db.domain_exists?('baddomain1').should_not be_true
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe 'create_domain' do
|
46
|
+
it 'should create a new domain' do
|
47
|
+
@db_mock.should_receive(:create_domain).with('newdomain').and_return(@response_stub)
|
48
|
+
|
49
|
+
@db.create_domain('newdomain').body['RequestId'].should == 'rid'
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should not create a duplicate domain' do
|
53
|
+
@db_mock.should_not_receive(:create_domain)
|
54
|
+
|
55
|
+
@db.create_domain('domain1').should be_nil
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe 'put_attributes' do
|
60
|
+
it 'should update the specified domain' do
|
61
|
+
@db_mock.should_receive(:put_attributes).with('domain1', 'item1', { 'key' => 'value' }, {}).and_return(@response_stub)
|
62
|
+
|
63
|
+
@db.put_attributes('domain1', 'item1', { 'key' => 'value' }, {}).body['RequestId'].should == 'rid'
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe 'select' do
|
68
|
+
it 'should return query items' do
|
69
|
+
@db_mock.should_receive(:select).with('item1', { "ConsistentRead" => true, "NextToken" => nil } ).and_return(@response_stub)
|
70
|
+
|
71
|
+
@db.select('item1').should == { 'item1' => { 'key' => ['value'] } }
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'should return multiple chunks of query items' do
|
75
|
+
@db_mock.should_receive(:select).with('item1', { "ConsistentRead" => true, "NextToken" => nil } ).and_return(@multi_response_stub)
|
76
|
+
@db_mock.should_receive(:select).with('item1', { "ConsistentRead" => true, "NextToken" => 'Chunk2' } ).and_return(@response_stub)
|
77
|
+
|
78
|
+
@db.select('item1').should == { 'item1' => { 'key' => ['value'] }, 'item1-2' => { 'key' => ['value'] } }
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe 'delete' do
|
83
|
+
it 'should delete the attributes identified by domain and key' do
|
84
|
+
@db_mock.should_receive(:delete_attributes).with('domain1', 'item1').and_return(@response_stub)
|
85
|
+
|
86
|
+
@db.delete('domain1', 'item1').body['RequestId'].should == 'rid'
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|