stackster 0.2.2 → 0.2.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.
@@ -0,0 +1,30 @@
1
+ require 'xmlsimple'
2
+
3
+ module Stackster
4
+ class AWS
5
+ class CloudFormation
6
+ class Error
7
+
8
+ def initialize(args)
9
+ @exception = args[:exception]
10
+ @config = args[:config]
11
+ @logger = @config.logger
12
+ end
13
+
14
+ def process
15
+ message = XmlSimple.xml_in(@exception.response.body)
16
+ message['Error'].first['Message'].each do |msg|
17
+ case msg
18
+ when 'No updates are to be performed.'
19
+ @logger.info msg
20
+ else
21
+ @logger.error msg
22
+ exit 1
23
+ end
24
+ end
25
+ end
26
+
27
+ end
28
+ end
29
+ end
30
+ end
@@ -5,28 +5,47 @@ module Stackster
5
5
  class CloudFormation
6
6
 
7
7
  def initialize(args)
8
- c = args[:config]
9
- @connect = Fog::AWS::CloudFormation.new :aws_access_key_id => c.access_key,
10
- :aws_secret_access_key => c.secret_key,
11
- :region => c.region
8
+ @config = args[:config]
9
+ @logger = @config.logger
10
+ @connect = Fog::AWS::CloudFormation.new :aws_access_key_id => @config.access_key,
11
+ :aws_secret_access_key => @config.secret_key,
12
+ :region => @config.region
12
13
  end
13
14
 
14
15
  def create(args)
15
16
  parameters = { 'Parameters' => args[:parameters] }
16
17
  data = { 'Capabilities' => ['CAPABILITY_IAM'],
17
18
  'TemplateBody' => args[:template] }.merge parameters
18
- @connect.create_stack(args[:name], data)
19
+ begin
20
+ @connect.create_stack(args[:name], data)
21
+ rescue Exception => e
22
+ Error.new(:config => @config,
23
+ :exception => e).process
24
+ end
25
+ @logger.info "Cloud Formation stack creation completed."
19
26
  end
20
27
 
21
28
  def update(args)
22
29
  parameters = { 'Parameters' => args[:parameters] }
23
30
  data = { 'Capabilities' => ['CAPABILITY_IAM'],
24
31
  'TemplateBody' => args[:template] }.merge parameters
25
- @connect.update_stack(args[:name], data)
32
+ begin
33
+ @connect.update_stack(args[:name], data)
34
+ rescue Exception => e
35
+ Error.new(:config => @config,
36
+ :exception => e).process
37
+ end
38
+ @logger.info "Cloud Formation stack update completed."
26
39
  end
27
40
 
28
41
  def destroy(name)
29
- @connect.delete_stack name
42
+ begin
43
+ @connect.delete_stack name
44
+ rescue Exception => e
45
+ Error.new(:config => @config,
46
+ :exception => e).process
47
+ end
48
+ @logger.info "Cloud Formation stack destroy completed."
30
49
  end
31
50
 
32
51
  def describe_stack(name)
data/lib/stackster/aws.rb CHANGED
@@ -1,3 +1,4 @@
1
1
  require "stackster/aws/cloud_formation"
2
+ require "stackster/aws/cloud_formation/error"
2
3
  require "stackster/aws/ec2"
3
4
  require "stackster/aws/simpledb"
data/lib/stackster/cli.rb CHANGED
@@ -4,6 +4,7 @@ module Stackster
4
4
  module CLI
5
5
  def self.start
6
6
  @opts = Trollop::options do
7
+ version Stackster::VERSION
7
8
  banner <<-EOS
8
9
 
9
10
  I build and manage AWS Cloud Formation Stacks
@@ -7,6 +7,7 @@ module Stackster
7
7
  def initialize(args)
8
8
  @domain = 'stacks'
9
9
  @config = args[:config]
10
+ @logger = @config.logger
10
11
  self.name = region_specific_name args[:name]
11
12
  create_domain
12
13
  get_attributes
@@ -25,12 +26,15 @@ module Stackster
25
26
  def save
26
27
  attributes.merge!('Name' => name)
27
28
  attributes.each_pair do |k,v|
28
- sdb_connect.put_attributes('stacks', name, { k => v }, { :replace => k })
29
+ @logger.debug "Setting attribute #{k}=#{v}"
29
30
  end
31
+ sdb_connect.put_attributes('stacks', name, attributes, { :replace => attributes.keys })
32
+ @logger.info "Save to SimpleDB successful."
30
33
  end
31
34
 
32
35
  def delete_attributes
33
36
  sdb_connect.delete('stacks', name)
37
+ @logger.info "Delete from SimpleDB successful."
34
38
  end
35
39
 
36
40
  private
@@ -14,8 +14,16 @@ module Stackster
14
14
  @logger
15
15
  end
16
16
 
17
+ def debug(msg)
18
+ @logger.debug msg
19
+ end
20
+
17
21
  def info(msg)
18
22
  @logger.info msg
19
23
  end
24
+
25
+ def error(msg)
26
+ @logger.error msg
27
+ end
20
28
  end
21
29
  end
@@ -5,12 +5,14 @@ module Stackster
5
5
 
6
6
  def initialize(args)
7
7
  @config = args[:config]
8
+ @logger = @config.logger
8
9
  @entry = args[:entry]
9
10
  @name = args[:name]
10
11
  @template = read_template_from_file args[:template_file]
11
12
  end
12
13
 
13
14
  def create
15
+ @logger.info "Creating Cloud Formation stack #{@name}."
14
16
  cloud_formation.create :name => @name,
15
17
  :parameters => read_parameters_from_entry,
16
18
  :template => @template
@@ -11,7 +11,7 @@ module Stackster
11
11
  'attributes' => stack_reader.attributes,
12
12
  'status' => stack_reader.status,
13
13
  'outputs' => stack_reader.outputs,
14
- 'events' => stack_reader.events,
14
+ 'events' => stack_reader.events(3),
15
15
  'resources' => stack_reader.resources,
16
16
  }
17
17
  end
@@ -5,18 +5,26 @@ module Stackster
5
5
 
6
6
  def initialize(args)
7
7
  @config = args[:config]
8
+ @logger = @config.logger
8
9
  @entry = args[:entry]
9
10
  @name = args[:name]
10
11
  @template_body = args[:template_body]
11
12
  end
12
13
 
13
14
  def update_stack_if_parameters_changed(attributes)
14
- parameter_updated?(attributes) ? update : false
15
+ if parameter_updated?(attributes)
16
+ @logger.info "Updated parameters found."
17
+ update
18
+ else
19
+ @logger.info "No Cloud Formation parameters require updating."
20
+ return false
21
+ end
15
22
  end
16
23
 
17
24
  private
18
25
 
19
26
  def update
27
+ @logger.info "Updating Cloud Formation stack #{@name}."
20
28
  cloud_formation.update :name => @name,
21
29
  :parameters => read_parameters_from_entry_attributes,
22
30
  :template => @template_body
@@ -1,3 +1,3 @@
1
1
  module Stackster
2
- VERSION = "0.2.2"
2
+ VERSION = "0.2.3"
3
3
  end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe Stackster do
4
+
5
+ ['error'].each do |t|
6
+ it "should test #{t}"
7
+ end
8
+
9
+ end
data/spec/entry_spec.rb CHANGED
@@ -61,9 +61,7 @@ describe Stackster do
61
61
 
62
62
  it "should set the attributes in simple db" do
63
63
  @simple_db_mock.should_receive(:put_attributes).
64
- with("stacks", "test-stack-us-west-1", {"key"=>"value"}, {:replace=>"key"})
65
- @simple_db_mock.should_receive(:put_attributes).
66
- with("stacks", "test-stack-us-west-1", {"Name"=>"test-stack-us-west-1"}, {:replace=>"Name"})
64
+ with("stacks", "test-stack-us-west-1", {"key"=>"value", "Name"=>"test-stack-us-west-1"}, {:replace=>["key", "Name"]})
67
65
  @entry.attributes = {"key"=>"value"}
68
66
 
69
67
  @entry.save
@@ -21,6 +21,7 @@ describe Stackster do
21
21
 
22
22
  it "should map the attributes to a template's parameters and create a stack " do
23
23
  config_mock = mock 'config mock'
24
+ logger_mock = mock 'logger mock'
24
25
  entry_mock = mock 'entry mock'
25
26
  file_mock = mock 'file mock'
26
27
  cloud_formation_mock = mock 'cloud formation mock'
@@ -30,6 +31,8 @@ describe Stackster do
30
31
  File.should_receive(:open).with('path_to_file').
31
32
  and_return file_mock
32
33
  file_mock.should_receive(:read).and_return @template_json
34
+ config_mock.should_receive(:logger).and_return(logger_mock)
35
+ logger_mock.should_receive(:info).exactly(1).times
33
36
  entry_mock.should_receive(:attributes).and_return @attributes
34
37
  cloud_formation_mock.should_receive(:create).
35
38
  with(:name => 'test-stack',
@@ -21,6 +21,7 @@ describe Stackster do
21
21
  it "should update the stack when parameters change" do
22
22
  attributes = { "param1" => "value1", "param3" => "value3" }
23
23
  config_mock = mock 'config mock'
24
+ logger_mock = mock 'logger mock'
24
25
  entry_mock = mock 'entry mock'
25
26
  cloud_formation_mock = mock 'cloud formation mock'
26
27
  Stackster::AWS::CloudFormation.should_receive(:new).
@@ -32,6 +33,8 @@ describe Stackster do
32
33
  :parameters => { 'param1' => 'value1' },
33
34
  :template => @template_body).
34
35
  and_return true
36
+ config_mock.should_receive(:logger).and_return(logger_mock)
37
+ logger_mock.should_receive(:info).exactly(2).times
35
38
  stack_updater = Stackster::StackUpdater.new :name => 'test-stack',
36
39
  :template_body => @template_body,
37
40
  :entry => entry_mock,
@@ -44,8 +47,11 @@ describe Stackster do
44
47
  it "should not update the stack when parameters don't change" do
45
48
  attributes = { "param3" => "value3" }
46
49
  config_mock = mock 'config mock'
50
+ logger_mock = mock 'logger mock'
47
51
  entry_mock = mock 'entry mock'
48
52
  Stackster::AWS::CloudFormation.should_receive(:new).exactly(0).times
53
+ config_mock.should_receive(:logger).and_return(logger_mock)
54
+ logger_mock.should_receive(:info).with("No Cloud Formation parameters require updating.")
49
55
  stack_updater = Stackster::StackUpdater.new :name => 'test-stack',
50
56
  :template_body => @template_body,
51
57
  :entry => entry_mock,
data/stackster.gemspec CHANGED
@@ -24,4 +24,5 @@ Gem::Specification.new do |s|
24
24
  s.add_runtime_dependency "fog"
25
25
  s.add_runtime_dependency 'logger'
26
26
  s.add_runtime_dependency "trollop"
27
+ s.add_runtime_dependency "xml-simple"
27
28
  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.2.2
4
+ version: 0.2.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-07-09 00:00:00.000000000 Z
12
+ date: 2012-07-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &70133562700240 !ruby/object:Gem::Requirement
16
+ requirement: &70332607252860 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *70133562700240
24
+ version_requirements: *70332607252860
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: fog
27
- requirement: &70133562699820 !ruby/object:Gem::Requirement
27
+ requirement: &70332607252400 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70133562699820
35
+ version_requirements: *70332607252400
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: logger
38
- requirement: &70133562699400 !ruby/object:Gem::Requirement
38
+ requirement: &70332607251960 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70133562699400
46
+ version_requirements: *70332607251960
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: trollop
49
- requirement: &70133562698600 !ruby/object:Gem::Requirement
49
+ requirement: &70332607251540 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,7 +54,18 @@ dependencies:
54
54
  version: '0'
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *70133562698600
57
+ version_requirements: *70332607251540
58
+ - !ruby/object:Gem::Dependency
59
+ name: xml-simple
60
+ requirement: &70332607251100 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :runtime
67
+ prerelease: false
68
+ version_requirements: *70332607251100
58
69
  description: Thats what I do
59
70
  email:
60
71
  - brett@weav.net
@@ -72,6 +83,7 @@ files:
72
83
  - lib/stackster.rb
73
84
  - lib/stackster/aws.rb
74
85
  - lib/stackster/aws/cloud_formation.rb
86
+ - lib/stackster/aws/cloud_formation/error.rb
75
87
  - lib/stackster/aws/ec2.rb
76
88
  - lib/stackster/aws/simpledb.rb
77
89
  - lib/stackster/cli.rb
@@ -90,6 +102,7 @@ files:
90
102
  - lib/stackster/stack/stack_updater.rb
91
103
  - lib/stackster/version.rb
92
104
  - script/ci_setup
105
+ - spec/aws/cloud_formation/error_spec.rb
93
106
  - spec/aws/cloud_formation_spec.rb
94
107
  - spec/aws/ec2_spec.rb
95
108
  - spec/aws/simpledb_spec.rb
@@ -121,7 +134,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
121
134
  version: '0'
122
135
  segments:
123
136
  - 0
124
- hash: 2941852262455620206
137
+ hash: 4366725332877882823
125
138
  required_rubygems_version: !ruby/object:Gem::Requirement
126
139
  none: false
127
140
  requirements:
@@ -130,7 +143,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
130
143
  version: '0'
131
144
  segments:
132
145
  - 0
133
- hash: 2941852262455620206
146
+ hash: 4366725332877882823
134
147
  requirements: []
135
148
  rubyforge_project: stackster
136
149
  rubygems_version: 1.8.16
@@ -138,6 +151,7 @@ signing_key:
138
151
  specification_version: 3
139
152
  summary: I make deployments easier
140
153
  test_files:
154
+ - spec/aws/cloud_formation/error_spec.rb
141
155
  - spec/aws/cloud_formation_spec.rb
142
156
  - spec/aws/ec2_spec.rb
143
157
  - spec/aws/simpledb_spec.rb