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.
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