interu-backup 3.0.16

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.
Files changed (151) hide show
  1. data/.gitignore +2 -0
  2. data/Gemfile +31 -0
  3. data/Gemfile.lock +117 -0
  4. data/Guardfile +17 -0
  5. data/LICENSE.md +24 -0
  6. data/README.md +332 -0
  7. data/backup.gemspec +31 -0
  8. data/bin/backup +267 -0
  9. data/lib/backup.rb +181 -0
  10. data/lib/backup/archive.rb +73 -0
  11. data/lib/backup/cli.rb +82 -0
  12. data/lib/backup/compressor/base.rb +17 -0
  13. data/lib/backup/compressor/bzip2.rb +64 -0
  14. data/lib/backup/compressor/gzip.rb +61 -0
  15. data/lib/backup/configuration/base.rb +15 -0
  16. data/lib/backup/configuration/compressor/base.rb +10 -0
  17. data/lib/backup/configuration/compressor/bzip2.rb +23 -0
  18. data/lib/backup/configuration/compressor/gzip.rb +23 -0
  19. data/lib/backup/configuration/database/base.rb +18 -0
  20. data/lib/backup/configuration/database/mongodb.rb +41 -0
  21. data/lib/backup/configuration/database/mysql.rb +37 -0
  22. data/lib/backup/configuration/database/postgresql.rb +37 -0
  23. data/lib/backup/configuration/database/redis.rb +35 -0
  24. data/lib/backup/configuration/encryptor/base.rb +10 -0
  25. data/lib/backup/configuration/encryptor/gpg.rb +17 -0
  26. data/lib/backup/configuration/encryptor/open_ssl.rb +26 -0
  27. data/lib/backup/configuration/helpers.rb +54 -0
  28. data/lib/backup/configuration/notifier/base.rb +39 -0
  29. data/lib/backup/configuration/notifier/campfire.rb +25 -0
  30. data/lib/backup/configuration/notifier/mail.rb +52 -0
  31. data/lib/backup/configuration/notifier/presently.rb +25 -0
  32. data/lib/backup/configuration/notifier/twitter.rb +21 -0
  33. data/lib/backup/configuration/storage/base.rb +18 -0
  34. data/lib/backup/configuration/storage/cloudfiles.rb +21 -0
  35. data/lib/backup/configuration/storage/dropbox.rb +29 -0
  36. data/lib/backup/configuration/storage/ftp.rb +25 -0
  37. data/lib/backup/configuration/storage/rsync.rb +25 -0
  38. data/lib/backup/configuration/storage/s3.rb +25 -0
  39. data/lib/backup/configuration/storage/scp.rb +25 -0
  40. data/lib/backup/configuration/storage/sftp.rb +25 -0
  41. data/lib/backup/configuration/syncer/rsync.rb +45 -0
  42. data/lib/backup/configuration/syncer/s3.rb +33 -0
  43. data/lib/backup/database/base.rb +33 -0
  44. data/lib/backup/database/mongodb.rb +179 -0
  45. data/lib/backup/database/mysql.rb +104 -0
  46. data/lib/backup/database/postgresql.rb +111 -0
  47. data/lib/backup/database/redis.rb +105 -0
  48. data/lib/backup/dependency.rb +96 -0
  49. data/lib/backup/encryptor/base.rb +17 -0
  50. data/lib/backup/encryptor/gpg.rb +78 -0
  51. data/lib/backup/encryptor/open_ssl.rb +67 -0
  52. data/lib/backup/exception/command_not_found.rb +8 -0
  53. data/lib/backup/finder.rb +39 -0
  54. data/lib/backup/logger.rb +102 -0
  55. data/lib/backup/model.rb +272 -0
  56. data/lib/backup/notifier/base.rb +29 -0
  57. data/lib/backup/notifier/binder.rb +32 -0
  58. data/lib/backup/notifier/campfire.rb +194 -0
  59. data/lib/backup/notifier/mail.rb +141 -0
  60. data/lib/backup/notifier/presently.rb +105 -0
  61. data/lib/backup/notifier/templates/notify_failure.erb +33 -0
  62. data/lib/backup/notifier/templates/notify_success.erb +16 -0
  63. data/lib/backup/notifier/twitter.rb +87 -0
  64. data/lib/backup/storage/base.rb +67 -0
  65. data/lib/backup/storage/cloudfiles.rb +95 -0
  66. data/lib/backup/storage/dropbox.rb +91 -0
  67. data/lib/backup/storage/ftp.rb +114 -0
  68. data/lib/backup/storage/object.rb +45 -0
  69. data/lib/backup/storage/rsync.rb +129 -0
  70. data/lib/backup/storage/s3.rb +180 -0
  71. data/lib/backup/storage/scp.rb +106 -0
  72. data/lib/backup/storage/sftp.rb +106 -0
  73. data/lib/backup/syncer/base.rb +10 -0
  74. data/lib/backup/syncer/rsync.rb +152 -0
  75. data/lib/backup/syncer/s3.rb +118 -0
  76. data/lib/backup/version.rb +43 -0
  77. data/lib/templates/archive +7 -0
  78. data/lib/templates/compressor/bzip2 +7 -0
  79. data/lib/templates/compressor/gzip +7 -0
  80. data/lib/templates/database/mongodb +14 -0
  81. data/lib/templates/database/mysql +14 -0
  82. data/lib/templates/database/postgresql +14 -0
  83. data/lib/templates/database/redis +13 -0
  84. data/lib/templates/encryptor/gpg +12 -0
  85. data/lib/templates/encryptor/openssl +8 -0
  86. data/lib/templates/notifier/campfire +11 -0
  87. data/lib/templates/notifier/mail +17 -0
  88. data/lib/templates/notifier/presently +12 -0
  89. data/lib/templates/notifier/twitter +12 -0
  90. data/lib/templates/readme +15 -0
  91. data/lib/templates/storage/cloudfiles +10 -0
  92. data/lib/templates/storage/dropbox +12 -0
  93. data/lib/templates/storage/ftp +11 -0
  94. data/lib/templates/storage/rsync +10 -0
  95. data/lib/templates/storage/s3 +21 -0
  96. data/lib/templates/storage/scp +11 -0
  97. data/lib/templates/storage/sftp +11 -0
  98. data/lib/templates/syncer/rsync +17 -0
  99. data/lib/templates/syncer/s3 +15 -0
  100. data/spec/archive_spec.rb +90 -0
  101. data/spec/backup_spec.rb +11 -0
  102. data/spec/compressor/bzip2_spec.rb +59 -0
  103. data/spec/compressor/gzip_spec.rb +59 -0
  104. data/spec/configuration/base_spec.rb +35 -0
  105. data/spec/configuration/compressor/gzip_spec.rb +28 -0
  106. data/spec/configuration/database/base_spec.rb +16 -0
  107. data/spec/configuration/database/mongodb_spec.rb +30 -0
  108. data/spec/configuration/database/mysql_spec.rb +32 -0
  109. data/spec/configuration/database/postgresql_spec.rb +32 -0
  110. data/spec/configuration/database/redis_spec.rb +30 -0
  111. data/spec/configuration/encryptor/gpg_spec.rb +25 -0
  112. data/spec/configuration/encryptor/open_ssl_spec.rb +31 -0
  113. data/spec/configuration/notifier/campfire_spec.rb +20 -0
  114. data/spec/configuration/notifier/mail_spec.rb +32 -0
  115. data/spec/configuration/notifier/twitter_spec.rb +22 -0
  116. data/spec/configuration/storage/cloudfiles_spec.rb +34 -0
  117. data/spec/configuration/storage/dropbox_spec.rb +43 -0
  118. data/spec/configuration/storage/ftp_spec.rb +40 -0
  119. data/spec/configuration/storage/rsync_spec.rb +37 -0
  120. data/spec/configuration/storage/s3_spec.rb +37 -0
  121. data/spec/configuration/storage/scp_spec.rb +40 -0
  122. data/spec/configuration/storage/sftp_spec.rb +40 -0
  123. data/spec/configuration/syncer/rsync_spec.rb +46 -0
  124. data/spec/configuration/syncer/s3_spec.rb +43 -0
  125. data/spec/database/base_spec.rb +30 -0
  126. data/spec/database/mongodb_spec.rb +181 -0
  127. data/spec/database/mysql_spec.rb +150 -0
  128. data/spec/database/postgresql_spec.rb +164 -0
  129. data/spec/database/redis_spec.rb +122 -0
  130. data/spec/encryptor/gpg_spec.rb +57 -0
  131. data/spec/encryptor/open_ssl_spec.rb +102 -0
  132. data/spec/logger_spec.rb +58 -0
  133. data/spec/model_spec.rb +236 -0
  134. data/spec/notifier/campfire_spec.rb +96 -0
  135. data/spec/notifier/mail_spec.rb +97 -0
  136. data/spec/notifier/presently_spec.rb +99 -0
  137. data/spec/notifier/twitter_spec.rb +86 -0
  138. data/spec/spec_helper.rb +25 -0
  139. data/spec/storage/base_spec.rb +33 -0
  140. data/spec/storage/cloudfiles_spec.rb +102 -0
  141. data/spec/storage/dropbox_spec.rb +105 -0
  142. data/spec/storage/ftp_spec.rb +133 -0
  143. data/spec/storage/object_spec.rb +74 -0
  144. data/spec/storage/rsync_spec.rb +131 -0
  145. data/spec/storage/s3_spec.rb +110 -0
  146. data/spec/storage/scp_spec.rb +129 -0
  147. data/spec/storage/sftp_spec.rb +125 -0
  148. data/spec/syncer/rsync_spec.rb +195 -0
  149. data/spec/syncer/s3_spec.rb +139 -0
  150. data/spec/version_spec.rb +21 -0
  151. metadata +231 -0
@@ -0,0 +1,32 @@
1
+ # encoding: utf-8
2
+
3
+ module Backup
4
+ module Notifier
5
+ class Binder
6
+
7
+ ##
8
+ # Shortcut to create a new instance of a binder, setting
9
+ # the instance variables using a Hash of key/values and getting
10
+ # the instance's binding. This returns the binding of the new Binder instance
11
+ def self.bind(key_and_values = {})
12
+ Binder.new(key_and_values).get_binding
13
+ end
14
+
15
+ ##
16
+ # Creates a new Backup::Notifier::Binder instance. Loops through the provided
17
+ # Hash to set instance variables
18
+ def initialize(key_and_values)
19
+ key_and_values.each do |key, value|
20
+ instance_variable_set("@#{key}", value)
21
+ end
22
+ end
23
+
24
+ ##
25
+ # Returns the binding (needs a wrapper method because #binding is a private method)
26
+ def get_binding
27
+ binding
28
+ end
29
+
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,194 @@
1
+ # encoding: utf-8
2
+
3
+ ##
4
+ # If the Ruby version of this process is 1.8.x or less
5
+ # then use the JSON gem. Otherwise if the current process is running
6
+ # Ruby 1.9.x or later then it is built in and we can load it from the Ruby core lib
7
+ if RUBY_VERSION < '1.9.0'
8
+ Backup::Dependency.load('json')
9
+ else
10
+ require 'json'
11
+ end
12
+
13
+ ##
14
+ # Load the HTTParty library from the gem
15
+ Backup::Dependency.load('httparty')
16
+
17
+ module Backup
18
+ module Notifier
19
+ class Campfire < Base
20
+
21
+ ##
22
+ # Campfire api authentication token
23
+ attr_accessor :api_token
24
+
25
+ ##
26
+ # Campfire account's subdomain
27
+ attr_accessor :subdomain
28
+
29
+ ##
30
+ # Campfire account's room id
31
+ attr_accessor :room_id
32
+
33
+ ##
34
+ # Container for the Model object
35
+ attr_accessor :model
36
+
37
+ ##
38
+ # Instantiates a new Backup::Notifier::Campfire object
39
+ def initialize(&block)
40
+ load_defaults!
41
+
42
+ instance_eval(&block) if block_given?
43
+
44
+ set_defaults!
45
+ end
46
+
47
+ ##
48
+ # Performs the notification
49
+ # Takes an exception object that might've been created if an exception occurred.
50
+ # If this is the case it'll invoke notify_failure!(exception), otherwise, if no
51
+ # error was raised, it'll go ahead and notify_success!
52
+ #
53
+ # If'll only perform these if on_success is true or on_failure is true
54
+ def perform!(model, exception = false)
55
+ @model = model
56
+
57
+ if notify_on_success? and exception.eql?(false)
58
+ log!
59
+ notify_success!
60
+ elsif notify_on_failure? and not exception.eql?(false)
61
+ log!
62
+ notify_failure!(exception)
63
+ end
64
+ end
65
+
66
+ private
67
+
68
+ ##
69
+ # Sends a message informing the user that the backup operation
70
+ # proceeded without any errors
71
+ def notify_success!
72
+ send_message("[Backup::Succeeded] #{model.label} (#{ File.basename(Backup::Model.file) })")
73
+ end
74
+
75
+ ##
76
+ # Sends a message informing the user that the backup operation
77
+ # raised an exception
78
+ def notify_failure!(exception)
79
+ send_message("[Backup::Failed] #{model.label} (#{ File.basename(Backup::Model.file) })")
80
+ end
81
+
82
+ ##
83
+ # Setting up credentials
84
+ def set_defaults!
85
+ @campfire_client = {
86
+ :api_token => @api_token,
87
+ :subdomain => @subdomain,
88
+ :room_id => @room_id
89
+ }
90
+ end
91
+
92
+ ##
93
+ # Creates a new Campfire::Interface object and passes in the
94
+ # campfire clients "room_id", "subdomain" and "api_token". Using this object
95
+ # the provided "message" will be sent to the desired Campfire chat room
96
+ def send_message(message)
97
+ room = Interface.room(
98
+ @campfire_client[:room_id],
99
+ @campfire_client[:subdomain],
100
+ @campfire_client[:api_token]
101
+ )
102
+ room.message(message)
103
+ end
104
+
105
+ ##
106
+ # The Campfire::Interface acts as the Interface for the Campfire class.
107
+ # It uses the HTTParty library and the Campfire::Room class to communicate
108
+ # with the Campfire rooms. HTTParty provides the Campfire::Interface with the methods
109
+ # necessary to communicate (inside the HTTParty module) such as the class methods:
110
+ # * post
111
+ # * base_uri
112
+ # * basic_auth
113
+ class Interface
114
+ include HTTParty
115
+
116
+ ##
117
+ # We communicate using the JSON data format
118
+ headers 'Content-Type' => 'application/json'
119
+
120
+ ##
121
+ # Instantiates a new Campfire::Room object with
122
+ # the provided arguments and returns this object
123
+ def self.room(room_id, subdomain, api_token)
124
+ Room.new(room_id, subdomain, api_token)
125
+ end
126
+ end
127
+
128
+ ##
129
+ # The Campfire::Room acts as a model for an actual room on the Campfire service.
130
+ # And it uses the Campfire::Interface's (HTTParty) class methods to communicate based
131
+ # on the provided parameters (room_id, subdomain and api_token)
132
+ class Room
133
+
134
+ ##
135
+ # Campfire api authentication api_token
136
+ attr_accessor :api_token
137
+
138
+ ##
139
+ # Campfire account's subdomain
140
+ attr_accessor :subdomain
141
+
142
+ ##
143
+ # Campfire account's room id
144
+ attr_accessor :room_id
145
+
146
+ ##
147
+ # Instantiates a new Campfire::Room object and sets all the
148
+ # necessary arguments (@room_id, @subdomain, @api_token)
149
+ def initialize(room_id, subdomain, api_token)
150
+ @room_id = room_id
151
+ @subdomain = subdomain
152
+ @api_token = api_token
153
+ end
154
+
155
+ ##
156
+ # Wrapper method for the #send_message (private) method
157
+ def message(message)
158
+ send_message(message)
159
+ end
160
+
161
+ private
162
+
163
+ ##
164
+ # Takes a "message" as argument, the "type" defaults to "Textmessage".
165
+ # This method builds up a POST request with the necessary params (serialized to JSON format)
166
+ # and sends it to the Campfire service in order to submit the message
167
+ def send_message(message, type = 'Textmessage')
168
+ post 'speak', :body => {
169
+ :message => {
170
+ :body => message,
171
+ :type => type
172
+ }
173
+ }.to_json
174
+ end
175
+
176
+ ##
177
+ # Builds/sets up the Campfire::Interface attributes and submits
178
+ # the POST request that was built in the #send_message (private) method
179
+ def post(action, options = {})
180
+ Interface.base_uri("https://#{subdomain}.campfirenow.com")
181
+ Interface.basic_auth(api_token, 'x')
182
+ Interface.post(room_url_for(action), options)
183
+ end
184
+
185
+ ##
186
+ # Returns the url for the specified room (in JSON format)
187
+ def room_url_for(action)
188
+ "/room/#{room_id}/#{action}.json"
189
+ end
190
+ end
191
+
192
+ end
193
+ end
194
+ end
@@ -0,0 +1,141 @@
1
+ # encoding: utf-8
2
+
3
+ ##
4
+ # Only load the Mail gem and Erb library when using Mail notifications
5
+ Backup::Dependency.load('mail')
6
+ require 'erb'
7
+
8
+ module Backup
9
+ module Notifier
10
+ class Mail < Base
11
+
12
+ ##
13
+ # Container for the Mail object
14
+ attr_accessor :mail
15
+
16
+ ##
17
+ # Container for the Model object
18
+ attr_accessor :model
19
+
20
+ ##
21
+ # Sender and Receiver email addresses
22
+ # Examples:
23
+ # sender - my.email.address@gmail.com
24
+ # receiver - your.email.address@gmail.com
25
+ attr_accessor :from, :to
26
+
27
+ ##
28
+ # The address to use
29
+ # Example: smtp.gmail.com
30
+ attr_accessor :address
31
+
32
+ ##
33
+ # The port to connect to
34
+ # Example: 587
35
+ attr_accessor :port
36
+
37
+ ##
38
+ # Your domain (if applicable)
39
+ # Example: mydomain.com
40
+ attr_accessor :domain
41
+
42
+ ##
43
+ # Username and Password (sender email's credentials)
44
+ # Examples:
45
+ # user_name - meskyanichi
46
+ # password - my_secret_password
47
+ attr_accessor :user_name, :password
48
+
49
+ ##
50
+ # Authentication type
51
+ # Example: plain
52
+ attr_accessor :authentication
53
+
54
+ ##
55
+ # Automatically set TLS
56
+ # Example: true
57
+ attr_accessor :enable_starttls_auto
58
+
59
+ ##
60
+ # Instantiates a new Backup::Notifier::Mail object
61
+ def initialize(&block)
62
+ load_defaults!
63
+
64
+ instance_eval(&block) if block_given?
65
+
66
+ set_defaults!
67
+ end
68
+
69
+ ##
70
+ # Performs the notification
71
+ # Takes an exception object that might've been created if an exception occurred.
72
+ # If this is the case it'll invoke notify_failure!(exception), otherwise, if no
73
+ # error was raised, it'll go ahead and notify_success!
74
+ #
75
+ # If'll only perform these if on_success is true or on_failure is true
76
+ def perform!(model, exception = false)
77
+ @model = model
78
+
79
+ if notify_on_success? and exception.eql?(false)
80
+ log!
81
+ notify_success!
82
+ elsif notify_on_failure? and not exception.eql?(false)
83
+ log!
84
+ notify_failure!(exception)
85
+ end
86
+ end
87
+
88
+ private
89
+
90
+ ##
91
+ # Sends an email informing the user that the backup operation
92
+ # proceeded without any errors
93
+ def notify_success!
94
+ mail[:subject] = "[Backup::Succeeded] #{model.label} (#{model.trigger})"
95
+ mail[:body] = read_template('notify_success', Binder.bind(:model => @model))
96
+ mail.deliver!
97
+ end
98
+
99
+ ##
100
+ # Sends an email informing the user that the backup operation
101
+ # raised an exception and will send the user the error details
102
+ def notify_failure!(exception)
103
+ mail[:subject] = "[Backup::Failed] #{model.label} (#{model.trigger})"
104
+ mail[:body] = read_template('notify_failure', Binder.bind(:model => @model, :exception => exception))
105
+ mail.deliver!
106
+ end
107
+
108
+ ##
109
+ # Configures the Mail gem by setting the defaults.
110
+ # Instantiates the @mail object with the @to and @from attributes
111
+ def set_defaults!
112
+ defaults = {
113
+ :address => @address,
114
+ :port => @port,
115
+ :domain => @domain,
116
+ :user_name => @user_name,
117
+ :password => @password,
118
+ :authentication => @authentication,
119
+ :enable_starttls_auto => @enable_starttls_auto
120
+ }
121
+
122
+ ::Mail.defaults do
123
+ delivery_method :smtp, defaults
124
+ end
125
+
126
+ @mail = ::Mail.new
127
+ @mail[:from] = @from
128
+ @mail[:to] = @to
129
+ end
130
+
131
+ ##
132
+ # Returns the path to the templates, appended by the passed in argument
133
+ def read_template(file, binder)
134
+ ERB.new(File.read(
135
+ File.join( File.dirname(__FILE__), "templates", "#{file}.erb" )
136
+ )).result(binder)
137
+ end
138
+
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,105 @@
1
+ # encoding: utf-8
2
+
3
+ Backup::Dependency.load('httparty')
4
+
5
+ module Backup
6
+ module Notifier
7
+ class Presently < Base
8
+
9
+ ##
10
+ # Container for the Presently Client object
11
+ attr_accessor :presently_client
12
+
13
+ ##
14
+ # Container for the Model object
15
+ attr_accessor :model
16
+
17
+ ##
18
+ # Presently subdomain
19
+ attr_accessor :subdomain
20
+
21
+ ##
22
+ # Presently credentials
23
+ attr_accessor :user_name, :password
24
+
25
+ ##
26
+ # Group id
27
+ attr_accessor :group_id
28
+
29
+ ##
30
+ # Instantiates a new Backup::Notifier::Presently object
31
+ def initialize(&block)
32
+ load_defaults!
33
+
34
+ instance_eval(&block) if block_given?
35
+
36
+ set_defaults!
37
+ end
38
+
39
+ ##
40
+ # Performs the notification
41
+ # Takes an exception object that might've been created if an exception occurred.
42
+ # If this is the case it'll invoke notify_failure!(exception), otherwise, if no
43
+ # error was raised, it'll go ahead and notify_success!
44
+ #
45
+ # If'll only perform these if on_success is true or on_failure is true
46
+ def perform!(model, exception = false)
47
+ @model = model
48
+
49
+ if notify_on_success? and exception.eql?(false)
50
+ log!
51
+ notify_success!
52
+ elsif notify_on_failure? and not exception.eql?(false)
53
+ log!
54
+ notify_failure!(exception)
55
+ end
56
+ end
57
+
58
+ private
59
+
60
+ ##
61
+ # Sends a tweet informing the user that the backup operation
62
+ # proceeded without any errors
63
+ def notify_success!
64
+ presently_client.update("[Backup::Succeeded] #{model.label} (#{ File.basename(Backup::Model.file) })")
65
+ end
66
+
67
+ ##
68
+ # Sends a tweet informing the user that the backup operation
69
+ # raised an exception
70
+ def notify_failure!(exception)
71
+ presently_client.update("[Backup::Failed] #{model.label} (#{ File.basename(Backup::Model.file) })")
72
+ end
73
+
74
+ ##
75
+ # Create a default Presently::Client object
76
+ def set_defaults!
77
+ @presently_client = Client.new subdomain, user_name, password, group_id
78
+ end
79
+
80
+ class Client
81
+ include HTTParty
82
+
83
+ attr_accessor :subdomain, :user_name, :password, :group_id
84
+
85
+ def initialize(subdomain, user_name, password, group_id)
86
+ @subdomain = subdomain
87
+ @user_name = user_name
88
+ @password = password
89
+ @group_id = group_id
90
+
91
+ self.class.base_uri "https://#{subdomain}.presently.com"
92
+ self.class.basic_auth user_name, password
93
+ end
94
+
95
+ def update(message)
96
+ message = "d @#{group_id} #{message}" if group_id
97
+ self.class.post "/api/twitter/statuses/update.json", :body => {
98
+ :status => message,
99
+ :source => "Backup Notifier"
100
+ }
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end