nfm-backup 4.0.1a

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 (117) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.md +24 -0
  3. data/README.md +20 -0
  4. data/bin/backup +5 -0
  5. data/lib/backup.rb +133 -0
  6. data/lib/backup/archive.rb +170 -0
  7. data/lib/backup/binder.rb +22 -0
  8. data/lib/backup/cleaner.rb +116 -0
  9. data/lib/backup/cli.rb +364 -0
  10. data/lib/backup/cloud_io/base.rb +41 -0
  11. data/lib/backup/cloud_io/cloud_files.rb +298 -0
  12. data/lib/backup/cloud_io/s3.rb +260 -0
  13. data/lib/backup/compressor/base.rb +35 -0
  14. data/lib/backup/compressor/bzip2.rb +39 -0
  15. data/lib/backup/compressor/custom.rb +53 -0
  16. data/lib/backup/compressor/gzip.rb +74 -0
  17. data/lib/backup/config.rb +119 -0
  18. data/lib/backup/config/dsl.rb +102 -0
  19. data/lib/backup/config/helpers.rb +143 -0
  20. data/lib/backup/database/base.rb +85 -0
  21. data/lib/backup/database/mongodb.rb +186 -0
  22. data/lib/backup/database/mysql.rb +123 -0
  23. data/lib/backup/database/postgresql.rb +133 -0
  24. data/lib/backup/database/redis.rb +179 -0
  25. data/lib/backup/database/riak.rb +82 -0
  26. data/lib/backup/encryptor/base.rb +29 -0
  27. data/lib/backup/encryptor/gpg.rb +747 -0
  28. data/lib/backup/encryptor/open_ssl.rb +72 -0
  29. data/lib/backup/errors.rb +58 -0
  30. data/lib/backup/logger.rb +199 -0
  31. data/lib/backup/logger/console.rb +51 -0
  32. data/lib/backup/logger/fog_adapter.rb +29 -0
  33. data/lib/backup/logger/logfile.rb +119 -0
  34. data/lib/backup/logger/syslog.rb +116 -0
  35. data/lib/backup/model.rb +454 -0
  36. data/lib/backup/notifier/base.rb +98 -0
  37. data/lib/backup/notifier/campfire.rb +69 -0
  38. data/lib/backup/notifier/hipchat.rb +93 -0
  39. data/lib/backup/notifier/http_post.rb +122 -0
  40. data/lib/backup/notifier/mail.rb +238 -0
  41. data/lib/backup/notifier/nagios.rb +69 -0
  42. data/lib/backup/notifier/prowl.rb +69 -0
  43. data/lib/backup/notifier/pushover.rb +80 -0
  44. data/lib/backup/notifier/slack.rb +149 -0
  45. data/lib/backup/notifier/twitter.rb +65 -0
  46. data/lib/backup/package.rb +51 -0
  47. data/lib/backup/packager.rb +101 -0
  48. data/lib/backup/pipeline.rb +124 -0
  49. data/lib/backup/splitter.rb +76 -0
  50. data/lib/backup/storage/base.rb +57 -0
  51. data/lib/backup/storage/cloud_files.rb +158 -0
  52. data/lib/backup/storage/cycler.rb +65 -0
  53. data/lib/backup/storage/dropbox.rb +236 -0
  54. data/lib/backup/storage/ftp.rb +98 -0
  55. data/lib/backup/storage/local.rb +64 -0
  56. data/lib/backup/storage/ninefold.rb +74 -0
  57. data/lib/backup/storage/rsync.rb +248 -0
  58. data/lib/backup/storage/s3.rb +154 -0
  59. data/lib/backup/storage/scp.rb +67 -0
  60. data/lib/backup/storage/sftp.rb +82 -0
  61. data/lib/backup/syncer/base.rb +70 -0
  62. data/lib/backup/syncer/cloud/base.rb +179 -0
  63. data/lib/backup/syncer/cloud/cloud_files.rb +83 -0
  64. data/lib/backup/syncer/cloud/local_file.rb +100 -0
  65. data/lib/backup/syncer/cloud/s3.rb +110 -0
  66. data/lib/backup/syncer/rsync/base.rb +48 -0
  67. data/lib/backup/syncer/rsync/local.rb +31 -0
  68. data/lib/backup/syncer/rsync/pull.rb +51 -0
  69. data/lib/backup/syncer/rsync/push.rb +205 -0
  70. data/lib/backup/template.rb +46 -0
  71. data/lib/backup/utilities.rb +221 -0
  72. data/lib/backup/version.rb +5 -0
  73. data/templates/cli/archive +28 -0
  74. data/templates/cli/compressor/bzip2 +4 -0
  75. data/templates/cli/compressor/custom +7 -0
  76. data/templates/cli/compressor/gzip +4 -0
  77. data/templates/cli/config +123 -0
  78. data/templates/cli/databases/mongodb +15 -0
  79. data/templates/cli/databases/mysql +18 -0
  80. data/templates/cli/databases/postgresql +16 -0
  81. data/templates/cli/databases/redis +16 -0
  82. data/templates/cli/databases/riak +17 -0
  83. data/templates/cli/encryptor/gpg +27 -0
  84. data/templates/cli/encryptor/openssl +9 -0
  85. data/templates/cli/model +26 -0
  86. data/templates/cli/notifiers/campfire +12 -0
  87. data/templates/cli/notifiers/hipchat +15 -0
  88. data/templates/cli/notifiers/http_post +32 -0
  89. data/templates/cli/notifiers/mail +21 -0
  90. data/templates/cli/notifiers/nagios +13 -0
  91. data/templates/cli/notifiers/prowl +11 -0
  92. data/templates/cli/notifiers/pushover +11 -0
  93. data/templates/cli/notifiers/twitter +13 -0
  94. data/templates/cli/splitter +7 -0
  95. data/templates/cli/storages/cloud_files +11 -0
  96. data/templates/cli/storages/dropbox +19 -0
  97. data/templates/cli/storages/ftp +12 -0
  98. data/templates/cli/storages/local +7 -0
  99. data/templates/cli/storages/ninefold +9 -0
  100. data/templates/cli/storages/rsync +17 -0
  101. data/templates/cli/storages/s3 +14 -0
  102. data/templates/cli/storages/scp +14 -0
  103. data/templates/cli/storages/sftp +14 -0
  104. data/templates/cli/syncers/cloud_files +22 -0
  105. data/templates/cli/syncers/rsync_local +20 -0
  106. data/templates/cli/syncers/rsync_pull +28 -0
  107. data/templates/cli/syncers/rsync_push +28 -0
  108. data/templates/cli/syncers/s3 +27 -0
  109. data/templates/general/links +3 -0
  110. data/templates/general/version.erb +2 -0
  111. data/templates/notifier/mail/failure.erb +16 -0
  112. data/templates/notifier/mail/success.erb +16 -0
  113. data/templates/notifier/mail/warning.erb +16 -0
  114. data/templates/storage/dropbox/authorization_url.erb +6 -0
  115. data/templates/storage/dropbox/authorized.erb +4 -0
  116. data/templates/storage/dropbox/cache_file_written.erb +10 -0
  117. metadata +688 -0
@@ -0,0 +1,69 @@
1
+ # encoding: utf-8
2
+
3
+ module Backup
4
+ module Notifier
5
+ class Nagios < Base
6
+
7
+ ##
8
+ # Host of Nagios server to notify on backup completion.
9
+ attr_accessor :nagios_host
10
+
11
+ ##
12
+ # Port of Nagios server to notify on backup completion.
13
+ attr_accessor :nagios_port
14
+
15
+ ##
16
+ # Name of the Nagios service for the backup check.
17
+ attr_accessor :service_name
18
+
19
+ ##
20
+ # Host name in Nagios for the backup check.
21
+ attr_accessor :service_host
22
+
23
+ def initialize(model, &block)
24
+ super
25
+ instance_eval(&block) if block_given?
26
+
27
+ @nagios_host ||= Config.hostname
28
+ @nagios_port ||= 5667
29
+ @service_name ||= "Backup #{ model.trigger }"
30
+ @service_host ||= Config.hostname
31
+ end
32
+
33
+ private
34
+
35
+ ##
36
+ # Notify the user of the backup operation results.
37
+ #
38
+ # `status` indicates one of the following:
39
+ #
40
+ # `:success`
41
+ # : The backup completed successfully.
42
+ # : Notification will be sent if `on_success` is `true`.
43
+ #
44
+ # `:warning`
45
+ # : The backup completed successfully, but warnings were logged.
46
+ # : Notification will be sent if `on_warning` or `on_success` is `true`.
47
+ #
48
+ # `:failure`
49
+ # : The backup operation failed.
50
+ # : Notification will be sent if `on_warning` or `on_success` is `true`.
51
+ #
52
+ def notify!(status)
53
+ message = case status
54
+ when :success then 'Completed Successfully'
55
+ when :warning then 'Completed Successfully (with Warnings)'
56
+ when :failure then 'Failed'
57
+ end
58
+ send_message("#{ message } in #{ model.duration }")
59
+ end
60
+
61
+ def send_message(message)
62
+ cmd = "#{ utility(:send_nsca) } -H '#{ nagios_host }' -p '#{ nagios_port }'"
63
+ msg = [service_host, service_name, model.exit_status, message].join("\t")
64
+ run("echo '#{ msg }' | #{ cmd }")
65
+ end
66
+
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,69 @@
1
+ # encoding: utf-8
2
+ require 'uri'
3
+
4
+ module Backup
5
+ module Notifier
6
+ class Prowl < Base
7
+
8
+ ##
9
+ # Application name
10
+ # Tell something like your server name. Example: "Server1 Backup"
11
+ attr_accessor :application
12
+
13
+ ##
14
+ # API-Key
15
+ # Create a Prowl account and request an API key on prowlapp.com.
16
+ attr_accessor :api_key
17
+
18
+ def initialize(model, &block)
19
+ super
20
+ instance_eval(&block) if block_given?
21
+ end
22
+
23
+ private
24
+
25
+ ##
26
+ # Notify the user of the backup operation results.
27
+ #
28
+ # `status` indicates one of the following:
29
+ #
30
+ # `:success`
31
+ # : The backup completed successfully.
32
+ # : Notification will be sent if `on_success` is `true`.
33
+ #
34
+ # `:warning`
35
+ # : The backup completed successfully, but warnings were logged.
36
+ # : Notification will be sent if `on_warning` or `on_success` is `true`.
37
+ #
38
+ # `:failure`
39
+ # : The backup operation failed.
40
+ # : Notification will be sent if `on_warning` or `on_success` is `true`.
41
+ #
42
+ def notify!(status)
43
+ tag = case status
44
+ when :success then '[Backup::Success]'
45
+ when :warning then '[Backup::Warning]'
46
+ when :failure then '[Backup::Failure]'
47
+ end
48
+ send_message(tag)
49
+ end
50
+
51
+ def send_message(message)
52
+ uri = 'https://api.prowlapp.com/publicapi/add'
53
+ data = {
54
+ :application => application,
55
+ :apikey => api_key,
56
+ :event => message,
57
+ :description => "#{ model.label } (#{ model.trigger })"
58
+ }
59
+ options = {
60
+ :headers => { 'Content-Type' => 'application/x-www-form-urlencoded' },
61
+ :body => URI.encode_www_form(data)
62
+ }
63
+ options.merge!(:expects => 200) # raise error if unsuccessful
64
+ Excon.post(uri, options)
65
+ end
66
+
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,80 @@
1
+ # encoding: utf-8
2
+ require 'uri'
3
+
4
+ module Backup
5
+ module Notifier
6
+ class Pushover < Base
7
+
8
+ ##
9
+ # The API User Token
10
+ attr_accessor :user
11
+
12
+ ##
13
+ # The API Application Token
14
+ attr_accessor :token
15
+
16
+ ##
17
+ # The user's device identifier to sent the message directly to,
18
+ # rather than all of the user's devices
19
+ attr_accessor :device
20
+
21
+ ##
22
+ # The message title
23
+ attr_accessor :title
24
+
25
+ ##
26
+ # The priority of the notification
27
+ attr_accessor :priority
28
+
29
+ def initialize(model, &block)
30
+ super
31
+ instance_eval(&block) if block_given?
32
+ end
33
+
34
+ private
35
+
36
+ ##
37
+ # Notify the user of the backup operation results.
38
+ #
39
+ # `status` indicates one of the following:
40
+ #
41
+ # `:success`
42
+ # : The backup completed successfully.
43
+ # : Notification will be sent if `on_success` is `true`.
44
+ #
45
+ # `:warning`
46
+ # : The backup completed successfully, but warnings were logged.
47
+ # : Notification will be sent if `on_warning` or `on_success` is `true`.
48
+ #
49
+ # `:failure`
50
+ # : The backup operation failed.
51
+ # : Notification will be sent if `on_warning` or `on_success` is `true`.
52
+ #
53
+ def notify!(status)
54
+ tag = case status
55
+ when :success then '[Backup::Success]'
56
+ when :failure then '[Backup::Failure]'
57
+ when :warning then '[Backup::Warning]'
58
+ end
59
+ message = "#{ tag } #{ model.label } (#{ model.trigger })"
60
+ send_message(message)
61
+ end
62
+
63
+ def send_message(message)
64
+ uri = 'https://api.pushover.net/1/messages.json'
65
+ data = { :user => user, :token => token, :message => message }
66
+ [:device, :title, :priority].each do |param|
67
+ val = send(param)
68
+ data.merge!(param => val) if val
69
+ end
70
+ options = {
71
+ :headers => { 'Content-Type' => 'application/x-www-form-urlencoded' },
72
+ :body => URI.encode_www_form(data)
73
+ }
74
+ options.merge!(:expects => 200) # raise error if unsuccessful
75
+ Excon.post(uri, options)
76
+ end
77
+
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,149 @@
1
+ # encoding: utf-8
2
+ require 'uri'
3
+ require 'json'
4
+
5
+ module Backup
6
+ module Notifier
7
+ class Slack < Base
8
+
9
+ ##
10
+ # The Team name
11
+ attr_accessor :team
12
+
13
+ ##
14
+ # The Integration Token
15
+ attr_accessor :token
16
+
17
+ ##
18
+ # The channel to send messages to
19
+ attr_accessor :channel
20
+
21
+ ##
22
+ # The username to display along with the notification
23
+ attr_accessor :username
24
+
25
+ ##
26
+ # Array of statuses for which the log file should be attached.
27
+ #
28
+ # Available statuses are: `:success`, `:warning` and `:failure`.
29
+ # Default: [:warning, :failure]
30
+ attr_accessor :send_log_on
31
+
32
+ def initialize(model, &block)
33
+ super
34
+ instance_eval(&block) if block_given?
35
+
36
+ @send_log_on ||= [:warning, :failure]
37
+ end
38
+
39
+ private
40
+
41
+ ##
42
+ # Notify the user of the backup operation results.
43
+ #
44
+ # `status` indicates one of the following:
45
+ #
46
+ # `:success`
47
+ # : The backup completed successfully.
48
+ # : Notification will be sent if `on_success` is `true`.
49
+ #
50
+ # `:warning`
51
+ # : The backup completed successfully, but warnings were logged.
52
+ # : Notification will be sent if `on_warning` or `on_success` is `true`.
53
+ #
54
+ # `:failure`
55
+ # : The backup operation failed.
56
+ # : Notification will be sent if `on_warning` or `on_success` is `true`.
57
+ #
58
+ def notify!(status)
59
+ tag = case status
60
+ when :success then '[Backup::Success]'
61
+ when :failure then '[Backup::Failure]'
62
+ when :warning then '[Backup::Warning]'
63
+ end
64
+ message = "#{ tag } #{ model.label } (#{ model.trigger })"
65
+
66
+ data = { :text => message }
67
+ [:channel, :username].each do |param|
68
+ val = send(param)
69
+ data.merge!(param => val) if val
70
+ end
71
+
72
+ data.merge!(:attachments => [attachment(status)])
73
+
74
+ options = {
75
+ :headers => { 'Content-Type' => 'application/x-www-form-urlencoded' },
76
+ :body => URI.encode_www_form(:payload => JSON.dump(data))
77
+ }
78
+ options.merge!(:expects => 200) # raise error if unsuccessful
79
+ Excon.post(uri, options)
80
+ end
81
+
82
+ def attachment(status)
83
+ {
84
+ :fallback => "#{title(status)} - Job: #{model.label} (#{model.trigger})",
85
+ :text => title(status),
86
+ :color => color(status),
87
+ :fields => [
88
+ {
89
+ :title => "Job",
90
+ :value => "#{model.label} (#{model.trigger})",
91
+ :short => false
92
+ },
93
+ {
94
+ :title => "Started",
95
+ :value => model.started_at,
96
+ :short => true
97
+ },
98
+ {
99
+ :title => "Finished",
100
+ :value => model.finished_at,
101
+ :short => true
102
+ },
103
+ {
104
+ :title => "Duration",
105
+ :value => model.duration,
106
+ :short => true
107
+ },
108
+ {
109
+ :title => "Version",
110
+ :value => "Backup v#{Backup::VERSION}\nRuby: #{RUBY_DESCRIPTION}",
111
+ :short => false
112
+ },
113
+ log_field(status)
114
+ ].compact
115
+ }
116
+ end
117
+
118
+ def log_field(status)
119
+ send_log = send_log_on.include?(status)
120
+
121
+ return {
122
+ :title => "Detailed Backup Log",
123
+ :value => Logger.messages.map(&:formatted_lines).flatten.join("\n"),
124
+ :short => false,
125
+ } if send_log
126
+ end
127
+
128
+ def color(status)
129
+ case status
130
+ when :success then 'good'
131
+ when :failure then 'danger'
132
+ when :warning then 'warning'
133
+ end
134
+ end
135
+
136
+ def title(status)
137
+ case status
138
+ when :success then 'Backup Completed Successfully!'
139
+ when :failure then 'Backup Failed!'
140
+ when :warning then 'Backup Completed Successfully (with Warnings)!'
141
+ end
142
+ end
143
+
144
+ def uri
145
+ @uri ||= "https://#{team}.slack.com/services/hooks/incoming-webhook?token=#{token}"
146
+ end
147
+ end
148
+ end
149
+ end
@@ -0,0 +1,65 @@
1
+ # encoding: utf-8
2
+ require 'twitter'
3
+
4
+ module Backup
5
+ module Notifier
6
+ class Twitter < Base
7
+
8
+ ##
9
+ # Twitter consumer key credentials
10
+ attr_accessor :consumer_key, :consumer_secret
11
+
12
+ ##
13
+ # OAuth credentials
14
+ attr_accessor :oauth_token, :oauth_token_secret
15
+
16
+ def initialize(model, &block)
17
+ super
18
+ instance_eval(&block) if block_given?
19
+ end
20
+
21
+ private
22
+
23
+ ##
24
+ # Notify the user of the backup operation results.
25
+ #
26
+ # `status` indicates one of the following:
27
+ #
28
+ # `:success`
29
+ # : The backup completed successfully.
30
+ # : Notification will be sent if `on_success` is `true`.
31
+ #
32
+ # `:warning`
33
+ # : The backup completed successfully, but warnings were logged.
34
+ # : Notification will be sent if `on_warning` or `on_success` is `true`.
35
+ #
36
+ # `:failure`
37
+ # : The backup operation failed.
38
+ # : Notification will be sent if `on_warning` or `on_success` is `true`.
39
+ #
40
+ def notify!(status)
41
+ tag = case status
42
+ when :success then '[Backup::Success]'
43
+ when :warning then '[Backup::Warning]'
44
+ when :failure then '[Backup::Failure]'
45
+ end
46
+ message = "#{ tag } #{ model.label } (#{ model.trigger }) (@ #{ model.time })"
47
+ send_message(message)
48
+ end
49
+
50
+ # Twitter::Client will raise an error if unsuccessful.
51
+ def send_message(message)
52
+ ::Twitter.configure do |config|
53
+ config.consumer_key = @consumer_key
54
+ config.consumer_secret = @consumer_secret
55
+ config.oauth_token = @oauth_token
56
+ config.oauth_token_secret = @oauth_token_secret
57
+ end
58
+
59
+ client = ::Twitter::Client.new
60
+ client.update(message)
61
+ end
62
+
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,51 @@
1
+ # encoding: utf-8
2
+
3
+ module Backup
4
+ class Package
5
+
6
+ ##
7
+ # The time when the backup initiated (in format: 2011.02.20.03.29.59)
8
+ attr_accessor :time
9
+
10
+ ##
11
+ # The trigger which initiated the backup process
12
+ attr_reader :trigger
13
+
14
+ ##
15
+ # Extension for the final archive file(s)
16
+ attr_accessor :extension
17
+
18
+ ##
19
+ # Set by the Splitter if the final archive was "chunked"
20
+ attr_accessor :chunk_suffixes
21
+
22
+ ##
23
+ # If true, the Cycler will not attempt to remove the package when Cycling.
24
+ attr_accessor :no_cycle
25
+
26
+ ##
27
+ # The version of Backup used to create the package
28
+ attr_reader :version
29
+
30
+ def initialize(model)
31
+ @trigger = model.trigger
32
+ @extension = 'tar'
33
+ @chunk_suffixes = Array.new
34
+ @no_cycle = false
35
+ @version = VERSION
36
+ end
37
+
38
+ def filenames
39
+ if chunk_suffixes.empty?
40
+ [basename]
41
+ else
42
+ chunk_suffixes.map {|suffix| "#{ basename }-#{ suffix }" }
43
+ end
44
+ end
45
+
46
+ def basename
47
+ "#{ trigger }.#{ extension }"
48
+ end
49
+
50
+ end
51
+ end