ext_backup 5.0.0.beta.2.1

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 (137) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +19 -0
  3. data/README.md +33 -0
  4. data/bin/backup +5 -0
  5. data/bin/docker_test +24 -0
  6. data/lib/backup.rb +140 -0
  7. data/lib/backup/archive.rb +169 -0
  8. data/lib/backup/binder.rb +18 -0
  9. data/lib/backup/cleaner.rb +112 -0
  10. data/lib/backup/cli.rb +370 -0
  11. data/lib/backup/cloud_io/base.rb +38 -0
  12. data/lib/backup/cloud_io/cloud_files.rb +296 -0
  13. data/lib/backup/cloud_io/s3.rb +253 -0
  14. data/lib/backup/compressor/base.rb +32 -0
  15. data/lib/backup/compressor/bzip2.rb +35 -0
  16. data/lib/backup/compressor/custom.rb +49 -0
  17. data/lib/backup/compressor/gzip.rb +73 -0
  18. data/lib/backup/config.rb +128 -0
  19. data/lib/backup/config/dsl.rb +102 -0
  20. data/lib/backup/config/helpers.rb +137 -0
  21. data/lib/backup/database/base.rb +86 -0
  22. data/lib/backup/database/mongodb.rb +186 -0
  23. data/lib/backup/database/mysql.rb +191 -0
  24. data/lib/backup/database/openldap.rb +93 -0
  25. data/lib/backup/database/postgresql.rb +132 -0
  26. data/lib/backup/database/redis.rb +176 -0
  27. data/lib/backup/database/riak.rb +79 -0
  28. data/lib/backup/database/sqlite.rb +55 -0
  29. data/lib/backup/encryptor/base.rb +27 -0
  30. data/lib/backup/encryptor/gpg.rb +737 -0
  31. data/lib/backup/encryptor/open_ssl.rb +74 -0
  32. data/lib/backup/errors.rb +53 -0
  33. data/lib/backup/logger.rb +197 -0
  34. data/lib/backup/logger/console.rb +48 -0
  35. data/lib/backup/logger/fog_adapter.rb +25 -0
  36. data/lib/backup/logger/logfile.rb +131 -0
  37. data/lib/backup/logger/syslog.rb +114 -0
  38. data/lib/backup/model.rb +472 -0
  39. data/lib/backup/notifier/base.rb +126 -0
  40. data/lib/backup/notifier/campfire.rb +61 -0
  41. data/lib/backup/notifier/command.rb +99 -0
  42. data/lib/backup/notifier/datadog.rb +104 -0
  43. data/lib/backup/notifier/flowdock.rb +99 -0
  44. data/lib/backup/notifier/hipchat.rb +116 -0
  45. data/lib/backup/notifier/http_post.rb +114 -0
  46. data/lib/backup/notifier/mail.rb +232 -0
  47. data/lib/backup/notifier/nagios.rb +65 -0
  48. data/lib/backup/notifier/pagerduty.rb +79 -0
  49. data/lib/backup/notifier/prowl.rb +68 -0
  50. data/lib/backup/notifier/pushover.rb +71 -0
  51. data/lib/backup/notifier/ses.rb +123 -0
  52. data/lib/backup/notifier/slack.rb +147 -0
  53. data/lib/backup/notifier/twitter.rb +55 -0
  54. data/lib/backup/notifier/zabbix.rb +60 -0
  55. data/lib/backup/package.rb +51 -0
  56. data/lib/backup/packager.rb +106 -0
  57. data/lib/backup/pipeline.rb +120 -0
  58. data/lib/backup/splitter.rb +73 -0
  59. data/lib/backup/storage/base.rb +66 -0
  60. data/lib/backup/storage/cloud_files.rb +156 -0
  61. data/lib/backup/storage/cycler.rb +70 -0
  62. data/lib/backup/storage/dropbox.rb +206 -0
  63. data/lib/backup/storage/ftp.rb +116 -0
  64. data/lib/backup/storage/local.rb +61 -0
  65. data/lib/backup/storage/qiniu.rb +65 -0
  66. data/lib/backup/storage/rsync.rb +246 -0
  67. data/lib/backup/storage/s3.rb +155 -0
  68. data/lib/backup/storage/scp.rb +65 -0
  69. data/lib/backup/storage/sftp.rb +80 -0
  70. data/lib/backup/syncer/base.rb +67 -0
  71. data/lib/backup/syncer/cloud/base.rb +176 -0
  72. data/lib/backup/syncer/cloud/cloud_files.rb +81 -0
  73. data/lib/backup/syncer/cloud/local_file.rb +97 -0
  74. data/lib/backup/syncer/cloud/s3.rb +109 -0
  75. data/lib/backup/syncer/rsync/base.rb +50 -0
  76. data/lib/backup/syncer/rsync/local.rb +27 -0
  77. data/lib/backup/syncer/rsync/pull.rb +47 -0
  78. data/lib/backup/syncer/rsync/push.rb +201 -0
  79. data/lib/backup/template.rb +41 -0
  80. data/lib/backup/utilities.rb +233 -0
  81. data/lib/backup/version.rb +3 -0
  82. data/lib/ext_backup.rb +5 -0
  83. data/lib/ext_backup/version.rb +5 -0
  84. data/templates/cli/archive +28 -0
  85. data/templates/cli/compressor/bzip2 +4 -0
  86. data/templates/cli/compressor/custom +7 -0
  87. data/templates/cli/compressor/gzip +4 -0
  88. data/templates/cli/config +123 -0
  89. data/templates/cli/databases/mongodb +15 -0
  90. data/templates/cli/databases/mysql +18 -0
  91. data/templates/cli/databases/openldap +24 -0
  92. data/templates/cli/databases/postgresql +16 -0
  93. data/templates/cli/databases/redis +16 -0
  94. data/templates/cli/databases/riak +17 -0
  95. data/templates/cli/databases/sqlite +11 -0
  96. data/templates/cli/encryptor/gpg +27 -0
  97. data/templates/cli/encryptor/openssl +9 -0
  98. data/templates/cli/model +26 -0
  99. data/templates/cli/notifier/zabbix +15 -0
  100. data/templates/cli/notifiers/campfire +12 -0
  101. data/templates/cli/notifiers/command +32 -0
  102. data/templates/cli/notifiers/datadog +57 -0
  103. data/templates/cli/notifiers/flowdock +16 -0
  104. data/templates/cli/notifiers/hipchat +16 -0
  105. data/templates/cli/notifiers/http_post +32 -0
  106. data/templates/cli/notifiers/mail +24 -0
  107. data/templates/cli/notifiers/nagios +13 -0
  108. data/templates/cli/notifiers/pagerduty +12 -0
  109. data/templates/cli/notifiers/prowl +11 -0
  110. data/templates/cli/notifiers/pushover +11 -0
  111. data/templates/cli/notifiers/ses +15 -0
  112. data/templates/cli/notifiers/slack +22 -0
  113. data/templates/cli/notifiers/twitter +13 -0
  114. data/templates/cli/splitter +7 -0
  115. data/templates/cli/storages/cloud_files +11 -0
  116. data/templates/cli/storages/dropbox +20 -0
  117. data/templates/cli/storages/ftp +13 -0
  118. data/templates/cli/storages/local +8 -0
  119. data/templates/cli/storages/qiniu +12 -0
  120. data/templates/cli/storages/rsync +17 -0
  121. data/templates/cli/storages/s3 +16 -0
  122. data/templates/cli/storages/scp +15 -0
  123. data/templates/cli/storages/sftp +15 -0
  124. data/templates/cli/syncers/cloud_files +22 -0
  125. data/templates/cli/syncers/rsync_local +20 -0
  126. data/templates/cli/syncers/rsync_pull +28 -0
  127. data/templates/cli/syncers/rsync_push +28 -0
  128. data/templates/cli/syncers/s3 +27 -0
  129. data/templates/general/links +3 -0
  130. data/templates/general/version.erb +2 -0
  131. data/templates/notifier/mail/failure.erb +16 -0
  132. data/templates/notifier/mail/success.erb +16 -0
  133. data/templates/notifier/mail/warning.erb +16 -0
  134. data/templates/storage/dropbox/authorization_url.erb +6 -0
  135. data/templates/storage/dropbox/authorized.erb +4 -0
  136. data/templates/storage/dropbox/cache_file_written.erb +10 -0
  137. metadata +506 -0
@@ -0,0 +1,65 @@
1
+ module Backup
2
+ module Notifier
3
+ class Nagios < Base
4
+ ##
5
+ # Host of Nagios server to notify on backup completion.
6
+ attr_accessor :nagios_host
7
+
8
+ ##
9
+ # Port of Nagios server to notify on backup completion.
10
+ attr_accessor :nagios_port
11
+
12
+ ##
13
+ # Nagios nrpe configuration file.
14
+ attr_accessor :send_nsca_cfg
15
+
16
+ ##
17
+ # Name of the Nagios service for the backup check.
18
+ attr_accessor :service_name
19
+
20
+ ##
21
+ # Host name in Nagios for the backup check.
22
+ attr_accessor :service_host
23
+
24
+ def initialize(model, &block)
25
+ super
26
+ instance_eval(&block) if block_given?
27
+
28
+ @nagios_host ||= Config.hostname
29
+ @nagios_port ||= 5667
30
+ @send_nsca_cfg ||= "/etc/nagios/send_nsca.cfg"
31
+ @service_name ||= "Backup #{model.trigger}"
32
+ @service_host ||= Config.hostname
33
+ end
34
+
35
+ private
36
+
37
+ ##
38
+ # Notify the user of the backup operation results.
39
+ #
40
+ # `status` indicates one of the following:
41
+ #
42
+ # `:success`
43
+ # : The backup completed successfully.
44
+ # : Notification will be sent if `on_success` is `true`.
45
+ #
46
+ # `:warning`
47
+ # : The backup completed successfully, but warnings were logged.
48
+ # : Notification will be sent if `on_warning` or `on_success` is `true`.
49
+ #
50
+ # `:failure`
51
+ # : The backup operation failed.
52
+ # : Notification will be sent if `on_warning` or `on_success` is `true`.
53
+ #
54
+ def notify!(status)
55
+ send_message(message.call(model, status: status_data_for(status)))
56
+ end
57
+
58
+ def send_message(message)
59
+ cmd = "#{utility(:send_nsca)} -H '#{nagios_host}' -p '#{nagios_port}' -c '#{send_nsca_cfg}'"
60
+ msg = [service_host, service_name, model.exit_status, message].join("\t")
61
+ run("echo '#{msg}' | #{cmd}")
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,79 @@
1
+ require "pagerduty"
2
+
3
+ module Backup
4
+ module Notifier
5
+ class PagerDuty < Base
6
+ ##
7
+ # PagerDuty Service API Key. Should be a 32 character hex string.
8
+ attr_accessor :service_key
9
+
10
+ ##
11
+ # Determines if a backup with a warning should resolve an incident rather
12
+ # than trigger one.
13
+ #
14
+ # Defaults to false.
15
+ attr_accessor :resolve_on_warning
16
+
17
+ def initialize(mode, &block)
18
+ super
19
+ instance_eval(&block) if block_given?
20
+
21
+ @resolve_on_warning ||= false
22
+ end
23
+
24
+ private
25
+
26
+ ##
27
+ # Trigger or resolve a PagerDuty incident for this model
28
+ #
29
+ # `status` indicates one of the following:
30
+ #
31
+ # `:success`
32
+ # : The backup completed successfully.
33
+ # : The incident will be resolved if `on_success` is `true`.
34
+ #
35
+ # `:warning`
36
+ # : The backup completed successfully, but warnings were logged.
37
+ # : An incident will be triggered if `on_warning` or `on_success` is `true`.
38
+ #
39
+ # `:failure`
40
+ # : The backup operation failed.
41
+ # : An incident will be triggered if `on_failure` is `true`.
42
+ #
43
+ def notify!(status)
44
+ incident_description = "Backup - #{model.label}"
45
+ incident_key = "backup/#{model.trigger}"
46
+ incident_details = {
47
+ incident_key: incident_key,
48
+ details: {
49
+ trigger: model.trigger,
50
+ label: model.label,
51
+ started_at: model.started_at,
52
+ finished_at: model.finished_at,
53
+ duration: model.duration,
54
+ status: status,
55
+ exception: model.exception
56
+ }
57
+ }
58
+
59
+ event_type = case status
60
+ when :success then :resolve
61
+ when :warning then resolve_on_warning ? :resolve : :trigger
62
+ when :failure then :trigger
63
+ end
64
+
65
+ case event_type
66
+ when :trigger
67
+ pagerduty.trigger(incident_description, incident_details)
68
+ when :resolve
69
+ incident = pagerduty.get_incident(incident_key)
70
+ incident.resolve(incident_description, incident_details)
71
+ end
72
+ end
73
+
74
+ def pagerduty
75
+ @pagerduty ||= Pagerduty.new(service_key)
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,68 @@
1
+ require "uri"
2
+
3
+ module Backup
4
+ module Notifier
5
+ class Prowl < Base
6
+ ##
7
+ # Application name
8
+ # Tell something like your server name. Example: "Server1 Backup"
9
+ attr_accessor :application
10
+
11
+ ##
12
+ # API-Key
13
+ # Create a Prowl account and request an API key on prowlapp.com.
14
+ attr_accessor :api_key
15
+
16
+ def initialize(model, &block)
17
+ @message =
18
+ lambda do |m, _|
19
+ "#{m.label} (#{m.trigger})"
20
+ end
21
+
22
+ super
23
+
24
+ instance_eval(&block) if block_given?
25
+ end
26
+
27
+ private
28
+
29
+ ##
30
+ # Notify the user of the backup operation results.
31
+ #
32
+ # `status` indicates one of the following:
33
+ #
34
+ # `:success`
35
+ # : The backup completed successfully.
36
+ # : Notification will be sent if `on_success` is `true`.
37
+ #
38
+ # `:warning`
39
+ # : The backup completed successfully, but warnings were logged.
40
+ # : Notification will be sent if `on_warning` or `on_success` is `true`.
41
+ #
42
+ # `:failure`
43
+ # : The backup operation failed.
44
+ # : Notification will be sent if `on_warning` or `on_success` is `true`.
45
+ #
46
+ def notify!(status)
47
+ send_message(status)
48
+ end
49
+
50
+ def send_message(status)
51
+ uri = "https://api.prowlapp.com/publicapi/add"
52
+ status_data = status_data_for(status)
53
+ data = {
54
+ application: application,
55
+ apikey: api_key,
56
+ event: status_data[:message],
57
+ description: message.call(model, status: status_data)
58
+ }
59
+ options = {
60
+ headers: { "Content-Type" => "application/x-www-form-urlencoded" },
61
+ body: URI.encode_www_form(data)
62
+ }
63
+ options[:expects] = 200 # raise error if unsuccessful
64
+ Excon.post(uri, options)
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,71 @@
1
+ require "uri"
2
+
3
+ module Backup
4
+ module Notifier
5
+ class Pushover < Base
6
+ ##
7
+ # The API User Token
8
+ attr_accessor :user
9
+
10
+ ##
11
+ # The API Application Token
12
+ attr_accessor :token
13
+
14
+ ##
15
+ # The user's device identifier to sent the message directly to,
16
+ # rather than all of the user's devices
17
+ attr_accessor :device
18
+
19
+ ##
20
+ # The message title
21
+ attr_accessor :title
22
+
23
+ ##
24
+ # The priority of the notification
25
+ attr_accessor :priority
26
+
27
+ def initialize(model, &block)
28
+ super
29
+ instance_eval(&block) if block_given?
30
+ end
31
+
32
+ private
33
+
34
+ ##
35
+ # Notify the user of the backup operation results.
36
+ #
37
+ # `status` indicates one of the following:
38
+ #
39
+ # `:success`
40
+ # : The backup completed successfully.
41
+ # : Notification will be sent if `on_success` is `true`.
42
+ #
43
+ # `:warning`
44
+ # : The backup completed successfully, but warnings were logged.
45
+ # : Notification will be sent if `on_warning` or `on_success` is `true`.
46
+ #
47
+ # `:failure`
48
+ # : The backup operation failed.
49
+ # : Notification will be sent if `on_warning` or `on_success` is `true`.
50
+ #
51
+ def notify!(status)
52
+ send_message(message.call(model, status: status_data_for(status)))
53
+ end
54
+
55
+ def send_message(message)
56
+ uri = "https://api.pushover.net/1/messages.json"
57
+ data = { user: user, token: token, message: message }
58
+ [:device, :title, :priority].each do |param|
59
+ val = send(param)
60
+ data.merge!(param => val) if val
61
+ end
62
+ options = {
63
+ headers: { "Content-Type" => "application/x-www-form-urlencoded" },
64
+ body: URI.encode_www_form(data)
65
+ }
66
+ options[:expects] = 200 # raise error if unsuccessful
67
+ Excon.post(uri, options)
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,123 @@
1
+ require "aws-sdk"
2
+ require "mail"
3
+
4
+ module Backup
5
+ module Notifier
6
+ class Ses < Base
7
+ ##
8
+ # Amazon Simple Email Service (SES) Credentials
9
+ attr_accessor :access_key_id, :secret_access_key, :use_iam_profile
10
+
11
+ ##
12
+ # SES Region
13
+ attr_accessor :region
14
+
15
+ ##
16
+ # Sender Email Address
17
+ attr_accessor :from
18
+
19
+ ##
20
+ # Receiver Email Address
21
+ attr_accessor :to
22
+
23
+ ##
24
+ # CC receiver Email Address
25
+ attr_accessor :cc
26
+
27
+ ##
28
+ # BCC receiver Email Address
29
+ attr_accessor :bcc
30
+
31
+ ##
32
+ # Set reply to email address
33
+ attr_accessor :reply_to
34
+
35
+ def initialize(model, &block)
36
+ super
37
+ instance_eval(&block) if block_given?
38
+
39
+ @region ||= "eu-west-1"
40
+ @send_log_on ||= [:warning, :failure]
41
+ end
42
+
43
+ ##
44
+ # Array of statuses for which the log file should be attached.
45
+ #
46
+ # Available statuses are: `:success`, `:warning` and `:failure`.
47
+ # Default: [:warning, :failure]
48
+ attr_accessor :send_log_on
49
+
50
+ private
51
+
52
+ def client
53
+ credentials = if use_iam_profile
54
+ Aws::InstanceProfileCredentials.new
55
+ else
56
+ Aws::Credentials.new(access_key_id, secret_access_key)
57
+ end
58
+
59
+ Aws::SES::Client.new(
60
+ region: region,
61
+ credentials: credentials
62
+ )
63
+ end
64
+
65
+ ##
66
+ # Notify the user of the backup operation results.
67
+ #
68
+ # `status` indicates one of the following:
69
+ #
70
+ # `:success`
71
+ # : The backup completed successfully.
72
+ # : Notification will be sent if `on_success` is `true`.
73
+ #
74
+ # `:warning`
75
+ # : The backup completed successfully, but warnings were logged.
76
+ # : Notification will be sent, including a copy of the current
77
+ # : backup log, if `on_warning` or `on_success` is `true`.
78
+ #
79
+ # `:failure`
80
+ # : The backup operation failed.
81
+ # : Notification will be sent, including a copy of the current
82
+ # : backup log, if `on_failure` is `true`.
83
+ #
84
+ def notify!(status)
85
+ email = ::Mail.new
86
+ email.to = to
87
+ email.from = from
88
+ email.cc = cc
89
+ email.bcc = bcc
90
+ email.reply_to = reply_to
91
+ email.subject = message.call(model, status: status_data_for(status))
92
+
93
+ # By default, the `mail` gem doesn't include BCC in raw output, which is
94
+ # needed for SES to send to those addresses.
95
+ email[:bcc].include_in_headers = true
96
+
97
+ send_log = send_log_on.include?(status)
98
+ template = Backup::Template.new(model: model, send_log: send_log)
99
+ email.body = template.result(sprintf("notifier/mail/%s.erb", status.to_s))
100
+
101
+ if send_log
102
+ email.convert_to_multipart
103
+ email.attachments["#{model.time}.#{model.trigger}.log"] = {
104
+ mime_type: "text/plain;",
105
+ content: Logger.messages.map(&:formatted_lines).flatten.join("\n")
106
+ }
107
+ end
108
+
109
+ send_opts = {
110
+ raw_message: {
111
+ data: email.to_s
112
+ }
113
+ }
114
+
115
+ if email.respond_to?(:destinations)
116
+ send_opts[:destinations] = email.destinations
117
+ end
118
+
119
+ client.send_raw_email(send_opts)
120
+ end
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,147 @@
1
+ require "uri"
2
+ require "json"
3
+
4
+ module Backup
5
+ module Notifier
6
+ class Slack < Base
7
+ ##
8
+ # The incoming webhook url
9
+ attr_accessor :webhook_url
10
+
11
+ ##
12
+ # The channel to send messages to
13
+ attr_accessor :channel
14
+
15
+ ##
16
+ # The username to display along with the notification
17
+ attr_accessor :username
18
+
19
+ ##
20
+ # The emoji icon to display along with the notification
21
+ #
22
+ # See http://www.emoji-cheat-sheet.com for a list of icons.
23
+ #
24
+ # Default: :floppy_disk:
25
+ attr_accessor :icon_emoji
26
+
27
+ ##
28
+ # Array of statuses for which the log file should be attached.
29
+ #
30
+ # Available statuses are: `:success`, `:warning` and `:failure`.
31
+ # Default: [:warning, :failure]
32
+ attr_accessor :send_log_on
33
+
34
+ def initialize(model, &block)
35
+ super
36
+ instance_eval(&block) if block_given?
37
+
38
+ @send_log_on ||= [:warning, :failure]
39
+ @icon_emoji ||= ":floppy_disk:"
40
+ end
41
+
42
+ private
43
+
44
+ ##
45
+ # Notify the user of the backup operation results.
46
+ #
47
+ # `status` indicates one of the following:
48
+ #
49
+ # `:success`
50
+ # : The backup completed successfully.
51
+ # : Notification will be sent if `on_success` is `true`.
52
+ #
53
+ # `:warning`
54
+ # : The backup completed successfully, but warnings were logged.
55
+ # : Notification will be sent if `on_warning` or `on_success` is `true`.
56
+ #
57
+ # `:failure`
58
+ # : The backup operation failed.
59
+ # : Notification will be sent if `on_warning` or `on_success` is `true`.
60
+ #
61
+ def notify!(status)
62
+ data = {
63
+ text: message.call(model, status: status_data_for(status)),
64
+ attachments: [attachment(status)]
65
+ }
66
+ [:channel, :username, :icon_emoji].each do |param|
67
+ val = send(param)
68
+ data.merge!(param => val) if val
69
+ end
70
+
71
+ options = {
72
+ headers: { "Content-Type" => "application/x-www-form-urlencoded" },
73
+ body: URI.encode_www_form(payload: JSON.dump(data))
74
+ }
75
+ options[:expects] = 200 # raise error if unsuccessful
76
+ Excon.post(uri, options)
77
+ end
78
+
79
+ def attachment(status)
80
+ {
81
+ fallback: "#{title(status)} - Job: #{model.label} (#{model.trigger})",
82
+ text: title(status),
83
+ color: color(status),
84
+ fields: [
85
+ {
86
+ title: "Job",
87
+ value: "#{model.label} (#{model.trigger})",
88
+ short: false
89
+ },
90
+ {
91
+ title: "Started",
92
+ value: model.started_at,
93
+ short: true
94
+ },
95
+ {
96
+ title: "Finished",
97
+ value: model.finished_at,
98
+ short: true
99
+ },
100
+ {
101
+ title: "Duration",
102
+ value: model.duration,
103
+ short: true
104
+ },
105
+ {
106
+ title: "Version",
107
+ value: "Backup v#{Backup::VERSION}\nRuby: #{RUBY_DESCRIPTION}",
108
+ short: false
109
+ },
110
+ log_field(status)
111
+ ].compact
112
+ }
113
+ end
114
+
115
+ def log_field(status)
116
+ send_log = send_log_on.include?(status)
117
+ return unless send_log
118
+
119
+ {
120
+ title: "Detailed Backup Log",
121
+ value: Logger.messages.map(&:formatted_lines).flatten.join("\n"),
122
+ short: false
123
+ }
124
+ end
125
+
126
+ def color(status)
127
+ case status
128
+ when :success then "good"
129
+ when :failure then "danger"
130
+ when :warning then "warning"
131
+ end
132
+ end
133
+
134
+ def title(status)
135
+ case status
136
+ when :success then "Backup Completed Successfully!"
137
+ when :failure then "Backup Failed!"
138
+ when :warning then "Backup Completed Successfully (with Warnings)!"
139
+ end
140
+ end
141
+
142
+ def uri
143
+ @uri ||= webhook_url
144
+ end
145
+ end
146
+ end
147
+ end