Module: Aptible::CLI::Subcommands::Backup

Included in:
Agent
Defined in:
lib/aptible/cli/subcommands/backup.rb

Class Method Summary collapse

Class Method Details

.included(thor) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/aptible/cli/subcommands/backup.rb', line 5

def self.included(thor)
  thor.class_eval do
    include Helpers::Token
    include Helpers::Database

    desc 'backup:restore BACKUP_ID ' \
         '[--environment ENVIRONMENT_HANDLE] [--handle HANDLE] ' \
         '[--container-size SIZE_MB] [--disk-size SIZE_GB] ' \
         '[--key-arn KEY_ARN]',
         'Restore a backup'
    option :handle, desc: 'a name to use for the new database'
    option :environment, desc: 'a different environment to restore to'
    option :container_size, type: :numeric
    option :size, type: :numeric
    option :disk_size, type: :numeric
    option :key_arn, type: :string
    define_method 'backup:restore' do |backup_id|
      backup = Aptible::Api::Backup.find(backup_id, token: fetch_token)
      raise Thor::Error, "Backup ##{backup_id} not found" if backup.nil?

      handle = options[:handle]
      unless handle
        ts_suffix = backup.created_at.getgm.strftime '%Y-%m-%d-%H-%M-%S'
        handle =
          "#{backup.database_with_deleted.handle}-at-#{ts_suffix}"
      end

       = if options[:environment]
                              ensure_environment(
                                environment: options[:environment]
                              )
                            end

      opts = {
        type: 'restore',
        handle: handle,
        container_size: options[:container_size],
        disk_size: options[:disk_size],
        destination_account: ,
        key_arn: options[:key_arn]
      }.delete_if { |_, v| v.nil? }

      if options[:size]
        m = 'You have used the "--size" option to specify a disk size.'\
            'This abiguous option has been removed.'\
            'Please use the "--disk-size" option, instead.'
        raise Thor::Error, m
      end

      operation = backup.create_operation!(opts)
      CLI.logger.info "Restoring backup into #{handle}"
      attach_to_operation_logs(operation)

       =  || backup.

      database = databases_from_handle(handle, ).first
      render_database(database, )
    end

    desc 'backup:list DB_HANDLE', 'List backups for a database'
    option :environment
    option :max_age,
           default: '1mo',
           desc: 'Limit backups returned (example usage: 1w, 1y, etc.)'
    define_method 'backup:list' do |handle|
      age = ChronicDuration.parse(options[:max_age])
      raise Thor::Error, "Invalid age: #{options[:max_age]}" if age.nil?
      min_created_at = Time.now - age

      database = ensure_database(options.merge(db: handle))

      Formatter.render(Renderer.current) do |root|
        root.keyed_list('description') do |node|
          database.each_backup do |backup|
            if backup.created_at < min_created_at && !backup.copied_from
              break
            end
            node.object do |n|
              ResourceFormatter.inject_backup(n, backup)
            end
          end
        end
      end
    end

    desc 'backup:orphaned', 'List backups associated with ' \
                            'deprovisioned databases'
    option :environment
    option :max_age, default: '1y',
                     desc: 'Limit backups returned '\
                           '(example usage: 1w, 1y, etc.)'
    define_method 'backup:orphaned' do
      age = ChronicDuration.parse(options[:max_age])
      raise Thor::Error, "Invalid age: #{options[:max_age]}" if age.nil?
      min_created_at = Time.now - age

      Formatter.render(Renderer.current) do |root|
        root.keyed_list('description') do |node|
          scoped_environments(options).each do ||
            .each_orphaned_backup do |backup|
              created_at = backup.created_at
              copied_from = backup.copied_from
              break if created_at < min_created_at && !copied_from
              node.object do |n|
                ResourceFormatter.inject_backup(
                  n, backup, include_db: true
                )
              end
            end
          end
        end
      end
    end

    desc 'backup:purge BACKUP_ID',
         'Permanently delete a backup and any copies of it'
    define_method 'backup:purge' do |backup_id|
      backup = Aptible::Api::Backup.find(backup_id, token: fetch_token)
      raise Thor::Error, "Backup ##{backup_id} not found" if backup.nil?

      operation = backup.create_operation!(type: 'purge')
      CLI.logger.info "Purging backup #{backup_id}"
      begin
        attach_to_operation_logs(operation)
      rescue HyperResource::ClientError => e
        # A 404 here means that the operation completed successfully,
        # and was removed faster than attach_to_operation_logs
        # could attach to the logs.
        raise if e.response.status != 404
      end
    end
  end
end