Class: PgbackupsS3

Inherits:
Object
  • Object
show all
Includes:
HTTParty
Defined in:
lib/pgbackups_s3.rb,
lib/pgbackups_s3/client.rb,
lib/pgbackups_s3/configuration.rb,
lib/generators/pgbackups_s3/install_generator.rb

Defined Under Namespace

Modules: Generators Classes: Configuration, Railtie

Constant Summary collapse

@@configuration =
nil

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializePgbackupsS3

Returns a new instance of PgbackupsS3.



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/pgbackups_s3/client.rb', line 31

def initialize
  uri = URI.parse(ENV['PGBACKUPS_URL'])
  @host = "#{uri.scheme}://#{uri.host}"
  @host += ":#{uri.port}" if uri.port
  self.class.basic_auth uri.user, uri.password
  @backup_url = ""
  @tmp_file = "./tmp/#{DateTime.now.strftime('%k:%M:%S')}.dump"
  @bucket = PgbackupsS3.configuration.bucket
  @directories = PgbackupsS3.configuration.directories
  @capture_database = PgbackupsS3.configuration.capture_database
  @restore_database = PgbackupsS3.configuration.restore_database
  File.new(@tmp_file, 'w+')

  @s3 = AWS::S3.new(
    access_key_id:  PgbackupsS3.configuration.access_key_id,
    secret_access_key: PgbackupsS3.configuration.secret_access_key
  )
end

Class Method Details

.backupObject



9
10
11
12
13
14
15
16
# File 'lib/pgbackups_s3/client.rb', line 9

def self.backup
  p = new
  p.capture
  p.get_latest_backup
  p.download
  p.send_to_s3
  p.clean
end

.configurationObject



14
15
16
# File 'lib/pgbackups_s3/configuration.rb', line 14

def self.configuration
  @@configuration || configure
end

.configureObject



4
5
6
7
8
9
10
11
12
# File 'lib/pgbackups_s3/configuration.rb', line 4

def self.configure
  @@configuration = Configuration.new

  if block_given?
    yield configuration
  end

  configuration
end

.list_backups(year = nil, month = nil, day = nil) ⇒ Object



18
19
20
21
22
23
24
# File 'lib/pgbackups_s3/client.rb', line 18

def self.list_backups(year=nil, month=nil, day=nil)
  p = new
  year ||= Date.today.year
  month ||= Date.today.month
  day ||= Date.today.day
  p.list_backups(year, month, day)
end

.restore(key) ⇒ Object



26
27
28
29
# File 'lib/pgbackups_s3/client.rb', line 26

def self.restore(key)
  p = new
  p.restore_from(key)
end

.setupObject



4
5
6
7
# File 'lib/pgbackups_s3/client.rb', line 4

def self.setup
  p = new
  p.create_bucket
end

Instance Method Details

#captureObject



59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/pgbackups_s3/client.rb', line 59

def capture
  params = {:from_url => ENV[@capture_database], :from_name => ENV[@capture_database], :to_url => nil, :to_name => 'BACKUP', expire: true}
  backup = self.class.post("#{@host}/client/transfers", query: params)

  print "Wrangling up that postgres\n"

  until backup["finished_at"]
    print '.'
    sleep 1
    backup = self.class.get("#{@host}/client/transfers/#{backup['id']}")
  end

  print "\nYar we got it!\n"
end

#cleanObject



96
97
98
99
# File 'lib/pgbackups_s3/client.rb', line 96

def clean
  print "Removing backup from local server\n"
  File.delete(@tmp_file)
end

#create_bucketObject



50
51
52
53
# File 'lib/pgbackups_s3/client.rb', line 50

def create_bucket
  bucket = @s3.buckets.create(@bucket)
  bucket.acl = :private
end

#downloadObject



74
75
76
77
78
79
80
81
82
83
84
# File 'lib/pgbackups_s3/client.rb', line 74

def download
  print "Downloading that postgres\n"
  File.open(@tmp_file, "wb") do |output|
    streamer = lambda do |chunk, remaining_bytes, total_bytes|
      print '.'
      output.write chunk
    end
    Excon.get(@backup_url, :response_block => streamer)
  end
  print "\nSaved as #{@tmp_file} on local server\n"
end

#get_latest_backupObject



55
56
57
# File 'lib/pgbackups_s3/client.rb', line 55

def get_latest_backup
  @backup_url = self.class.get("#{@host}/client/latest_backup")['public_url']
end

#list_backups(year, month, day) ⇒ Object



101
102
103
104
105
106
107
108
109
# File 'lib/pgbackups_s3/client.rb', line 101

def list_backups(year, month, day)
  prefix = "#{@directories}/#{year}/#{month}/#{day}"
  keys = @s3.buckets[@bucket].objects.with_prefix(prefix).collect(&:key)

  print "Backups for #{month}-#{day}-#{year} ----------------------- \n"
  keys.each do |key|
    print "-- #{key} \n"
  end
end

#restore_from(key) ⇒ Object



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/pgbackups_s3/client.rb', line 111

def restore_from(key)
  print "\n\nWARNING: This will overwrite the production database with restore: #{key}\n"
  print "Type 'Give me my data!' to confirm \n"

  input = gets.chomp

  if input == 'Give me my data!'
    object = @s3.buckets[@bucket].objects.with_prefix(key).first
    object.acl = :public_read
    params = {:to_url => ENV[@restore_database], :to_name => ENV[@restore_database], :from_url => object.public_url, :from_name => "EXTERNAL_BACKUP"}
    backup = self.class.post("#{@host}/client/transfers", query: params)
    sleep 20
    object.acl = :private

    print "Database restore is being run in the background. Check your apps logs for more info"
  else
    print "Not overwriting your data. Phew that was a close one!"
  end
end

#send_to_s3Object



86
87
88
89
90
91
92
93
94
# File 'lib/pgbackups_s3/client.rb', line 86

def send_to_s3
  print "Shipping that sucka to S3\t"
  key = File.basename(@tmp_file)
  object = @s3.buckets[@bucket]
              .objects["#{@directories}/#{Date.today.year}/#{Date.today.month}/#{Date.today.day}/#{key}"]
              .write(:file => @tmp_file)
  object.acl = :private
  puts "Backup uploaded to #{@bucket} bucket."
end