stax 0.1.15 → 0.1.16

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2f568912290ecbedb81651020823c805d852d376bb7258143cecf3f4fada6669
4
- data.tar.gz: f05fefe06932f2cfb2d61ef46dae6ea61ffd64cb861fb165505e59946ace1a56
3
+ metadata.gz: 71409fa2f0b164176dd1939b5db76d2f61459debdaad1ea5ff2d8c78f4068860
4
+ data.tar.gz: a054ede18a8a56ddb3be6d142d75e0a14e5ccec43ac816213b561b6a3549fcdb
5
5
  SHA512:
6
- metadata.gz: 98b027a525e66191c981c8ef664bd803765cee72df66d2106acffd21ead9409ccb17749991144ec09da57415bf971e4c0124a68fec71485cc49f0432ae07d4a5
7
- data.tar.gz: a038562e8c5524f78c2a20a8ff7b5580c14c40d5af86b2a210cd4627c2347d16cbd73338b63a52ee116885a245005691bc02a6ca275ca6ee5506e24f1dc1312c
6
+ metadata.gz: f4e8797a309b2558fcc316a69acda2a8125c08b8b104dcc5f1b9fd1d78f0d56229c3253147d13e6457add20171416f8c0a96f36eca1e75fd5127ba32f3ed47b4
7
+ data.tar.gz: 9fd02c1d9048cb92bf996808e8956dbf8eb1c5ce95134ebfb54402e3a094d039804128c3ba5cf235fc124bf9a6a63cbff8267b250a9ac55532f01b43054fffb5
@@ -17,6 +17,9 @@ module Stax
17
17
  'in-sync': :green,
18
18
  Complete: :green,
19
19
  Active: :green,
20
+ COMPLETED: :green,
21
+ AVAILABLE: :green,
22
+ SWITCHOVER_COMPLETED: :green,
20
23
  }
21
24
 
22
25
  no_commands do
@@ -132,6 +135,205 @@ module Stax
132
135
  end
133
136
  end
134
137
 
138
+ desc 'create-upgrade-candidate', 'create blue/green deployment'
139
+ method_option :target_engine_version, type: :string, default: '', desc: 'target engine version'
140
+ method_option :target_cluster_parameter_group, type: :string, default: '', desc: 'target cluster parameter group'
141
+ method_option :target_instance_parameter_group, type: :string, default: '', desc: 'target instance parameter group'
142
+ method_option :target_db_instance_class, type: :string, default: '', desc: 'target instance class'
143
+ def create_upgrade_candidate
144
+ target_engine_version = options[:target_engine_version]
145
+ target_cluster_parameter_group = options[:target_cluster_parameter_group]
146
+ target_instance_parameter_group = options[:target_instance_parameter_group]
147
+ target_db_instance_class = options[:target_db_instance_class]
148
+
149
+ unless stack_rds_clusters.is_a?(Array) && stack_rds_clusters.any?
150
+ say("No DB clusters associated with #{my.stack_name}", :red)
151
+ return
152
+ end
153
+
154
+ # get cluster source_arn from stack
155
+ if stack_rds_clusters.length == 1
156
+ source_arn = stack_rds_clusters[0].db_cluster_arn
157
+ else
158
+ say("Multiple DB Clusters associated with #{my.stack_name}. Cannot determine which cluster to use as source.", :red)
159
+ return
160
+ end
161
+
162
+ # Specify the required blue/green deployment parameters
163
+ deployment_params = {
164
+ blue_green_deployment_name: "#{my.stack_name}-next-#{SecureRandom.alphanumeric(12)}",
165
+ source: source_arn,
166
+ }
167
+
168
+ # Check if optional values are set and add them to the deployment parameters
169
+ if !target_engine_version.empty?
170
+ deployment_params[:target_engine_version] = target_engine_version
171
+ end
172
+
173
+ if !target_cluster_parameter_group.empty?
174
+ deployment_params[:target_db_cluster_parameter_group_name] = target_cluster_parameter_group
175
+ end
176
+
177
+ if !target_instance_parameter_group.empty?
178
+ deployment_params[:target_db_parameter_group_name] = target_instance_parameter_group
179
+ end
180
+
181
+ if !target_db_instance_class.empty?
182
+ deployment_params[:target_db_instance_class] = target_db_instance_class
183
+ end
184
+
185
+ say("Creating blue/green deployment #{deployment_params[:blue_green_deployment_name]} for #{source_arn}", :yellow)
186
+ resp = Aws::Rds.client.create_blue_green_deployment(deployment_params)
187
+ if resp.blue_green_deployment.status != "PROVISIONING"
188
+ say("Failed to create blue/green deployment #{deployment_params[:blue_green_deployment_name]}", :red)
189
+ puts resp.to_h
190
+ return
191
+ end
192
+
193
+ invoke(:tail_upgrade_candidate, [], id: resp.blue_green_deployment.blue_green_deployment_identifier)
194
+ end
195
+
196
+ desc 'delete-upgrade-candidate', 'delete blue/green deployment'
197
+ method_option :id, type: :string, required: true, desc: 'id of blue/green deployment to delete'
198
+ method_option :delete_target, type: :boolean, default: false, desc: 'delete resources in green deployment'
199
+ def delete_upgrade_candidate
200
+ deployment_identifier = options[:id]
201
+ delete_target = options[:delete_target]
202
+
203
+ # Future TODO: Even though the RDS API doesn't allow for target resources to be deleted
204
+ # post-switchover (likely because these resources are the old DB resources), we could
205
+ # allow for an automatic clean up the leftover resources by deleting these resources
206
+ # with specific RDS API calls.
207
+ if delete_target && Aws::Rds.client.describe_blue_green_deployments({ blue_green_deployment_identifier: deployment_identifier }).blue_green_deployments[0].status == "SWITCHOVER_COMPLETED"
208
+ say("You can't specify --delete-target if the blue/green deployment status is SWITCHOVER_COMPLETED", :red)
209
+ return
210
+ end
211
+
212
+ if yes?("Really delete blue/green deployment #{deployment_identifier}?", :yellow)
213
+ say("Deleting blue/green deployment #{deployment_identifier}", :red)
214
+ resp = Aws::Rds.client.delete_blue_green_deployment({
215
+ blue_green_deployment_identifier: deployment_identifier,
216
+ delete_target: delete_target,
217
+ })
218
+
219
+ if resp.blue_green_deployment.status != "DELETING"
220
+ say("Failed to delete blue/green deployment #{deployment_identifier}", :red)
221
+ puts resp.to_h
222
+ return
223
+ end
224
+
225
+ # tail the blue/green deployment until it is deleted
226
+ begin
227
+ invoke(:tail_upgrade_candidate, [], id: deployment_identifier)
228
+ rescue ::Aws::RDS::Errors::BlueGreenDeploymentNotFoundFault
229
+ say("Deleted blue/green deployment #{deployment_identifier}", :green)
230
+ end
231
+ end
232
+ end
233
+
234
+ desc 'switchover-upgrade-candidate', 'switchover blue/green deployment'
235
+ method_option :id, type: :string, required: true, desc: 'id of blue/green deployment'
236
+ method_option :timeout, type: :numeric, default: 300, desc: 'amount of time, in seconds, for the switchover to complete'
237
+ def switchover_upgrade_candidate
238
+ deployment_identifier = options[:id]
239
+ timeout = options[:timeout]
240
+
241
+ if yes?("Really switchover blue/green deployment #{deployment_identifier}?", :yellow)
242
+ say("Switchover blue/green deployment #{deployment_identifier}", :yellow)
243
+ resp = Aws::Rds.client.switchover_blue_green_deployment({
244
+ blue_green_deployment_identifier: deployment_identifier,
245
+ switchover_timeout: timeout,
246
+ })
247
+
248
+ if resp.blue_green_deployment.status != "SWITCHOVER_IN_PROGRESS"
249
+ say("Failed to switchover blue/green deployment #{deployment_identifier}", :red)
250
+ puts resp.to_h
251
+ return
252
+ end
253
+
254
+ # tail the blue/green deployment until it is complete
255
+ invoke(:tail_upgrade_candidate, [], id: deployment_identifier)
256
+ end
257
+ end
258
+
259
+ desc 'tail-upgrade-candidate', 'tail blue/green deployment'
260
+ method_option :id, type: :string, required: true, desc: 'id of blue/green deployment'
261
+ def tail_upgrade_candidate
262
+ deployment_identifier = options[:id]
263
+
264
+ previous_status = nil
265
+ previous_switchover_details = []
266
+ previous_tasks = []
267
+
268
+ loop do
269
+ resp = Aws::Rds.client.describe_blue_green_deployments({
270
+ blue_green_deployment_identifier: deployment_identifier,
271
+ })
272
+
273
+ if resp[:blue_green_deployments].empty?
274
+ say("Deployment not found: #{deployment_identifier}", :red)
275
+ return
276
+ end
277
+
278
+ deployment = resp[:blue_green_deployments][0]
279
+
280
+ current_status = color(deployment[:status])
281
+ current_switchover_details = deployment[:switchover_details]
282
+ current_tasks = deployment[:tasks]
283
+
284
+ if previous_status.nil?
285
+ say("Deployment Name: #{deployment[:blue_green_deployment_name]}", :blue)
286
+ say("Deployment ID: #{deployment_identifier}", :white)
287
+ say("Create Time: #{deployment[:create_time]}", :green)
288
+ end
289
+
290
+ if previous_status.nil? || previous_status != current_status
291
+ print_table [[Time.now.utc.strftime('%Y-%m-%d %H:%M:%S UTC'), "Deployment Status", current_status]]
292
+ end
293
+
294
+ if !current_switchover_details.nil?
295
+ current_switchover_details.each do |current_item|
296
+ previous_item = previous_switchover_details.find { |item| item[:source_member] == current_item[:source_member] }
297
+
298
+ if previous_item.nil? || current_item != previous_item
299
+ if current_item[:target_member].nil?
300
+ prefix = "#{set_color('Pending DB Resource', :cyan)}"
301
+ else
302
+ prefix = current_item[:target_member].include?(':cluster:') ? "#{set_color('DB Cluster', :cyan)}" : "#{set_color('DB Instance', :cyan)}"
303
+ end
304
+ print_table [[Time.now.utc.strftime('%Y-%m-%d %H:%M:%S UTC'), prefix, current_item[:target_member], color(current_item[:status] || :CREATING)]]
305
+ end
306
+ end
307
+ end
308
+
309
+ if !current_tasks.nil?
310
+ current_tasks.each do |current_item|
311
+ previous_item = previous_tasks.find { |item| item[:name] == current_item[:name] }
312
+
313
+ if previous_item.nil? || current_item != previous_item
314
+ print_table [[Time.now.utc.strftime('%Y-%m-%d %H:%M:%S UTC'), "#{set_color('Task', :magenta)}", current_item[:name], color(current_item[:status])]]
315
+ end
316
+ end
317
+ end
318
+
319
+ if deployment[:status] == "AVAILABLE"
320
+ say("Deployment is complete.", :green)
321
+ break
322
+ end
323
+
324
+ if deployment[:status] == "SWITCHOVER_COMPLETED"
325
+ say("Deployment switchover is complete.", :green)
326
+ break
327
+ end
328
+
329
+ previous_status = current_status
330
+ previous_switchover_details = current_switchover_details
331
+ previous_tasks = current_tasks
332
+
333
+ sleep 10 # Wait for 10 seconds before polling again
334
+ end
335
+ end
336
+
135
337
  desc 'snapshots', 'list snapshots for stack clusters'
136
338
  def snapshots
137
339
  stack_db_clusters.map(&:physical_resource_id).each do |id|
data/lib/stax/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Stax
2
- VERSION = '0.1.15'
2
+ VERSION = '0.1.16'
3
3
  end
data/stax.gemspec CHANGED
@@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
22
22
  spec.require_paths = ["lib"]
23
23
 
24
24
  spec.add_development_dependency "bundler"
25
- spec.add_development_dependency "rake", "~> 10.0"
25
+ spec.add_development_dependency "rake"
26
26
  spec.add_development_dependency "stax-examples"
27
27
 
28
28
  spec.add_dependency('aws-sdk-cloudformation')
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stax
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.15
4
+ version: 0.1.16
5
5
  platform: ruby
6
6
  authors:
7
7
  - Richard Lister
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-04-10 00:00:00.000000000 Z
11
+ date: 2023-12-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -28,16 +28,16 @@ dependencies:
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: stax-examples
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -610,7 +610,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
610
610
  - !ruby/object:Gem::Version
611
611
  version: '0'
612
612
  requirements: []
613
- rubygems_version: 3.1.6
613
+ rubygems_version: 3.4.10
614
614
  signing_key:
615
615
  specification_version: 4
616
616
  summary: Control Cloudformation stack and other stuff.