forked from koding/koding
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathterminate-leftover
More file actions
executable file
·134 lines (83 loc) · 2.9 KB
/
Copy pathterminate-leftover
File metadata and controls
executable file
·134 lines (83 loc) · 2.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#!/usr/bin/env coffee
async = require 'async'
argv = (require 'minimist') process.argv.slice 2
if argv.help
printHelp()
process.exit 1
AWS = require './aws'
EC2 = new AWS.EC2()
LIFETIME_HARD_LIMIT = 2 * 60 * 60 * 1000 # 2 hours
run = ->
unless argv.hours or argv.minutes
console.error "error: Please specify an expiration time\n"
printHelp()
process.exit 1
{DryRun, ExpirationTime} = getOptions argv
Filters = [
{ Name: 'instance-state-name', Values: ['running'] }
{ Name: 'tag:Role', Values: ['test-instance'] }
]
EC2.describeInstances {Filters}, (err, data) ->
return error err if err
unless data or data.Reservations
return error 'Reservations not found'
instances = []
data.Reservations.forEach ({Instances}) ->
return unless Instances
Instances.forEach (instance) ->
{InstanceId, LaunchTime, State} = instance
return if State.Name is 'terminated'
return if ExpirationTime <= LaunchTime
instances.push instance
return process.exit 0 unless instances.length
async.filter instances, checkApiTermination, (Instances) ->
return process.exit 0 unless Instances.length
InstanceIds = Instances.map (instance) -> instance.InstanceId
EC2.terminateInstances {DryRun, InstanceIds}, (err) ->
return error err if err
getOptions = (argv) ->
DryRun = argv['dry-run']
ExpirationTime = getExpirationTime argv
return {DryRun, ExpirationTime}
getExpirationTime = (argv) ->
{hours, minutes} = argv
hours ?= 0
minutes ?= 0 + (hours * 60)
return new Date Date.now() - (minutes * 60 * 1000)
checkApiTermination = (instance, callback) ->
{InstanceId} = instance
Attribute = 'disableApiTermination'
params = {InstanceId, Attribute}
EC2.describeInstanceAttribute params, (err, data) ->
return callback no if err or not data
return callback yes if not data.DisableApiTermination.Value
lifetime = Date.now() - instance.LaunchTime
return callback no if lifetime < LIFETIME_HARD_LIMIT
disableApiTermination instance, (err) ->
if err
error err
callback no
else
callback yes
disableApiTermination = (instance, callback) ->
{InstanceId} = instance
Attribute = 'disableApiTermination'
Value = 'false'
params = {InstanceId, Attribute, Value}
EC2.modifyInstanceAttribute params, callback
error = (err) ->
console.error "error: #{JSON.stringify err}" if err
printHelp = ->
console.log """
Invalid options are given. Please specify only options described
below.
--dry-run Specify this option to test run
--hours How many hours to set expiration time
--minutes How many minutes to set expiration time
Hours and minutes options are combined.
Example usage:
./terminate-leftover-test-instances --hours 1 --minutes 15
This command will terminate test instances older than an hour and 15
minutes.
"""
run()