capistrano-ops 0.2.2 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 686aab7630f72e2ca576bc58f02862bf8b5762510ff40f2ce604be0d1ada88bd
4
- data.tar.gz: f875a5b4c61817a51f7997595a0f68fa4f83e6fccfa0613f089918ff28dd568d
3
+ metadata.gz: 48c373221e575d786df6abaf731ae417311c95584c1ae9db507b2f509b83a9f4
4
+ data.tar.gz: 5aa7c63a62cc0d3f9dd8ac8af6f0eab4b16b8d0ac43f121961b5a1510757ddc5
5
5
  SHA512:
6
- metadata.gz: 9c8a40071b97244aebb277e4aaeb97530852260fe5e2d0f15e494b251e39e19fc3842bf37bcc5e21afaa81b4acb2059e142b6b869c3d22dea7a725adc1570ff6
7
- data.tar.gz: 31db42f2591646789b7ce809e3bc7fd3ea5a9d4ee6b6fd5466d5777fe62d085716b6b73bb9f92bd4503494c58da48f33791223ca4adf0ec27e2061146f157587
6
+ metadata.gz: 11e060e8ed7888ffb2459a16b0482bae06d9ac7818d965a976345da0e06ab608948a5c46ba31e39c3989e240f02b5fd03ee305ef7e1c2ffc0ab4c15c0d453ca4
7
+ data.tar.gz: afc62c529fe831ef17d8f32bb0f89a20687c031472e49b433baf1be7a9a993ce6bbac468a9ec5b0b37e982ee266709faac3d74e5d61985d3ef33e43ebc003b7f
data/README.md CHANGED
@@ -9,6 +9,9 @@ Library of useful scripts for DevOps using capistrano with rails.
9
9
  ```ruby
10
10
  'capistrano', '~> 3.0'
11
11
  'whenever'
12
+ 'capistrano-figaro-yml'
13
+
14
+ # hint: if you use other aws-sdk gems, its possible that you have to update them too
12
15
  ```
13
16
 
14
17
  ## Installation
@@ -69,17 +72,23 @@ production:
69
72
 
70
73
  ### Optional Settings for backup task
71
74
 
72
- | env | description | type/options |
73
- | ------------------ | ---------------------------------------------------------------------- | :----------------------------------------------------------------: |
74
- | NUMBER_OF_BACKUPS | number of backups to keep (default: 1) | `number` |
75
- | BACKUPS_ENABLED | enable/disable backup task (default: Rails.env == 'production') | `boolean` |
76
- | DEFAULT_URL | notification message title (default: "#{database} Backup") | `string` |
77
- | NOTIFICATION_TYPE | for notification (default: nil) | `string` (`webhook`/`slack`) |
78
- | NOTIFICATION_LEVEL | for notification (default: nil) | `string` (`info`/`error`) |
79
- | SLACK_SECRET | for slack integration | `string` (e.g. `xoxb-1234567890-1234567890-1234567890-1234567890`) |
80
- | SLACK_CHANNEL | for slack integration | `string` (e.g. `C234567890`) |
81
- | WEBHOOK_URL | Webhook server to send message | e.g `http://example.com` |
82
- | WEBHOOK_SECRET | Secret to send with uses md5-hmac hexdigest in header`x-hub-signature` | --- |
75
+ | env | description | type/options |
76
+ | ------------------ | ------------------------------------------------------------------------- | :----------------------------------------------------------------: |
77
+ | NUMBER_OF_BACKUPS | number of backups to keep (default: 1) | `number` |
78
+ | BACKUPS_ENABLED | enable/disable backup task (default: Rails.env == 'production') | `boolean` |
79
+ | DEFAULT_URL | notification message title (default: "#{database} Backup") | `string` |
80
+ | NOTIFICATION_TYPE | for notification (default: nil) | `string` (`webhook`/`slack`) |
81
+ | NOTIFICATION_LEVEL | for notification (default: nil) | `string` (`info`/`error`) |
82
+ | SLACK_SECRET | for slack integration | `string` (e.g. `xoxb-1234567890-1234567890-1234567890-1234567890`) |
83
+ | SLACK_CHANNEL | for slack integration | `string` (e.g. `C234567890`) |
84
+ | WEBHOOK_URL | Webhook server to send message | e.g `http://example.com` |
85
+ | WEBHOOK_SECRET | Secret to send with uses md5-hmac hexdigest in header`x-hub-signature` | --- |
86
+ | BACKUP_PROVIDER | Backup provider (default: nil) | `string` (`s3`) |
87
+ | S3_BACKUP_BUCKET | S3 bucket name for backups | `string` |
88
+ | S3_BACKUP_REGION | S3 region for backups | `string` |
89
+ | S3_BACKUP_KEY | S3 access key for backups | `string` |
90
+ | S3_BACKUP_SECRET | S3 secret key for backups | `string` |
91
+ | S3_BACKUP_ENDPOINT | S3 endpoint for backups (optional, used for other S3 compatible services) | `string` |
83
92
 
84
93
  ### use with whenever/capistrano
85
94
 
@@ -23,7 +23,7 @@ Gem::Specification.new do |s|
23
23
 
24
24
  s.add_dependency 'rails'
25
25
  s.add_dependency 'nokogiri'
26
-
26
+ s.add_dependency 'aws-sdk-s3', '~> 1.128'
27
27
  s.add_development_dependency 'bundler', '~> 2.4.12'
28
28
  s.add_development_dependency 'rake', '~> 10.0'
29
29
  end
@@ -0,0 +1,38 @@
1
+ module Backup
2
+ class Api
3
+ attr_accessor :backup_provider, :provider_config
4
+
5
+ def initialize(provider: ENV['BACKUP_PROVIDER'], provider_config: {})
6
+ self.backup_provider = provider
7
+ self.provider_config = provider_config
8
+ end
9
+
10
+ def upload(backup_file, filename)
11
+ case backup_provider
12
+ when 's3'
13
+ s3 = Backup::S3.new(**provider_config)
14
+ s3.upload(backup_file, filename)
15
+ when 'scp'
16
+ p "SCP backup not implemented yet"
17
+ when 'rsync'
18
+ p "Rsync backup not implemented yet"
19
+ else
20
+ raise Backup::Error, "Backup provider not configured"
21
+ end
22
+ end
23
+
24
+ def remove_old_backups(basename,keep)
25
+ case backup_provider
26
+ when 's3'
27
+ s3 = Backup::S3.new(**provider_config)
28
+ s3.remove_old_backups(basename,keep: keep)
29
+ when 'scp'
30
+ p "SCP backup not implemented yet"
31
+ when 'rsync'
32
+ p "Rsync backup not implemented yet"
33
+ else
34
+ raise Backup::Error, "Backup provider not configured"
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,49 @@
1
+ module Backup
2
+ require 'aws-sdk-s3'
3
+ class S3
4
+ attr_accessor :endpoint, :region, :access_key_id, :secret_access_key, :s3_client
5
+
6
+ def initialize( endpoint: ENV['S3_BACKUP_ENDPOINT'], region: ENV['S3_BACKUP_REGION'], access_key_id: ENV['S3_BACKUP_KEY'], secret_access_key: ENV['S3_BACKUP_SECRET'])
7
+ self.endpoint = endpoint
8
+ self.region = region
9
+ self.access_key_id = access_key_id
10
+ self.secret_access_key = secret_access_key
11
+ config = {
12
+ region: region,
13
+ access_key_id: access_key_id,
14
+ secret_access_key: secret_access_key
15
+ }
16
+ config[:endpoint] = endpoint unless endpoint.nil?
17
+ self.s3_client = Aws::S3::Client.new(config)
18
+ end
19
+
20
+ def upload(backup_file, key)
21
+ begin
22
+ s3_client.put_object(
23
+ bucket: ENV['S3_BACKUP_BUCKET'],
24
+ key: key,
25
+ body: File.open(backup_file)
26
+ )
27
+ rescue => e
28
+ puts "Error uploading backup to S3: #{e.message}"
29
+ raise e
30
+ end
31
+ "File uploaded to S3"
32
+ end
33
+
34
+ def remove_old_backups(basename, keep: 5)
35
+ bucket = ENV['S3_BACKUP_BUCKET']
36
+ all_items = s3_client.list_objects_v2(bucket:bucket, prefix: basename).contents
37
+ count = all_items.count
38
+ if count <= keep
39
+ p 'Nothing to remove'
40
+ return
41
+ end
42
+ items = all_items.sort_by(&:last_modified).reverse.slice(keep..-1).map(&:key)
43
+ items.each do |item|
44
+ p "Removing #{item} from S3"
45
+ s3_client.delete_object(bucket: bucket, key: item)
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,7 @@
1
+ require 'capistrano/ops/backup/api'
2
+ require 'capistrano/ops/backup/s3'
3
+
4
+
5
+ module Backup
6
+ class Error < StandardError; end
7
+ end
@@ -7,13 +7,13 @@ module Notification
7
7
  self.notification_level = notification_level || 'error'
8
8
  end
9
9
 
10
- def send_backup_notification(result, date, database, backup_path)
10
+ def send_backup_notification(result, title, content)
11
11
  return if notification_type.nil?
12
12
  case notification_type
13
13
  when 'slack'
14
- Slack.new.backup_notification(result, date, database, backup_path, notification_level)
14
+ Slack.new.backup_notification(result, title, content, notification_level)
15
15
  when 'webhook'
16
- Webhook.new.backup_notification(result, date, database, backup_path, notification_level)
16
+ Webhook.new.backup_notification(result, title, content, notification_level)
17
17
  end
18
18
  end
19
19
 
@@ -23,15 +23,14 @@ module Notification
23
23
  puts response.body
24
24
  end
25
25
 
26
- def backup_notification(result, date, database, backup_path, notification_level)
26
+ def backup_notification(result, title, content, notification_level)
27
27
  return if @slack_secret.nil? || @slack_channel.nil?
28
28
  return if notification_level == 'error' && result
29
29
  uri = URI.parse("#{@slack_base_url}chat.postMessage")
30
30
  http = Net::HTTP.new(uri.host, uri.port)
31
31
  http.use_ssl = true
32
32
  request = Net::HTTP::Post.new(uri.request_uri, initHeader = {'Content-Type' =>'application/json', 'Authorization' => 'Bearer ' + @slack_secret})
33
- message_one = "Backup of #{database} successfully finished at #{Time.now}"
34
- message_two = "Backup path:\`#{backup_path}/#{database}_#{date}.dump\`"
33
+
35
34
  data = {
36
35
  channel: @slack_channel,
37
36
  blocks: [
@@ -39,7 +38,7 @@ module Notification
39
38
  type: 'header',
40
39
  text: {
41
40
  type: 'plain_text',
42
- text: ENV['DEFAULT_URL'] || "#{database} Backup",
41
+ text: title || "#{Rails.env} Message",
43
42
  emoji: true
44
43
  }
45
44
  },
@@ -47,7 +46,7 @@ module Notification
47
46
  type: 'section',
48
47
  text: {
49
48
  type: 'mrkdwn',
50
- text: result ? "#{message_one}\n#{message_two}" : "Backup of #{database} failed at #{Time.now}"
49
+ text: content || 'No content'
51
50
  }
52
51
  }
53
52
  ]
@@ -2,38 +2,74 @@
2
2
 
3
3
  # rubocop:disable Metrics/BlockLength
4
4
  namespace :pg do
5
- default_backup_path = Rails.env.development? ? 'tmp/backups' : '../../shared/backups'
6
- database = Rails.configuration.database_configuration[Rails.env]['database']
7
- username = Rails.configuration.database_configuration[Rails.env]['username']
8
- password = Rails.configuration.database_configuration[Rails.env]['password']
9
- hostname = Rails.configuration.database_configuration[Rails.env]['host']
10
- portnumber = Rails.configuration.database_configuration[Rails.env]['port']
11
- backup_path = Rails.root.join(default_backup_path).to_s
12
- backups_enabled = Rails.env.production? || ENV['BACKUPS_ENABLED'] == 'true'
13
5
 
6
+ @database = Rails.configuration.database_configuration[Rails.env]['database']
7
+ @username = Rails.configuration.database_configuration[Rails.env]['username']
8
+ @password = Rails.configuration.database_configuration[Rails.env]['password']
9
+ @hostname = Rails.configuration.database_configuration[Rails.env]['host']
10
+ @portnumber = Rails.configuration.database_configuration[Rails.env]['port']
11
+ @backup_path = Rails.root.join(Rails.env.development? ? 'tmp/backups' : '../../shared/backups').to_s
12
+ backups_enabled = Rails.env.production? || ENV['BACKUPS_ENABLED'] == 'true'
13
+
14
14
  task :dump do
15
- api = Notification::Api.new
16
- date = Time.now.to_i
17
- user = username.present? ? " -U #{username}" : ''
18
- host = hostname.present? ? " -h #{hostname}" : ''
19
- port = portnumber.present? ? " -p #{portnumber}" : ''
20
- # rubocop:disable Layout/LineLength
21
- dump_cmd = "export PGPASSWORD='#{password}' && cd #{backup_path} && pg_dump -Fc -d #{database}#{user}#{host}#{port} > #{database}_#{date}.dump"
22
- # rubocop:enable Layout/LineLength
23
- if backups_enabled
24
- system "mkdir -p #{backup_path}" unless Dir.exist?(backup_path)
25
- result = system(dump_cmd)
26
- api.send_backup_notification(result, date, database, backup_path)
27
- # Notification::Slack.new.backup_notification(result, date, database, backup_path)
15
+ unless backups_enabled
16
+ p 'dump: Backups are disabled'
17
+ exit(0)
18
+ end
19
+
20
+ notification = Notification::Api.new
21
+ commandlist = dump_cmd
22
+
23
+ system "mkdir -p #{@backup_path}" unless Dir.exist?(@backup_path)
24
+
25
+ result = system(commandlist.join(' && '))
26
+
27
+ if ENV['BACKUP_PROVIDER'].present? && result
28
+ p "Uploading #{@filename} to #{ENV['BACKUP_PROVIDER']}..."
29
+ provider = Backup::Api.new
30
+ begin
31
+ provider.upload("#{@backup_path}/#{@filename}", "#{@filename}")
32
+ p "#{@filename} uploaded to #{ENV['BACKUP_PROVIDER']}"
33
+ rescue StandardError => e
34
+ p "#{@filename} upload failed: #{e.message}"
35
+ end
28
36
  end
29
- if backups_enabled
30
- # rubocop:disable Layout/LineLength
31
- p result ? "Backup created: #{backup_path}/#{database}_#{date}.dump" : "Backup failed, created empty file at #{backup_path}/#{database}_#{date}.dump"
32
- system "rm #{backup_path}/#{database}_#{date}.dump" unless result
33
- # rubocop:enable Layout/LineLength
37
+ notification.send_backup_notification(result,title,content(result))
38
+ p result ? "Backup created: #{@backup_path}/#{@filename}" : "Backup failed removing dump file"
39
+ system "rm #{@backup_path}/#{@filename}" unless result
40
+
41
+ end
42
+
43
+ def title
44
+ ENV['DEFAULT_URL'] || "#{Rails.env} Backup"
45
+ end
46
+
47
+ def content(result)
48
+ messages = []
49
+ if result
50
+ messages << "Backup of #{@database} successfully finished at #{Time.now}"
51
+ messages << "Backup path:\`#{@backup_path}/#{@filename}\`"
34
52
  else
35
- p 'dump: Backups are disabled'
53
+ messages << "Backup of #{@database} failed at #{Time.now}"
36
54
  end
55
+ messages.join("\n")
37
56
  end
57
+
58
+ def dump_cmd
59
+ date = Time.now.to_i
60
+ options = []
61
+ options << " -d #{@database}" if @database.present?
62
+ options << " -U #{@username}" if @username.present?
63
+ options << " -h #{@hostname}" if @hostname.present?
64
+ options << " -p #{@portnumber}" if @portnumber.present?
65
+
66
+ @filename = "#{@database}_#{date}.dump"
67
+
68
+ commandlist = []
69
+ commandlist << "export PGPASSWORD='#{@password}'"
70
+ commandlist << "cd #{@backup_path}"
71
+ commandlist << "pg_dump -Fc #{options.join('')} > #{@filename}"
72
+ end
73
+
38
74
  end
39
75
  # rubocop:enable Metrics/BlockLength
@@ -1,19 +1,38 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  namespace :pg do
4
- default_backup_path = Rails.env.development? ? 'tmp/backups' : '../../shared/backups'
5
- database = Rails.configuration.database_configuration[Rails.env]['database']
6
-
7
- backup_path = Rails.root.join(default_backup_path).to_s
4
+ @backup_path = Rails.root.join(Rails.env.development? ? 'tmp/backups' : '../../shared/backups').to_s
5
+ @database = Rails.configuration.database_configuration[Rails.env]['database']
6
+ @total_backups_no = (ENV['NUMBER_OF_BACKUPS'] || 7).to_i
8
7
  backups_enabled = Rails.env.production? || ENV['BACKUPS_ENABLED'] == 'true'
9
8
 
10
9
  task :remove_old_dumps do
11
- bash_regex = "'#{database}.{0,}\.dump'"
12
- total_backups_no = ENV['NUMBER_OF_BACKUPS'] || 1
13
- # rubocop:disable Layout/LineLength
14
- cmd = "cd #{backup_path} && ls -lt | grep -E -i #{bash_regex} | tail -n +#{total_backups_no.to_i + 1} | awk '{print $9}'|xargs rm -rf"
15
- # rubocop:enable Layout/LineLength
16
- system(cmd) if backups_enabled
17
- p backups_enabled ? 'Old backups removed' : 'remove_old_dumps: Backups are disabled'
10
+ bash_regex = "'#{@database}.{0,}\.dump'"
11
+
12
+ unless backups_enabled && @total_backups_no > 0
13
+ p 'remove_old_dumps: Backups are disabled'
14
+ exit(0)
15
+ end
16
+
17
+
18
+ commandlist = [
19
+ "cd #{@backup_path} && ls -lt ",
20
+ "grep -E -i #{bash_regex} ",
21
+ "tail -n +#{@total_backups_no + 1} ",
22
+ "awk '{print $9}' ",
23
+ "xargs rm -rf"
24
+ ]
25
+
26
+ system(commandlist.join(' | '))
27
+
28
+ if ENV['BACKUP_PROVIDER'].present?
29
+ provider = Backup::Api.new
30
+ begin
31
+ result = provider.remove_old_backups(@database, @total_backups_no)
32
+ rescue StandardError => e
33
+ p "remove_old_dumps failed: #{e.message}"
34
+ end
35
+ p 'remove_old_dumps finished' if result
36
+ end
18
37
  end
19
38
  end
@@ -0,0 +1,71 @@
1
+
2
+ namespace :storage do
3
+ @backup_path = Rails.root.join(Rails.env.development? ? 'tmp/backups' : '../../shared/backups').to_s
4
+ @storage_path = Rails.root.join(Rails.env.development? ? 'storage' : '../../shared/storage').to_s
5
+ backups_enabled = Rails.env.production? || ENV['BACKUPS_ENABLED'] == 'true'
6
+
7
+ desc 'backup storage'
8
+ task :backup do
9
+ unless backups_enabled
10
+ puts 'storage: Backups are disabled'
11
+ exit(0)
12
+ end
13
+ notification = Notification::Api.new
14
+
15
+ date = Time.now.to_i
16
+ @filename = "storage_#{date}.tar.gz"
17
+ FileUtils.mkdir_p(@backup_path) unless Dir.exist?(@backup_path)
18
+
19
+ result = system "tar -zcf #{@backup_path}/#{@filename} -C #{@storage_path} ."
20
+ FileUtils.rm_rf("#{@backup_path}/#{filename}") unless result
21
+
22
+
23
+ filesize = size_str(File.size("#{@backup_path}/#{@filename}"))
24
+
25
+ p result ? "Backup created: #{@backup_path}/#{@filename} (#{filesize})" : "Backup failed removing dump file"
26
+
27
+ if ENV["BACKUP_PROVIDER"].present? && result
28
+ puts "Uploading #{@filename} to #{ENV["BACKUP_PROVIDER"]}..."
29
+ provider = Backup::Api.new
30
+ begin
31
+ provider.upload("#{@backup_path}/#{@filename}", "#{@filename}")
32
+ puts "#{@filename} uploaded to #{ENV["BACKUP_PROVIDER"]}"
33
+ rescue => e
34
+ puts "#{@filename} upload failed: #{e.message}"
35
+ end
36
+ end
37
+ notification.send_backup_notification(result,title,message(result))
38
+
39
+ end
40
+
41
+
42
+
43
+ def title
44
+ ENV['DEFAULT_URL'] || "#{Rails.env} Backup"
45
+ end
46
+
47
+
48
+ def message(result)
49
+ messages = []
50
+ if result
51
+ messages << "Backup of storage folder successfully finished at #{Time.now}"
52
+ messages << "Backup path:\`#{@backup_path}/#{@filename}\`"
53
+ else
54
+ messages << "Backup of storage folder failed at #{Time.now}"
55
+ end
56
+ messages.join("\n")
57
+ end
58
+
59
+ def size_str(size)
60
+ case size
61
+ when 0..1024
62
+ "#{size} B"
63
+ when 1024..1024*1024
64
+ "#{size/1024} KB"
65
+ when 1024*1024..1024*1024*1024
66
+ "#{size/1024/1024} MB"
67
+ when 1024*1024*1024..1024*1024*1024*1024
68
+ "#{size/1024/1024/1024} GB"
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+ require 'rake'
3
+ namespace :storage do
4
+ default_backup_path = Rails.env.development? ? 'tmp/backups' : '../../shared/backups'
5
+ backup_path = Rails.root.join(default_backup_path).to_s
6
+ backups_enabled = Rails.env.production? || ENV['BACKUPS_ENABLED'] == 'true'
7
+
8
+
9
+ desc 'remove old storage backups'
10
+ task :remove_old_backups do
11
+ bash_regex = "'storage_.{0,}\.tar.gz'"
12
+ total_backups_no = (ENV['NUMBER_OF_BACKUPS'] || 7).to_i
13
+
14
+ unless backups_enabled && total_backups_no.to_i > 0
15
+ p 'remove_old_backups: Backups are disabled'
16
+ exit(0)
17
+ end
18
+
19
+
20
+ commandlist = [
21
+ "cd #{backup_path} && ls -lt ",
22
+ "grep -E -i #{bash_regex} ",
23
+ "tail -n +#{total_backups_no + 1} ",
24
+ "awk '{print $9}' ",
25
+ "xargs rm -rf"
26
+ ]
27
+
28
+ system(commandlist.join(' | '))
29
+
30
+ if ENV['BACKUP_PROVIDER'].present?
31
+ provider = Backup::Api.new
32
+ begin
33
+ result = provider.remove_old_backups('storage_', total_backups_no)
34
+ rescue StandardError => e
35
+ p "remove_old_backups failed: #{e.message}"
36
+ end
37
+ p 'remove_old_backups finished' if result
38
+ end
39
+
40
+ end
41
+ end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  module Capistrano
3
3
  module Ops
4
- VERSION = '0.2.2'
4
+ VERSION = '0.2.3'
5
5
  end
6
6
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  module Capistrano
4
4
  module Ops
5
+ require 'capistrano/ops/backup'
5
6
  require 'capistrano/ops/notification'
6
7
  require 'capistrano/ops/railtie' if defined?(Rails)
7
8
  require 'capistrano/ops/capistrano' if defined?(Capistrano::VERSION)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: capistrano-ops
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Florian Crusius
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-07-08 00:00:00.000000000 Z
11
+ date: 2023-07-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: aws-sdk-s3
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.128'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.128'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: bundler
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -86,6 +100,9 @@ files:
86
100
  - bin/setup
87
101
  - capistrano-ops.gemspec
88
102
  - lib/capistrano/ops.rb
103
+ - lib/capistrano/ops/backup.rb
104
+ - lib/capistrano/ops/backup/api.rb
105
+ - lib/capistrano/ops/backup/s3.rb
89
106
  - lib/capistrano/ops/capistrano.rb
90
107
  - lib/capistrano/ops/capistrano/v3/tasks/backup.rake
91
108
  - lib/capistrano/ops/capistrano/v3/tasks/figaro_yml.rake
@@ -99,6 +116,8 @@ files:
99
116
  - lib/capistrano/ops/railtie.rb
100
117
  - lib/capistrano/ops/tasks/pg/dump.rake
101
118
  - lib/capistrano/ops/tasks/pg/remove_old_dumps.rake
119
+ - lib/capistrano/ops/tasks/storage/backup.rake
120
+ - lib/capistrano/ops/tasks/storage/remove_old_backups.rake
102
121
  - lib/capistrano/ops/version.rb
103
122
  homepage: https://github.com/zauberware/capistrano-ops
104
123
  licenses:
@@ -122,7 +141,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
122
141
  - !ruby/object:Gem::Version
123
142
  version: '0'
124
143
  requirements: []
125
- rubygems_version: 3.1.6
144
+ rubygems_version: 3.1.2
126
145
  signing_key:
127
146
  specification_version: 4
128
147
  summary: devops tasks for rails applications