stackster 0.4.2 → 0.4.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.
@@ -1,3 +1,9 @@
1
+ ## head:
2
+
3
+ ## 0.4.3 (03/14/2013)
4
+
5
+ * Properly return instances in an auto scaling group
6
+
1
7
  ## v0.4.2:
2
8
 
3
9
  * Fixed the handling of data from the select method
@@ -0,0 +1,22 @@
1
+ require 'fog'
2
+
3
+ module Stackster
4
+ class AWS
5
+ class AutoScalingGroups
6
+
7
+ def initialize(args)
8
+ c = args[:config]
9
+ @asg_id = args[:asg_id]
10
+ @connect = Fog::AWS::AutoScaling.new :aws_access_key_id => c.access_key,
11
+ :aws_secret_access_key => c.secret_key,
12
+ :region => c.region
13
+ end
14
+
15
+ def list_instances
16
+ body = @connect.describe_auto_scaling_groups('AutoScalingGroupNames' => [@asg_id]).body
17
+ result = body['DescribeAutoScalingGroupsResult']['AutoScalingGroups'].last
18
+ result['Instances'].map { |info| info['InstanceId'] }
19
+ end
20
+ end
21
+ end
22
+ end
@@ -7,18 +7,14 @@ module Stackster
7
7
  def initialize(args)
8
8
  c = args[:config]
9
9
  @connect = Fog::Compute::AWS.new :aws_access_key_id => c.access_key,
10
- :aws_secret_access_key => c.secret_key,
11
- :region => c.region
10
+ :aws_secret_access_key => c.secret_key,
11
+ :region => c.region
12
12
  end
13
13
 
14
- def describe_instances
15
- i = []
16
- @connect.describe_instances.body['reservationSet'].each do |instance|
17
- i << instance
18
- end
19
- i
14
+ def describe_instance(instance)
15
+ @connect.describe_instances('instance-state-name' => 'running',
16
+ 'instance-id' => instance).body['reservationSet']
20
17
  end
21
-
22
18
  end
23
19
  end
24
20
  end
data/lib/stackster/aws.rb CHANGED
@@ -2,3 +2,4 @@ require "stackster/aws/cloud_formation"
2
2
  require "stackster/aws/cloud_formation/error"
3
3
  require "stackster/aws/ec2"
4
4
  require "stackster/aws/simpledb"
5
+ require "stackster/aws/auto_scaling_groups"
@@ -6,17 +6,10 @@ module Stackster
6
6
  end
7
7
 
8
8
  def list_stack_instances(stack_name)
9
- h = []
10
- describe_instances.each do |instance|
11
- tag_set = instance['instancesSet'].first['tagSet']
12
- instance_stack_name = tag_set['aws:cloudformation:stack-name']
13
- if instance_stack_name && instance_stack_name == stack_name
14
- if instance_running? instance
15
- h << instance
16
- end
17
- end
18
- end
19
- h
9
+ @asg_id = auto_scaling_group_id(stack_name)
10
+ asg_instances = auto_scaling.list_instances if @asg_id
11
+ return [] unless asg_instances
12
+ ec2.describe_instance asg_instances
20
13
  end
21
14
 
22
15
  private
@@ -25,17 +18,26 @@ module Stackster
25
18
  @ec2 ||= AWS::EC2.new :config => @config
26
19
  end
27
20
 
28
- def get_instance_state(instance_hash)
29
- instance_hash['instancesSet'].first['instanceState']['name']
21
+ def auto_scaling
22
+ @auto_scaling ||= AWS::AutoScalingGroups.new :config => @config, :asg_id => @asg_id
30
23
  end
31
24
 
32
- def instance_running?(instance_hash)
33
- get_instance_state(instance_hash) == 'running'
25
+ def cloud_formation
26
+ @cloud_formation ||= AWS::CloudFormation.new :config => @config
34
27
  end
35
28
 
36
- def describe_instances
37
- ec2.describe_instances
29
+ def auto_scaling_group_id(stack_name)
30
+ cf_stack_resources = cloud_formation.stack_resources stack_name
31
+ parse_cf_stack_resources cf_stack_resources
38
32
  end
39
33
 
34
+ def parse_cf_stack_resources(cf_stack_resources)
35
+ cf_stack_resources.each do |resource|
36
+ if resource['ResourceType'] == 'AWS::AutoScaling::AutoScalingGroup'
37
+ return resource['PhysicalResourceId']
38
+ end
39
+ end
40
+ false
41
+ end
40
42
  end
41
43
  end
@@ -1,3 +1,3 @@
1
1
  module Stackster
2
- VERSION = "0.4.2"
2
+ VERSION = "0.4.3"
3
3
  end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ describe Stackster do
4
+ before do
5
+ @config_stub = stub 'Config', :access_key => 'key',
6
+ :secret_key => 'XXX',
7
+ :region => 'us-west1'
8
+ instances = ['first',{ 'Instances' => [{ 'InstanceId' => 'i-000001' },
9
+ { 'InstanceId' => 'i-000002' }] }]
10
+ body = { 'DescribeAutoScalingGroupsResult' => { 'AutoScalingGroups' => instances } }
11
+ @response_stub = stub 'Fog::Response', :body => body
12
+ @auto_scaling_mock = mock 'AutoScalingGroups'
13
+ Fog::AWS::AutoScaling.stub :new => @auto_scaling_mock
14
+ @auto_scaling_groups = Stackster::AWS::AutoScalingGroups.new(:config => @config_stub,
15
+ :asg_id => 'asg_name')
16
+ end
17
+
18
+ describe 'list_instances' do
19
+ it "should return the array of instance id's when passed the AutoScaleGroup name" do
20
+ @auto_scaling_mock.should_receive(:describe_auto_scaling_groups).
21
+ with('AutoScalingGroupNames' => ['asg_name']).
22
+ and_return(@response_stub)
23
+
24
+ @auto_scaling_groups.list_instances.should == ['i-000001','i-000002' ]
25
+
26
+
27
+ end
28
+ end
29
+ end
data/spec/aws/ec2_spec.rb CHANGED
@@ -2,9 +2,15 @@ require 'spec_helper'
2
2
 
3
3
  describe Stackster do
4
4
  before do
5
+ @logger_stub = stub 'logger stub', :info => 'true', :warn => 'true', :error => 'true'
5
6
  @config_stub = stub 'Config', :logger => @logger_stub, :access_key => 'key', :secret_key => 'XXX', :region => 'us-west1'
6
- @response_stub = stub 'Excon::Response', :body => {
7
- 'reservationSet' => [{'instanceSet' => [{'ipAddress' => '192.168.1.1'}]}]
7
+ @instance_id = 'i-123456'
8
+ @response_stub = stub 'Excon::Response', :body => {
9
+ 'reservationSet' => [{
10
+ 'instanceSet' => [{'instanceState' => {'name' => 'running'}},
11
+ {'ipAddress' => '54.10.10.1'},
12
+ {'instanceId' => 'i-123456'},
13
+ {'privateIpAddress' => '192.168.1.1'}]}]
8
14
  }
9
15
 
10
16
  @cf_mock = mock 'CloudFormation'
@@ -13,11 +19,15 @@ describe Stackster do
13
19
  @ec2 = Stackster::AWS::EC2.new(:config => @config_stub)
14
20
  end
15
21
 
16
- describe "describe_instances" do
17
- it "should return the Cloud Formation description of the instances" do
22
+ describe 'describe_instance' do
23
+ it 'should return the Cloud Formation description of only the running passed instance' do
18
24
  @cf_mock.should_receive(:describe_instances).and_return(@response_stub)
19
25
 
20
- @ec2.describe_instances.should == [{'instanceSet' => [{'ipAddress' => '192.168.1.1'}]}]
26
+ @ec2.describe_instance(@instance_id).should == [{
27
+ 'instanceSet' => [{'instanceState' => {'name' => 'running'}},
28
+ {'ipAddress' => '54.10.10.1'},
29
+ {'instanceId' => 'i-123456'},
30
+ {'privateIpAddress' => '192.168.1.1'}]}]
21
31
  end
22
32
  end
23
33
  end
@@ -1,84 +1,66 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Stackster do
3
+ describe Stackster::InstanceReader do
4
4
 
5
+ describe "list_stack_instances" do
5
6
 
6
- describe "with a single running instance" do
7
7
  before do
8
- @instances = [
9
- { 'instancesSet' =>
10
- [
11
- { 'tagSet' =>
12
- { 'aws:cloudformation:stack-name' => 'my-stack' },
13
- 'instanceState' =>
14
- { 'name' => 'running' }
15
- }
16
- ]
17
- },
18
- { 'instancesSet' =>
19
- [
20
- { 'tagSet' =>
21
- { 'aws:cloudformation:stack-name' => 'my-stack' },
22
- 'instanceState' =>
23
- { 'name' => 'terminated' }
24
- }
25
- ]
26
- },
27
- { 'instancesSet' =>
28
- [
29
- { 'tagSet' =>
30
- { 'aws:cloudformation:stack-name' => 'dead-stack' },
31
- 'instanceState' =>
32
- { 'name' => 'terminated' }
33
- }
34
- ]
35
- }
36
- ]
37
- end
8
+ @config_mock = mock 'config'
9
+ @cloud_formation_mock = mock 'cloud formation'
10
+ @auto_scaling_groups_mock = mock 'auto scaling'
11
+ @ec2_mock = mock 'ec2'
12
+ @instance_reservation_set_mock = mock 'reservation'
13
+ @instance_data_mock = mock 'instance data mock'
14
+
15
+ Stackster::AWS::CloudFormation.should_receive(:new).
16
+ with(:config => @config_mock).
17
+ and_return @cloud_formation_mock
18
+
19
+ stack_resource_results = [{'StackName' => 'stack',
20
+ 'ResourceType' => 'AWS::AutoScaling::AutoScalingGroup',
21
+ 'PhysicalResourceId' => 'asg1'}]
22
+
23
+ @cloud_formation_mock.should_receive(:stack_resources).
24
+ with('stack').
25
+ and_return stack_resource_results
26
+
27
+ Stackster::AWS::AutoScalingGroups.should_receive(:new).
28
+ with(:config => @config_mock, :asg_id => "asg1").
29
+ and_return @auto_scaling_groups_mock
38
30
 
39
- it "should list running instance within the given stack" do
40
- @ec2_mock = mock 'simple ec2'
41
- config = Stackster::Config.new(:config => { 'access_key' => 'the-key',
42
- 'secret_key' => 'secret',
43
- 'region' => 'us-west-1' })
44
31
  Stackster::AWS::EC2.should_receive(:new).
45
- with(:config => config).
32
+ with(:config => @config_mock).
46
33
  and_return @ec2_mock
47
- instance_reader = Stackster::InstanceReader.new :config => config
48
- @ec2_mock.should_receive(:describe_instances).
49
- and_return(@instances)
50
- instance_reader.list_stack_instances('my-stack').count.
51
- should == 1
52
34
  end
53
35
 
54
- it "should not include instances which are in different stacks" do
55
- @ec2_mock = mock 'simple ec2'
56
- config = Stackster::Config.new(:config => { 'access_key' => 'the-key',
57
- 'secret_key' => 'secret',
58
- 'region' => 'us-west-1' })
59
- Stackster::AWS::EC2.should_receive(:new).
60
- with(:config => config).
61
- and_return @ec2_mock
62
- instance_reader = Stackster::InstanceReader.new :config => config
63
- @ec2_mock.should_receive(:describe_instances).
64
- and_return(@instances)
65
- instance_reader.list_stack_instances('another-stack').count.
66
- should == 0
36
+ context "with no running instances" do
37
+ it "should return empty array" do
38
+ @auto_scaling_groups_mock.should_receive(:list_instances).
39
+ and_return []
40
+
41
+ @ec2_mock.should_receive(:describe_instance).
42
+ with([]).
43
+ and_return @instance_reservation_set_mock
44
+
45
+ @instance_reservation_set_mock.stub :any? => true
46
+ instance_reader = Stackster::InstanceReader.new :config => @config_mock
47
+ instance_reader.list_stack_instances('stack').should == @instance_reservation_set_mock
48
+ end
67
49
  end
68
50
 
69
- it "should not include instances which are not running" do
70
- @ec2_mock = mock 'simple ec2'
71
- config = Stackster::Config.new(:config => { 'access_key' => 'the-key',
72
- 'secret_key' => 'secret',
73
- 'region' => 'us-west-1' })
74
- Stackster::AWS::EC2.should_receive(:new).
75
- with(:config => config).
76
- and_return @ec2_mock
77
- instance_reader = Stackster::InstanceReader.new :config => config
78
- @ec2_mock.should_receive(:describe_instances).
79
- and_return(@instances)
80
- instance_reader.list_stack_instances('dead-stack').count.
81
- should == 0
51
+ context "with running instances" do
52
+ it "should return the reservation set for each running instance" do
53
+ @auto_scaling_groups_mock.should_receive(:list_instances).
54
+ and_return ['instance1']
55
+
56
+ @ec2_mock.should_receive(:describe_instance).
57
+ with(['instance1']).
58
+ and_return @instance_reservation_set_mock
59
+
60
+ @instance_reservation_set_mock.stub :any? => true
61
+ instance_reader = Stackster::InstanceReader.new :config => @config_mock
62
+ instance_reader.list_stack_instances('stack').should == @instance_reservation_set_mock
63
+ end
82
64
  end
83
65
  end
84
66
  end
data/stackster.gemspec CHANGED
@@ -24,7 +24,7 @@ Gem::Specification.new do |s|
24
24
  s.add_development_dependency "simplecov", "~> 0.6.4"
25
25
  s.add_development_dependency "timecop", "~> 0.5.3"
26
26
 
27
- s.add_runtime_dependency "fog", "= 1.6.0"
27
+ s.add_runtime_dependency "fog", "= 1.10.0"
28
28
  s.add_runtime_dependency "trollop", "= 2.0"
29
29
  s.add_runtime_dependency "xml-simple", "= 1.1.2"
30
30
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stackster
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.4.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-02-15 00:00:00.000000000 Z
12
+ date: 2013-03-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -82,7 +82,7 @@ dependencies:
82
82
  requirements:
83
83
  - - '='
84
84
  - !ruby/object:Gem::Version
85
- version: 1.6.0
85
+ version: 1.10.0
86
86
  type: :runtime
87
87
  prerelease: false
88
88
  version_requirements: !ruby/object:Gem::Requirement
@@ -90,7 +90,7 @@ dependencies:
90
90
  requirements:
91
91
  - - '='
92
92
  - !ruby/object:Gem::Version
93
- version: 1.6.0
93
+ version: 1.10.0
94
94
  - !ruby/object:Gem::Dependency
95
95
  name: trollop
96
96
  requirement: !ruby/object:Gem::Requirement
@@ -134,7 +134,7 @@ files:
134
134
  - .gitignore
135
135
  - .rvmrc
136
136
  - .travis.yml
137
- - CHANGELOG
137
+ - CHANGELOG.md
138
138
  - Gemfile
139
139
  - LICENSE
140
140
  - README.md
@@ -142,6 +142,7 @@ files:
142
142
  - bin/stackster
143
143
  - lib/stackster.rb
144
144
  - lib/stackster/aws.rb
145
+ - lib/stackster/aws/auto_scaling_groups.rb
145
146
  - lib/stackster/aws/cloud_formation.rb
146
147
  - lib/stackster/aws/cloud_formation/error.rb
147
148
  - lib/stackster/aws/ec2.rb
@@ -163,6 +164,7 @@ files:
163
164
  - lib/stackster/stack/stack_updater.rb
164
165
  - lib/stackster/stack/status.rb
165
166
  - lib/stackster/version.rb
167
+ - spec/aws/auto_scaling_groups_spec.rb
166
168
  - spec/aws/cloud_formation/error_spec.rb
167
169
  - spec/aws/cloud_formation_spec.rb
168
170
  - spec/aws/ec2_spec.rb
@@ -196,7 +198,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
196
198
  version: '0'
197
199
  segments:
198
200
  - 0
199
- hash: 2937720752334534318
201
+ hash: -3513599222543714350
200
202
  required_rubygems_version: !ruby/object:Gem::Requirement
201
203
  none: false
202
204
  requirements:
@@ -205,7 +207,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
205
207
  version: '0'
206
208
  segments:
207
209
  - 0
208
- hash: 2937720752334534318
210
+ hash: -3513599222543714350
209
211
  requirements: []
210
212
  rubyforge_project: stackster
211
213
  rubygems_version: 1.8.24
@@ -213,6 +215,7 @@ signing_key:
213
215
  specification_version: 3
214
216
  summary: I make deployments easier
215
217
  test_files:
218
+ - spec/aws/auto_scaling_groups_spec.rb
216
219
  - spec/aws/cloud_formation/error_spec.rb
217
220
  - spec/aws/cloud_formation_spec.rb
218
221
  - spec/aws/ec2_spec.rb