simple_deploy 0.7.2 → 0.7.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|