monsoon 0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in monsoon.gemspec
4
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,4 @@
1
+ guard 'rspec' do
2
+ watch(%r{^spec/.+_spec\.rb$})
3
+ watch(%r{^lib/monsoon/(.+)\.rb}) { |m| "spec/monsoon/#{m[1]}_spec.rb" }
4
+ end
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Brandon Hilkert
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,38 @@
1
+ Monsoon Gem
2
+ =======================
3
+
4
+ Monsoon is a MongoDB backup tool that allows you to take backups and store them in Amazon S3.
5
+
6
+
7
+ Usage
8
+ -----
9
+
10
+ To install:
11
+
12
+ gem install monsoon
13
+
14
+ To Configure:
15
+
16
+ Monsoon.configure do |config|
17
+ config.bucket = "mongo_backups"
18
+ config.key = "my_super_secret_aws_key"
19
+ config.secret = "my_super_secret_aws_secret"
20
+ config.backup_directory = "tmp"
21
+ config.mongo_uri = "mongodb://user:password@test.mongohq.com:10036/add_development"
22
+ end
23
+
24
+ To use:
25
+
26
+ client = Monsoon::Client.new
27
+ client.run
28
+
29
+
30
+ Requirements
31
+ ----
32
+
33
+ `mongodump` must be installed on the system and available from anywhere on in the console.
34
+
35
+ The gem also utilizes `tar` to compress the back so this, too, must be accessible form the command line.
36
+
37
+ Released under the [MIT license](http://www.opensource.org/licenses/mit-license.php).
38
+
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+ RSpec::Core::RakeTask.new(:spec)
4
+
5
+ task :test => :spec
6
+ task :default => :spec
@@ -0,0 +1,79 @@
1
+ require 'uri'
2
+
3
+ module Monsoon
4
+ class Backup
5
+
6
+ attr_reader :backup_directory
7
+
8
+ def initialize(uri, backup_directory = "tmp")
9
+ @uri = uri
10
+ @backup_directory = backup_directory
11
+ end
12
+
13
+ # Run the Monsoon Backup process.
14
+ #
15
+ # Examples
16
+ #
17
+ # Monsoon::Backup("mongodb://@test.mongohq.com:10036/app_development").run
18
+ # # => #<Monsoon::Backup>
19
+ #
20
+ # Returns an instance of the Monsoon::Backup class
21
+ def run
22
+ Kernel.system "#{mongo_dump_command}"
23
+ self
24
+ end
25
+
26
+ # Creates the config hash for the connection string
27
+ #
28
+ # Examples
29
+ #
30
+ # Monsoon::Backup("mongodb://test.mongohq.com:10036/app_development").config
31
+ # # => {"host" => "test.mongohq.com",
32
+ # "post" => 10036,
33
+ # "database" => "app_development",
34
+ # "username" => "testuser",
35
+ # "password" => "pass1"}
36
+ #
37
+ # Returns an instance of the Monsoon::Backup class
38
+ def config
39
+ return {} unless @uri
40
+
41
+ uri = URI.parse(@uri)
42
+ raise "must be a mongo DB" unless uri.scheme == 'mongodb'
43
+ {
44
+ "host" => uri.host,
45
+ "port" => uri.port,
46
+ "database" => uri.path.gsub(/^\//, ''),
47
+ "username" => uri.user,
48
+ "password" => uri.password
49
+ }
50
+ end
51
+
52
+ # Helper method for database name.
53
+ #
54
+ # Examples
55
+ #
56
+ # Monsoon::Backup("mongodb://test.mongohq.com:10036/app_development").database
57
+ # # => "app_development"
58
+ #
59
+ # Returns a String of the database name.
60
+ def database
61
+ config["database"]
62
+ end
63
+
64
+ # Helper to form the mongodump command.
65
+ #
66
+ # Examples
67
+ #
68
+ # Monsoon::Backup("mongodb://test.mongohq.com:10036/app_development").mongo_dump_command
69
+ # # => "mongodump -h test.mongohq.com:10036 -d app_development -o tmp"
70
+ #
71
+ # Returns the command as a String.
72
+ def mongo_dump_command
73
+ cmd = ""
74
+ cmd = "mongodump -h #{config['host']}:#{config['port']} -d #{config['database']} -o #{@backup_directory} "
75
+ cmd += "--username #{config['username']} --password #{config['password']}" unless config["username"].nil? and config["password"].nil?
76
+ cmd
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,77 @@
1
+ module Monsoon
2
+ class Client
3
+
4
+ def initialize(bucket = Monsoon.bucket, key = Monsoon.key, secret = Monsoon.secret, backup_directory = Monsoon.backup_directory, mongo_uri = Monsoon.mongo_uri)
5
+ @bucket = bucket
6
+ @key = key
7
+ @secret = secret
8
+ @backup_directory = backup_directory
9
+ @mongo_uri = mongo_uri
10
+ end
11
+
12
+ # Run the Monsoon process to backup, save, and clean the work.
13
+ #
14
+ # Examples
15
+ #
16
+ # Monsoon::Client.new.run
17
+ # # => True
18
+ #
19
+ # Returns True
20
+ def run
21
+ # Backup the MongoDB database to filesystem
22
+ b = backup.run
23
+
24
+ # Compress the contents of the backup
25
+ c = compress(b).run
26
+
27
+ # Sent to AWS
28
+ store(c.filename).save
29
+
30
+ # Remove the compressed file from the filesystem
31
+ c.clean
32
+
33
+ true
34
+ end
35
+
36
+ # Creates an instance of the Monsoon::Backup class
37
+ #
38
+ # Examples
39
+ #
40
+ # Monsoon::Client.new.backup
41
+ # # => #<Monsoon::Backup>
42
+ #
43
+ # Returns an instance of the Monsoon::Client object
44
+ def backup
45
+ Backup.new(@mongo_uri, @backup_directory)
46
+ end
47
+
48
+ # Creates an instnace of the Monsoon::Compress class
49
+ #
50
+ # backup - The Monsoon::Backup instance the preceeded.
51
+ #
52
+ # Examples
53
+ #
54
+ # Monsoon::Client.new.compress(#<Monsoon::Backup>)
55
+ # # => #<Monsoon::Compress>
56
+ #
57
+ # Returns an instance of the Monsoon::Compress object
58
+ def compress(backup)
59
+ Compress.new(backup)
60
+ end
61
+
62
+ # Creates an instance of the Monsoon::Store class
63
+ #
64
+ # filename - The String filename of the compressed backup to push to S3.
65
+ #
66
+ # Examples
67
+ #
68
+ # Monsoon::Client.new.store("test.tar.gz")
69
+ # # => #<Monsoon::Store>
70
+ #
71
+ # Returns an instance of the Monsoon::Store object
72
+ def store(filename)
73
+ Store.new(filename, @bucket, @key, @secret)
74
+ end
75
+
76
+ end
77
+ end
@@ -0,0 +1,60 @@
1
+ require 'fileutils'
2
+
3
+ module Monsoon
4
+ class Compress
5
+
6
+ def initialize(backup)
7
+ @backup = backup
8
+ end
9
+
10
+ # Run the Monsoon Compress process.
11
+ #
12
+ # Examples
13
+ #
14
+ # Monsoon::Compress(#<Monsoon::Backup>).run
15
+ # # => #<Monsoon::Compress>
16
+ #
17
+ # Returns an instance of the Monsoon::Compress class
18
+ def run
19
+ Kernel.system "#{compress_command}"
20
+ self
21
+ end
22
+
23
+ # Helper to form the tar compress command.
24
+ #
25
+ # Examples
26
+ #
27
+ # Monsoon::Compress(#<Monsoon::Backup>).compress_command
28
+ # # => "tar -czf app_development_1234.tar.gz tmp"
29
+ #
30
+ # Returns the command as a String.
31
+ def compress_command
32
+ "tar -czf #{filename} #{@backup.backup_directory}"
33
+ end
34
+
35
+ # Helper to form the tar compress command.
36
+ #
37
+ # Examples
38
+ #
39
+ # Monsoon::Compress(#<Monsoon::Backup>).filename
40
+ # # => "app_development_1234.tar.gz"
41
+ #
42
+ # Returns the filename as a String.
43
+ def filename
44
+ @filename ||= "#{@backup.database}_#{Time.now.utc.to_i.to_s}.tar.gz"
45
+ end
46
+
47
+ # Helper to delete the backup file once finished.
48
+ #
49
+ # Examples
50
+ #
51
+ # Monsoon::Compress(#<Monsoon::Backup>).clean
52
+ # # => "app_development_1234.tar.gz"
53
+ #
54
+ # Returns results of the command.
55
+ def clean
56
+ FileUtils.rm filename, force: true
57
+ end
58
+
59
+ end
60
+ end
@@ -0,0 +1,55 @@
1
+ begin
2
+ require "aws/s3"
3
+ rescue LoadError
4
+ raise "You don't have the 'aws' gem installed."
5
+ end
6
+
7
+ module Monsoon
8
+ class Store
9
+
10
+ def initialize(filename, bucket, key, secret)
11
+ @filename, @bucket, @key, @secret = filename, bucket, key, secret
12
+ end
13
+
14
+ # Runs the Monsoon Store save process.
15
+ #
16
+ # Examples
17
+ #
18
+ # Monsoon::Store("backup.tar.gz", "backups_bucket", "super_secret_key", "super_secret_secret").save
19
+ # # => #<AWS::S3::S3Object>
20
+ #
21
+ # Returns an instance of the AWS::S3::S3Object class
22
+ def save
23
+ connect
24
+ AWS::S3::S3Object.store(@filename, read_file_contents, @bucket)
25
+ end
26
+
27
+ # Parses the contents of the compressed backup.
28
+ #
29
+ # Examples
30
+ #
31
+ # Monsoon::Store("backup.tar.gz", "backups_bucket", "super_secret_key", "super_secret_secret").read_file_contents
32
+ # # => #<AWS::S3::S3Object>
33
+ #
34
+ # Returns contents of the binary file.
35
+ def read_file_contents
36
+ file = File.open(@filename, "rb")
37
+ file.read
38
+ end
39
+
40
+ # Connects to AWS.
41
+ #
42
+ # Examples
43
+ #
44
+ # Monsoon::Store("backup.tar.gz", "backups_bucket", "super_secret_key", "super_secret_secret").connect
45
+ # # => #<AWS::S3::Connection>
46
+ #
47
+ # Returns an instance of the AWS::S3::Connection class.
48
+ def connect
49
+ AWS::S3::Base.establish_connection!(
50
+ :access_key_id => @key,
51
+ :secret_access_key => @secret
52
+ )
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,3 @@
1
+ module Monsoon
2
+ VERSION = "0.1"
3
+ end
data/lib/monsoon.rb ADDED
@@ -0,0 +1,39 @@
1
+ module Monsoon
2
+
3
+ class << self
4
+ attr_accessor :bucket, :key, :secret, :backup_directory, :mongo_uri
5
+
6
+ # config/initializers/monsoon.rb (for instance)
7
+ #
8
+ # Monsoon.configure do |config|
9
+ # config.bucket = 'backups'
10
+ # config.key = 'consumer_key'
11
+ # config.secret = 'consumer_secret'
12
+ # config.backup_directory = 'data'
13
+ # config.mongo_uri = 'mongodb://testuser:pass1@test.mongohq.com:10036/app_development'
14
+ # end
15
+ #
16
+ def configure
17
+ yield self
18
+ true
19
+ end
20
+
21
+ # Run the Monsoon process to backup, save, and clean the work.
22
+ #
23
+ # Examples
24
+ #
25
+ # Monsoon.perform
26
+ # # => True
27
+ #
28
+ # Returns True
29
+ def perform
30
+ Monsoon::Client.new.run
31
+ end
32
+ end
33
+
34
+ autoload :Backup, "monsoon/backup"
35
+ autoload :Client, "monsoon/client"
36
+ autoload :Compress, "monsoon/compress"
37
+ autoload :Store, "monsoon/store"
38
+ autoload :Version, "monsoon/version"
39
+ end
data/monsoon.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "monsoon/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "monsoon"
7
+ s.version = Monsoon::VERSION
8
+ s.authors = ["Brandon Hilkert"]
9
+ s.email = ["brandonhilkert@gmail.com"]
10
+ s.homepage = "https://github.com/brandonhilkert/egg_carton"
11
+ s.summary = %q{Monsoon MongoDB Backup Utility}
12
+ s.description = %q{Monsoon is a MongoDB backup tool that allows you to take backups and store them in Amazon S3.}
13
+
14
+ s.rubyforge_project = "monsoon"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_development_dependency "rspec", "~> 2.8"
22
+ s.add_development_dependency "guard-rspec"
23
+ s.add_development_dependency "rake"
24
+
25
+ s.add_dependency "aws-s3"
26
+ end
@@ -0,0 +1,143 @@
1
+ require 'spec_helper'
2
+
3
+ module Monsoon
4
+
5
+ describe Backup do
6
+ let(:uri) { "mongodb://testuser:pass1@test.mongohq.com:10036/app_development" }
7
+ let(:directory) { "tmp" }
8
+
9
+ describe "initalization" do
10
+ let(:backup) { Backup.new(uri) }
11
+
12
+ it "should set the @uri instance variable" do
13
+ backup.instance_variable_get(:@uri).should == uri
14
+ end
15
+
16
+ it "should set the @directory instance variable to default directory if none is provided" do
17
+ backup.instance_variable_get(:@backup_directory).should == "tmp"
18
+ end
19
+
20
+ it "should set the @directory instance variable to specified directory" do
21
+ backup = Backup.new(uri, "tmp/data")
22
+ backup.instance_variable_get(:@backup_directory).should == "tmp/data"
23
+ end
24
+
25
+ it "should be able to read backup_directory instance variable" do
26
+ backup.backup_directory.should == "tmp"
27
+ end
28
+ end
29
+
30
+ describe "#run" do
31
+ let(:backup) { Backup.new(uri) }
32
+
33
+ before(:each) do
34
+ backup.stub(:mongo_dump_command).and_return("mongodump -h test -p 10000")
35
+ Kernel.stub(:system).and_return(nil)
36
+ end
37
+
38
+ it "should run call on system" do
39
+ Kernel.should_receive(:system).with("mongodump -h test -p 10000")
40
+ backup.run
41
+ end
42
+
43
+ it "should call mongo_dump method" do
44
+ backup.should_receive(:mongo_dump_command)
45
+ backup.run
46
+ end
47
+
48
+ it "should return backup instance" do
49
+ backup.run.should == backup
50
+ end
51
+ end
52
+
53
+ describe "#config" do
54
+ it "should raise error if uri is not a mongodb connection string" do
55
+ bad_uri = "http://user:pass1@test.mongohq.com:10036/app_development"
56
+
57
+ b = Backup.new(bad_uri)
58
+ expect { raise b.config }.to raise_error
59
+ end
60
+
61
+ describe "with valid URI" do
62
+ subject{ Backup.new(uri).config }
63
+
64
+ it "should return 'test.mongohq.com' as the host" do
65
+ subject["host"].should == "test.mongohq.com"
66
+ end
67
+
68
+ it "should return 10036 as the port" do
69
+ subject["port"].should == 10036
70
+ end
71
+
72
+ it "should return 'app_development' as the database" do
73
+ subject["database"].should == "app_development"
74
+ end
75
+
76
+ it "should return 'testuser' as the username" do
77
+ subject["username"].should == "testuser"
78
+ end
79
+
80
+ it "should return 'pass1' as the password" do
81
+ subject["password"].should == "pass1"
82
+ end
83
+ end
84
+ end
85
+
86
+ describe "#database" do
87
+ subject{ Backup.new(uri).database }
88
+
89
+ it "should return 'app_development' for database" do
90
+ subject.should == "app_development"
91
+ end
92
+ end
93
+
94
+ describe "#mongo_dump_command" do
95
+ subject{ Backup.new(uri).mongo_dump_command }
96
+
97
+ it "should include mongo dump command" do
98
+ subject.should include("mongodump")
99
+ end
100
+
101
+ it "should include switch for host including port" do
102
+ subject.should include("-h test.mongohq.com:10036")
103
+ end
104
+
105
+ it "should include switch for database" do
106
+ subject.should include("-d app_development")
107
+ end
108
+
109
+ it "should include switch for username" do
110
+ subject.should include("--username testuser")
111
+ end
112
+
113
+ it "should include switch for password" do
114
+ subject.should include("--password pass1")
115
+ end
116
+
117
+ it "should include switch for output directory" do
118
+ subject.should include("-o tmp")
119
+ end
120
+
121
+ it "should change output directory if intialized with it" do
122
+ Backup.new(uri, "tmp/data").mongo_dump_command.should include("-o tmp/data")
123
+
124
+ end
125
+
126
+ describe "when user and password is not included" do
127
+ let(:backup) { Backup.new("mongodb://test.mongohq.com:10036/app_development").mongo_dump_command }
128
+
129
+ it "should not include username switch" do
130
+ backup.should_not include("--username")
131
+ end
132
+
133
+ it "should not include password switch" do
134
+ backup.should_not include("--password")
135
+ end
136
+ end
137
+
138
+
139
+ end
140
+
141
+ end
142
+
143
+ end
@@ -0,0 +1,128 @@
1
+ require 'spec_helper'
2
+
3
+ module Monsoon
4
+
5
+ describe Client do
6
+ let(:bucket) { "bucket" }
7
+ let(:key) { "key" }
8
+ let(:secret) { "secret" }
9
+ let(:backup_directory) { "tmp" }
10
+ let(:mongo_uri) { "mongodb://testuser:pass1@test.mongohq.com:10036/app_development" }
11
+ let(:client) { Monsoon::Client.new(bucket, key, secret, backup_directory, mongo_uri) }
12
+
13
+ describe "initalization" do
14
+ it "should set the @bucket instance variable" do
15
+ client.instance_variable_get(:@bucket).should == bucket
16
+ end
17
+
18
+ it "should set the @key instance variable" do
19
+ client.instance_variable_get(:@key).should == key
20
+ end
21
+
22
+ it "should set the @secret instance variable" do
23
+ client.instance_variable_get(:@secret).should == secret
24
+ end
25
+
26
+ it "should set the @backup_directory instance variable" do
27
+ client.instance_variable_get(:@backup_directory).should == backup_directory
28
+ end
29
+
30
+ it "should set the @mongo_uri instance variable" do
31
+ client.instance_variable_get(:@mongo_uri).should == mongo_uri
32
+ end
33
+
34
+ describe "config variables" do
35
+ it "should set instance variable bucket" do
36
+ Monsoon.bucket = "bucket"
37
+ c = Monsoon::Client.new
38
+ c.instance_variable_get(:@bucket).should == "bucket"
39
+ end
40
+
41
+ it "should set instance variable key" do
42
+ Monsoon.key = "key"
43
+ c = Monsoon::Client.new
44
+ c.instance_variable_get(:@key).should == "key"
45
+ end
46
+
47
+ it "should set instance variable secret" do
48
+ Monsoon.secret = "secret"
49
+ c = Monsoon::Client.new
50
+ c.instance_variable_get(:@secret).should == "secret"
51
+ end
52
+
53
+ it "should set instance variable backup_directory" do
54
+ Monsoon.backup_directory = "tmp/data"
55
+ c = Monsoon::Client.new
56
+ c.instance_variable_get(:@backup_directory).should == "tmp/data"
57
+ end
58
+
59
+ it "should set instance variable mongo_uri" do
60
+ Monsoon.mongo_uri = "mongo://localhost"
61
+ c = Monsoon::Client.new
62
+ c.instance_variable_get(:@mongo_uri).should == "mongo://localhost"
63
+ end
64
+ end
65
+
66
+ end
67
+
68
+ describe "#run" do
69
+ let(:backup) { Backup.new(mongo_uri, backup_directory) }
70
+ let(:compress) { Compress.new(backup) }
71
+ let(:store) { Store.new(compress, bucket, key, secret) }
72
+
73
+ before(:each) do
74
+ Backup.any_instance.stub(:run).and_return(backup)
75
+ Compress.any_instance.stub(:run).and_return(compress)
76
+ Store.any_instance.stub(:save).and_return(store)
77
+ end
78
+
79
+ it "should run the backup process" do
80
+ Backup.any_instance.should_receive(:run)
81
+ client.run
82
+ end
83
+
84
+ it "should run the compress process" do
85
+ Compress.any_instance.should_receive(:run)
86
+ client.run
87
+ end
88
+
89
+ it "should run the store process" do
90
+ Store.any_instance.should_receive(:save)
91
+ client.run
92
+ end
93
+
94
+ it "should remove the compressed file" do
95
+ compress.should_receive(:clean)
96
+ client.run
97
+ end
98
+ end
99
+
100
+ describe "#backup" do
101
+ it "should initalize a new Backup object" do
102
+ Backup.should_receive(:new).with(mongo_uri, backup_directory)
103
+ client.backup
104
+ end
105
+ end
106
+
107
+ describe "#compress" do
108
+ let(:backup) { Backup.new(mongo_uri, backup_directory) }
109
+
110
+ it "should initalize a new Compress object" do
111
+ Compress.should_receive(:new).with(backup)
112
+ client.compress(backup)
113
+ end
114
+ end
115
+
116
+ describe "#store" do
117
+ let(:backup) { Backup.new(mongo_uri, backup_directory) }
118
+ let(:compress) { Compress.new(backup) }
119
+
120
+ it "should initalize a new Compress object" do
121
+ Compress.should_receive(:new).with(compress, bucket, key, secret)
122
+ client.store(compress)
123
+ end
124
+ end
125
+
126
+ end
127
+
128
+ end
@@ -0,0 +1,76 @@
1
+ require 'spec_helper'
2
+
3
+ module Monsoon
4
+
5
+ describe Compress do
6
+ let(:backup) { double("backup", backup_directory: "tmp", database: "app_development") }
7
+ let(:compress) { Compress.new(backup) }
8
+
9
+ describe "initalization" do
10
+ it "should set the @directory instance variable" do
11
+ compress.instance_variable_get(:@backup).should == backup
12
+ end
13
+ end
14
+
15
+ describe "#run" do
16
+ before(:each) do
17
+ compress.stub(:compress_command).and_return("tar -czf")
18
+ Kernel.stub(:system).and_return(nil)
19
+ end
20
+
21
+ it "should run call on system" do
22
+ Kernel.should_receive(:system).with("tar -czf")
23
+ compress.run
24
+ end
25
+
26
+ it "should call compress method" do
27
+ compress.should_receive(:compress_command)
28
+ compress.run
29
+ end
30
+
31
+ it "should return compress instance" do
32
+ compress.run.should == compress
33
+ end
34
+ end
35
+
36
+ describe "#compress_command" do
37
+ it "should include the tar command" do
38
+ compress.compress_command.should include("tar -czf")
39
+ end
40
+
41
+ it "should include filename with timestamp and tar.gz extension" do
42
+ compress.stub(:filename).and_return("app_development.1234.tar.gz")
43
+ compress.compress_command.should include("app_development.1234.tar.gz")
44
+ end
45
+ end
46
+
47
+ describe "#filename" do
48
+ it "should return the correct filename with timestamp" do
49
+ Time.stub_chain(:now, :utc, :to_i, :to_s).and_return("1234")
50
+ compress.filename.should == "app_development_1234.tar.gz"
51
+ end
52
+
53
+ it "should return original filename if subsequently requseted" do
54
+ Time.stub_chain(:now, :utc, :to_i, :to_s).and_return("1234")
55
+ filename = compress.filename
56
+ Time.stub_chain(:now, :utc, :to_i, :to_s).and_return("0000")
57
+ compress.filename.should == filename
58
+ end
59
+ end
60
+
61
+ describe "#clean" do
62
+ let(:filename) { compress.filename }
63
+
64
+ it "should trigger the rm command" do
65
+ FileUtils.should_receive(:rm).with(filename, force: true)
66
+ compress.clean
67
+ end
68
+
69
+ it "should delete a file" do
70
+ File
71
+ end
72
+ end
73
+
74
+ end
75
+
76
+ end
@@ -0,0 +1,77 @@
1
+ require 'spec_helper'
2
+
3
+ module Monsoon
4
+
5
+ describe Store do
6
+ let(:store) { Store.new("app_development.tar.gz", "backups", "key", "secret") }
7
+
8
+ describe "initalization" do
9
+ it "should set the @filename instance variable" do
10
+ store.instance_variable_get(:@filename).should == "app_development.tar.gz"
11
+ end
12
+
13
+ it "should set the @key instance variable" do
14
+ store.instance_variable_get(:@key).should == "key"
15
+ end
16
+
17
+ it "should set the @secret instance variable" do
18
+ store.instance_variable_get(:@secret).should == "secret"
19
+ end
20
+
21
+ it "should set the @bucket instance variable" do
22
+ store.instance_variable_get(:@bucket).should == "backups"
23
+ end
24
+
25
+ end
26
+
27
+ describe "#save" do
28
+ before(:each) do
29
+ AWS::S3::S3Object.stub(:store).and_return(AWS::S3::S3Object)
30
+ store.stub(:read_file_contents).and_return("test")
31
+ end
32
+
33
+ it "should connect to AWS" do
34
+ store.should_receive(:connect)
35
+ store.save
36
+ end
37
+
38
+ it "should execute store method on fog S3Object" do
39
+ AWS::S3::S3Object.should_receive(:store).with("app_development.tar.gz", "test", "backups")
40
+ store.save
41
+ end
42
+
43
+ it "should call the read_file_contents method" do
44
+ store.should_receive(:read_file_contents)
45
+ store.save
46
+ end
47
+ end
48
+
49
+ describe "#read_file_contents" do
50
+ before(:each) do
51
+ File.stub(:open).with("app_development.tar.gz", "rb").and_return("test")
52
+ String.any_instance.stub(:read).and_return("test")
53
+ end
54
+
55
+ it "should open the File" do
56
+ File.should_receive(:open).with("app_development.tar.gz", "rb")
57
+ store.read_file_contents
58
+ end
59
+
60
+ it "should execute the read operation on the file object" do
61
+ String.any_instance.should_receive(:read)
62
+ store.read_file_contents
63
+ end
64
+ end
65
+
66
+ describe "#connect" do
67
+ subject{ store.connection }
68
+
69
+ it "should connect to AWS" do
70
+ AWS::S3::Base.should_receive(:establish_connection!).with(:access_key_id => "key", :secret_access_key => "secret")
71
+ store.connect
72
+ end
73
+ end
74
+
75
+ end
76
+
77
+ end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+
3
+ describe Monsoon do
4
+ before(:each) do
5
+ Monsoon.bucket = nil
6
+ Monsoon.key = nil
7
+ Monsoon.secret = nil
8
+ Monsoon.backup_directory = nil
9
+ Monsoon.mongo_uri = nil
10
+ end
11
+
12
+ it "should be able to set AWS properties" do
13
+ Monsoon.bucket = "backups"
14
+ Monsoon.key = "key"
15
+ Monsoon.secret = "secret"
16
+
17
+ Monsoon.bucket.should == "backups"
18
+ Monsoon.key.should == "key"
19
+ Monsoon.secret.should == "secret"
20
+ end
21
+
22
+ it "should be able to set options through configure block" do
23
+ Monsoon.configure do |config|
24
+ config.bucket = "backups"
25
+ config.key = "key"
26
+ config.secret = "secret"
27
+ config.backup_directory = "tmp/data"
28
+ config.mongo_uri = "mongodb://testuser:pass1@test.mongohq.com:10036/app_development"
29
+ end
30
+
31
+ Monsoon.bucket.should == "backups"
32
+ Monsoon.key.should == "key"
33
+ Monsoon.secret.should == "secret"
34
+ Monsoon.backup_directory.should == "tmp/data"
35
+ Monsoon.mongo_uri.should == "mongodb://testuser:pass1@test.mongohq.com:10036/app_development"
36
+ end
37
+
38
+ describe ".perform" do
39
+ before(:each) do
40
+ Monsoon::Client.any_instance.stub(:run).and_return(true)
41
+ end
42
+
43
+ it "should excute the run method on a client instance" do
44
+ Monsoon::Client.any_instance.should_receive(:run)
45
+ Monsoon.perform
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,7 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ require 'monsoon'
5
+
6
+ RSpec.configure do |config|
7
+ end
metadata ADDED
@@ -0,0 +1,116 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: monsoon
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Brandon Hilkert
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-01-17 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: &70222012651180 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '2.8'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *70222012651180
25
+ - !ruby/object:Gem::Dependency
26
+ name: guard-rspec
27
+ requirement: &70222012650760 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *70222012650760
36
+ - !ruby/object:Gem::Dependency
37
+ name: rake
38
+ requirement: &70222012650300 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70222012650300
47
+ - !ruby/object:Gem::Dependency
48
+ name: aws-s3
49
+ requirement: &70222024478080 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: *70222024478080
58
+ description: Monsoon is a MongoDB backup tool that allows you to take backups and
59
+ store them in Amazon S3.
60
+ email:
61
+ - brandonhilkert@gmail.com
62
+ executables: []
63
+ extensions: []
64
+ extra_rdoc_files: []
65
+ files:
66
+ - .gitignore
67
+ - .rspec
68
+ - Gemfile
69
+ - Guardfile
70
+ - LICENSE
71
+ - README.md
72
+ - Rakefile
73
+ - lib/monsoon.rb
74
+ - lib/monsoon/backup.rb
75
+ - lib/monsoon/client.rb
76
+ - lib/monsoon/compress.rb
77
+ - lib/monsoon/store.rb
78
+ - lib/monsoon/version.rb
79
+ - monsoon.gemspec
80
+ - spec/monsoon/backup_spec.rb
81
+ - spec/monsoon/client_spec.rb
82
+ - spec/monsoon/compress_spec.rb
83
+ - spec/monsoon/store_spec.rb
84
+ - spec/monsoon_spec.rb
85
+ - spec/spec_helper.rb
86
+ homepage: https://github.com/brandonhilkert/egg_carton
87
+ licenses: []
88
+ post_install_message:
89
+ rdoc_options: []
90
+ require_paths:
91
+ - lib
92
+ required_ruby_version: !ruby/object:Gem::Requirement
93
+ none: false
94
+ requirements:
95
+ - - ! '>='
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ required_rubygems_version: !ruby/object:Gem::Requirement
99
+ none: false
100
+ requirements:
101
+ - - ! '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ requirements: []
105
+ rubyforge_project: monsoon
106
+ rubygems_version: 1.8.10
107
+ signing_key:
108
+ specification_version: 3
109
+ summary: Monsoon MongoDB Backup Utility
110
+ test_files:
111
+ - spec/monsoon/backup_spec.rb
112
+ - spec/monsoon/client_spec.rb
113
+ - spec/monsoon/compress_spec.rb
114
+ - spec/monsoon/store_spec.rb
115
+ - spec/monsoon_spec.rb
116
+ - spec/spec_helper.rb