Class: DatadogBackup::Core

Inherits:
Object
  • Object
show all
Includes:
LocalFilesystem, Options
Defined in:
lib/datadog_backup/core.rb

Direct Known Subclasses

Dashboards, Monitors

Instance Method Summary collapse

Methods included from Options

#action, #backup_dir, #client, #concurrency_limit, #datadog_api_key, #datadog_app_key, #diff_format, #logger, #output_format, #resources

Methods included from LocalFilesystem

#all_file_ids, #all_file_ids_for_selected_resources, #all_files, #class_from_id, #dump, #file_type, #filename, #find_file_by_id, #load_from_file, #load_from_file_by_id, #mydir, #purge, #write_file

Constructor Details

#initialize(options) ⇒ Core

Returns a new instance of Core.



74
75
76
77
# File 'lib/datadog_backup/core.rb', line 74

def initialize(options)
  @options = options
  ::FileUtils.mkdir_p(mydir)
end

Instance Method Details

#api_resource_nameObject



19
20
21
# File 'lib/datadog_backup/core.rb', line 19

def api_resource_name
  raise 'subclass is expected to implement #api_resource_name'
end

#api_serviceObject



11
12
13
# File 'lib/datadog_backup/core.rb', line 11

def api_service
  raise 'subclass is expected to implement #api_service'
end

#api_versionObject



15
16
17
# File 'lib/datadog_backup/core.rb', line 15

def api_version
  raise 'subclass is expected to implement #api_version'
end

#backupObject



23
24
25
# File 'lib/datadog_backup/core.rb', line 23

def backup
  raise 'subclass is expected to implement #backup'
end

#client_with_200(method, *id) ⇒ Object

Calls out to Datadog and checks for a ‘200’ response



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/datadog_backup/core.rb', line 28

def client_with_200(method, *id)
  max_retries = 6
  retries ||= 0

  response = client.send(method, *id)

  # logger.debug response
  raise "Method #{method} failed with error #{response}" unless response[0] == '200'

  response[1]
rescue ::Net::OpenTimeout => e
  if (retries += 1) <= max_retries
    sleep(0.1 * retries**5) # 0.1, 3.2, 24.3, 102.4 seconds per retry
    retry
  else
    raise "Method #{method} failed with error #{e.message}"
  end
end

#diff(id, banlist = []) ⇒ Object

Returns the diffy diff. Optionally, supply an array of keys to remove from comparison



49
50
51
52
53
54
55
# File 'lib/datadog_backup/core.rb', line 49

def diff(id, banlist = [])
  current = except(get_by_id(id), banlist).deep_sort.to_yaml
  filesystem = except(load_from_file_by_id(id), banlist).deep_sort.to_yaml
  result = ::Diffy::Diff.new(current, filesystem, include_plus_and_minus_in_html: true).to_s(diff_format)
  logger.debug("Compared ID #{id} and found #{result}")
  result
end

#except(hash, banlist) ⇒ Object

Returns a hash with banlist elements removed



58
59
60
61
62
63
64
# File 'lib/datadog_backup/core.rb', line 58

def except(hash, banlist)
  hash.tap do # tap returns self
    banlist.each do |key|
      hash.delete(key) # delete returns the value at the deleted key, hence the tap wrapper
    end
  end
end

#get_and_write_file(id) ⇒ Object



66
67
68
# File 'lib/datadog_backup/core.rb', line 66

def get_and_write_file(id)
  write_file(dump(get_by_id(id)), filename(id))
end

#get_by_id(_id) ⇒ Object



70
71
72
# File 'lib/datadog_backup/core.rb', line 70

def get_by_id(_id)
  raise 'subclass is expected to implement #get_by_id(id)'
end

#myclassObject



79
80
81
# File 'lib/datadog_backup/core.rb', line 79

def myclass
  self.class.to_s.split(':').last.downcase
end

#restoreObject



83
84
85
# File 'lib/datadog_backup/core.rb', line 83

def restore
  raise 'subclass is expected to implement #restore'
end

#update(id, body) ⇒ Object



87
88
89
# File 'lib/datadog_backup/core.rb', line 87

def update(id, body)
  api_service.request(Net::HTTP::Put, "/api/#{api_version}/#{api_resource_name}/#{id}", nil, body, true)
end

#update_with_200(id, body) ⇒ Object

Calls out to Datadog and checks for a ‘200’ response



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/datadog_backup/core.rb', line 92

def update_with_200(id, body)
  max_retries = 6
  retries ||= 0

  response = update(id, body)

  # logger.debug response
  raise "Update failed with error #{response}" unless response[0] == '200'

  logger.warn "Successfully restored #{id} to datadog."

  response[1]
rescue ::Net::OpenTimeout => e
  if (retries += 1) <= max_retries
    sleep(0.1 * retries**5) # 0.1, 3.2, 24.3, 102.4 seconds per retry
    retry
  else
    raise "Update failed with error #{e.message}"
  end
end