rds-s3-backup 0.0.6 → 0.0.8
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.
- data/.rspec +1 -1
- data/Rakefile +8 -0
- data/bin/.gitignore +1 -0
- data/lib/rds-s3-backup.rb +23 -14
- data/lib/rds-s3-backup/myrds.rb +20 -17
- data/lib/rds-s3-backup/mys3.rb +81 -48
- data/lib/rds-s3-backup/version.rb +1 -1
- data/spec/rds-s3-backup/datadog_spec.rb +45 -0
- data/spec/rds-s3-backup/myrds_spec.rb +55 -0
- data/spec/rds-s3-backup_spec.rb +38 -41
- metadata +8 -2
data/.rspec
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
--color
|
2
|
-
--format
|
2
|
+
--format documentation
|
data/Rakefile
CHANGED
data/bin/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
/#rds-s3-backup.rb#
|
data/lib/rds-s3-backup.rb
CHANGED
@@ -14,18 +14,18 @@ module Rds
|
|
14
14
|
|
15
15
|
options = thor_defaults
|
16
16
|
|
17
|
-
if thor_options[
|
17
|
+
if thor_options["config_file"] && File.exists?(thor_options["config_file"])
|
18
18
|
begin
|
19
|
-
options = options.merge(YAML.load(File.read(thor_options[
|
19
|
+
options = options.merge(YAML.load(File.read(thor_options["config_file"])))
|
20
20
|
rescue Exception => e
|
21
|
-
raise "Unable to read and parse #{thor_options[
|
21
|
+
raise "Unable to read and parse #{thor_options["config_file"]}: #{e.class}: #{e}"
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
25
|
options.merge!(thor_options)
|
26
26
|
|
27
27
|
# Check for required options
|
28
|
-
missing_options = %w{rds_instance_id s3_bucket aws_access_key_id aws_secret_access_key mysql_database mysql_username mysql_password}.
|
28
|
+
missing_options = %w{rds_instance_id s3_bucket aws_access_key_id aws_secret_access_key mysql_database mysql_username mysql_password}.select {|o| o unless options.has_key?(o)}
|
29
29
|
|
30
30
|
raise "Missing required options #{missing_options.inspect} in either configuration or command line" if missing_options.count > 0
|
31
31
|
|
@@ -36,8 +36,10 @@ module Rds
|
|
36
36
|
|
37
37
|
def run(thor_options,thor_defaults)
|
38
38
|
|
39
|
-
@options = process_options(thor_options,thor_defaults)
|
40
39
|
$logger = Logger.new(STDOUT)
|
40
|
+
@options = process_options(thor_options,thor_defaults)
|
41
|
+
$logger.debug "Running with Options: #{@options.to_yaml}"
|
42
|
+
|
41
43
|
$logger.level = set_logger_level(@options["log_level"])
|
42
44
|
|
43
45
|
$dogger = DataDog.new(@options['data_dog_api_key'])
|
@@ -50,24 +52,31 @@ module Rds
|
|
50
52
|
|
51
53
|
$logger.debug "#{File.basename(__FILE__)}:#{__LINE__}: Running with options:"
|
52
54
|
debug_opts = @options.dup
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
55
|
+
|
56
|
+
$logger.debug @options.merge(
|
57
|
+
'aws_access_key_id' => 'X'*10,
|
58
|
+
'aws_secret_access_key' => 'Y'*15,
|
59
|
+
'mysql_password' => "ZZY"*5,
|
60
|
+
'data_dog_api_key' => 'XYZZY'*3
|
61
|
+
).to_yaml
|
58
62
|
|
59
63
|
begin
|
60
64
|
|
61
65
|
$logger.info "Creating RDS and S3 Connections"
|
62
66
|
rds = MyRDS.new(@options)
|
63
|
-
|
67
|
+
$logger.debug "rds: #{rds.to_yaml}"
|
64
68
|
|
65
|
-
$logger.info "Restoring Database"
|
69
|
+
$logger.info "Restoring Database"
|
66
70
|
rds.restore_db()
|
67
71
|
|
68
72
|
$logger.info "Dumping and saving original database contents"
|
69
|
-
real_data_file = "#{rds.server.id}-mysqldump-#{@options['timestamp']}.sql.gz"
|
70
|
-
|
73
|
+
real_data_file = "#{rds.server.id}-mysqldump-#{@options['timestamp']}.sql.gz".
|
74
|
+
tap{|t| $logger.debug "real_data_file: #{t}"}
|
75
|
+
|
76
|
+
real_dump_file = rds.dump(real_data_file).tap{|t| $logger.debug "rds.dump returns: #{t}"}
|
77
|
+
s3 = MyS3.new(@options)
|
78
|
+
$logger.debug "s3: #{s3.to_yaml}"
|
79
|
+
s3.save_production(real_dump_file)
|
71
80
|
|
72
81
|
if @options['dump_ttl'] > 0
|
73
82
|
$logger.info "Pruning old dumps"
|
data/lib/rds-s3-backup/myrds.rb
CHANGED
@@ -20,23 +20,26 @@ module Rds::S3::Backup
|
|
20
20
|
class MyRDSException < RuntimeError ; end
|
21
21
|
class MyRDS
|
22
22
|
|
23
|
-
attr_accessor :rds, :server
|
24
|
-
|
25
23
|
def initialize(opts)
|
26
24
|
@opts = opts
|
25
|
+
end
|
27
26
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
@server = get_rds_server(@opts['rds_instance_id'])
|
27
|
+
def rds
|
28
|
+
# Memoize @rds
|
29
|
+
@rds ||= get_rds_connection()
|
30
|
+
end
|
33
31
|
|
32
|
+
def server
|
33
|
+
# Memoize @server
|
34
|
+
@server ||= get_rds_server(@opts['rds_instance_id'])
|
34
35
|
end
|
35
36
|
|
37
|
+
|
38
|
+
# Restore the production database from the most recent snapshot
|
36
39
|
def restore_db
|
37
40
|
|
38
41
|
begin
|
39
|
-
|
42
|
+
self.rds.restore_db_instance_from_db_snapshot(new_snap.id,
|
40
43
|
backup_server_id,
|
41
44
|
{"DBSubnetGroupName" => @opts['db_subnet_group_name'],
|
42
45
|
"DBInstanceClass" => @opts['db_instance_type'] } )
|
@@ -47,6 +50,7 @@ module Rds::S3::Backup
|
|
47
50
|
end
|
48
51
|
|
49
52
|
|
53
|
+
# Dump the database to the backup file name
|
50
54
|
def dump(backup_file_name)
|
51
55
|
@mysqlcmds ||= ::Rds::S3::Backup::MySqlCmds.new(backup_server.endpoint['Address'],
|
52
56
|
@opts['mysql_username'],
|
@@ -59,15 +63,13 @@ module Rds::S3::Backup
|
|
59
63
|
@mysqlcmds.dump(backup_file_path(backup_file_name)) # returns the dump file path
|
60
64
|
end
|
61
65
|
|
66
|
+
# Convert personal data in the production data into random generic data
|
62
67
|
def obfuscate
|
63
68
|
@mysqlcmds ||= ::Rds::S3::Backup::MySqlCmds.new(backup_server.endpoint['Address'],
|
64
69
|
@opts['mysql_username'],
|
65
70
|
@opts['mysql_password'],
|
66
71
|
@opts['mysql_database'])
|
67
72
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
73
|
@mysqlcmds.exec(@opts['obfuscate_sql'])
|
72
74
|
end
|
73
75
|
|
@@ -76,7 +78,7 @@ module Rds::S3::Backup
|
|
76
78
|
end
|
77
79
|
|
78
80
|
def backup_server_id
|
79
|
-
@backup_server_id ||= "#{
|
81
|
+
@backup_server_id ||= "#{self.server.id}-s3-dump-server-#{@opts['timestamp']}"
|
80
82
|
end
|
81
83
|
|
82
84
|
def new_snap
|
@@ -103,11 +105,11 @@ module Rds::S3::Backup
|
|
103
105
|
@snap_name ||= "s3-dump-snap-#{@opts['timestamp']}"
|
104
106
|
end
|
105
107
|
|
106
|
-
def get_rds_connection(
|
108
|
+
def get_rds_connection()
|
107
109
|
options = {
|
108
110
|
:aws_access_key_id => @opts['aws_access_key_id'],
|
109
111
|
:aws_secret_access_key => @opts['aws_secret_access_key'],
|
110
|
-
:region => @opts['aws_region']}
|
112
|
+
:region => @opts['aws_region']}
|
111
113
|
Fog.timeout=@opts['fog_timeout']
|
112
114
|
begin
|
113
115
|
connection = Fog::AWS::RDS.new(options)
|
@@ -116,14 +118,15 @@ module Rds::S3::Backup
|
|
116
118
|
end
|
117
119
|
|
118
120
|
raise MyRDSException.new("Unable to make RDS connection") if connection.nil?
|
119
|
-
connection
|
120
121
|
|
122
|
+
connection
|
121
123
|
|
122
124
|
end
|
123
125
|
|
124
126
|
def get_rds_server(id)
|
125
|
-
|
126
|
-
|
127
|
+
|
128
|
+
begin
|
129
|
+
server = self.rds.servers.get(id)
|
127
130
|
rescue Exception => e
|
128
131
|
raise MyRDSException.new("Error getting server in #{self.class}#get_rds_server: #{e.class}: #{e}")
|
129
132
|
end
|
data/lib/rds-s3-backup/mys3.rb
CHANGED
@@ -18,12 +18,79 @@ module Rds::S3::Backup
|
|
18
18
|
|
19
19
|
def initialize(options)
|
20
20
|
@options = options
|
21
|
+
end
|
22
|
+
|
23
|
+
# Lazy loaders
|
24
|
+
def s3
|
25
|
+
@s3 ||= get_storage(:aws_access_key_id => @options['aws_access_key_id'],
|
26
|
+
:aws_secret_access_key => @options['aws_secret_access_key'],
|
27
|
+
:region => @options['aws_s3_region'] ||= @options['aws_region'])
|
28
|
+
end
|
21
29
|
|
22
|
-
|
23
|
-
|
24
|
-
:region => @options['aws_s3_region'] ||= @options['aws_region'])
|
30
|
+
def s3_bucket
|
31
|
+
@s3_bucket ||= get_bucket(@options['s3_bucket'])
|
25
32
|
end
|
26
33
|
|
34
|
+
def backup_bucket
|
35
|
+
@backup_bucket ||= get_bucket(@options['backup_bucket'])
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
|
40
|
+
# Save the Real version of the Production Database
|
41
|
+
#
|
42
|
+
# == Input
|
43
|
+
#
|
44
|
+
# :file_path:: the path where the production database resides to save up to S3
|
45
|
+
#
|
46
|
+
def save_production(file_path)
|
47
|
+
save(s3_bucket, file_path, :acl => 'private')
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
# Save the Cleaned (Obfuscated) Version of the Database
|
52
|
+
#
|
53
|
+
# == Input
|
54
|
+
#
|
55
|
+
# :file_path:: the path where the file resides to save up to S3
|
56
|
+
#
|
57
|
+
def save_clean(file_path)
|
58
|
+
save(backup_bucket, file_path, :acl => 'authenticated-read')
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
# Remove older files from S3
|
63
|
+
#
|
64
|
+
# == Input
|
65
|
+
#
|
66
|
+
# o -- an options hash, expecting the following keys:
|
67
|
+
#
|
68
|
+
# :prefix:: the prefix to use with the s3 bucket
|
69
|
+
# :keep:: the number of files to keep. Must keep at least one.
|
70
|
+
def prune_files(o={})
|
71
|
+
options = {
|
72
|
+
:prefix => '',
|
73
|
+
:keep => 1
|
74
|
+
}.merge(o)
|
75
|
+
|
76
|
+
raise MyS3Exception "Must keep at least one file. options[:keep] = #{options[:keep]}" if options[:keep] < 1 # must keep at least one, the last one!
|
77
|
+
|
78
|
+
my_files = s3_bucket.files.all('prefix' => options[:prefix])
|
79
|
+
return if my_files.nil?
|
80
|
+
|
81
|
+
if my_files.count > options[:keep]
|
82
|
+
my_files.
|
83
|
+
sort {|x,y| x.last_modified <=> y.last_modified}.
|
84
|
+
take(files_by_date.count - options[:keep]).
|
85
|
+
each do |f|
|
86
|
+
$logger.info "Deleting #{f.name}"
|
87
|
+
f.destroy
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
# Make a connection to AWS S3 using Fog::Storage
|
27
94
|
def get_storage(o={})
|
28
95
|
options = {
|
29
96
|
:aws_access_key_id => nil,
|
@@ -38,33 +105,30 @@ module Rds::S3::Backup
|
|
38
105
|
raise MyS3Exception.new "Error establishing storage connection: #{e.class}: #{e}"
|
39
106
|
end
|
40
107
|
|
108
|
+
$logger.debug "What is storage? #{storage.class}:#{storage.inspect}"
|
41
109
|
raise MyS3Exception.new "In #{self.class}#get_storage: storage is nil!" if storage.nil?
|
42
110
|
|
111
|
+
storage
|
43
112
|
end
|
44
113
|
|
114
|
+
|
115
|
+
# Retrieve a pointer to an AWS S3 Bucket
|
45
116
|
def get_bucket(bucket)
|
46
117
|
|
47
118
|
begin
|
48
|
-
bucket =
|
119
|
+
bucket = self.s3.directories.get(bucket)
|
49
120
|
rescue Exception => e
|
50
121
|
raise MyS3Exception.new "Error getting bucket #{bucket} in S3: #{e.class}: #{e}"
|
51
122
|
end
|
52
123
|
|
53
124
|
raise MyS3Exception.new "In #{self.class}#get_bucket: bucket is nil!" if bucket.nil?
|
54
125
|
|
126
|
+
bucket
|
55
127
|
end
|
56
128
|
|
57
|
-
|
58
|
-
save(s3_bucket, file_path, :acl => 'private')
|
59
|
-
end
|
60
|
-
|
61
|
-
def save_clean(file_path)
|
62
|
-
save(backup_bucket, file_path, :acl => 'authenticated-read')
|
63
|
-
end
|
64
|
-
|
65
|
-
|
66
|
-
|
129
|
+
# Perform the actual save from a local file_path to AWS S3
|
67
130
|
def save(bucket, file_path, o={})
|
131
|
+
raise MyS3Exception.new "bucket is nil!!" if bucket.nil?
|
68
132
|
options = {
|
69
133
|
:key => File.join(@options['s3_prefix'], File.basename(file_path)),
|
70
134
|
:body => File.open(file_path),
|
@@ -79,8 +143,9 @@ module Rds::S3::Backup
|
|
79
143
|
|
80
144
|
rescue Exception => e
|
81
145
|
if tries < 3
|
82
|
-
|
146
|
+
$logger.info "Retrying S3 upload after #{tries} tries"
|
83
147
|
tries += 1
|
148
|
+
sleep tries * 60 # progressive back off
|
84
149
|
retry
|
85
150
|
else
|
86
151
|
raise MyS3Exception.new "Could not save #{File.basename(file_path)} to S3 after 3 tries: #{e.class}: #{e}"
|
@@ -89,40 +154,8 @@ module Rds::S3::Backup
|
|
89
154
|
|
90
155
|
end
|
91
156
|
|
92
|
-
|
93
|
-
def s3_bucket
|
94
|
-
@s3_bucket ||= get_bucket(@options['s3_bucket'])
|
95
|
-
end
|
96
|
-
|
97
|
-
def backup_bucket
|
98
|
-
@backup_bucket ||= get_bucket(@options['backup_bucket'])
|
99
|
-
end
|
100
|
-
|
101
|
-
|
102
|
-
def prune_files(o={})
|
103
|
-
options = {
|
104
|
-
:prefix => '',
|
105
|
-
:keep => 1
|
106
|
-
}.merge(o)
|
107
|
-
|
108
|
-
return if options[:keep] < 1 # must keep at least one, the last one!
|
109
|
-
|
110
|
-
my_files = s3_bucket.files.all('prefix' => options[:prefix])
|
111
|
-
return if my_files.nil?
|
112
|
-
|
113
|
-
if my_files.count > options[:keep]
|
114
|
-
my_files.
|
115
|
-
sort {|x,y| x.last_modified <=> y.last_modified}.
|
116
|
-
take(files_by_date.count - options[:keep]).
|
117
|
-
each do |f|
|
118
|
-
logger.info "Deleting #{f.name}"
|
119
|
-
f.destroy
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
157
|
+
# nothing really to do here...
|
124
158
|
def destroy
|
125
|
-
# nothing really to do here...
|
126
159
|
end
|
127
160
|
|
128
161
|
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'dogapi'
|
3
|
+
require 'rds-s3-backup'
|
4
|
+
|
5
|
+
module Rds::S3::Backup
|
6
|
+
|
7
|
+
describe "DataDog" do
|
8
|
+
it { DataDog.should respond_to(:new) }
|
9
|
+
|
10
|
+
describe "#make_dog_client" do
|
11
|
+
|
12
|
+
it "should return the client object" do
|
13
|
+
Dogapi::Client.stub(:new).with("apikey").and_return("apikey")
|
14
|
+
DataDog.new("apikey").make_dog_client.should == "apikey"
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should raise an exception" do
|
18
|
+
Dogapi::Client.stub(:new) { raise RuntimeError }
|
19
|
+
expect { DataDog.new("apikey").make_dog_client }.to raise_error(RuntimeError)
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "#send" do
|
25
|
+
it "should do something interesting" do
|
26
|
+
Dogapi::Client.stub_chain(:new, :emit_event) {"event"}
|
27
|
+
Dogapi::Event.stub(:new)
|
28
|
+
DataDog.new("apikey").send("message").should == "event"
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should raise and exception" do
|
32
|
+
Dogapi::Client.stub_chain(:new, :emit_event) { raise RuntimeError }
|
33
|
+
expect { DataDog.new("apikey").send("message")}.to raise_error(RuntimeError)
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'rds-s3-backup'
|
3
|
+
require 'fog'
|
4
|
+
|
5
|
+
module Rds::S3::Backup
|
6
|
+
|
7
|
+
describe "MyRDS" do
|
8
|
+
|
9
|
+
let(:myrds_options) {{'aws_access_key_id' => 'abcdef',
|
10
|
+
'aws_secret_access_key' => 'xyzzy',
|
11
|
+
'region' => 'us-west',
|
12
|
+
'rds_instance_id' => 'honeybadger',
|
13
|
+
'db_subnet_group_name' => 'test',
|
14
|
+
'db_instance_type' => 'big',
|
15
|
+
'mysql_username' => 'JoeBob',
|
16
|
+
'mysql_password' => 'BillyBriggs',
|
17
|
+
'mysql_database' => 'test',
|
18
|
+
'dump_directory' => '.',
|
19
|
+
'obfuscate_sql' => 'obfuscate_database.sql',
|
20
|
+
'timestamp' => Time.new.strftime('%Y-%m-%d-%H-%M-%S-%Z')
|
21
|
+
}}
|
22
|
+
|
23
|
+
let(:myrds) {MyRDS.new(myrds_options)}
|
24
|
+
|
25
|
+
before(:each) do
|
26
|
+
Fog.stub(:timeout=)
|
27
|
+
Fog::AWS::RDS.stub(:new) { Object.new }
|
28
|
+
end
|
29
|
+
|
30
|
+
it ":get_rds_connection should return an exception" do
|
31
|
+
Fog::AWS::RDS.stub(:new) { raise RuntimeError }
|
32
|
+
expect { myrds.get_rds_connection }.to raise_error(RuntimeError)
|
33
|
+
end
|
34
|
+
|
35
|
+
xit "execute :dump" do
|
36
|
+
Fog::AWS::RDS.stub_chain(:new, :servers)
|
37
|
+
Rds::S3::Backup::MySqlCmds.stub_chain(:new, :dump) {"dumpfile.sql.gz"}
|
38
|
+
myrds.dump("dumpfile.sql.gz").should == "dumpfile.sql.gz"
|
39
|
+
end
|
40
|
+
|
41
|
+
xit "execute :obfuscate" do
|
42
|
+
Rds::S3::Backup::MySqlCmds.stub_chain(:new, :exec)
|
43
|
+
myrds.exec(myrds_options['obfuscate_sql']).should == 0
|
44
|
+
end
|
45
|
+
|
46
|
+
xit "executing :obfuscate returns an error" do
|
47
|
+
Rds::S3::Backup::MySqlCmds.stub_chain(:new, :exec) {raise RuntimeError}
|
48
|
+
expect {myrds.exec(myrds_options['obfuscate_sql'])}.to raise_error(RuntimeError)
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
end
|
data/spec/rds-s3-backup_spec.rb
CHANGED
@@ -17,10 +17,6 @@ require 'rds-s3-backup'
|
|
17
17
|
|
18
18
|
module Rds::S3::Backup
|
19
19
|
|
20
|
-
describe "has version" do
|
21
|
-
it {Rds::S3::Backup::VERSION.should == '0.0.1' }
|
22
|
-
end
|
23
|
-
|
24
20
|
describe "module methods" do
|
25
21
|
|
26
22
|
it { Rds::S3::Backup.should respond_to(:run) }
|
@@ -31,54 +27,55 @@ module Rds::S3::Backup
|
|
31
27
|
|
32
28
|
describe "#run method" do
|
33
29
|
let(:options) { {
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
30
|
+
"rds_instance_id" => 'stagingdb',
|
31
|
+
"s3_bucket" => 'novu-backups',
|
32
|
+
"backup_bucket" => 'novu-backups',
|
33
|
+
"s3_prefix" => 'db_dumps',
|
34
|
+
"aws_access_key_id" => 'ABCDE',
|
35
|
+
"aws_secret_access_key" => '0987654321',
|
36
|
+
"mysql_database" => 'novu_text',
|
37
|
+
"mysql_username" => 'novurun',
|
38
|
+
"mysql_password" => 'passw0rd',
|
39
|
+
"obfuscate_sql" => '/usr/local/etc/obfuscate.sql',
|
40
|
+
"dump_ttl" => 0,
|
41
|
+
"dump_directory" => '/mnt/secure',
|
42
|
+
"aws_region" => 'us-east-1',
|
43
|
+
"aws_s3_region" => 'us-west-2',
|
44
|
+
"db_subnet_group_name" => 'staging db subnet',
|
45
|
+
"db_instance_type" => 'db.m1.small',
|
46
|
+
"instance_id" => '',
|
47
|
+
"log_level" => 'debug',
|
48
|
+
"quiet" => false,
|
49
|
+
"verbose" => true
|
54
50
|
} }
|
55
51
|
|
56
52
|
|
57
53
|
before(:each) do
|
58
|
-
DataDog.
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
MyS3.
|
68
|
-
|
69
|
-
|
70
|
-
|
54
|
+
DataDog.stub_chain(:new, :send)
|
55
|
+
|
56
|
+
|
57
|
+
MyRDS.stub_chain(:new, :restore_db)
|
58
|
+
MyRDS.stub_chain(:new, :destroy)
|
59
|
+
MyRDS.stub_chain(:new, :server, :id).and_return 1
|
60
|
+
MyRDS.stub_chain(:new, :obfuscate)
|
61
|
+
MyRDS.stub_chain(:new, :dump).and_return "dump_path"
|
62
|
+
|
63
|
+
MyS3.stub_chain(:new, :save_production)
|
64
|
+
MyS3.stub_chain(:new, :save_clean)
|
65
|
+
MyS3.stub_chain(:new, :prune_files)
|
66
|
+
MyS3.stub_chain(:new, :destroy)
|
67
|
+
|
71
68
|
end
|
72
69
|
|
73
70
|
it "should process options" do
|
74
|
-
opts = Rds::S3::Backup.process_options(options)
|
71
|
+
opts = Rds::S3::Backup.process_options(options,{})
|
75
72
|
opts.should be_a(Hash)
|
76
|
-
opts.should have_key(
|
77
|
-
opts[
|
73
|
+
opts.should have_key("timestamp")
|
74
|
+
opts["timestamp"].should_not be_nil
|
78
75
|
end
|
79
76
|
|
80
77
|
|
81
|
-
it { Rds::S3::Backup.run(options).should == 0 }
|
78
|
+
it { Rds::S3::Backup.run(options,{}).should == 0 }
|
82
79
|
|
83
80
|
end
|
84
81
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rds-s3-backup
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.8
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-04-26 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: thor
|
@@ -160,6 +160,7 @@ description: ! '"Thor script and libraries to backup an AWS RDS snapshot to AWS
|
|
160
160
|
email:
|
161
161
|
- tamouse@gmail.com
|
162
162
|
executables:
|
163
|
+
- .gitignore
|
163
164
|
- rds-s3-backup.rb
|
164
165
|
extensions: []
|
165
166
|
extra_rdoc_files: []
|
@@ -171,6 +172,7 @@ files:
|
|
171
172
|
- LICENSE.txt
|
172
173
|
- README.md
|
173
174
|
- Rakefile
|
175
|
+
- bin/.gitignore
|
174
176
|
- bin/rds-s3-backup.rb
|
175
177
|
- lib/rds-s3-backup.rb
|
176
178
|
- lib/rds-s3-backup/datadog.rb
|
@@ -179,6 +181,8 @@ files:
|
|
179
181
|
- lib/rds-s3-backup/mysqlcmds.rb
|
180
182
|
- lib/rds-s3-backup/version.rb
|
181
183
|
- rds-s3-backup.gemspec
|
184
|
+
- spec/rds-s3-backup/datadog_spec.rb
|
185
|
+
- spec/rds-s3-backup/myrds_spec.rb
|
182
186
|
- spec/rds-s3-backup_spec.rb
|
183
187
|
- spec/spec_helper.rb
|
184
188
|
- test_data/.gitignore
|
@@ -209,6 +213,8 @@ signing_key:
|
|
209
213
|
specification_version: 3
|
210
214
|
summary: ! '"Backup from AWS RDS snapshot to AWS S3 as mysqldump"'
|
211
215
|
test_files:
|
216
|
+
- spec/rds-s3-backup/datadog_spec.rb
|
217
|
+
- spec/rds-s3-backup/myrds_spec.rb
|
212
218
|
- spec/rds-s3-backup_spec.rb
|
213
219
|
- spec/spec_helper.rb
|
214
220
|
has_rdoc:
|