cfn_manage 0.5.5 → 0.6.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: daf22645a1dd51d55807d398df71ab7f15f5563a5106870b0bbc4e0cdd806204
4
- data.tar.gz: 13aa605715c98964d3eba1dab19eef1aeba71fac673815951d3b8c3e0ea37f40
3
+ metadata.gz: 035ab73bb14da783dcba810528e796a5a5fd21cea291b533b69a54aeeab66930
4
+ data.tar.gz: c3317a41490aa56e188e5692d1edf9e64be73ca800bd172906c58297137135ec
5
5
  SHA512:
6
- metadata.gz: f94c368ebc84a840fab86d0f519a2299ed1e7a8c56b0a0a01f1b0dedbdde48f57ac645e92a9c49ef4b5e684893fb733e1ce7f04df69c9b9f6a2c5769ca7126ce
7
- data.tar.gz: da029041566807f3b542b39c6b1e1b1a080ec142cb9afc7a03d13172b44500f9e53eeb898fee8a459a13fba9640de8a3c5b050afa3d4c2f74161b550c5e39407
6
+ metadata.gz: 0e81937b62aa1ae30ae87b18376103d3b27dbf8a942422655524d97818082be1e4da70e455fd6139df6060a49e89aff5bda20af9ea9c422629b20c1a51cad2a5
7
+ data.tar.gz: 389307f1ac698c5d52e2bc8e612f01d0bb85252c4e71f07cdf14e36a6547577be4f9a46a7474a4b1f8f3f323beddc0465a2d5c9251d82a7359b8d1b13f7e815d
@@ -54,6 +54,10 @@ OptionParser.new do |opts|
54
54
  $options['AURORA_CLUSTER_ID'] = cluster
55
55
  end
56
56
 
57
+ opts.on('--docdb-cluster-id [DOCDB_CLUSTER_ID]') do |cluster|
58
+ $options['DOCDB_CLUSTER_ID'] = cluster
59
+ end
60
+
57
61
  opts.on('--ec2-instance-id [EC2_INSTANCE_ID]') do |ec2|
58
62
  $options['EC2_INSTANCE_ID'] = ec2
59
63
  end
@@ -99,6 +103,10 @@ OptionParser.new do |opts|
99
103
  ENV['IGNORE_MISSING_ECS_CONFIG'] = '1'
100
104
  end
101
105
 
106
+ opts.on('--asg-suspend-termination') do
107
+ ENV['ASG_SUSPEND_TERMINATION'] = '1'
108
+ end
109
+
102
110
  end.parse!
103
111
 
104
112
  command = ARGV[0]
@@ -129,6 +137,12 @@ case command
129
137
  when 'start-aurora-cluster'
130
138
  CfnManage::CloudFormation::EnvironmentRunStop.new().start_resource($options['AURORA_CLUSTER_ID'],'AWS::RDS::DBCluster')
131
139
 
140
+ # docdb cluster commands
141
+ when 'stop-docdb-cluster'
142
+ CfnManage::CloudFormation::EnvironmentRunStop.new().stop_resource($options['DOCDB_CLUSTER_ID'],'AWS::DocDB::DBCluster')
143
+ when 'start-docdb-cluster'
144
+ CfnManage::CloudFormation::EnvironmentRunStop.new().start_resource($options['DOCDB_CLUSTER_ID'],'AWS::DocDB::DBCluster')
145
+
132
146
  # ec2 instance
133
147
  when 'stop-ec2'
134
148
  CfnManage::CloudFormation::EnvironmentRunStop.new().stop_resource($options['EC2_INSTANCE_ID'],'AWS::EC2::Instance')
@@ -22,6 +22,10 @@ cfn_manage stop-aurora-cluster --aurora-cluster-id [AURORA_CLUSTER_ID]
22
22
 
23
23
  cfn_manage start-aurora-cluster --aurora-cluster-id [AURORA_CLUSTER_ID]
24
24
 
25
+ cfn_manage stop-docdb-cluster --docdb-cluster-id [DOCDB_CLUSTER_ID]
26
+
27
+ cfn_manage start-docdb-cluster --docdb-cluster-id [DOCDB_CLUSTER_ID]
28
+
25
29
  cfn_manage stop-ec2 --ec2-instance-id [EC2_INSTANCE_ID]
26
30
 
27
31
  cfn_manage start-ec2 --ec2-instance-id [EC2_INSTANCE_ID]
@@ -84,3 +88,7 @@ General options:
84
88
  --ignore-missing-ecs-config
85
89
 
86
90
  This option is required for starting a ecs service that was stopped outside of cfn_manage.
91
+
92
+ --asg-suspend-termination
93
+
94
+ Will stop instances in the autoscaling group(s) instead of the default behaviour of termination.
@@ -7,10 +7,13 @@ module CfnManage
7
7
  def initialize(asg_id, skip_wait)
8
8
  @asg_name = asg_id
9
9
  @skip_wait = skip_wait
10
+ @asg_suspend_termination = (ENV.key?('ASG_SUSPEND_TERMINATION') and ENV['ASG_SUSPEND_TERMINATION'] == '1')
10
11
  credentials = CfnManage::AWSCredentials.get_session_credentials("stopasg_#{@asg_name}")
11
12
  @asg_client = Aws::AutoScaling::Client.new(retry_limit: 20)
13
+ @ec2_client = Aws::EC2::Client.new(retry_limit: 20)
12
14
  if credentials != nil
13
15
  @asg_client = Aws::AutoScaling::Client.new(credentials: credentials, retry_limit: 20)
16
+ @ec2_client = Aws::EC2::Client.new(credentials: credentials, retry_limit: 20)
14
17
  end
15
18
 
16
19
  asg_details = @asg_client.describe_auto_scaling_groups(
@@ -29,23 +32,61 @@ module CfnManage
29
32
  # nil and false configurations are not saved
30
33
  return nil
31
34
  else
32
- # store asg configuration to S3
33
- configuration = {
35
+
36
+ puts @asg.auto_scaling_group_name
37
+
38
+ unless @asg_suspend_termination
39
+ # store asg configuration to S3
40
+ configuration = {
41
+ desired_capacity: @asg.desired_capacity,
42
+ min_size: @asg.min_size,
43
+ max_size: @asg.max_size
44
+ }
45
+
46
+ $log.info("Setting desired capacity to 0/0/0 for ASG #{@asg.auto_scaling_group_name}A")
47
+
48
+ puts @asg.auto_scaling_group_name
49
+ @asg_client.update_auto_scaling_group({
50
+ auto_scaling_group_name: "#{@asg.auto_scaling_group_name}",
51
+ min_size: 0,
52
+ max_size: 0,
53
+ desired_capacity: 0
54
+ })
55
+ return configuration
56
+ else
57
+
58
+ configuration = {
34
59
  desired_capacity: @asg.desired_capacity,
35
60
  min_size: @asg.min_size,
36
- max_size: @asg.max_size
37
- }
61
+ max_size: @asg.max_size,
62
+ suspended_processes: @asg.suspended_processes
63
+ }
38
64
 
39
- $log.info("Setting desired capacity to 0/0/0 for ASG #{@asg.auto_scaling_group_name}A")
40
- # set asg configuration to 0/0/0
41
- puts @asg.auto_scaling_group_name
42
- @asg_client.update_auto_scaling_group({
65
+ $log.info("Suspending processes for ASG #{@asg.auto_scaling_group_name}A")
66
+
67
+ @asg_client.suspend_processes({
43
68
  auto_scaling_group_name: "#{@asg.auto_scaling_group_name}",
44
- min_size: 0,
45
- max_size: 0,
46
- desired_capacity: 0
47
- })
48
- return configuration
69
+ })
70
+
71
+ $log.info("Stopping all instances in ASG #{@asg.auto_scaling_group_name}A")
72
+
73
+ @asg.instances.each do |instance|
74
+ @instance_id = instance.instance_id
75
+ @instance = Aws::EC2::Resource.new(client: @ec2_client, retry_limit: 20).instance(@instance_id)
76
+
77
+ if %w(stopped stopping).include?(@instance.state.name)
78
+ $log.info("Instance #{@instance_id} already stopping or stopped")
79
+ return
80
+ end
81
+
82
+ $log.info("Stopping instance #{@instance_id}")
83
+ @instance.stop()
84
+ end
85
+
86
+ return configuration
87
+
88
+ end
89
+
49
90
  end
50
91
 
51
92
  end
@@ -57,13 +98,78 @@ module CfnManage
57
98
  end
58
99
  $log.info("Starting ASG #{@asg_name} with following configuration\n#{configuration}")
59
100
 
60
- # restore asg sizes
61
- @asg_client.update_auto_scaling_group({
101
+ unless @asg_suspend_termination
102
+ # restore asg sizes
103
+ @asg_client.update_auto_scaling_group({
62
104
  auto_scaling_group_name: @asg_name,
63
105
  min_size: configuration['min_size'],
64
106
  max_size: configuration['max_size'],
65
107
  desired_capacity: configuration['desired_capacity']
66
- })
108
+ })
109
+ else
110
+
111
+ $log.info("Starting instances for ASG #{@asg_name}...")
112
+
113
+ @asg.instances.each do |instance|
114
+ @instance_id = instance.instance_id
115
+ @instance = Aws::EC2::Resource.new(client: @ec2_client, retry_limit: 20).instance(@instance_id)
116
+
117
+ if %w(running).include?(@instance.state.name)
118
+ $log.info("Instance #{@instance_id} already running")
119
+ return
120
+ end
121
+ $log.info("Starting instance #{@instance_id}")
122
+ @instance.start()
123
+ end
124
+
125
+ unhealthy = true
126
+
127
+ $log.info("Checking health status for instances for ASG #{@asg_name}")
128
+
129
+ while unhealthy do
130
+
131
+ asg_curr_details = @asg_client.describe_auto_scaling_groups(
132
+ auto_scaling_group_names: [@asg_name]
133
+ )
134
+ @asg_status = asg_curr_details.auto_scaling_groups[0]
135
+
136
+ allHealthy = 0
137
+
138
+ @asg_status.instances.each do |instance|
139
+ @instance_health = instance.health_status
140
+ if @instance_health == "Healthy"
141
+ allHealthy += 1
142
+ else
143
+ $log.info("Instance #{instance.instance_id} not currently healthy...")
144
+ end
145
+ end
146
+
147
+ if allHealthy == @asg_status.instances.length
148
+ $log.info("All instances healthy in ASG #{@asg_name}")
149
+ unhealthy = false
150
+ break
151
+ end
152
+
153
+ end
154
+
155
+ $log.info("Resuming all processes for ASG #{@asg_name}")
156
+
157
+ @asg_client.resume_processes({
158
+ auto_scaling_group_name: "#{@asg.auto_scaling_group_name}",
159
+ })
160
+
161
+ if configuration['suspended_processes'].any?
162
+
163
+ $log.info("Suspending processes stored in configuration for ASG #{@asg_name}")
164
+
165
+ @asg_client.suspend_processes({
166
+ auto_scaling_group_name: "#{@asg.auto_scaling_group_name}",
167
+ scaling_processes: configuration['suspended_processes'],
168
+ })
169
+ end
170
+
171
+ end
172
+
67
173
  end
68
174
 
69
175
  def wait(wait_states=[])
@@ -14,7 +14,6 @@ module CfnManage
14
14
  end
15
15
  rds = Aws::RDS::Resource.new(client: @rds_client)
16
16
  @rds_cluster = rds.db_cluster(cluster_id)
17
-
18
17
  end
19
18
 
20
19
  def start(configuration)
@@ -23,6 +22,11 @@ module CfnManage
23
22
  return
24
23
  end
25
24
 
25
+ if @rds_cluster.engine_mode != 'provisioned'
26
+ $log.info("Aurora Cluster #{@cluster_id} is not a provisioned cluster and cannot be started using this method.")
27
+ return
28
+ end
29
+
26
30
  # start rds cluster
27
31
  if @rds_cluster.status == 'stopped'
28
32
  $log.info("Starting Aurora cluster #{@cluster_id}")
@@ -47,6 +51,11 @@ module CfnManage
47
51
  $log.info("Aurora Cluster #{@cluster_id} is not in a available state. State: #{@rds_cluster.status}")
48
52
  return {}
49
53
  end
54
+
55
+ if @rds_cluster.engine_mode != 'provisioned'
56
+ $log.info("Aurora Cluster #{@cluster_id} is not a provisioned cluster and cannot be stopped using this method.")
57
+ return {}
58
+ end
50
59
  # stop rds cluster and wait for it to be fully stopped
51
60
  $log.info("Stopping aurora cluster #{@cluster_id}")
52
61
  @rds_client.stop_db_cluster({ db_cluster_identifier: @cluster_id })
@@ -6,6 +6,7 @@ require 'aws-sdk-rds'
6
6
  require 'aws-sdk-cloudwatch'
7
7
  require 'aws-sdk-autoscaling'
8
8
  require 'aws-sdk-ecs'
9
+ require 'aws-sdk-docdb'
9
10
 
10
11
  require 'cfn_manage/cf_common'
11
12
  require 'cfn_manage/aws_credentials'
@@ -27,6 +28,7 @@ module CfnManage
27
28
  @@resource_start_priorities = {
28
29
  'AWS::RDS::DBInstance' => '100',
29
30
  'AWS::RDS::DBCluster' => '100',
31
+ 'AWS::DocDB::DBCluster' => '100',
30
32
  'AWS::AutoScaling::AutoScalingGroup' => '200',
31
33
  'AWS::EC2::Instance' => '200',
32
34
  'AWS::EC2::SpotFleet' => '200',
@@ -0,0 +1,89 @@
1
+ require 'cfn_manage/aws_credentials'
2
+
3
+ module CfnManage
4
+
5
+ class DocumentDbClusterStartStopHandler
6
+
7
+ def initialize(cluster_id, skip_wait)
8
+ @cluster_id = cluster_id
9
+ @skip_wait = skip_wait
10
+ credentials = CfnManage::AWSCredentials.get_session_credentials("startstopcluster_#{cluster_id}")
11
+ @docdb_client = Aws::DocDB::Client.new(retry_limit: 20)
12
+ if credentials != nil
13
+ @docdb_client = Aws::DocDB::Client.new(credentials: credentials, retry_limit: 20)
14
+ end
15
+ cluster = @docdb_client.describe_db_clusters({ db_cluster_identifier: @cluster_id })
16
+ @docdb_cluster = cluster.db_clusters.first
17
+ end
18
+
19
+ def start(configuration)
20
+ if @docdb_cluster.status == 'available'
21
+ $log.info("DocDB Cluster #{@cluster_id} is already in available state")
22
+ return
23
+ end
24
+
25
+ # start docdb cluster
26
+ if @docdb_cluster.status == 'stopped'
27
+ $log.info("Starting DocDB cluster #{@cluster_id}")
28
+ @docdb_client.start_db_cluster({ db_cluster_identifier: @cluster_id })
29
+ unless @skip_wait
30
+ # wait cluster to become available
31
+ $log.info("Waiting DocDB cluster to become available #{@cluster_id}")
32
+ wait('available')
33
+ end
34
+ else
35
+ $log.info("DocDB Cluster #{@cluster_id} is not in a stopped state. State: #{@docdb_cluster.status}")
36
+ end
37
+ end
38
+
39
+ def stop
40
+ if @docdb_cluster.status == 'stopped'
41
+ $log.info("DocDB Cluster #{@cluster_id} is already stopped")
42
+ return {}
43
+ end
44
+
45
+ if @docdb_cluster.status != 'available'
46
+ $log.info("DocDB Cluster #{@cluster_id} is not in a available state. State: #{@docdb_cluster.status}")
47
+ return {}
48
+ end
49
+ # stop docdb cluster and wait for it to be fully stopped
50
+ $log.info("Stopping DocDB cluster #{@cluster_id}")
51
+ @docdb_client.stop_db_cluster({ db_cluster_identifier: @cluster_id })
52
+ unless @skip_wait
53
+ $log.info("Waiting DocDB cluster to be stopped #{@cluster_id}")
54
+ wait('stopped')
55
+ end
56
+ return {}
57
+ end
58
+
59
+ def wait(completed_state)
60
+ # reached state must be steady, at least a minute.
61
+ state_count = 0
62
+ steady_count = 4
63
+ attempts = 0
64
+
65
+ until attempts == (max_attempts = 60*6) do
66
+ # Declare client and cluster variable a second time inside the loop so it re-evaluates each time.
67
+ docdb = @docdb_client.describe_db_clusters({ db_cluster_identifier: @cluster_id })
68
+ cluster = docdb.db_clusters.first
69
+ $log.info("DocDB Cluster #{cluster.db_cluster_identifier} state: #{cluster.status}, waiting for #{completed_state}")
70
+
71
+ if cluster.status == "#{completed_state}"
72
+ state_count = state_count + 1
73
+ $log.info("#{state_count}/#{steady_count}")
74
+ else
75
+ state_count = 0
76
+ end
77
+ break if state_count == steady_count
78
+ attempts = attempts + 1
79
+ sleep(15)
80
+ end
81
+
82
+ if attempts == max_attempts
83
+ $log.error("DocDB Cluster #{@cluster_id} did not enter #{completed_state} state, however continuing operations...")
84
+ end
85
+ end
86
+
87
+ end
88
+
89
+ end
@@ -5,6 +5,7 @@ require 'cfn_manage/aurora_cluster_start_stop_handler'
5
5
  require 'cfn_manage/alarm_start_stop_handler'
6
6
  require 'cfn_manage/spot_fleet_start_stop_handler'
7
7
  require 'cfn_manage/ecs_cluster_start_stop_handler'
8
+ require 'cfn_manage/documentdb_cluster_start_stop_handler'
8
9
 
9
10
  module CfnManage
10
11
 
@@ -27,6 +28,9 @@ module CfnManage
27
28
  when 'AWS::RDS::DBCluster'
28
29
  return CfnManage::AuroraClusterStartStopHandler.new(resource_id, skip_wait)
29
30
 
31
+ when 'AWS::DocDB::DBCluster'
32
+ return CfnManage::DocumentDbClusterStartStopHandler.new(resource_id, skip_wait)
33
+
30
34
  when 'AWS::CloudWatch::Alarm'
31
35
  return CfnManage::AlarmStartStopHandler.new(resource_id)
32
36
 
@@ -1,3 +1,3 @@
1
1
  module CfnManage
2
- VERSION="0.5.5".freeze
2
+ VERSION="0.6.0".freeze
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cfn_manage
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.5
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Base2Services
@@ -10,15 +10,15 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2019-05-31 00:00:00.000000000 Z
13
+ date: 2019-07-11 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: aws-sdk-core
17
17
  requirement: !ruby/object:Gem::Requirement
18
18
  requirements:
19
- - - "~>"
19
+ - - ">="
20
20
  - !ruby/object:Gem::Version
21
- version: '3'
21
+ version: 3.39.0
22
22
  - - "<"
23
23
  - !ruby/object:Gem::Version
24
24
  version: '4'
@@ -26,9 +26,9 @@ dependencies:
26
26
  prerelease: false
27
27
  version_requirements: !ruby/object:Gem::Requirement
28
28
  requirements:
29
- - - "~>"
29
+ - - ">="
30
30
  - !ruby/object:Gem::Version
31
- version: '3'
31
+ version: 3.39.0
32
32
  - - "<"
33
33
  - !ruby/object:Gem::Version
34
34
  version: '4'
@@ -192,6 +192,26 @@ dependencies:
192
192
  - - "<"
193
193
  - !ruby/object:Gem::Version
194
194
  version: '2'
195
+ - !ruby/object:Gem::Dependency
196
+ name: aws-sdk-docdb
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - ">="
200
+ - !ruby/object:Gem::Version
201
+ version: 1.9.0
202
+ - - "<"
203
+ - !ruby/object:Gem::Version
204
+ version: '2'
205
+ type: :runtime
206
+ prerelease: false
207
+ version_requirements: !ruby/object:Gem::Requirement
208
+ requirements:
209
+ - - ">="
210
+ - !ruby/object:Gem::Version
211
+ version: 1.9.0
212
+ - - "<"
213
+ - !ruby/object:Gem::Version
214
+ version: '2'
195
215
  - !ruby/object:Gem::Dependency
196
216
  name: bundler
197
217
  requirement: !ruby/object:Gem::Requirement
@@ -307,6 +327,7 @@ files:
307
327
  - lib/cfn_manage/cf_common.rb
308
328
  - lib/cfn_manage/cf_progress_tracker.rb
309
329
  - lib/cfn_manage/cf_start_stop_environment.rb
330
+ - lib/cfn_manage/documentdb_cluster_start_stop_handler.rb
310
331
  - lib/cfn_manage/ec2_start_stop_handler.rb
311
332
  - lib/cfn_manage/ecs_cluster_start_stop_handler.rb
312
333
  - lib/cfn_manage/rds_start_stop_handler.rb
@@ -332,7 +353,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
332
353
  - !ruby/object:Gem::Version
333
354
  version: '0'
334
355
  requirements: []
335
- rubygems_version: 3.0.3
356
+ rubygems_version: 3.0.4
336
357
  signing_key:
337
358
  specification_version: 4
338
359
  summary: Manage AWS Cloud Formation stacks