cfn_manage 0.7.0 → 0.8.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.
- checksums.yaml +4 -4
- data/.gitignore +8 -0
- data/.rspec +2 -0
- data/.travis.yml +20 -0
- data/Dockerfile +7 -0
- data/Gemfile +9 -0
- data/LICENSE +21 -0
- data/README.md +311 -0
- data/Rakefile +9 -0
- data/cfn_manage.gemspec +58 -0
- data/{bin → exe}/cfn_manage +78 -7
- data/{bin → exe}/usage.txt +31 -0
- data/lib/cfn_manage/cf_start_stop_environment.rb +84 -56
- data/lib/cfn_manage/globals.rb +90 -0
- data/lib/cfn_manage/handlers/alarm.rb +45 -0
- data/lib/cfn_manage/handlers/asg.rb +311 -0
- data/lib/cfn_manage/handlers/aurora_cluster.rb +97 -0
- data/lib/cfn_manage/handlers/documentdb.rb +89 -0
- data/lib/cfn_manage/handlers/ec2.rb +42 -0
- data/lib/cfn_manage/handlers/ecs_cluster.rb +219 -0
- data/lib/cfn_manage/handlers/rds.rb +142 -0
- data/lib/cfn_manage/handlers/spot_fleet.rb +56 -0
- data/lib/cfn_manage/handlers/transfer.rb +96 -0
- data/lib/cfn_manage/start_stop_handler_factory.rb +19 -19
- data/lib/cfn_manage/tag_finder.rb +77 -0
- data/lib/cfn_manage/version.rb +1 -1
- metadata +56 -21
- data/lib/cfn_manage/alarm_start_stop_handler.rb +0 -44
- data/lib/cfn_manage/asg_start_stop_handler.rb +0 -181
- data/lib/cfn_manage/aurora_cluster_start_stop_handler.rb +0 -97
- data/lib/cfn_manage/documentdb_cluster_start_stop_handler.rb +0 -89
- data/lib/cfn_manage/ec2_start_stop_handler.rb +0 -43
- data/lib/cfn_manage/ecs_cluster_start_stop_handler.rb +0 -80
- data/lib/cfn_manage/rds_start_stop_handler.rb +0 -134
- data/lib/cfn_manage/spot_fleet_start_stop_handler.rb +0 -57
- data/lib/cfn_manage/transfer_start_stop_handler.rb +0 -97
@@ -1,80 +0,0 @@
|
|
1
|
-
require 'cfn_manage/aws_credentials'
|
2
|
-
|
3
|
-
module CfnManage
|
4
|
-
class EcsClusterStartStopHandler
|
5
|
-
|
6
|
-
def initialize(cluster_id, skip_wait)
|
7
|
-
credentials = CfnManage::AWSCredentials.get_session_credentials("stoprun_#{cluster_id}")
|
8
|
-
@ecs_client = Aws::ECS::Client.new(credentials: credentials, retry_limit: 20)
|
9
|
-
@services = []
|
10
|
-
@ecs_client.list_services(cluster: cluster_id, scheduling_strategy: 'REPLICA', max_results: 100).each do |results|
|
11
|
-
@services.push(*results.service_arns)
|
12
|
-
end
|
13
|
-
$log.info("Found #{@services.count} services in ECS cluster #{cluster_id}")
|
14
|
-
@cluster = cluster_id
|
15
|
-
@skip_wait = skip_wait
|
16
|
-
@ignore_missing_ecs_config = (ENV.key? 'IGNORE_MISSING_ECS_CONFIG' and ENV['IGNORE_MISSING_ECS_CONFIG'] == '1')
|
17
|
-
end
|
18
|
-
|
19
|
-
def start(configuration)
|
20
|
-
@services.each do |service_arn|
|
21
|
-
|
22
|
-
$log.info("Searching for ECS service #{service_arn} in cluster #{@cluster}")
|
23
|
-
service = @ecs_client.describe_services(services:[service_arn], cluster: @cluster).services[0]
|
24
|
-
|
25
|
-
if service.desired_count != 0
|
26
|
-
$log.info("ECS service #{service.service_name} is already running")
|
27
|
-
next
|
28
|
-
end
|
29
|
-
|
30
|
-
if configuration.has_key?(service.service_name)
|
31
|
-
desired_count = configuration[service.service_name]['desired_count']
|
32
|
-
elsif @ignore_missing_ecs_config
|
33
|
-
$log.info("ECS service #{service.service_name} wasn't previosly stopped by cfn_manage. Option --ignore-missing-ecs-config set and setting desired count to 1")
|
34
|
-
desired_count = 1
|
35
|
-
else
|
36
|
-
$log.warn("ECS service #{service.service_name} wasn't previosly stopped by cfn_manage. Skipping ...")
|
37
|
-
next
|
38
|
-
end
|
39
|
-
|
40
|
-
$log.info("Starting ECS service #{service.service_name} with desired count of #{desired_count}")
|
41
|
-
@ecs_client.update_service({
|
42
|
-
desired_count: desired_count,
|
43
|
-
service: service_arn,
|
44
|
-
cluster: @cluster
|
45
|
-
})
|
46
|
-
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def stop
|
51
|
-
configuration = {}
|
52
|
-
@services.each do |service_arn|
|
53
|
-
|
54
|
-
$log.info("Searching for ECS service #{service_arn} in cluster #{@cluster}")
|
55
|
-
service = @ecs_client.describe_services(services:[service_arn], cluster: @cluster).services[0]
|
56
|
-
|
57
|
-
if service.desired_count == 0
|
58
|
-
$log.info("ECS service #{service.service_name} is already stopped")
|
59
|
-
next
|
60
|
-
end
|
61
|
-
|
62
|
-
configuration[service.service_name] = { desired_count: service.desired_count }
|
63
|
-
$log.info("Stopping ECS service #{service.service_name}")
|
64
|
-
@ecs_client.update_service({
|
65
|
-
desired_count: 0,
|
66
|
-
service: service_arn,
|
67
|
-
cluster: @cluster
|
68
|
-
})
|
69
|
-
|
70
|
-
end
|
71
|
-
|
72
|
-
return configuration.empty? ? nil : configuration
|
73
|
-
end
|
74
|
-
|
75
|
-
def wait(completed_status)
|
76
|
-
$log.debug("Not waiting for ECS Services in cluster #{@cluster}")
|
77
|
-
end
|
78
|
-
|
79
|
-
end
|
80
|
-
end
|
@@ -1,134 +0,0 @@
|
|
1
|
-
require 'cfn_manage/aws_credentials'
|
2
|
-
|
3
|
-
module CfnManage
|
4
|
-
|
5
|
-
class RdsStartStopHandler
|
6
|
-
|
7
|
-
def initialize(instance_id, skip_wait)
|
8
|
-
@instance_id = instance_id
|
9
|
-
@skip_wait = skip_wait
|
10
|
-
@excluded_engines = %w(aurora aurora-mysql aurora-postgresql) # RDS list of exluded engines that don't support RDS stop start
|
11
|
-
credentials = CfnManage::AWSCredentials.get_session_credentials("startstoprds_#{instance_id}")
|
12
|
-
@rds_client = Aws::RDS::Client.new(retry_limit: 20)
|
13
|
-
if credentials != nil
|
14
|
-
@rds_client = Aws::RDS::Client.new(credentials: credentials, retry_limit: 20)
|
15
|
-
end
|
16
|
-
rds = Aws::RDS::Resource.new(client: @rds_client)
|
17
|
-
@rds_instance = rds.db_instance(instance_id)
|
18
|
-
|
19
|
-
end
|
20
|
-
|
21
|
-
def start(configuration)
|
22
|
-
if @excluded_engines.include? @rds_instance.engine
|
23
|
-
$log.info("RDS Instance #{@instance_id} engine is #{@rds_instance.engine} and cannot be started by instance.")
|
24
|
-
return
|
25
|
-
end
|
26
|
-
|
27
|
-
if @rds_instance.db_instance_status == 'available'
|
28
|
-
$log.info("RDS Instance #{@instance_id} is already in available state")
|
29
|
-
end
|
30
|
-
|
31
|
-
# start rds instance
|
32
|
-
if @rds_instance.db_instance_status == 'stopped'
|
33
|
-
$log.info("Starting db instance #{@instance_id}")
|
34
|
-
@rds_client.start_db_instance({ db_instance_identifier: @instance_id })
|
35
|
-
|
36
|
-
# wait instance to become available
|
37
|
-
unless @skip_wait
|
38
|
-
$log.info("Waiting db instance to become available #{@instance_id}")
|
39
|
-
wait('available')
|
40
|
-
end
|
41
|
-
else
|
42
|
-
wait('available') unless @skip_wait
|
43
|
-
end
|
44
|
-
|
45
|
-
# convert rds instance to mutli-az if required
|
46
|
-
if configuration['is_multi_az']
|
47
|
-
$log.info("Converting to Multi-AZ instance after start (instance #{@instance_id})")
|
48
|
-
set_rds_instance_multi_az( true)
|
49
|
-
end unless configuration.nil?
|
50
|
-
end
|
51
|
-
|
52
|
-
def stop
|
53
|
-
|
54
|
-
configuration = {
|
55
|
-
is_multi_az: @rds_instance.multi_az
|
56
|
-
}
|
57
|
-
# RDS list of exluded engines that don't support RDS stop start
|
58
|
-
if @excluded_engines.include? @rds_instance.engine
|
59
|
-
$log.info("RDS Instance #{@instance_id} engine is #{@rds_instance.engine} and cannot be stoped by instance.")
|
60
|
-
return configuration
|
61
|
-
end
|
62
|
-
|
63
|
-
# check if available
|
64
|
-
if @rds_instance.db_instance_status != 'available'
|
65
|
-
$log.warn("RDS Instance #{@instance_id} not in available state, and thus can not be stopped")
|
66
|
-
$log.warn("RDS Instance #{@instance_id} state: #{@rds_instance.db_instance_status}")
|
67
|
-
return configuration
|
68
|
-
end
|
69
|
-
|
70
|
-
# check if already stopped
|
71
|
-
if @rds_instance.db_instance_status == 'stopped'
|
72
|
-
$log.info("RDS Instance #{@instance_id} is already stopped")
|
73
|
-
return configuration
|
74
|
-
end
|
75
|
-
|
76
|
-
#check if mutli-az RDS. if so, convert to single-az
|
77
|
-
if @rds_instance.multi_az
|
78
|
-
$log.info("Converting to Non-Multi-AZ instance before stop (instance #{@instance_id}")
|
79
|
-
set_rds_instance_multi_az(false)
|
80
|
-
end
|
81
|
-
|
82
|
-
# stop rds instance and wait for it to be fully stopped
|
83
|
-
$log.info("Stopping instance #{@instance_id}")
|
84
|
-
@rds_client.stop_db_instance({ db_instance_identifier: @instance_id })
|
85
|
-
unless @skip_wait
|
86
|
-
$log.info("Waiting db instance to be stopped #{@instance_id}")
|
87
|
-
wait('stopped')
|
88
|
-
end
|
89
|
-
|
90
|
-
return configuration
|
91
|
-
end
|
92
|
-
|
93
|
-
def set_rds_instance_multi_az(multi_az)
|
94
|
-
if @rds_instance.multi_az == multi_az
|
95
|
-
$log.info("Rds instance #{@rds_instance.db_instance_identifier} already multi-az=#{multi_az}")
|
96
|
-
return
|
97
|
-
end
|
98
|
-
@rds_instance.modify({ multi_az: multi_az, apply_immediately: true })
|
99
|
-
# allow half an hour for instance to be converted
|
100
|
-
wait('available')
|
101
|
-
end
|
102
|
-
|
103
|
-
def wait(completed_state)
|
104
|
-
# reached state must be steady, at least a minute. Modifying an instance to/from MultiAZ can't be shorter
|
105
|
-
# than 40 seconds, hence steady count is 4
|
106
|
-
state_count = 0
|
107
|
-
steady_count = 4
|
108
|
-
attempts = 0
|
109
|
-
rds = Aws::RDS::Resource.new(client: @rds_client)
|
110
|
-
until attempts == (max_attempts = 60*6) do
|
111
|
-
instance = rds.db_instance(@instance_id)
|
112
|
-
$log.info("Instance #{instance.db_instance_identifier} state: #{instance.db_instance_status}, waiting for #{completed_state}")
|
113
|
-
|
114
|
-
if instance.db_instance_status == "#{completed_state}"
|
115
|
-
state_count = state_count + 1
|
116
|
-
$log.info("#{state_count}/#{steady_count}")
|
117
|
-
else
|
118
|
-
state_count = 0
|
119
|
-
end
|
120
|
-
break if state_count == steady_count
|
121
|
-
attempts = attempts + 1
|
122
|
-
sleep(15)
|
123
|
-
end
|
124
|
-
|
125
|
-
if attempts == max_attempts
|
126
|
-
$log.error("RDS Database Instance #{@instance_id} did not enter #{state} state, however continuing operations...")
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
private :set_rds_instance_multi_az
|
131
|
-
|
132
|
-
end
|
133
|
-
|
134
|
-
end
|
@@ -1,57 +0,0 @@
|
|
1
|
-
require 'cfn_manage/aws_credentials'
|
2
|
-
|
3
|
-
module CfnManage
|
4
|
-
|
5
|
-
class SpotFleetStartStopHandler
|
6
|
-
|
7
|
-
def initialize(fleet_id, skip_wait)
|
8
|
-
@fleet_id = fleet_id
|
9
|
-
@skip_wait = skip_wait
|
10
|
-
credentials = CfnManage::AWSCredentials.get_session_credentials("startstopfleet_#{fleet_id}")
|
11
|
-
@ec2_client = Aws::EC2::Client.new(retry_limit: 20)
|
12
|
-
if credentials != nil
|
13
|
-
@ec2_client = Aws::EC2::Client.new(credentials: credentials, retry_limit: 20)
|
14
|
-
end
|
15
|
-
|
16
|
-
@fleet = @ec2_client.describe_spot_fleet_requests({spot_fleet_request_ids:[fleet_id]})
|
17
|
-
@fleet = @fleet.spot_fleet_request_configs[0].spot_fleet_request_config
|
18
|
-
end
|
19
|
-
|
20
|
-
def start(configuration)
|
21
|
-
|
22
|
-
$log.info("Setting fleet #{@fleet_id} capacity to #{configuration['target_capacity']}")
|
23
|
-
@ec2_client.modify_spot_fleet_request({
|
24
|
-
spot_fleet_request_id: @fleet_id,
|
25
|
-
target_capacity: configuration['target_capacity'],
|
26
|
-
})
|
27
|
-
|
28
|
-
return configuration
|
29
|
-
end
|
30
|
-
|
31
|
-
def stop
|
32
|
-
|
33
|
-
if @fleet.target_capacity == 0
|
34
|
-
$log.info("Spot fleet #{@fleet_id} already stopped")
|
35
|
-
return nil
|
36
|
-
end
|
37
|
-
|
38
|
-
configuration = {
|
39
|
-
target_capacity: @fleet.target_capacity
|
40
|
-
}
|
41
|
-
|
42
|
-
$log.info("Setting fleet #{@fleet_id} capacity to 0")
|
43
|
-
@ec2_client.modify_spot_fleet_request({
|
44
|
-
spot_fleet_request_id: @fleet_id,
|
45
|
-
target_capacity: 0,
|
46
|
-
})
|
47
|
-
|
48
|
-
return configuration
|
49
|
-
end
|
50
|
-
|
51
|
-
def wait(wait_states=[])
|
52
|
-
$log.debug("Not waiting for spot fleet #{@fleet_id}")
|
53
|
-
end
|
54
|
-
|
55
|
-
end
|
56
|
-
|
57
|
-
end
|
@@ -1,97 +0,0 @@
|
|
1
|
-
require 'cfn_manage/aws_credentials'
|
2
|
-
require 'aws-sdk-transfer'
|
3
|
-
|
4
|
-
module CfnManage
|
5
|
-
|
6
|
-
class TransferStartStopHandler
|
7
|
-
|
8
|
-
def initialize(server_id, skip_wait)
|
9
|
-
sftpId = server_id.split("/")
|
10
|
-
@server_id = sftpId.last
|
11
|
-
@skip_wait = skip_wait
|
12
|
-
credentials = CfnManage::AWSCredentials.get_session_credentials("startstoptransfer_#{@server_id}")
|
13
|
-
@client = Aws::Transfer::Client.new(retry_limit: 20)
|
14
|
-
if credentials != nil
|
15
|
-
@client = Aws::Transfer::Client.new(credentials: credentials, retry_limit: 20)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def start(configuration)
|
20
|
-
|
21
|
-
state = get_state()
|
22
|
-
|
23
|
-
if state != "OFFLINE"
|
24
|
-
$log.warn("SFTP Server #{@server_id} is in a state of #{state} and can not be started.")
|
25
|
-
return
|
26
|
-
end
|
27
|
-
|
28
|
-
$log.info("Starting SFTP Server #{@server_id}")
|
29
|
-
@client.start_server({
|
30
|
-
server_id: @server_id,
|
31
|
-
})
|
32
|
-
unless @skip_wait
|
33
|
-
$log.info("Waiting for SFTP to start #{@cluster_id}")
|
34
|
-
wait('ONLINE')
|
35
|
-
end
|
36
|
-
|
37
|
-
return configuration
|
38
|
-
end
|
39
|
-
|
40
|
-
def stop()
|
41
|
-
|
42
|
-
state = get_state()
|
43
|
-
|
44
|
-
if state != "ONLINE"
|
45
|
-
$log.warn("SFTP Server #{@server_id} is in a state of #{state} and can not be stopped.")
|
46
|
-
return {}
|
47
|
-
end
|
48
|
-
|
49
|
-
@client.stop_server({
|
50
|
-
server_id: @server_id,
|
51
|
-
})
|
52
|
-
unless @skip_wait
|
53
|
-
$log.info("Waiting for SFTP to stop #{@cluster_id}")
|
54
|
-
wait('OFFLINE')
|
55
|
-
end
|
56
|
-
return {}
|
57
|
-
end
|
58
|
-
|
59
|
-
def get_state()
|
60
|
-
resp = @client.describe_server({
|
61
|
-
server_id: @server_id,
|
62
|
-
})
|
63
|
-
return resp.server.state
|
64
|
-
end
|
65
|
-
|
66
|
-
def wait(completed_state)
|
67
|
-
|
68
|
-
state_count = 0
|
69
|
-
steady_count = 2
|
70
|
-
attempts = 0
|
71
|
-
until attempts == (max_attempts = 60*6) do
|
72
|
-
state = get_state()
|
73
|
-
$log.info("SFTP Server #{@server_id} state: #{state}, waiting for #{completed_state}")
|
74
|
-
|
75
|
-
if state == "#{completed_state}"
|
76
|
-
state_count = state_count + 1
|
77
|
-
$log.info("#{state_count}/#{steady_count}")
|
78
|
-
elsif ["START_FAILED", "STOP_FAILED"].include?(state)
|
79
|
-
$log.error("SFTP Server #{@server_id} failed to reach state #{completed_state} with current state #{state}!")
|
80
|
-
break
|
81
|
-
else
|
82
|
-
state_count = 0
|
83
|
-
end
|
84
|
-
break if state_count == steady_count
|
85
|
-
attempts = attempts + 1
|
86
|
-
sleep(15)
|
87
|
-
end
|
88
|
-
|
89
|
-
if attempts == max_attempts
|
90
|
-
$log.error("SFTP Server #{@server_id} did not enter #{completed_state} state, however continuing operations...")
|
91
|
-
end
|
92
|
-
|
93
|
-
end
|
94
|
-
|
95
|
-
end
|
96
|
-
|
97
|
-
end
|