cfn_manage 0.5.5 → 0.6.0

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