Class: Automan::RDS::Snapshot
Constant Summary
Mixins::AwsCaller::S3_PROTO
Instance Attribute Summary
Attributes inherited from Base
#logger, #wait
#as, #cfn, #eb, #ec, #ec2, #elb, #r53, #rds, #s3
Instance Method Summary
collapse
#region_from_az
Methods inherited from Base
add_option, #log_options, #wait_until
#account, #configure_aws, #looks_like_s3_path?, #parse_s3_path, #s3_object_exists?, #s3_read
Constructor Details
#initialize(options = {}) ⇒ Snapshot
Returns a new instance of Snapshot.
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
# File 'lib/automan/rds/snapshot.rb', line 16
def initialize(options={})
@prune = true
@wait_for_completion = false
@max_snapshots = 50
super
@wait = Wait.new({
delay: 30,
attempts: 20, debug: true,
rescuer: WaitRescuer.new(),
logger: @logger
})
if ENV['MAX_SNAPSHOTS']
@max_snapshots = ENV['MAX_SNAPSHOTS'].to_i
end
end
|
Instance Method Details
#available?(snapshot) ⇒ Boolean
197
198
199
|
# File 'lib/automan/rds/snapshot.rb', line 197
def available?(snapshot)
snapshot.status == 'available'
end
|
#count_snapshots ⇒ Object
250
251
252
253
254
255
256
257
258
259
|
# File 'lib/automan/rds/snapshot.rb', line 250
def count_snapshots
log_options
db = find_db
if db.nil?
logger.info "Database not found"
else
logger.info "Number of snapshots for database #{db.id} is #{snapshot_count}"
logger.info "Number of prunable snapshots for database #{db.id} is #{prunable_snapshots.count}"
end
end
|
#create ⇒ Object
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
|
# File 'lib/automan/rds/snapshot.rb', line 74
def create
log_options
db = find_db
if db.nil? || !db.exists?
if quiet
logger.warn "Database for #{environment} does not exist"
exit
else
raise DatabaseDoesNotExistError, "Database for #{environment} does not exist"
end
end
myname = name.nil? ? default_snapshot_name(db) : name.dup
wait_until_database_available(db)
logger.info "Creating snapshot #{myname} for #{db.id}"
snap = db.create_snapshot(myname)
if prune == true
logger.info "Setting snapshot to be prunable and tagging environment"
set_prunable_and_env(snap)
end
if wait_for_completion == true
wait.until do
logger.info "Waiting for snapshot to complete..."
snapshot_finished?(snap)
end
logger.info "Snapshot finished (or timed out)."
end
end
|
#database_available?(database) ⇒ Boolean
49
50
51
|
# File 'lib/automan/rds/snapshot.rb', line 49
def database_available?(database)
database.db_instance_status == 'available'
end
|
#db_arn(database) ⇒ Object
136
137
138
139
|
# File 'lib/automan/rds/snapshot.rb', line 136
def db_arn(database)
region = region_from_az(database.availability_zone_name)
"arn:aws:rds:#{region}:#{account}:db:#{database.id}"
end
|
#db_environment(db) ⇒ Object
116
117
118
|
# File 'lib/automan/rds/snapshot.rb', line 116
def db_environment(db)
return db_tags(db)['Name']
end
|
170
171
172
173
|
# File 'lib/automan/rds/snapshot.rb', line 170
def db_tags(db)
arn = db_arn(db)
resource_tags(arn)
end
|
#default_snapshot_name(db) ⇒ Object
120
121
122
123
124
125
|
# File 'lib/automan/rds/snapshot.rb', line 120
def default_snapshot_name(db)
env = db_environment db
stime = Time.new.strftime("%Y-%m-%dT%H-%M")
return env + "-" + stime
end
|
#delete ⇒ Object
163
164
165
166
167
168
|
# File 'lib/automan/rds/snapshot.rb', line 163
def delete
log_options
logger.info "Deleting snapshot #{name}"
rds.db_snapshots[name].delete
end
|
#find_db ⇒ Object
TODO move this and dependecies to an RDS utils class so we can re-use it
39
40
41
42
43
44
45
46
47
|
# File 'lib/automan/rds/snapshot.rb', line 39
def find_db
db = nil
if !database.nil?
db = rds.db_instances[database]
elsif !environment.nil?
db = find_db_by_environment(environment)
end
db
end
|
#find_db_by_environment(environment) ⇒ Object
127
128
129
130
131
132
133
134
|
# File 'lib/automan/rds/snapshot.rb', line 127
def find_db_by_environment(environment)
rds.db_instances.each do |db|
if db_environment(db) == environment
return db
end
end
return nil
end
|
#get_all_snapshots ⇒ Object
201
202
203
|
# File 'lib/automan/rds/snapshot.rb', line 201
def get_all_snapshots
rds.snapshots
end
|
#latest ⇒ Object
261
262
263
264
265
266
267
268
269
270
|
# File 'lib/automan/rds/snapshot.rb', line 261
def latest
log_options
logger.info "Finding most recent snapshot for #{environment}"
tags = { 'Environment' => environment }
s = snapshots_with_tags(tags).sort_by {|s| s.created_at}.last
logger.info "Most recent snapshot is #{s.id}"
s.id
end
|
#prune_snapshots ⇒ Object
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
|
# File 'lib/automan/rds/snapshot.rb', line 222
def prune_snapshots
logger.info "Pruning old db snapshots"
tags = {
'Environment' => environment,
'Type' => type,
'CanPrune' => 'yes'
}
sorted_snaps = nil
AWS.memoize do
sorted_snaps = snapshots_with_tags(tags).sort_by {|s| s.created_at}
end
logger.info "snaps #{sorted_snaps.count} max #{max_snapshots}"
if sorted_snaps.count >= max_snapshots
logger.info "Too many snapshots ( #{sorted_snaps.count} >= #{max_snapshots})."
number_to_delete = sorted_snaps.count - max_snapshots + 1
logger.info "deleting #{number_to_delete}."
condemned = sorted_snaps.take(number_to_delete)
condemned.each do |snap|
logger.info "Deleting #{snap.id}"
snap.delete
end
end
end
|
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
|
# File 'lib/automan/rds/snapshot.rb', line 180
def resource_tags(arn)
opts = {
resource_name: arn
}
response = rds.client.list_tags_for_resource opts
unless response.successful?
raise RequestFailedError "list_tags_for_resource failed: #{response.error}"
end
result = {}
response.data[:tag_list].each do |t|
result[ t[:key] ] = t[:value]
end
result
end
|
#set_prunable_and_env(snapshot) ⇒ Object
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
|
# File 'lib/automan/rds/snapshot.rb', line 147
def set_prunable_and_env(snapshot)
opts = {
resource_name: snapshot_arn(snapshot),
tags: [
{ key: 'CanPrune', value: 'yes'},
{ key: 'Environment', value: environment},
{ key: 'Type', value: type }
]
}
response = rds.client.add_tags_to_resource opts
unless response.successful?
raise RequestFailedError "add_tags_to_resource failed: #{response.error}"
end
end
|
#snapshot_arn(snapshot) ⇒ Object
141
142
143
144
|
# File 'lib/automan/rds/snapshot.rb', line 141
def snapshot_arn(snapshot)
region = region_from_az(snapshot.availability_zone_name)
"arn:aws:rds:#{region}:#{account}:snapshot:#{snapshot.id}"
end
|
#snapshot_count ⇒ Object
68
69
70
71
72
|
# File 'lib/automan/rds/snapshot.rb', line 68
def snapshot_count
AWS.memoize do
rds.db_instances[find_db.id].snapshots.count
end
end
|
#snapshot_finished?(snapshot) ⇒ Boolean
109
110
111
112
113
114
|
# File 'lib/automan/rds/snapshot.rb', line 109
def snapshot_finished?(snapshot)
unless snapshot.exists?
return false
end
snapshot.status == "available"
end
|
tags = => ‘mytagvalue’, …
206
207
208
209
210
211
212
213
214
215
|
# File 'lib/automan/rds/snapshot.rb', line 206
def snapshot_has_tags?(snapshot, tags)
snap_tags = snapshot_tags(snapshot)
tags.each do |tk,tv|
if snap_tags[tk] != tv
return false
end
end
true
end
|
175
176
177
178
|
# File 'lib/automan/rds/snapshot.rb', line 175
def snapshot_tags(snapshot)
arn = snapshot_arn(snapshot)
resource_tags(arn)
end
|
tags = => ‘mytagvalue’, …
218
219
220
|
# File 'lib/automan/rds/snapshot.rb', line 218
def snapshots_with_tags(tags)
rds.snapshots.select {|s| snapshot_has_tags?(s, tags)}
end
|
#wait_until_database_available(database) ⇒ Object
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
# File 'lib/automan/rds/snapshot.rb', line 53
def wait_until_database_available(database)
state_wait = Wait.new({
delay: 10,
attempts: 20,
debug: true,
rescuer: WaitRescuer.new(),
logger: @logger
})
state_wait.until do
logger.info "Waiting for database #{database.id} to be available"
database_available?(database)
end
end
|