cfn_manage 0.4.3 → 0.5.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 +5 -5
- data/bin/cfn_manage +157 -1
- data/bin/usage.txt +32 -2
- data/lib/cfn_manage.rb +1 -0
- data/lib/{alarm_start_stop_handler.rb → cfn_manage/alarm_start_stop_handler.rb} +9 -4
- data/lib/{asg_start_stop_handler.rb → cfn_manage/asg_start_stop_handler.rb} +10 -6
- data/lib/{aurora_cluster_start_stop_handler.rb → cfn_manage/aurora_cluster_start_stop_handler.rb} +35 -36
- data/lib/{aws_credentials.rb → cfn_manage/aws_credentials.rb} +2 -2
- data/lib/{cf_common.rb → cfn_manage/cf_common.rb} +1 -1
- data/lib/{cf_progress_tracker.rb → cfn_manage/cf_progress_tracker.rb} +6 -6
- data/lib/{cf_start_stop_environment.rb → cfn_manage/cf_start_stop_environment.rb} +107 -63
- data/lib/{ec2_start_stop_handler.rb → cfn_manage/ec2_start_stop_handler.rb} +9 -7
- data/lib/cfn_manage/ecs_cluster_start_stop_handler.rb +66 -0
- data/lib/{rds_start_stop_handler.rb → cfn_manage/rds_start_stop_handler.rb} +41 -42
- data/lib/{spot_fleet_start_stop_handler.rb → cfn_manage/spot_fleet_start_stop_handler.rb} +10 -6
- data/lib/cfn_manage/start_stop_handler_factory.rb +44 -0
- data/lib/cfn_manage/version.rb +3 -0
- metadata +137 -16
- data/bin/cfn_manage.rb +0 -108
- data/lib/start_stop_handler_factory.rb +0 -39
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 069e9448ce6f6efafd546df321dd4dbb52503f73586d23f718dc10c211e0de36
|
4
|
+
data.tar.gz: 9cb836b6ea9b0071743386dd7fe030c6c3f013b1be2270671b1df31722b0a2ea
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a8e2ae95ea5bb3600a46cc637a32f969831190ea2b3cf3d8553a7ee9e4f726ad6aab360f7cc389f08e2fd1df7a1c507cde5e7a9142b79179359590c908048424
|
7
|
+
data.tar.gz: 7d2dcc801ce2c239519fcc8f410b4f2395f56963c8b89e8b2d169131b00f588126b1aa65ccb5a1bff91d6f4434f562ee535b3609e4f6c2585fed195f4ff338c2
|
data/bin/cfn_manage
CHANGED
@@ -1,2 +1,158 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
|
2
|
+
require 'optparse'
|
3
|
+
require 'cfn_manage/version'
|
4
|
+
require 'cfn_manage/cf_common'
|
5
|
+
require 'cfn_manage/cf_start_stop_environment'
|
6
|
+
require 'logger'
|
7
|
+
|
8
|
+
# exit with usage information
|
9
|
+
def print_usage_exit(code)
|
10
|
+
STDERR.puts(File.open("#{File.expand_path(File.dirname(__FILE__))}/usage.txt").read)
|
11
|
+
exit code
|
12
|
+
end
|
13
|
+
|
14
|
+
# global options
|
15
|
+
$options = {}
|
16
|
+
$options['SOURCE_BUCKET'] = ENV['SOURCE_BUCKET']
|
17
|
+
$options['AWS_ASSUME_ROLE'] = ENV['AWS_ASSUME_ROLE']
|
18
|
+
|
19
|
+
# global logger
|
20
|
+
$log = Logger.new(STDOUT)
|
21
|
+
|
22
|
+
# always flush output
|
23
|
+
STDOUT.sync = true
|
24
|
+
|
25
|
+
# parse command line options
|
26
|
+
OptionParser.new do |opts|
|
27
|
+
|
28
|
+
Version = CfnManage::VERSION
|
29
|
+
|
30
|
+
opts.banner = 'Usage: cfn_manage [command] [options]'
|
31
|
+
|
32
|
+
opts.on('--source-bucket [BUCKET]') do |bucket|
|
33
|
+
$options['SOURCE_BUCKET'] = bucket
|
34
|
+
ENV['SOURCE_BUCKET'] = bucket
|
35
|
+
end
|
36
|
+
|
37
|
+
opts.on('--aws-role [ROLE]') do |role|
|
38
|
+
ENV['AWS_ASSUME_ROLE'] = role
|
39
|
+
end
|
40
|
+
|
41
|
+
opts.on('--stack-name [STACK_NAME]') do |stack|
|
42
|
+
$options['STACK_NAME'] = stack
|
43
|
+
end
|
44
|
+
|
45
|
+
opts.on('--asg-name [ASG]') do |asg|
|
46
|
+
$options['ASG'] = asg
|
47
|
+
end
|
48
|
+
|
49
|
+
opts.on('--rds-instance-id [RDS_INSTANCE_ID]') do |rds|
|
50
|
+
$options['RDS_INSTANCE_ID'] = rds
|
51
|
+
end
|
52
|
+
|
53
|
+
opts.on('--aurora-cluster-id [AURORA_CLUSTER_ID]') do |cluster|
|
54
|
+
$options['AURORA_CLUSTER_ID'] = cluster
|
55
|
+
end
|
56
|
+
|
57
|
+
opts.on('--ec2-instance-id [EC2_INSTANCE_ID]') do |ec2|
|
58
|
+
$options['EC2_INSTANCE_ID'] = ec2
|
59
|
+
end
|
60
|
+
|
61
|
+
opts.on('--spot-fleet-id [SPOT_FLEET]') do |spot|
|
62
|
+
$options['SPOT_FLEET'] = spot
|
63
|
+
end
|
64
|
+
|
65
|
+
opts.on('--ecs-cluster [ECS_CLUSTER]') do |ecs|
|
66
|
+
$options['ECS_CLUSTER'] = ecs
|
67
|
+
end
|
68
|
+
|
69
|
+
opts.on('--alarm [ALARM]') do |alarm|
|
70
|
+
$options['ALARM'] = alarm
|
71
|
+
end
|
72
|
+
|
73
|
+
opts.on('-r [AWS_REGION]', '--region [AWS_REGION]') do |region|
|
74
|
+
ENV['AWS_REGION'] = region
|
75
|
+
end
|
76
|
+
|
77
|
+
opts.on('-p [AWS_PROFILE]', '--profile [AWS_PROFILE]') do |profile|
|
78
|
+
ENV['CFN_AWS_PROFILE'] = profile
|
79
|
+
end
|
80
|
+
|
81
|
+
opts.on('--dry-run') do
|
82
|
+
ENV['DRY_RUN'] = '1'
|
83
|
+
end
|
84
|
+
|
85
|
+
opts.on('--continue-on-error') do
|
86
|
+
ENV['CFN_CONTINUE_ON_ERROR'] = '1'
|
87
|
+
end
|
88
|
+
|
89
|
+
opts.on('--wait-async') do
|
90
|
+
ENV['WAIT_ASYNC'] = '1'
|
91
|
+
ENV['SKIP_WAIT'] = '1'
|
92
|
+
end
|
93
|
+
|
94
|
+
opts.on('--skip_wait') do
|
95
|
+
ENV['SKIP_WAIT'] = '1'
|
96
|
+
end
|
97
|
+
|
98
|
+
end.parse!
|
99
|
+
|
100
|
+
command = ARGV[0]
|
101
|
+
|
102
|
+
if command.nil?
|
103
|
+
print_usage_exit(-1)
|
104
|
+
end
|
105
|
+
|
106
|
+
# execute action based on command
|
107
|
+
case command
|
108
|
+
when 'help'
|
109
|
+
print_usage_exit(0)
|
110
|
+
# asg commands
|
111
|
+
when 'stop-asg'
|
112
|
+
CfnManage::CloudFormation::EnvironmentRunStop.new().start_resource($options['ASG'],'AWS::AutoScaling::AutoScalingGroup')
|
113
|
+
when 'start-asg'
|
114
|
+
CfnManage::CloudFormation::EnvironmentRunStop.new().start_resource($options['ASG'],'AWS::AutoScaling::AutoScalingGroup')
|
115
|
+
|
116
|
+
# rds commands
|
117
|
+
when 'stop-rds'
|
118
|
+
CfnManage::CloudFormation::EnvironmentRunStop.new().start_resource($options['RDS_INSTANCE_ID'],'AWS::RDS::DBInstance')
|
119
|
+
when 'start-rds'
|
120
|
+
CfnManage::CloudFormation::EnvironmentRunStop.new().start_resource($options['RDS_INSTANCE_ID'],'AWS::RDS::DBInstance')
|
121
|
+
|
122
|
+
# aurora cluster commands
|
123
|
+
when 'stop-aurora-cluster'
|
124
|
+
CfnManage::CloudFormation::EnvironmentRunStop.new().start_resource($options['AURORA_CLUSTER_ID'],'AWS::RDS::DBCluster')
|
125
|
+
when 'start-aurora-cluster'
|
126
|
+
CfnManage::CloudFormation::EnvironmentRunStop.new().start_resource($options['AURORA_CLUSTER_ID'],'AWS::RDS::DBCluster')
|
127
|
+
|
128
|
+
# ec2 instance
|
129
|
+
when 'stop-ec2'
|
130
|
+
CfnManage::CloudFormation::EnvironmentRunStop.new().start_resource($options['EC2_INSTANCE_ID'],'AWS::EC2::Instance')
|
131
|
+
when 'start-ec2'
|
132
|
+
CfnManage::CloudFormation::EnvironmentRunStop.new().start_resource($options['EC2_INSTANCE_ID'],'AWS::EC2::Instance')
|
133
|
+
|
134
|
+
# spot fleet
|
135
|
+
when 'stop-spot-fleet'
|
136
|
+
CfnManage::CloudFormation::EnvironmentRunStop.new().start_resource($options['SPOT_FLEET'],'AWS::EC2::SpotFleet')
|
137
|
+
when 'start-spot-fleet'
|
138
|
+
CfnManage::CloudFormation::EnvironmentRunStop.new().start_resource($options['SPOT_FLEET'],'AWS::EC2::SpotFleet')
|
139
|
+
|
140
|
+
# spot fleet
|
141
|
+
when 'stop-ecs-cluster'
|
142
|
+
CfnManage::CloudFormation::EnvironmentRunStop.new().start_resource($options['ECS_CLUSTER'],'AWS::ECS::Cluster')
|
143
|
+
when 'start-ecs-cluster'
|
144
|
+
CfnManage::CloudFormation::EnvironmentRunStop.new().start_resource($options['ECS_CLUSTER'],'AWS::ECS::Cluster')
|
145
|
+
|
146
|
+
|
147
|
+
# cloudwatch alarm
|
148
|
+
when 'disable-alarm'
|
149
|
+
CfnManage::CloudFormation::EnvironmentRunStop.new().start_resource($options['ALARM'],'AWS::CloudWatch::Alarm')
|
150
|
+
when 'enable-alarm'
|
151
|
+
CfnManage::CloudFormation::EnvironmentRunStop.new().start_resource($options['ALARM'],'AWS::CloudWatch::Alarm')
|
152
|
+
|
153
|
+
# stack commands
|
154
|
+
when 'stop-environment'
|
155
|
+
CfnManage::CloudFormation::EnvironmentRunStop.new().stop_environment($options['STACK_NAME'])
|
156
|
+
when 'start-environment'
|
157
|
+
CfnManage::CloudFormation::EnvironmentRunStop.new().start_environment($options['STACK_NAME'])
|
158
|
+
end
|
data/bin/usage.txt
CHANGED
@@ -2,6 +2,10 @@ Usage: cfn_manage [command] [options]
|
|
2
2
|
|
3
3
|
Commands:
|
4
4
|
|
5
|
+
cfn_manage help
|
6
|
+
|
7
|
+
cfn_manage version
|
8
|
+
|
5
9
|
cfn_manage stop-environment --stack-name [STACK_NAME]
|
6
10
|
|
7
11
|
cfn_manage start-environment --stack-name [STACK_NAME]
|
@@ -18,7 +22,23 @@ cfn_manage stop-aurora-cluster --aurora-cluster-id [AURORA_CLUSTER_ID]
|
|
18
22
|
|
19
23
|
cfn_manage start-aurora-cluster --aurora-cluster-id [AURORA_CLUSTER_ID]
|
20
24
|
|
21
|
-
|
25
|
+
cfn_manage stop-ec2 --ec2-instance-id [EC2_INSTANCE_ID]
|
26
|
+
|
27
|
+
cfn_manage start-ec2 --ec2-instance-id [EC2_INSTANCE_ID]
|
28
|
+
|
29
|
+
cfn_manage stop-spot-fleet --spot-fleet [SPOT_FLEET]
|
30
|
+
|
31
|
+
cfn_manage start-spot-fleet --spot-fleet [SPOT_FLEET]
|
32
|
+
|
33
|
+
cfn_manage stop-ecs-cluster --ecs-cluster [ECS_CLUSTER]
|
34
|
+
|
35
|
+
cfn_manage start-ecs-cluster --ecs-cluster [ECS_CLUSTER]
|
36
|
+
|
37
|
+
cfn_manage disable-alarm --alarm [ALARM]
|
38
|
+
|
39
|
+
cfn_manage enable-alarm --alarm [ALARM]
|
40
|
+
|
41
|
+
General options:
|
22
42
|
|
23
43
|
--source-bucket [BUCKET]
|
24
44
|
|
@@ -48,5 +68,15 @@ General options
|
|
48
68
|
|
49
69
|
Applicable only to [start|stop-environment] commands. If there is problem with stopping a resource,
|
50
70
|
(e.g. cloudformation stack not being synced or manual resource deletion) script will continue it's
|
51
|
-
operation. By
|
71
|
+
operation. By default script stops when there is problem with starting/stopping resource, and expects
|
52
72
|
manual intervention to fix the root cause for failure.
|
73
|
+
|
74
|
+
--skip-wait
|
75
|
+
|
76
|
+
Skips waiting for resources to achieve stopped or started states.
|
77
|
+
|
78
|
+
--wait-async
|
79
|
+
|
80
|
+
Default wait action is to wait for each individual resource to be stopped and started before continuing.
|
81
|
+
This will enabled waiting for resources in groups based on priority. Option only useful when used with
|
82
|
+
start-environment and stop-environment commands.
|
data/lib/cfn_manage.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
module CfnManage; end
|
@@ -1,12 +1,12 @@
|
|
1
|
-
|
1
|
+
require 'cfn_manage/aws_credentials'
|
2
2
|
|
3
|
-
module
|
3
|
+
module CfnManage
|
4
4
|
|
5
5
|
class AlarmStartStopHandler
|
6
6
|
|
7
7
|
def initialize(alarm_name)
|
8
8
|
@alarm_id = alarm_name
|
9
|
-
credentials =
|
9
|
+
credentials = CfnManage::AWSCredentials.get_session_credentials("startstopalarm_#{@asg_name}")
|
10
10
|
@cwclient = Aws::CloudWatch::Client.new(retry_limit: 20)
|
11
11
|
if credentials != nil
|
12
12
|
@cwclient = Aws::CloudWatch::Client.new(credentials: credentials, retry_limit: 20)
|
@@ -34,6 +34,11 @@ module Base2
|
|
34
34
|
@alarm.disable_actions({})
|
35
35
|
return {}
|
36
36
|
end
|
37
|
+
|
38
|
+
def wait(wait_states=[])
|
39
|
+
$log.debug("Not waiting for alarm #{@alarm_id}")
|
40
|
+
end
|
41
|
+
|
37
42
|
end
|
38
43
|
|
39
|
-
end
|
44
|
+
end
|
@@ -1,13 +1,13 @@
|
|
1
|
-
|
1
|
+
require 'cfn_manage/aws_credentials'
|
2
2
|
|
3
|
-
module
|
3
|
+
module CfnManage
|
4
4
|
|
5
5
|
class AsgStartStopHandler
|
6
6
|
|
7
|
-
def initialize(asg_id)
|
7
|
+
def initialize(asg_id, skip_wait)
|
8
8
|
@asg_name = asg_id
|
9
|
-
|
10
|
-
credentials =
|
9
|
+
@skip_wait = skip_wait
|
10
|
+
credentials = CfnManage::AWSCredentials.get_session_credentials("stopasg_#{@asg_name}")
|
11
11
|
@asg_client = Aws::AutoScaling::Client.new(retry_limit: 20)
|
12
12
|
if credentials != nil
|
13
13
|
@asg_client = Aws::AutoScaling::Client.new(credentials: credentials, retry_limit: 20)
|
@@ -66,5 +66,9 @@ module Base2
|
|
66
66
|
})
|
67
67
|
end
|
68
68
|
|
69
|
+
def wait(wait_states=[])
|
70
|
+
$log.debug("Not waiting for ASG #{@asg_name}")
|
71
|
+
end
|
72
|
+
|
69
73
|
end
|
70
|
-
end
|
74
|
+
end
|
data/lib/{aurora_cluster_start_stop_handler.rb → cfn_manage/aurora_cluster_start_stop_handler.rb}
RENAMED
@@ -1,13 +1,13 @@
|
|
1
|
-
|
1
|
+
require 'cfn_manage/aws_credentials'
|
2
2
|
|
3
|
-
module
|
3
|
+
module CfnManage
|
4
4
|
|
5
5
|
class AuroraClusterStartStopHandler
|
6
6
|
|
7
|
-
def initialize(cluster_id)
|
7
|
+
def initialize(cluster_id, skip_wait)
|
8
8
|
@cluster_id = cluster_id
|
9
|
-
|
10
|
-
credentials =
|
9
|
+
@skip_wait = skip_wait
|
10
|
+
credentials = CfnManage::AWSCredentials.get_session_credentials("startstopcluster_#{cluster_id}")
|
11
11
|
@rds_client = Aws::RDS::Client.new(retry_limit: 20)
|
12
12
|
if credentials != nil
|
13
13
|
@rds_client = Aws::RDS::Client.new(credentials: credentials, retry_limit: 20)
|
@@ -27,10 +27,11 @@ module Base2
|
|
27
27
|
if @rds_cluster.status == 'stopped'
|
28
28
|
$log.info("Starting Aurora cluster #{@cluster_id}")
|
29
29
|
@rds_client.start_db_cluster({ db_cluster_identifier: @cluster_id })
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
30
|
+
unless @skip_wait
|
31
|
+
# wait cluster to become available
|
32
|
+
$log.info("Waiting Aurora cluster to become available #{@cluster_id}")
|
33
|
+
wait('available')
|
34
|
+
end
|
34
35
|
else
|
35
36
|
$log.info("Aurora Cluster #{@cluster_id} is not in a stopped state. State: #{@rds_cluster.status}")
|
36
37
|
end
|
@@ -46,41 +47,39 @@ module Base2
|
|
46
47
|
$log.info("Aurora Cluster #{@cluster_id} is not in a available state. State: #{@rds_cluster.status}")
|
47
48
|
return {}
|
48
49
|
end
|
49
|
-
|
50
50
|
# stop rds cluster and wait for it to be fully stopped
|
51
51
|
$log.info("Stopping aurora cluster #{@cluster_id}")
|
52
52
|
@rds_client.stop_db_cluster({ db_cluster_identifier: @cluster_id })
|
53
|
-
|
54
|
-
|
55
|
-
|
53
|
+
unless @skip_wait
|
54
|
+
$log.info("Waiting aurora cluster to be stopped #{@cluster_id}")
|
55
|
+
wait('stopped')
|
56
|
+
end
|
56
57
|
return {}
|
57
58
|
end
|
58
59
|
|
59
|
-
def
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
state_count = 0
|
75
|
-
end
|
76
|
-
break if state_count == steady_count
|
77
|
-
attempts = attempts + 1
|
78
|
-
sleep(15)
|
60
|
+
def wait(completed_state)
|
61
|
+
# reached state must be steady, at least a minute.
|
62
|
+
state_count = 0
|
63
|
+
steady_count = 4
|
64
|
+
attempts = 0
|
65
|
+
rds = Aws::RDS::Resource.new(client: @rds_client)
|
66
|
+
until attempts == (max_attempts = 60*6) do
|
67
|
+
cluster = rds.db_cluster(@cluster_id)
|
68
|
+
$log.info("Aurora Cluster #{cluster.db_cluster_identifier} state: #{cluster.status}, waiting for #{completed_state}")
|
69
|
+
|
70
|
+
if cluster.status == "#{completed_state}"
|
71
|
+
state_count = state_count + 1
|
72
|
+
$log.info("#{state_count}/#{steady_count}")
|
73
|
+
else
|
74
|
+
state_count = 0
|
79
75
|
end
|
76
|
+
break if state_count == steady_count
|
77
|
+
attempts = attempts + 1
|
78
|
+
sleep(15)
|
79
|
+
end
|
80
80
|
|
81
|
-
|
82
|
-
|
83
|
-
end
|
81
|
+
if attempts == max_attempts
|
82
|
+
$log.error("RDS Aurora Cluster #{@cluster_id} did not enter #{state} state, however continuing operations...")
|
84
83
|
end
|
85
84
|
end
|
86
85
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'aws-sdk-cloudformation'
|
2
|
-
|
2
|
+
require 'cfn_manage/cf_common'
|
3
3
|
|
4
|
-
module
|
4
|
+
module CfnManage
|
5
5
|
module CloudFormation
|
6
6
|
class ProgressTracker
|
7
7
|
@cf_client = nil
|
@@ -34,17 +34,17 @@ module Base2
|
|
34
34
|
@period_from = period_from
|
35
35
|
end
|
36
36
|
|
37
|
-
|
37
|
+
|
38
38
|
def track_single_stack(stack)
|
39
39
|
stack_id = stack['stack_id']
|
40
40
|
# Default to period_from if first run, take from last run otherwise
|
41
41
|
event_from = last_event_times[stack_id] if @last_event_times.key?(stack_id)
|
42
42
|
event_from = @period_from unless @last_event_times.key?(stack_id)
|
43
|
-
|
43
|
+
|
44
44
|
|
45
45
|
stack_resources = @cf_client.describe_stack_events(stack_name: stack['stack_id'],)
|
46
|
-
|
47
|
-
|
46
|
+
|
47
|
+
|
48
48
|
end
|
49
49
|
|
50
50
|
def track_progress(_show_only_failures = false)
|
@@ -5,14 +5,15 @@ require 'aws-sdk-cloudformation'
|
|
5
5
|
require 'aws-sdk-rds'
|
6
6
|
require 'aws-sdk-cloudwatch'
|
7
7
|
require 'aws-sdk-autoscaling'
|
8
|
+
require 'aws-sdk-ecs'
|
8
9
|
|
9
|
-
|
10
|
-
|
10
|
+
require 'cfn_manage/cf_common'
|
11
|
+
require 'cfn_manage/aws_credentials'
|
11
12
|
require 'json'
|
12
13
|
require 'yaml'
|
13
|
-
|
14
|
+
require 'cfn_manage/start_stop_handler_factory'
|
14
15
|
|
15
|
-
module
|
16
|
+
module CfnManage
|
16
17
|
module CloudFormation
|
17
18
|
class EnvironmentRunStop
|
18
19
|
|
@@ -29,6 +30,7 @@ module Base2
|
|
29
30
|
'AWS::AutoScaling::AutoScalingGroup' => '200',
|
30
31
|
'AWS::EC2::Instance' => '200',
|
31
32
|
'AWS::EC2::SpotFleet' => '200',
|
33
|
+
'AWS::ECS::Cluster' => '250',
|
32
34
|
'AWS::CloudWatch::Alarm' => '300'
|
33
35
|
}
|
34
36
|
|
@@ -37,11 +39,13 @@ module Base2
|
|
37
39
|
@s3_client = Aws::S3::Client.new(retry_limit: 20)
|
38
40
|
@s3_bucket = ENV['SOURCE_BUCKET']
|
39
41
|
@cf_client = Aws::CloudFormation::Client.new(retry_limit: 20)
|
40
|
-
@credentials =
|
42
|
+
@credentials = CfnManage::AWSCredentials.get_session_credentials('start_stop_environment')
|
41
43
|
if not @credentials.nil?
|
42
44
|
@cf_client = Aws::CloudFormation::Client.new(credentials: @credentials, retry_limit: 20)
|
43
45
|
end
|
44
46
|
@dry_run = (ENV.key?('DRY_RUN') and ENV['DRY_RUN'] == '1')
|
47
|
+
@skip_wait = (ENV.key?('SKIP_WAIT') and ENV['SKIP_WAIT'] == '1')
|
48
|
+
@wait_async = (ENV.key?('WAIT_ASYNC') and ENV['WAIT_ASYNC'] == '1')
|
45
49
|
@continue_on_error = (ENV.key? 'CFN_CONTINUE_ON_ERROR' and ENV['CFN_CONTINUE_ON_ERROR'] == '1')
|
46
50
|
rescue NoMethodError => e
|
47
51
|
puts "Got No Method Error on CloudFormation::initialize, this often means that you're missing a AWS_DEFAULT_REGION"
|
@@ -69,92 +73,131 @@ module Base2
|
|
69
73
|
$log.info("Environment #{stack_name} stopped")
|
70
74
|
end
|
71
75
|
|
72
|
-
def
|
73
|
-
start_stop_handler =
|
74
|
-
|
75
|
-
|
76
|
+
def start_resource(resource_id,resource_type)
|
77
|
+
start_stop_handler = CfnManage::StartStopHandlerFactory.get_start_stop_handler(
|
78
|
+
resource_type,
|
79
|
+
resource_id,
|
80
|
+
@skip_wait
|
76
81
|
)
|
77
82
|
@environment_resources << {
|
78
|
-
id:
|
79
|
-
priority: '
|
83
|
+
id: resource_id,
|
84
|
+
priority: @@resource_start_priorities[resource['resource_type']],
|
80
85
|
handler: start_stop_handler,
|
81
|
-
type:
|
86
|
+
type: resource_type
|
82
87
|
}
|
83
|
-
|
84
|
-
do_start_assets if action == 'start'
|
88
|
+
do_start_assets
|
85
89
|
end
|
86
90
|
|
87
|
-
def
|
88
|
-
start_stop_handler =
|
89
|
-
|
90
|
-
|
91
|
+
def stop_resource(resource_id,resource_type)
|
92
|
+
start_stop_handler = CfnManage::StartStopHandlerFactory.get_start_stop_handler(
|
93
|
+
resource_type,
|
94
|
+
resource_id,
|
95
|
+
@skip_wait
|
91
96
|
)
|
92
97
|
@environment_resources << {
|
93
|
-
id:
|
94
|
-
priority: '
|
98
|
+
id: resource_id,
|
99
|
+
priority: @@resource_start_priorities[resource['resource_type']],
|
95
100
|
handler: start_stop_handler,
|
96
|
-
type:
|
101
|
+
type: resource_type
|
97
102
|
}
|
98
|
-
do_stop_assets
|
99
|
-
do_start_assets if action == 'start'
|
103
|
+
do_stop_assets
|
100
104
|
end
|
101
105
|
|
102
106
|
def do_stop_assets
|
103
107
|
# sort start resource by priority
|
104
108
|
@environment_resources = @environment_resources.sort_by { |k| k[:priority] }.reverse
|
109
|
+
environment_resources_by_priority = @environment_resources.partition { |k| k[:priority] }
|
105
110
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
111
|
+
environment_resources_by_priority.each do |priority|
|
112
|
+
priority.each do |resource|
|
113
|
+
begin
|
114
|
+
$log.info("Stopping resource #{resource[:id]}")
|
115
|
+
# just print out information if running a dry run, otherwise start assets
|
116
|
+
if not @dry_run
|
117
|
+
configuration = resource[:handler].stop()
|
118
|
+
if configuration.class == Hash
|
119
|
+
s3_prefix = "environment_data/resource/#{resource[:id]}"
|
120
|
+
save_item_configuration(s3_prefix, configuration)
|
121
|
+
end
|
122
|
+
else
|
123
|
+
$log.info("Dry run enabled, skipping stop start\nFollowing resource would be stopped: #{resource[:id]}")
|
124
|
+
$log.debug("Resource type: #{resource[:type]}\n\n")
|
125
|
+
end
|
126
|
+
rescue => e
|
127
|
+
$log.error("An exception occurred during stop operation against resource #{resource[:id]}")
|
128
|
+
$log.error("#{e.to_s}")
|
129
|
+
$log.error(e.backtrace.join("\n\t"))
|
130
|
+
if not @continue_on_error
|
131
|
+
raise e
|
115
132
|
end
|
116
|
-
else
|
117
|
-
$log.info("Dry run enabled, skipping stop start\nFollowing resource would be stopped: #{resource[:id]}")
|
118
|
-
$log.debug("Resource type: #{resource[:type]}\n\n")
|
119
133
|
end
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
134
|
+
end
|
135
|
+
|
136
|
+
if not @dry_run and @wait_async
|
137
|
+
priority.each do |resource|
|
138
|
+
begin
|
139
|
+
resource[:handler].wait('stopped')
|
140
|
+
rescue => e
|
141
|
+
$log.error("An exception occurred during wait operation against resource #{resource[:id]}")
|
142
|
+
$log.error("#{e.to_s}")
|
143
|
+
$log.error(e.backtrace.join("\n\t"))
|
144
|
+
if not @continue_on_error
|
145
|
+
raise e
|
146
|
+
end
|
147
|
+
end
|
126
148
|
end
|
127
149
|
end
|
150
|
+
|
128
151
|
end
|
129
152
|
end
|
130
153
|
|
131
154
|
def do_start_assets
|
132
155
|
# sort start resource by priority
|
133
156
|
@environment_resources = @environment_resources.sort_by { |k| k[:priority] }
|
157
|
+
environment_resources_by_priority = @environment_resources.partition { |k| k[:priority] }
|
134
158
|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
159
|
+
environment_resources_by_priority.each do |priority|
|
160
|
+
priority.each do |resource|
|
161
|
+
begin
|
162
|
+
$log.info("Starting resource #{resource[:id]}")
|
163
|
+
# just print out information if running a dry run, otherwise start assets
|
164
|
+
if not @dry_run
|
165
|
+
# read configuration
|
166
|
+
s3_prefix = "environment_data/resource/#{resource[:id]}"
|
167
|
+
configuration = get_object_configuration(s3_prefix)
|
168
|
+
|
169
|
+
# start
|
170
|
+
resource[:handler].start(configuration)
|
171
|
+
else
|
172
|
+
$log.info("Dry run enabled, skipping actual start\nFollowing resource would be started: #{resource[:id]}")
|
173
|
+
$log.debug("Resource type: #{resource[:type]}\n\n")
|
174
|
+
end
|
175
|
+
rescue => e
|
176
|
+
$log.error("An exception occurred during start operation against resource #{resource[:id]}")
|
177
|
+
$log.error("#{e.to_s}")
|
178
|
+
$log.error(e.backtrace.join("\n\t"))
|
179
|
+
if not @continue_on_error
|
180
|
+
raise e
|
181
|
+
end
|
149
182
|
end
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
183
|
+
end
|
184
|
+
|
185
|
+
if not @dry_run and @wait_async
|
186
|
+
priority.each do |resource|
|
187
|
+
begin
|
188
|
+
resource[:handler].wait('available')
|
189
|
+
rescue => e
|
190
|
+
$log.error("An exception occurred during wait operation against resource #{resource[:id]}")
|
191
|
+
$log.error("#{e.to_s}")
|
192
|
+
$log.error(e.backtrace.join("\n\t"))
|
193
|
+
if not @continue_on_error
|
194
|
+
raise e
|
195
|
+
end
|
156
196
|
end
|
197
|
+
end
|
198
|
+
|
157
199
|
end
|
200
|
+
|
158
201
|
end
|
159
202
|
end
|
160
203
|
|
@@ -163,9 +206,10 @@ module Base2
|
|
163
206
|
resrouces['stack_resources'].each do |resource|
|
164
207
|
start_stop_handler = nil
|
165
208
|
begin
|
166
|
-
start_stop_handler =
|
209
|
+
start_stop_handler = CfnManage::StartStopHandlerFactory.get_start_stop_handler(
|
167
210
|
resource['resource_type'],
|
168
|
-
resource['physical_resource_id']
|
211
|
+
resource['physical_resource_id'],
|
212
|
+
@skip_wait
|
169
213
|
)
|
170
214
|
rescue Exception => e
|
171
215
|
$log.error("Error creating start-stop handler for resource of type #{resource['resource_type']}" +
|