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.
Files changed (89) hide show
  1. data/.gitignore +3 -0
  2. data/CHANGELOG.md +6 -0
  3. data/lib/simple_deploy/aws/cloud_formation/error.rb +32 -0
  4. data/lib/simple_deploy/aws/cloud_formation.rb +76 -0
  5. data/lib/simple_deploy/aws/instance_reader.rb +59 -0
  6. data/lib/simple_deploy/aws/simpledb.rb +52 -0
  7. data/lib/simple_deploy/aws.rb +4 -0
  8. data/lib/simple_deploy/cli/attributes.rb +7 -18
  9. data/lib/simple_deploy/cli/clone.rb +9 -19
  10. data/lib/simple_deploy/cli/create.rb +5 -14
  11. data/lib/simple_deploy/cli/deploy.rb +8 -11
  12. data/lib/simple_deploy/cli/destroy.rb +4 -10
  13. data/lib/simple_deploy/cli/environments.rb +1 -1
  14. data/lib/simple_deploy/cli/events.rb +5 -11
  15. data/lib/simple_deploy/cli/execute.rb +6 -9
  16. data/lib/simple_deploy/cli/instances.rb +4 -9
  17. data/lib/simple_deploy/cli/list.rb +5 -10
  18. data/lib/simple_deploy/cli/outputs.rb +5 -11
  19. data/lib/simple_deploy/cli/parameters.rb +5 -11
  20. data/lib/simple_deploy/cli/protect.rb +5 -10
  21. data/lib/simple_deploy/cli/resources.rb +5 -11
  22. data/lib/simple_deploy/cli/shared.rb +6 -6
  23. data/lib/simple_deploy/cli/status.rb +5 -11
  24. data/lib/simple_deploy/cli/template.rb +8 -13
  25. data/lib/simple_deploy/cli/update.rb +6 -10
  26. data/lib/simple_deploy/configuration.rb +102 -0
  27. data/lib/simple_deploy/entry.rb +71 -0
  28. data/lib/simple_deploy/entry_lister.rb +30 -0
  29. data/lib/simple_deploy/exceptions.rb +8 -0
  30. data/lib/simple_deploy/misc/attribute_merger.rb +2 -5
  31. data/lib/simple_deploy/notifier/campfire.rb +15 -12
  32. data/lib/simple_deploy/notifier.rb +6 -11
  33. data/lib/simple_deploy/stack/deployment/status.rb +5 -3
  34. data/lib/simple_deploy/stack/deployment.rb +8 -10
  35. data/lib/simple_deploy/stack/execute.rb +2 -3
  36. data/lib/simple_deploy/stack/output_mapper.rb +1 -4
  37. data/lib/simple_deploy/stack/ssh.rb +4 -4
  38. data/lib/simple_deploy/stack/{stack_attribute_formater.rb → stack_attribute_formatter.rb} +4 -6
  39. data/lib/simple_deploy/stack/stack_creator.rb +46 -0
  40. data/lib/simple_deploy/stack/stack_destroyer.rb +19 -0
  41. data/lib/simple_deploy/stack/stack_formatter.rb +25 -0
  42. data/lib/simple_deploy/stack/stack_lister.rb +18 -0
  43. data/lib/simple_deploy/stack/stack_reader.rb +56 -0
  44. data/lib/simple_deploy/stack/stack_updater.rb +67 -0
  45. data/lib/simple_deploy/stack/status.rb +53 -0
  46. data/lib/simple_deploy/stack.rb +89 -37
  47. data/lib/simple_deploy/version.rb +1 -1
  48. data/lib/simple_deploy.rb +31 -1
  49. data/simple_deploy.gemspec +6 -3
  50. data/spec/aws/cloud_formation/error_spec.rb +50 -0
  51. data/spec/aws/cloud_formation_spec.rb +207 -0
  52. data/spec/aws/instance_reader_spec.rb +96 -0
  53. data/spec/aws/simpledb_spec.rb +89 -0
  54. data/spec/cli/attributes_spec.rb +5 -15
  55. data/spec/cli/clone_spec.rb +14 -27
  56. data/spec/cli/create_spec.rb +11 -18
  57. data/spec/cli/deploy_spec.rb +24 -63
  58. data/spec/cli/destroy_spec.rb +7 -25
  59. data/spec/cli/outputs_spec.rb +12 -17
  60. data/spec/cli/protect_spec.rb +68 -106
  61. data/spec/cli/shared_spec.rb +12 -15
  62. data/spec/cli/update_spec.rb +9 -27
  63. data/spec/config_spec.rb +47 -14
  64. data/spec/contexts/config_contexts.rb +28 -0
  65. data/spec/contexts/logger_contexts.rb +9 -0
  66. data/spec/contexts/stack_contexts.rb +40 -0
  67. data/spec/entry_lister_spec.rb +31 -0
  68. data/spec/entry_spec.rb +86 -0
  69. data/spec/misc/attribute_merger_spec.rb +3 -8
  70. data/spec/notifier/campfire_spec.rb +21 -61
  71. data/spec/notifier_spec.rb +18 -40
  72. data/spec/spec_helper.rb +10 -0
  73. data/spec/stack/deployment/status_spec.rb +13 -13
  74. data/spec/stack/deployment_spec.rb +26 -21
  75. data/spec/stack/execute_spec.rb +7 -3
  76. data/spec/stack/output_mapper_spec.rb +3 -15
  77. data/spec/stack/ssh_spec.rb +14 -13
  78. data/spec/stack/{stack_attribute_formater_spec.rb → stack_attribute_formatter_spec.rb} +19 -16
  79. data/spec/stack/stack_creator_spec.rb +46 -0
  80. data/spec/stack/stack_destroyer_spec.rb +18 -0
  81. data/spec/stack/stack_formatter_spec.rb +37 -0
  82. data/spec/stack/stack_lister_spec.rb +17 -0
  83. data/spec/stack/stack_reader_spec.rb +81 -0
  84. data/spec/stack/stack_updater_spec.rb +79 -0
  85. data/spec/stack/status_spec.rb +106 -0
  86. data/spec/stack_spec.rb +160 -133
  87. metadata +112 -19
  88. data/.rvmrc +0 -1
  89. data/lib/simple_deploy/config.rb +0 -87
@@ -0,0 +1,19 @@
1
+ module SimpleDeploy
2
+ class StackDestroyer
3
+
4
+ def initialize(args)
5
+ @config = SimpleDeploy.config
6
+ @name = args[:name]
7
+ end
8
+
9
+ def destroy
10
+ cloud_formation.destroy @name
11
+ end
12
+
13
+ private
14
+
15
+ def cloud_formation
16
+ @cf ||= AWS::CloudFormation.new
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,25 @@
1
+ module SimpleDeploy
2
+ class StackFormatter
3
+
4
+ def initialize(args)
5
+ @name = args[:name]
6
+ @config = SimpleDeploy.config
7
+ end
8
+
9
+ def display
10
+ {
11
+ 'attributes' => stack_reader.attributes,
12
+ 'status' => stack_reader.status,
13
+ 'outputs' => stack_reader.outputs,
14
+ 'events' => stack_reader.events(3),
15
+ 'resources' => stack_reader.resources,
16
+ }
17
+ end
18
+
19
+ private
20
+
21
+ def stack_reader
22
+ @stack_reader ||= StackReader.new :name => @name
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,18 @@
1
+ module SimpleDeploy
2
+ class StackLister
3
+
4
+ def initialize(args = {})
5
+ @config = SimpleDeploy.config
6
+ end
7
+
8
+ def all
9
+ entry_lister.all
10
+ end
11
+
12
+ private
13
+
14
+ def entry_lister
15
+ @entry_lister ||= EntryLister.new
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,56 @@
1
+ module SimpleDeploy
2
+ class StackReader
3
+
4
+ def initialize(args)
5
+ @name = args[:name]
6
+ @config = SimpleDeploy.config
7
+ end
8
+
9
+ def attributes
10
+ entry.attributes
11
+ end
12
+
13
+ def outputs
14
+ cloud_formation.stack_outputs @name
15
+ end
16
+
17
+ def status
18
+ cloud_formation.stack_status @name
19
+ end
20
+
21
+ def events(limit)
22
+ cloud_formation.stack_events @name, limit
23
+ end
24
+
25
+ def resources
26
+ cloud_formation.stack_resources @name
27
+ end
28
+
29
+ def template
30
+ cloud_formation.template @name
31
+ end
32
+
33
+ def parameters
34
+ json = JSON.parse template
35
+ json['Parameters'].nil? ? [] : json['Parameters'].keys
36
+ end
37
+
38
+ def instances
39
+ instance_reader.list_stack_instances @name
40
+ end
41
+
42
+ private
43
+
44
+ def entry
45
+ @entry ||= Entry.find :name => @name
46
+ end
47
+
48
+ def cloud_formation
49
+ @cloud_formation ||= AWS::CloudFormation.new
50
+ end
51
+
52
+ def instance_reader
53
+ @instance_reader ||= AWS::InstanceReader.new
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,67 @@
1
+ require 'json'
2
+
3
+ module SimpleDeploy
4
+ class StackUpdater
5
+
6
+ def initialize(args)
7
+ @config = SimpleDeploy.config
8
+ @logger = SimpleDeploy.logger
9
+ @entry = args[:entry]
10
+ @name = args[:name]
11
+ @template_body = args[:template_body]
12
+ end
13
+
14
+ def update_stack_if_parameters_changed(attributes)
15
+ if parameter_updated?(attributes)
16
+ @logger.debug "Updated parameters found."
17
+ update
18
+ else
19
+ @logger.debug "No Cloud Formation parameters require updating."
20
+ false
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def update
27
+ if status.wait_for_stable
28
+ @logger.info "Updating Cloud Formation stack #{@name}."
29
+ cloud_formation.update :name => @name,
30
+ :parameters => read_parameters_from_entry_attributes,
31
+ :template => @template_body
32
+ else
33
+ raise "#{@name} did not reach a stable state."
34
+ end
35
+ end
36
+
37
+ def parameter_updated?(attributes)
38
+ (template_parameters - updated_parameters(attributes)) != template_parameters
39
+ end
40
+
41
+ def template_parameters
42
+ json = JSON.parse @template_body
43
+ json['Parameters'].nil? ? [] : json['Parameters'].keys
44
+ end
45
+
46
+ def updated_parameters attributes
47
+ (attributes.map { |s| s.keys }).flatten
48
+ end
49
+
50
+ def read_parameters_from_entry_attributes
51
+ h = {}
52
+ entry_attributes = @entry.attributes
53
+ template_parameters.each do |p|
54
+ h[p] = entry_attributes[p] if entry_attributes[p]
55
+ end
56
+ h
57
+ end
58
+
59
+ def cloud_formation
60
+ @cloud_formation ||= AWS::CloudFormation.new
61
+ end
62
+
63
+ def status
64
+ @status ||= Status.new :name => @name
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,53 @@
1
+ module SimpleDeploy
2
+ class Status
3
+
4
+ def initialize(args)
5
+ @name = args[:name]
6
+ @config = SimpleDeploy.config
7
+ @logger = SimpleDeploy.logger
8
+ end
9
+
10
+ def complete?
11
+ /_COMPLETE$/ === current
12
+ end
13
+
14
+ def failed?
15
+ /_FAILED$/ === current
16
+ end
17
+
18
+ def cleanup_in_progress?
19
+ /_CLEANUP_IN_PROGRESS$/ === current
20
+ end
21
+
22
+ def in_progress?
23
+ /_IN_PROGRESS$/ === current && !cleanup_in_progress?
24
+ end
25
+
26
+ def create_failed?
27
+ 'CREATE_FAILED' == current
28
+ end
29
+
30
+ def stable?
31
+ (complete? || failed?) && (! create_failed?)
32
+ end
33
+
34
+ def wait_for_stable(count=25)
35
+ 1.upto(count).each do |c|
36
+ break if stable?
37
+ @logger.info ("#{@name} not stable (#{current}). Sleeping #{c * c} second(s).")
38
+ Kernel.sleep (c * c)
39
+ end
40
+ stable?
41
+ end
42
+
43
+ private
44
+
45
+ def current
46
+ stack_reader.status
47
+ end
48
+
49
+ def stack_reader
50
+ @stack_reader ||= StackReader.new :name => @name
51
+ end
52
+ end
53
+ end
@@ -1,8 +1,14 @@
1
- require 'stackster'
2
1
  require 'simple_deploy/stack/deployment'
3
2
  require 'simple_deploy/stack/execute'
4
3
  require 'simple_deploy/stack/output_mapper'
5
- require 'simple_deploy/stack/stack_attribute_formater'
4
+ require 'simple_deploy/stack/stack_attribute_formatter'
5
+ require 'simple_deploy/stack/stack_creator'
6
+ require 'simple_deploy/stack/stack_destroyer'
7
+ require 'simple_deploy/stack/stack_formatter'
8
+ require 'simple_deploy/stack/stack_lister'
9
+ require 'simple_deploy/stack/stack_reader'
10
+ require 'simple_deploy/stack/stack_updater'
11
+ require 'simple_deploy/stack/status'
6
12
 
7
13
  module SimpleDeploy
8
14
  class Stack
@@ -10,16 +16,22 @@ module SimpleDeploy
10
16
  def initialize(args)
11
17
  @environment = args[:environment]
12
18
  @name = args[:name]
13
- @config = Config.new :logger => args[:logger]
14
- @logger = @config.logger
19
+
20
+ @config = SimpleDeploy.config
21
+ @logger = SimpleDeploy.logger
15
22
 
16
23
  @use_internal_ips = !!args[:internal]
24
+ @entry = Entry.new :name => @name
17
25
  end
18
26
 
19
27
  def create(args)
20
- attributes = stack_attribute_formater.updated_attributes args[:attributes]
21
- stack.create :attributes => attributes,
22
- :template => args[:template]
28
+ attributes = stack_attribute_formatter.updated_attributes args[:attributes]
29
+ @template_file = args[:template]
30
+
31
+ @entry.set_attributes attributes
32
+ stack_creator.create
33
+
34
+ @entry.save
23
35
  end
24
36
 
25
37
  def update(args)
@@ -34,9 +46,14 @@ module SimpleDeploy
34
46
 
35
47
  if deployment.clear_for_deployment?
36
48
  @logger.info "Updating #{@name}."
37
- attributes = stack_attribute_formater.updated_attributes args[:attributes]
38
- stack.update :attributes => attributes
49
+ attributes = stack_attribute_formatter.updated_attributes args[:attributes]
50
+ @template_body = template
51
+
52
+ @entry.set_attributes attributes
53
+ stack_updater.update_stack_if_parameters_changed attributes
39
54
  @logger.info "Update complete for #{@name}."
55
+
56
+ @entry.save
40
57
  true
41
58
  else
42
59
  @logger.info "Not clear to update."
@@ -44,6 +61,23 @@ module SimpleDeploy
44
61
  end
45
62
  end
46
63
 
64
+ def in_progress_update(args)
65
+ if args[:caller].kind_of? Stack::Deployment::Status
66
+ @logger.info "Updating #{@name}."
67
+ attributes = stack_attribute_formatter.updated_attributes args[:attributes]
68
+ @template_body = template
69
+
70
+ @entry.set_attributes attributes
71
+ stack_updater.update_stack_if_parameters_changed attributes
72
+ @logger.info "Update complete for #{@name}."
73
+
74
+ @entry.save
75
+ true
76
+ else
77
+ false
78
+ end
79
+ end
80
+
47
81
  def deploy(force = false)
48
82
  deployment.execute force
49
83
  end
@@ -58,7 +92,8 @@ module SimpleDeploy
58
92
 
59
93
  def destroy
60
94
  if attributes['protection'] != 'on'
61
- stack.destroy
95
+ stack_destroyer.destroy
96
+ @entry.delete_attributes
62
97
  @logger.info "#{@name} destroyed."
63
98
  true
64
99
  else
@@ -68,19 +103,19 @@ module SimpleDeploy
68
103
  end
69
104
 
70
105
  def events(limit)
71
- stack.events limit
106
+ stack_reader.events limit
72
107
  end
73
108
 
74
109
  def outputs
75
- stack.outputs
110
+ stack_reader.outputs
76
111
  end
77
112
 
78
113
  def resources
79
- stack.resources
114
+ stack_reader.resources
80
115
  end
81
116
 
82
117
  def instances
83
- stack.instances.map do |instance|
118
+ stack_reader.instances.map do |instance|
84
119
  instance['instancesSet'].map do |info|
85
120
  if info['vpcId'] || @use_internal_ips
86
121
  info['privateIpAddress']
@@ -91,63 +126,80 @@ module SimpleDeploy
91
126
  end.flatten.compact
92
127
  end
93
128
 
129
+ def raw_instances
130
+ stack_reader.instances
131
+ end
132
+
94
133
  def status
95
- stack.status
134
+ stack_reader.status
96
135
  end
97
136
 
98
137
  def wait_for_stable
99
- stack.wait_for_stable
138
+ stack_status.wait_for_stable
100
139
  end
101
140
 
102
141
  def exists?
103
- stack.status
142
+ status
104
143
  true
105
- rescue Stackster::Exceptions::UnknownStack
144
+ rescue Exceptions::UnknownStack
106
145
  false
107
146
  end
108
147
 
109
148
  def attributes
110
- stack.attributes
149
+ stack_reader.attributes
111
150
  end
112
151
 
113
152
  def parameters
114
- stack.parameters
153
+ stack_reader.parameters
115
154
  end
116
155
 
117
156
  def template
118
- JSON.parse stack.template
157
+ stack_reader.template
119
158
  end
120
159
 
121
160
  private
122
161
 
123
- def stack
124
- stackster_config = @config.environment @environment
125
- @stack ||= Stackster::Stack.new :name => @name,
126
- :config => stackster_config,
127
- :logger => @logger
162
+ def stack_creator
163
+ @stack_creator ||= StackCreator.new :name => @name,
164
+ :entry => @entry,
165
+ :template_file => @template_file
166
+ end
167
+
168
+ def stack_updater
169
+ @stack_updater ||= StackUpdater.new :name => @name,
170
+ :entry => @entry,
171
+ :template_body => @template_body
172
+ end
173
+
174
+ def stack_reader
175
+ @stack_reader ||= StackReader.new :name => @name
176
+ end
177
+
178
+ def stack_destroyer
179
+ @stack_destroyer ||= StackDestroyer.new :name => @name
128
180
  end
129
-
130
- def stack_attribute_formater
131
- @saf ||= StackAttributeFormater.new :config => @config,
132
- :environment => @environment,
133
- :main_attributes => attributes
181
+
182
+ def stack_status
183
+ @status ||= Status.new :name => @name
184
+ end
185
+
186
+ def stack_attribute_formatter
187
+ @saf ||= StackAttributeFormatter.new :main_attributes => attributes
134
188
  end
135
189
 
136
190
  def executer
137
- @executer ||= Stack::Execute.new :config => @config,
138
- :environment => @environment,
191
+ @executer ||= Stack::Execute.new :environment => @environment,
139
192
  :name => @name,
140
- :stack => stack,
193
+ :stack => self,
141
194
  :instances => instances,
142
195
  :ssh_user => ssh_user,
143
196
  :ssh_key => ssh_key
144
197
  end
145
198
 
146
199
  def deployment
147
- @deployment ||= Stack::Deployment.new :config => @config,
148
- :environment => @environment,
200
+ @deployment ||= Stack::Deployment.new :environment => @environment,
149
201
  :name => @name,
150
- :stack => stack,
202
+ :stack => self,
151
203
  :instances => instances,
152
204
  :ssh_user => ssh_user,
153
205
  :ssh_key => ssh_key