preserve-rds-snapshot 0.2.0 → 0.3.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
  SHA1:
3
- metadata.gz: 6ac1fad7b038d2f7714ce5775f6faca3f607865d
4
- data.tar.gz: 9c4b3e1d56a99892049df09479be7d2196a5164e
3
+ metadata.gz: af7578d5b6ba4324962222bf6bd9cf4644e62989
4
+ data.tar.gz: 13a489abbdce7d030d46814c6580546b4392029e
5
5
  SHA512:
6
- metadata.gz: 8b22cbca0519b61ada69d8ec3d0a2bfe29fd1af82c869d158694a493a5f23f22a1772ec42c599e944e0870eb6972814a281e8aecd5f22db33d7cea671beeb9e8
7
- data.tar.gz: 58ea25f44eaef6accac79fe4e6a811c9570034a362038d4464f67ef1269833b72184517bf80f1157c71a5999d9fe93e0cd361f8607d55520d3d90376da18d7df
6
+ metadata.gz: cfdcfa7f4f7c88dbf8425130c1b1ad54e04b6edf947b46a1ff248d45402c52ba3066a943cfa671fa88da2cdad08eb9284a009e4a231d8b567d73d4faff5e41d4
7
+ data.tar.gz: 767ffdf614c32684300dda5b69aa508814f099b6f3610f825f8e590e0a4cbb1b3c7d7bdcf7a74669a68dcc13aab4d0fe07f130253911f712fcea419f57a46323
data/README.md CHANGED
@@ -2,6 +2,19 @@
2
2
 
3
3
  Amazon RDS create a snapshot automatically. Snapshot that is created automatically, will be lost when the instance is terminated. This script preserve db snapshots by copy snapshots.
4
4
 
5
+ ### AWS API requirement
6
+
7
+ * RDS
8
+ * describe_db_instances
9
+ * describe_db_snapshots
10
+ * copy_db_snapshot
11
+ * delete_db_snapshots
12
+ * list_tags_for_resources
13
+ * EC2
14
+ * describe_security_groups
15
+
16
+ NOTE: describe_security_groups is required to get the AWS Account Number. You can use the '--aws-account-number' option instead.
17
+
5
18
  ## Installation
6
19
 
7
20
  Add this line to your application's Gemfile:
@@ -45,6 +58,7 @@ Options:
45
58
  i, [--instance=INSTANCE] # target DB Instance
46
59
  ```
47
60
 
61
+
48
62
  ## Development
49
63
 
50
64
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/console` for an interactive prompt that will allow you to experiment. Run `bundle exec preserve-rds-snapshot` to use the code located in this directory, ignoring other installed copies of this gem.
@@ -4,11 +4,19 @@ require 'thor/aws'
4
4
  module PreserveRdsSnapshot
5
5
  class CLI < Thor
6
6
  include Thor::Aws
7
+ PRESERVE_TAG_NAME = 'preserve-rds-snapshot'
7
8
 
8
9
  class_option :instance,
9
10
  aliases: [:i],
10
11
  type: :string,
11
12
  desc: 'target DB Instance'
13
+ class_option :aws_account_number,
14
+ aliases: [:n],
15
+ type: :string,
16
+ desc: 'AWS Account Number (ex: 012345678901)'
17
+ class_option :dry_run,
18
+ type: :boolean,
19
+ desc: "show only, don't modify"
12
20
 
13
21
  desc :list, 'Show list of RDS Snapshots'
14
22
  option :snapshot_type,
@@ -29,21 +37,55 @@ module PreserveRdsSnapshot
29
37
  end
30
38
  end
31
39
 
40
+ desc :init, "initialize instance"
41
+ option :generations,
42
+ aliases: [:g],
43
+ type: :numeric,
44
+ desc: "preserved snapshot generations",
45
+ default: 10
46
+ def init
47
+ begin
48
+ rds.db_instances.each do |instance|
49
+ if options[:dry_run]
50
+ puts "init(dry run)\t#{instance.db_instance_identifier}\t#{options[:generations]}"
51
+ else
52
+ if enable_preserve(instance.db_instance_identifier, options[:generations])
53
+ puts "init\t#{instance.db_instance_identifier}\t#{options[:generations]}"
54
+ end
55
+ end
56
+ end
57
+ fix_tags
58
+ rescue ::Aws::Errors::ServiceError => e
59
+ $stderr.puts e
60
+ end
61
+ end
62
+
32
63
  desc :preserve, 'copy automated snapshot to manual'
33
64
  def preserve
34
65
  begin
35
66
  instances = db_instances(options[:instance])
36
67
  instances.each do |i|
37
- latest = latest_auto_snapshot(i.db_instance_identifier)
68
+ instance = i.db_instance_identifier
69
+ latest = latest_auto_snapshot(instance)
38
70
  if latest
39
- db_snapshot_identifier = latest.db_snapshot_identifier
40
- resp = rds.client.copy_db_snapshot(
41
- source_db_snapshot_identifier: db_snapshot_identifier,
42
- target_db_snapshot_identifier: preserve_snapshot_name(db_snapshot_identifier),
43
- tags: [key: 'type', value: 'preserve']
44
- )
45
- s = resp.db_snapshot
46
- puts "#{s.db_snapshot_identifier}\t#{s.snapshot_create_time}"
71
+ if options[:dry_run]
72
+ puts "#{latest.db_snapshot_identifier}\t-\t-"
73
+ else
74
+ s = copy_snapshot(latest.db_snapshot_identifier)
75
+ puts "copy\t#{latest.db_snapshot_identifier}\t#{s.db_snapshot_identifier}\t#{s.snapshot_create_time}" if s
76
+ end
77
+ end
78
+
79
+ tag = preserve_tag(instance, 'db')
80
+ expireds = expired_snapshots(instance, tag[:value].to_i)
81
+ dry_run_msg = '(dry run)' if options[:dry_run]
82
+ expireds.each do |expired|
83
+ unless options[:dry_run]
84
+ rds.client.delete_db_snapshot(
85
+ db_snapshot_identifier: expired.db_snapshot_identifier
86
+ )
87
+ end
88
+ puts "delete#{dry_run_msg}\t#{expired.db_snapshot_identifier}"
47
89
  end
48
90
  end
49
91
  rescue ::Aws::Errors::ServiceError => e
@@ -60,14 +102,20 @@ module PreserveRdsSnapshot
60
102
  option :target_db_snapshot_identifier,
61
103
  aliases: [:t],
62
104
  type: :string,
63
- desc: 'target snapshot identifier',
64
- required: true
105
+ desc: 'target snapshot identifier'
65
106
  def copy
107
+ if options[:target_db_snapshot_identifier]
108
+ target = options[:target_db_snapshot_identifier]
109
+ else
110
+ target = preserve_snapshot_name(options[:source_db_snapshot_identifier])
111
+ end
112
+ source = options[:source_db_snapshot_identifier]
113
+
66
114
  begin
67
115
  resp = rds.client.copy_db_snapshot(
68
- source_db_snapshot_identifier: options[:source_db_snapshot_identifier],
69
- target_db_snapshot_identifier: options[:target_db_snapshot_identifier],
70
- tags: [key: 'type', value: 'preserve']
116
+ source_db_snapshot_identifier: source,
117
+ target_db_snapshot_identifier: target,
118
+ tags: [key: PRESERVE_TAG_NAME, value: 'true']
71
119
  )
72
120
  s = resp.db_snapshot
73
121
  puts "#{s.db_snapshot_identifier}\t#{s.snapshot_create_time}"
@@ -107,15 +155,120 @@ module PreserveRdsSnapshot
107
155
  if db_instance_identifier
108
156
  list << rds.db_instance(db_instance_identifier)
109
157
  else
110
- list = rds.db_instances.to_a
158
+ rds.db_instances.each do |i|
159
+ list << i if preserve_tag(i.db_instance_identifier, 'db')
160
+ end
111
161
  end
112
162
  rescue ::Aws::Errors::ServiceError => e
113
163
  $stderr.puts e
114
164
  end
165
+ list
115
166
  end
116
167
 
117
168
  def preserve_snapshot_name(db_snapshot_identifier)
118
169
  'preserve-' + db_snapshot_identifier.gsub(/^rds:/, '')
119
170
  end
171
+
172
+ def aws_account_number
173
+ if options[:aws_account_number]
174
+ return options[:aws_account_number]
175
+ else
176
+ begin
177
+ return ec2.security_groups(group_names: ['default']).first.owner_id
178
+ rescue ::Aws::Errors::ServiceError => e
179
+ $stderr.puts e
180
+ end
181
+ end
182
+ end
183
+
184
+ def rds_arn(resource_id, type)
185
+ "arn:aws:rds:#{options[:region]}:#{aws_account_number}:#{type}:#{resource_id}"
186
+ end
187
+
188
+ def preserve_tag(resource_id, type)
189
+ tag = nil
190
+ begin
191
+ resp = rds.client.list_tags_for_resource(
192
+ resource_name: rds_arn(resource_id, type)
193
+ )
194
+ tag = resp.tag_list.find {|t| t[:key] == PRESERVE_TAG_NAME}
195
+ rescue ::Aws::Errors::ServiceError => e
196
+ $stderr.puts e
197
+ end
198
+ tag
199
+ end
200
+
201
+ def enable_preserve(resource_id, generations)
202
+ return false unless generations.kind_of? Integer
203
+ begin
204
+ tag = preserve_tag(resource_id, 'db')
205
+ unless tag
206
+ resp = rds.client.add_tags_to_resource(
207
+ resource_name: rds_arn(resource_id, 'db'),
208
+ tags: [{key: PRESERVE_TAG_NAME, value: generations.to_s}]
209
+ )
210
+ return resp.successful?
211
+ end
212
+ rescue ::Aws::Errors::ServiceError => e
213
+ $stderr.puts e
214
+ end
215
+ end
216
+
217
+ # fix v0.2.0 format tag to latest
218
+ def fix_tags
219
+ begin
220
+ rds.client.describe_db_snapshots(
221
+ snapshot_type: 'manual'
222
+ ).db_snapshots.each do |s|
223
+ arn = rds_arn(s.db_snapshot_identifier, 'snapshot')
224
+ resp = rds.client.list_tags_for_resource(
225
+ resource_name: arn
226
+ )
227
+ tag = resp.tag_list.find {|t| t[:key] == 'type' && t[:value] == 'preserve'}
228
+ if tag
229
+ rds.client.add_tags_to_resource(
230
+ resource_name: arn,
231
+ tags: [{key: PRESERVE_TAG_NAME, value: 'true'}]
232
+ )
233
+ rds.client.remove_tags_from_resource(
234
+ resource_name: arn,
235
+ tag_keys: ['type']
236
+ )
237
+ end
238
+ end
239
+ rescue ::Aws::Errors::ServiceError => e
240
+ $stderr.puts e
241
+ end
242
+ end
243
+
244
+ def copy_snapshot(db_snapshot_identifier)
245
+ begin
246
+ resp = rds.client.copy_db_snapshot(
247
+ source_db_snapshot_identifier: db_snapshot_identifier,
248
+ target_db_snapshot_identifier: preserve_snapshot_name(db_snapshot_identifier),
249
+ tags: [key: PRESERVE_TAG_NAME, value: 'true']
250
+ )
251
+ return resp.db_snapshot
252
+ rescue ::Aws::Errors::ServiceError => e
253
+ $stderr.puts e
254
+ end
255
+ end
256
+
257
+ def expired_snapshots(db_instance_identifier, generations)
258
+ expired_snapshots = []
259
+ begin
260
+ resp = rds.client.describe_db_snapshots(
261
+ snapshot_type: 'manual',
262
+ db_instance_identifier: db_instance_identifier
263
+ )
264
+ snapshots = resp.db_snapshots.select {|s|
265
+ preserve_tag(s.db_snapshot_identifier, 'snapshot')
266
+ }.sort_by(&:snapshot_create_time).reverse
267
+ expired_snapshots = snapshots[generations..-1] if snapshots.size > generations
268
+ rescue ::Aws::Errors::ServiceError => e
269
+ $stderr.puts e
270
+ end
271
+ expired_snapshots
272
+ end
120
273
  end
121
274
  end
@@ -1,3 +1,3 @@
1
1
  module PreserveRdsSnapshot
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: preserve-rds-snapshot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ISOBE Kazuhiko