datadog_backup 0.10.3 → 1.0.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5833879f7fbadabad6111eae29c4e487e0d51a0b0802dcd61124985bae70cd23
4
- data.tar.gz: 5fdc04d6d1bf28671a4a2000a20c6f1513cbf27f406def181550d956cd270d48
3
+ metadata.gz: 1ff7695b471968ff7c34559829656149d0e77b139d484ff8e677424d90b4303d
4
+ data.tar.gz: d1bd644801cc09c4e8c442c2765e6b3da675f2de80b3acccd1e55e4ab5dbd8b4
5
5
  SHA512:
6
- metadata.gz: 9cc3623d68ec1e5c5872bda3d2e341c9e5d2b1bb954e16d08a2f4d289adb01751f0b7f3f2b0549bfba2fbf91d5ab86c233b59c74f2124642c4cd52b0074a1824
7
- data.tar.gz: 9ef0f647d84441c750a65a9cf18130fe89daad15af18ad0e07d61b74caf13ba160388551b4908609bf95a6113f3f39de854b5347becad449fcef0df70782fee2
6
+ metadata.gz: 8ee25ab151f20f67983335fefe4011a44a43aaf3819b9ef3264345b20aa05f0e2d212d0004bb2a9a8a170ae90a9cd6c1c3a5ef7cc7b573da269bcb01639c0fcc
7
+ data.tar.gz: f70bf349b96a98da7a48eff26ddb5841f0c41c82b08df298ab8ed3a2f2a17301a23b29ef43c60168771a016b290f7c0e1ca1186b149db9cd1c23304a635dd3a3
@@ -12,7 +12,7 @@ jobs:
12
12
  steps:
13
13
  - uses: actions/checkout@v2
14
14
  - name: Set up Ruby 2.7.2
15
- uses: actions/setup-ruby@v1.1.2
15
+ uses: actions/setup-ruby@v1.1.3
16
16
  with:
17
17
  ruby-version: 2.7.2
18
18
  - name: Test with Rspec
@@ -28,7 +28,7 @@ jobs:
28
28
  steps:
29
29
  - uses: actions/checkout@v2
30
30
  - name: Set up Ruby 2.7.2
31
- uses: actions/setup-ruby@v1.1.2
31
+ uses: actions/setup-ruby@v1.1.3
32
32
  with:
33
33
  ruby-version: 2.7.2
34
34
  - name: Build with bundler
data/.rubocop.yml ADDED
@@ -0,0 +1 @@
1
+ require: rubocop-rspec
data/CHANGELOG.md CHANGED
@@ -1,3 +1,28 @@
1
+ # [1.0.0](https://github.com/scribd/datadog_backup/compare/v0.11.0...v1.0.0) (2021-03-02)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * handle gets with no result ([8d016a1](https://github.com/scribd/datadog_backup/commit/8d016a1858b44d374a0dff121c71340bf18062e0))
7
+
8
+
9
+ ### Features
10
+
11
+ * If resource doesn't exist in Datadog, the resource is recreated. ([18ba241](https://github.com/scribd/datadog_backup/commit/18ba24183e136f9d899351bbb0999aba2c22308f))
12
+
13
+
14
+ ### BREAKING CHANGES
15
+
16
+ * `datadog-backup` used to exit with an error if a resource
17
+ wasn't found in Datadog.
18
+
19
+ # [0.11.0](https://github.com/scribd/datadog_backup/compare/v0.10.3...v0.11.0) (2021-01-12)
20
+
21
+
22
+ ### Features
23
+
24
+ * Add force-restore flag to allow running in automation ([#46](https://github.com/scribd/datadog_backup/issues/46)) ([e067386](https://github.com/scribd/datadog_backup/commit/e0673862b6f6d86297e1352faaee872f2c4884c8))
25
+
1
26
  ## [0.10.3](https://github.com/scribd/datadog_backup/compare/v0.10.2...v0.10.3) (2020-12-11)
2
27
 
3
28
 
data/Gemfile CHANGED
@@ -9,4 +9,5 @@ group :development, :test do
9
9
  gem 'guard-rspec'
10
10
  gem 'rspec'
11
11
  gem 'rubocop'
12
+ gem 'rubocop-rspec'
12
13
  end
data/bin/datadog_backup CHANGED
@@ -23,6 +23,7 @@ LOGGER.level = Logger::INFO
23
23
  diff_format: :color,
24
24
  resources: [DatadogBackup::Dashboards, DatadogBackup::Monitors],
25
25
  output_format: :yaml,
26
+ force_restore: false,
26
27
  logger: LOGGER
27
28
  }
28
29
 
@@ -54,7 +55,10 @@ def prereqs
54
55
  opts.on('--dashboards-only') do
55
56
  @options[:resources] = [DatadogBackup::Dashboards]
56
57
  end
57
- opts.on('--json', 'format backups as JSON instead of YAML. Does not impact `diffs` nor `restore`, but do not mix formats in the same backup-dir.') do
58
+ opts.on(
59
+ '--json',
60
+ 'format backups as JSON instead of YAML. Does not impact `diffs` nor `restore`, but do not mix formats in the same backup-dir.'
61
+ ) do
58
62
  @options[:output_format] = :json
59
63
  end
60
64
  opts.on('--no-color', 'removes colored output from diff format') do
@@ -63,6 +67,9 @@ def prereqs
63
67
  opts.on('--diff-format FORMAT', 'one of `color`, `html_simple`, `html`') do |format|
64
68
  @options[:diff_format] = format.to_sym
65
69
  end
70
+ opts.on('--force-restore', 'force restore to Datadog') do
71
+ @options[:force_restore] = true
72
+ end
66
73
  end
67
74
  options.parse!
68
75
 
@@ -24,7 +24,7 @@ Gem::Specification.new do |spec|
24
24
  spec.add_dependency 'concurrent-ruby-edge', '0.6.0'
25
25
  spec.add_dependency 'deepsort', '0.4.5'
26
26
  spec.add_dependency 'diffy', '3.4.0'
27
- spec.add_dependency 'dogapi', '1.42.0'
27
+ spec.add_dependency 'dogapi', '1.44.0'
28
28
 
29
29
  spec.add_development_dependency 'bundler'
30
30
  spec.add_development_dependency 'pry'
@@ -108,27 +108,30 @@ module DatadogBackup
108
108
  id, diff = *future.value!
109
109
  next unless diff
110
110
 
111
- puts '--------------------------------------------------------------------------------'
112
- puts format_diff_output([id, diff])
113
- puts '(r)estore to Datadog, overwrite local changes and (d)ownload, (s)kip, or (q)uit?'
114
- response = $stdin.gets.chomp
115
- case response
116
- when 'q'
117
- exit
118
- when 'r'
119
- puts "Restoring #{id} to Datadog."
120
- definitive_resource_instance(id).update(id, definitive_resource_instance(id).load_from_file_by_id(id))
121
- when 'd'
122
- puts "Downloading #{id} from Datadog."
123
- definitive_resource_instance(id).get_and_write_file(id)
124
- when 's'
125
- next
111
+ if @options[:force_restore]
112
+ definitive_resource_instance(id).restore(id)
126
113
  else
127
- puts 'Invalid response, please try again.'
114
+ puts '--------------------------------------------------------------------------------'
115
+ puts format_diff_output([id, diff])
116
+ puts '(r)estore to Datadog, overwrite local changes and (d)ownload, (s)kip, or (q)uit?'
128
117
  response = $stdin.gets.chomp
118
+ case response
119
+ when 'q'
120
+ exit
121
+ when 'r'
122
+ puts "Restoring #{id} to Datadog."
123
+ definitive_resource_instance(id).restore(id)
124
+ when 'd'
125
+ puts "Downloading #{id} from Datadog."
126
+ definitive_resource_instance(id).get_and_write_file(id)
127
+ when 's'
128
+ next
129
+ else
130
+ puts 'Invalid response, please try again.'
131
+ response = $stdin.gets.chomp
132
+ end
129
133
  end
130
134
  end
131
-
132
135
  watcher.join if watcher.status
133
136
  end
134
137
 
@@ -47,6 +47,9 @@ module DatadogBackup
47
47
  with_200 do
48
48
  api_service.request(Net::HTTP::Get, "/api/#{api_version}/#{api_resource_name}/#{id}", nil, nil, false)
49
49
  end
50
+ rescue RuntimeError => e
51
+ return {} if e.message.include?('Request failed with error ["404"')
52
+ raise e.message
50
53
  end
51
54
 
52
55
  def get_all
@@ -73,12 +76,38 @@ module DatadogBackup
73
76
  self.class.to_s.split(':').last.downcase
74
77
  end
75
78
 
79
+ # Calls out to Datadog and checks for a '200' response
80
+ def create(body)
81
+ result = with_200 do
82
+ api_service.request(Net::HTTP::Post, "/api/#{api_version}/#{api_resource_name}", nil, body, true)
83
+ end
84
+ logger.warn 'Successfully created in datadog.'
85
+ result
86
+ end
87
+
76
88
  # Calls out to Datadog and checks for a '200' response
77
89
  def update(id, body)
78
- with_200 do
90
+ result = with_200 do
79
91
  api_service.request(Net::HTTP::Put, "/api/#{api_version}/#{api_resource_name}/#{id}", nil, body, true)
80
92
  end
81
93
  logger.warn 'Successfully restored to datadog.'
94
+ result
95
+ end
96
+
97
+ def restore(id)
98
+ body = load_from_file_by_id(id)
99
+ begin
100
+ update(id, body)
101
+ rescue RuntimeError => e
102
+ if e.message.include?('Request failed with error ["404"')
103
+ new_id = create(body).fetch('id')
104
+
105
+ FileUtils.rm(find_file_by_id(id))
106
+ get_and_write_file(new_id)
107
+ else
108
+ raise e.message
109
+ end
110
+ end
82
111
  end
83
112
 
84
113
  def with_200
@@ -94,9 +123,8 @@ module DatadogBackup
94
123
  sleep(0.1 * retries**5) # 0.1, 3.2, 24.3, 102.4 seconds per retry
95
124
  retry
96
125
  else
97
- raise "Request failed with error #{e.message}"
126
+ raise "Net::OpenTimeout: #{e.message}"
98
127
  end
99
128
  end
100
-
101
129
  end
102
130
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DatadogBackup
4
- class Monitors < Core
4
+ class Monitors < Core
5
5
  def all_monitors
6
6
  @all_monitors ||= get_all
7
7
  end
@@ -27,7 +27,8 @@ module DatadogBackup
27
27
  end
28
28
 
29
29
  def get_by_id(id)
30
- except(all_monitors.select { |monitor| monitor['id'].to_s == id.to_s }.first)
30
+ monitor = all_monitors.select { |monitor| monitor['id'].to_s == id.to_s }.first
31
+ monitor.nil? ? {} : except(monitor)
31
32
  end
32
33
 
33
34
  def initialize(options)
@@ -42,5 +42,9 @@ module DatadogBackup
42
42
  def resources
43
43
  @options[:resources]
44
44
  end
45
+
46
+ def force_restore
47
+ @options[:force_restore]
48
+ end
45
49
  end
46
50
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DatadogBackup
4
- VERSION = '0.10.3'
4
+ VERSION = '1.0.0'
5
5
  end
@@ -19,10 +19,10 @@ describe DatadogBackup::Cli do
19
19
  resources: [DatadogBackup::Dashboards]
20
20
  }
21
21
  end
22
- let(:cli) { DatadogBackup::Cli.new(options) }
22
+ let(:cli) { described_class.new(options) }
23
23
  let(:dashboards) { DatadogBackup::Dashboards.new(options) }
24
24
 
25
- before(:example) do
25
+ before do
26
26
  allow(cli).to receive(:resource_instances).and_return([dashboards])
27
27
  end
28
28
 
@@ -39,15 +39,28 @@ describe DatadogBackup::Cli do
39
39
  }
40
40
  ]
41
41
  end
42
- before(:example) do
42
+
43
+ before do
43
44
  dashboards.write_file('{"text": "diff"}', "#{tempdir}/dashboards/stillthere.json")
44
45
  dashboards.write_file('{"text": "diff"}', "#{tempdir}/dashboards/alsostillthere.json")
45
46
  dashboards.write_file('{"text": "diff"}', "#{tempdir}/dashboards/deleted.json")
46
47
 
47
48
  allow(client_double).to receive(:instance_variable_get).with(:@dashboard_service).and_return(api_service_double)
48
- allow(api_service_double).to receive(:request).with(Net::HTTP::Get, "/api/v1/dashboard", nil, nil, false).and_return(all_boards)
49
- allow(api_service_double).to receive(:request).with(Net::HTTP::Get, "/api/v1/dashboard/stillthere", nil, nil, false).and_return(['200', {}])
50
- allow(api_service_double).to receive(:request).with(Net::HTTP::Get, "/api/v1/dashboard/alsostillthere", nil, nil, false).and_return(['200', {}])
49
+ allow(api_service_double).to receive(:request).with(Net::HTTP::Get,
50
+ '/api/v1/dashboard',
51
+ nil,
52
+ nil,
53
+ false).and_return(all_boards)
54
+ allow(api_service_double).to receive(:request).with(Net::HTTP::Get,
55
+ '/api/v1/dashboard/stillthere',
56
+ nil,
57
+ nil,
58
+ false).and_return(['200', {}])
59
+ allow(api_service_double).to receive(:request).with(Net::HTTP::Get,
60
+ '/api/v1/dashboard/alsostillthere',
61
+ nil,
62
+ nil,
63
+ false).and_return(['200', {}])
51
64
  end
52
65
 
53
66
  it 'deletes the file locally as well' do
@@ -58,16 +71,18 @@ describe DatadogBackup::Cli do
58
71
  end
59
72
 
60
73
  describe '#diffs' do
61
- before(:example) do
74
+ subject { cli.diffs }
75
+
76
+ before do
62
77
  dashboards.write_file('{"text": "diff"}', "#{tempdir}/dashboards/diffs1.json")
63
78
  dashboards.write_file('{"text": "diff"}', "#{tempdir}/dashboards/diffs2.json")
64
79
  dashboards.write_file('{"text": "diff"}', "#{tempdir}/dashboards/diffs3.json")
65
80
  allow(dashboards).to receive(:get_by_id).and_return({ 'text' => 'diff2' })
66
81
  allow(cli).to receive(:initialize_client).and_return(client_double)
67
82
  end
68
- subject { cli.diffs }
83
+
69
84
  it {
70
- is_expected.to include(
85
+ expect(subject).to include(
71
86
  " ---\n id: diffs1\n ---\n-text: diff2\n+text: diff\n",
72
87
  " ---\n id: diffs3\n ---\n-text: diff2\n+text: diff\n",
73
88
  " ---\n id: diffs2\n ---\n-text: diff2\n+text: diff\n"
@@ -76,14 +91,14 @@ describe DatadogBackup::Cli do
76
91
  end
77
92
 
78
93
  describe '#restore' do
79
- before(:example) do
94
+ subject { cli.restore }
95
+
96
+ before do
80
97
  dashboards.write_file('{"text": "diff"}', "#{tempdir}/dashboards/diffs1.json")
81
98
  allow(dashboards).to receive(:get_by_id).and_return({ 'text' => 'diff2' })
82
99
  allow(cli).to receive(:initialize_client).and_return(client_double)
83
100
  end
84
101
 
85
- subject { cli.restore }
86
-
87
102
  example 'starts interactive restore' do
88
103
  allow($stdin).to receive(:gets).and_return('q')
89
104
 
@@ -98,21 +113,24 @@ describe DatadogBackup::Cli do
98
113
  expect(dashboards).to receive(:update).with('diffs1', { 'text' => 'diff' })
99
114
  subject
100
115
  end
116
+
101
117
  example 'download' do
102
118
  allow($stdin).to receive(:gets).and_return('d')
103
119
  expect(dashboards).to receive(:write_file).with(%({\n "text": "diff2"\n}), "#{tempdir}/dashboards/diffs1.json")
104
120
  subject
105
121
  end
122
+
106
123
  example 'skip' do
107
124
  allow($stdin).to receive(:gets).and_return('s')
108
- expect(dashboards).to_not receive(:write_file)
109
- expect(dashboards).to_not receive(:update)
125
+ expect(dashboards).not_to receive(:write_file)
126
+ expect(dashboards).not_to receive(:update)
110
127
  subject
111
128
  end
129
+
112
130
  example 'quit' do
113
131
  allow($stdin).to receive(:gets).and_return('q')
114
- expect(dashboards).to_not receive(:write_file)
115
- expect(dashboards).to_not receive(:update)
132
+ expect(dashboards).not_to receive(:write_file)
133
+ expect(dashboards).not_to receive(:update)
116
134
  expect { subject }.to raise_error(SystemExit)
117
135
  end
118
136
  end
@@ -7,7 +7,7 @@ describe DatadogBackup::Core do
7
7
  let(:client_double) { double }
8
8
  let(:tempdir) { Dir.mktmpdir }
9
9
  let(:core) do
10
- DatadogBackup::Core.new(
10
+ described_class.new(
11
11
  action: 'backup',
12
12
  api_service: api_service_double,
13
13
  client: client_double,
@@ -21,18 +21,19 @@ describe DatadogBackup::Core do
21
21
 
22
22
  describe '#client' do
23
23
  subject { core.client }
24
+
24
25
  it { is_expected.to eq client_double }
25
26
  end
26
27
 
27
28
  describe '#with_200' do
28
29
  context 'with 200' do
29
- subject { core.with_200 {['200', { foo: :bar }]} }
30
+ subject { core.with_200 { ['200', { foo: :bar }] } }
30
31
 
31
32
  it { is_expected.to eq({ foo: :bar }) }
32
33
  end
33
34
 
34
35
  context 'with not 200' do
35
- subject { core.with_200 {['400', "Error message"]} }
36
+ subject { core.with_200 { ['400', 'Error message'] } }
36
37
 
37
38
  it 'raises an error' do
38
39
  expect { subject }.to raise_error(RuntimeError)
@@ -41,14 +42,15 @@ describe DatadogBackup::Core do
41
42
  end
42
43
 
43
44
  describe '#diff' do
44
- before(:example) do
45
+ subject { core.diff('diff') }
46
+
47
+ before do
45
48
  allow(core).to receive(:get_by_id).and_return({ 'text' => 'diff1', 'extra' => 'diff1' })
46
49
  core.write_file('{"text": "diff2", "extra": "diff2"}', "#{tempdir}/core/diff.json")
47
50
  end
48
51
 
49
- subject { core.diff('diff') }
50
52
  it {
51
- is_expected.to eq <<~EOF
53
+ expect(subject).to eq <<~EOF
52
54
  ---
53
55
  -extra: diff1
54
56
  -text: diff1
@@ -60,11 +62,13 @@ describe DatadogBackup::Core do
60
62
 
61
63
  describe '#except' do
62
64
  subject { core.except({ a: :b, b: :c }) }
65
+
63
66
  it { is_expected.to eq({ a: :b, b: :c }) }
64
67
  end
65
68
 
66
69
  describe '#initialize' do
67
70
  subject { core }
71
+
68
72
  it 'makes the subdirectories' do
69
73
  expect(FileUtils).to receive(:mkdir_p).with("#{tempdir}/core")
70
74
  subject
@@ -73,18 +77,93 @@ describe DatadogBackup::Core do
73
77
 
74
78
  describe '#myclass' do
75
79
  subject { core.myclass }
80
+
76
81
  it { is_expected.to eq 'core' }
77
82
  end
78
83
 
84
+ describe '#create' do
85
+ subject { core.create({ 'a' => 'b' }) }
86
+
87
+ example 'it calls Dogapi::APIService.request' do
88
+ stub_const('Dogapi::APIService::API_VERSION', 'v1')
89
+ allow(core).to receive(:api_service).and_return(api_service_double)
90
+ allow(core).to receive(:api_version).and_return('v1')
91
+ allow(core).to receive(:api_resource_name).and_return('dashboard')
92
+ expect(api_service_double).to receive(:request).with(Net::HTTP::Post,
93
+ '/api/v1/dashboard',
94
+ nil,
95
+ { 'a' => 'b' },
96
+ true).and_return(['200', { 'id' => 'whatever-id-abc' }])
97
+ subject
98
+ end
99
+ end
100
+
79
101
  describe '#update' do
80
- subject { core.update('abc-123-def', '{"a": "b"}') }
102
+ subject { core.update('abc-123-def', { 'a' => 'b' }) }
103
+
81
104
  example 'it calls Dogapi::APIService.request' do
82
105
  stub_const('Dogapi::APIService::API_VERSION', 'v1')
83
106
  allow(core).to receive(:api_service).and_return(api_service_double)
84
107
  allow(core).to receive(:api_version).and_return('v1')
85
108
  allow(core).to receive(:api_resource_name).and_return('dashboard')
86
- expect(api_service_double).to receive(:request).with(Net::HTTP::Put, '/api/v1/dashboard/abc-123-def', nil, '{"a": "b"}', true).and_return(%w[200 Created])
109
+ expect(api_service_double).to receive(:request).with(Net::HTTP::Put,
110
+ '/api/v1/dashboard/abc-123-def',
111
+ nil,
112
+ { 'a' => 'b' },
113
+ true).and_return(['200', { 'id' => 'whatever-id-abc' }])
87
114
  subject
88
115
  end
89
116
  end
117
+
118
+ describe '#restore' do
119
+ before do
120
+ allow(core).to receive(:api_service).and_return(api_service_double)
121
+ allow(core).to receive(:api_version).and_return('api-version-string')
122
+ allow(core).to receive(:api_resource_name).and_return('api-resource-name-string')
123
+ allow(api_service_double).to receive(:request).with(Net::HTTP::Get,
124
+ '/api/api-version-string/api-resource-name-string/abc-123-def',
125
+ nil,
126
+ nil,
127
+ false).and_return(['200', { test: :ok }])
128
+ allow(api_service_double).to receive(:request).with(Net::HTTP::Get,
129
+ '/api/api-version-string/api-resource-name-string/bad-123-id',
130
+ nil,
131
+ nil,
132
+ false).and_return(['404', { error: :blahblah_not_found }])
133
+ allow(core).to receive(:load_from_file_by_id).and_return({ 'load' => 'ok' })
134
+ end
135
+
136
+ context 'when id exists' do
137
+ subject { core.restore('abc-123-def') }
138
+
139
+ example 'it calls out to update' do
140
+ expect(core).to receive(:update).with('abc-123-def', { 'load' => 'ok' })
141
+ subject
142
+ end
143
+ end
144
+
145
+ context 'when id does not exist' do
146
+ subject { core.restore('bad-123-id') }
147
+
148
+ before do
149
+ allow(api_service_double).to receive(:request).with(Net::HTTP::Put,
150
+ '/api/api-version-string/api-resource-name-string/bad-123-id',
151
+ nil, { 'load' => 'ok' },
152
+ true).and_return(['404', { 'Error' => 'my not found' }])
153
+ allow(api_service_double).to receive(:request).with(Net::HTTP::Post,
154
+ '/api/api-version-string/api-resource-name-string',
155
+ nil,
156
+ { 'load' => 'ok' },
157
+ true).and_return(['200', { 'id' => 'my-new-id' }])
158
+ end
159
+
160
+ example 'it calls out to create then saves the new file and deletes the new file' do
161
+ expect(core).to receive(:create).with({ 'load' => 'ok' }).and_return({ 'id' => 'my-new-id' })
162
+ expect(core).to receive(:get_and_write_file).with('my-new-id')
163
+ allow(core).to receive(:find_file_by_id).with('bad-123-id').and_return('/path/to/bad-123-id.json')
164
+ expect(FileUtils).to receive(:rm).with('/path/to/bad-123-id.json')
165
+ subject
166
+ end
167
+ end
168
+ end
90
169
  end
@@ -7,7 +7,7 @@ describe DatadogBackup::Dashboards do
7
7
  let(:client_double) { double }
8
8
  let(:tempdir) { Dir.mktmpdir }
9
9
  let(:dashboards) do
10
- DatadogBackup::Dashboards.new(
10
+ described_class.new(
11
11
  action: 'backup',
12
12
  client: client_double,
13
13
  backup_dir: tempdir,
@@ -59,10 +59,13 @@ describe DatadogBackup::Dashboards do
59
59
  'title' => 'example dashboard'
60
60
  }
61
61
  end
62
- before(:example) do
62
+
63
+ before do
63
64
  allow(client_double).to receive(:instance_variable_get).with(:@dashboard_service).and_return(api_service_double)
64
- allow(api_service_double).to receive(:request).with(Net::HTTP::Get, "/api/v1/dashboard", nil, nil, false).and_return(all_boards)
65
- allow(api_service_double).to receive(:request).with(Net::HTTP::Get, "/api/v1/dashboard/abc-123-def", nil, nil, false).and_return(example_dashboard)
65
+ allow(api_service_double).to receive(:request).with(Net::HTTP::Get, '/api/v1/dashboard', nil, nil,
66
+ false).and_return(all_boards)
67
+ allow(api_service_double).to receive(:request).with(Net::HTTP::Get, '/api/v1/dashboard/abc-123-def', nil, nil,
68
+ false).and_return(example_dashboard)
66
69
  end
67
70
 
68
71
  describe '#backup' do
@@ -100,17 +103,19 @@ describe DatadogBackup::Dashboards do
100
103
  -title: example dashboard
101
104
  +a: b
102
105
  EOF
103
- )
106
+ )
104
107
  end
105
108
  end
106
109
 
107
110
  describe '#except' do
108
111
  subject { dashboards.except({ :a => :b, 'modified_at' => :c, 'url' => :d }) }
112
+
109
113
  it { is_expected.to eq({ a: :b }) }
110
114
  end
111
115
 
112
116
  describe '#get_by_id' do
113
117
  subject { dashboards.get_by_id('abc-123-def') }
118
+
114
119
  it { is_expected.to eq board_abc_123_def }
115
120
  end
116
121
  end
@@ -27,55 +27,61 @@ describe DatadogBackup::LocalFilesystem do
27
27
  end
28
28
 
29
29
  describe '#all_files' do
30
- before(:example) do
30
+ subject { core.all_files }
31
+
32
+ before do
31
33
  File.new("#{tempdir}/all_files.json", 'w')
32
34
  end
33
35
 
34
- after(:example) do
36
+ after do
35
37
  FileUtils.rm "#{tempdir}/all_files.json"
36
38
  end
37
39
 
38
- subject { core.all_files }
39
40
  it { is_expected.to eq(["#{tempdir}/all_files.json"]) }
40
41
  end
41
42
 
42
43
  describe '#all_file_ids_for_selected_resources' do
43
- before(:example) do
44
+ subject { core.all_file_ids_for_selected_resources }
45
+
46
+ before do
44
47
  Dir.mkdir("#{tempdir}/dashboards")
45
48
  Dir.mkdir("#{tempdir}/monitors")
46
49
  File.new("#{tempdir}/dashboards/all_files.json", 'w')
47
50
  File.new("#{tempdir}/monitors/12345.json", 'w')
48
51
  end
49
52
 
50
- after(:example) do
53
+ after do
51
54
  FileUtils.rm "#{tempdir}/dashboards/all_files.json"
52
55
  FileUtils.rm "#{tempdir}/monitors/12345.json"
53
56
  end
54
57
 
55
- subject { core.all_file_ids_for_selected_resources }
56
58
  it { is_expected.to eq(['all_files']) }
57
59
  end
58
60
 
59
61
  describe '#class_from_id' do
60
- before(:example) do
62
+ subject { core.class_from_id('abc-123-def') }
63
+
64
+ before do
61
65
  core.write_file('abc', "#{tempdir}/core/abc-123-def.json")
62
66
  end
63
67
 
64
- after(:example) do
68
+ after do
65
69
  FileUtils.rm "#{tempdir}/core/abc-123-def.json"
66
70
  end
67
- subject { core.class_from_id('abc-123-def') }
71
+
68
72
  it { is_expected.to eq DatadogBackup::Core }
69
73
  end
70
74
 
71
75
  describe '#dump' do
72
76
  context ':json' do
73
77
  subject { core.dump({ a: :b }) }
78
+
74
79
  it { is_expected.to eq(%({\n "a": "b"\n})) }
75
80
  end
76
81
 
77
82
  context ':yaml' do
78
83
  subject { core_yaml.dump({ 'a' => 'b' }) }
84
+
79
85
  it { is_expected.to eq(%(---\na: b\n)) }
80
86
  end
81
87
  end
@@ -83,80 +89,94 @@ describe DatadogBackup::LocalFilesystem do
83
89
  describe '#filename' do
84
90
  context ':json' do
85
91
  subject { core.filename('abc-123-def') }
92
+
86
93
  it { is_expected.to eq("#{tempdir}/core/abc-123-def.json") }
87
94
  end
88
95
 
89
96
  context ':yaml' do
90
97
  subject { core_yaml.filename('abc-123-def') }
98
+
91
99
  it { is_expected.to eq("#{tempdir}/core/abc-123-def.yaml") }
92
100
  end
93
101
  end
94
102
 
95
103
  describe '#file_type' do
96
- before(:example) do
104
+ subject { core.file_type("#{tempdir}/file_type.json") }
105
+
106
+ before do
97
107
  File.new("#{tempdir}/file_type.json", 'w')
98
108
  end
99
109
 
100
- after(:example) do
110
+ after do
101
111
  FileUtils.rm "#{tempdir}/file_type.json"
102
112
  end
103
113
 
104
- subject { core.file_type("#{tempdir}/file_type.json") }
105
114
  it { is_expected.to eq :json }
106
115
  end
107
116
 
108
117
  describe '#find_file_by_id' do
109
- before(:example) do
118
+ subject { core.find_file_by_id('find_file') }
119
+
120
+ before do
110
121
  File.new("#{tempdir}/find_file.json", 'w')
111
122
  end
112
123
 
113
- after(:example) do
124
+ after do
114
125
  FileUtils.rm "#{tempdir}/find_file.json"
115
126
  end
116
127
 
117
- subject { core.find_file_by_id('find_file') }
118
128
  it { is_expected.to eq "#{tempdir}/find_file.json" }
119
129
  end
120
130
 
121
131
  describe '#load_from_file' do
122
132
  context ':json' do
123
133
  subject { core.load_from_file(%({\n "a": "b"\n}), :json) }
134
+
124
135
  it { is_expected.to eq('a' => 'b') }
125
136
  end
126
137
 
127
138
  context ':yaml' do
128
139
  subject { core.load_from_file(%(---\na: b\n), :yaml) }
140
+
129
141
  it { is_expected.to eq('a' => 'b') }
130
142
  end
131
143
  end
132
144
 
133
145
  describe '#load_from_file_by_id' do
134
146
  context 'written in json read in yaml mode' do
135
- before(:example) { core.write_file(%({"a": "b"}), "#{tempdir}/core/abc-123-def.json") }
136
- after(:example) { FileUtils.rm "#{tempdir}/core/abc-123-def.json" }
137
-
138
147
  subject { core_yaml.load_from_file_by_id('abc-123-def') }
148
+
149
+ before { core.write_file(%({"a": "b"}), "#{tempdir}/core/abc-123-def.json") }
150
+
151
+ after { FileUtils.rm "#{tempdir}/core/abc-123-def.json" }
152
+
139
153
  it { is_expected.to eq('a' => 'b') }
140
154
  end
141
- context 'written in yaml read in json mode' do
142
- before(:example) { core.write_file(%(---\na: b), "#{tempdir}/core/abc-123-def.yaml") }
143
- after(:example) { FileUtils.rm "#{tempdir}/core/abc-123-def.yaml" }
144
155
 
156
+ context 'written in yaml read in json mode' do
145
157
  subject { core.load_from_file_by_id('abc-123-def') }
158
+
159
+ before { core.write_file(%(---\na: b), "#{tempdir}/core/abc-123-def.yaml") }
160
+
161
+ after { FileUtils.rm "#{tempdir}/core/abc-123-def.yaml" }
162
+
146
163
  it { is_expected.to eq('a' => 'b') }
147
164
  end
148
165
 
149
166
  context 'Integer as parameter' do
150
- before(:example) { core.write_file(%(---\na: b), "#{tempdir}/core/12345.yaml") }
151
- after(:example) { FileUtils.rm "#{tempdir}/core/12345.yaml" }
152
-
153
167
  subject { core.load_from_file_by_id(12_345) }
168
+
169
+ before { core.write_file(%(---\na: b), "#{tempdir}/core/12345.yaml") }
170
+
171
+ after { FileUtils.rm "#{tempdir}/core/12345.yaml" }
172
+
154
173
  it { is_expected.to eq('a' => 'b') }
155
174
  end
156
175
  end
157
176
 
158
177
  describe '#write_file' do
159
178
  subject { core.write_file('abc123', "#{tempdir}/core/abc-123-def.json") }
179
+
160
180
  let(:file_like_object) { double }
161
181
 
162
182
  it 'writes a file to abc-123-def.json' do
@@ -7,7 +7,7 @@ describe DatadogBackup::Monitors do
7
7
  let(:client_double) { double }
8
8
  let(:tempdir) { Dir.mktmpdir }
9
9
  let(:monitors) do
10
- DatadogBackup::Monitors.new(
10
+ described_class.new(
11
11
  action: 'backup',
12
12
  client: client_double,
13
13
  backup_dir: tempdir,
@@ -49,14 +49,17 @@ describe DatadogBackup::Monitors do
49
49
  ]
50
50
  end
51
51
 
52
- before(:example) do
52
+ before do
53
53
  allow(client_double).to receive(:instance_variable_get).with(:@monitor_svc).and_return(api_service_double)
54
- allow(api_service_double).to receive(:request).with(Net::HTTP::Get, "/api/v1/monitor", nil, nil, false).and_return(all_monitors)
55
- allow(api_service_double).to receive(:request).with(Net::HTTP::Get, "/api/v1/dashboard/123455", nil, nil, false).and_return(example_monitor)
54
+ allow(api_service_double).to receive(:request).with(Net::HTTP::Get, '/api/v1/monitor', nil, nil,
55
+ false).and_return(all_monitors)
56
+ allow(api_service_double).to receive(:request).with(Net::HTTP::Get, '/api/v1/dashboard/123455', nil, nil,
57
+ false).and_return(example_monitor)
56
58
  end
57
59
 
58
60
  describe '#all_monitors' do
59
61
  subject { monitors.all_monitors }
62
+
60
63
  it { is_expected.to eq [monitor_description] }
61
64
  end
62
65
 
@@ -100,16 +103,20 @@ describe DatadogBackup::Monitors do
100
103
 
101
104
  describe '#filename' do
102
105
  subject { monitors.filename(123_455) }
106
+
103
107
  it { is_expected.to eq("#{tempdir}/monitors/123455.json") }
104
108
  end
105
109
 
106
110
  describe '#get_by_id' do
107
111
  context 'Integer' do
108
112
  subject { monitors.get_by_id(123_455) }
113
+
109
114
  it { is_expected.to eq monitor_description }
110
115
  end
116
+
111
117
  context 'String' do
112
118
  subject { monitors.get_by_id('123455') }
119
+
113
120
  it { is_expected.to eq monitor_description }
114
121
  end
115
122
  end
@@ -47,7 +47,7 @@ describe 'bin/datadog_backup' do
47
47
  it "dies unless given ENV[#{v}]" do
48
48
  ClimateControl.env[v] = nil
49
49
  _, status = run_bin('backup')
50
- expect(status).to_not be_success
50
+ expect(status).not_to be_success
51
51
  end
52
52
  end
53
53
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: datadog_backup
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.3
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kamran Farhadi
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2020-12-11 00:00:00.000000000 Z
12
+ date: 2021-03-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: amazing_print
@@ -87,14 +87,14 @@ dependencies:
87
87
  requirements:
88
88
  - - '='
89
89
  - !ruby/object:Gem::Version
90
- version: 1.42.0
90
+ version: 1.44.0
91
91
  type: :runtime
92
92
  prerelease: false
93
93
  version_requirements: !ruby/object:Gem::Requirement
94
94
  requirements:
95
95
  - - '='
96
96
  - !ruby/object:Gem::Version
97
- version: 1.42.0
97
+ version: 1.44.0
98
98
  - !ruby/object:Gem::Dependency
99
99
  name: bundler
100
100
  requirement: !ruby/object:Gem::Requirement
@@ -135,6 +135,7 @@ files:
135
135
  - ".github/dependabot.yml"
136
136
  - ".github/workflows/rspec_and_release.yml"
137
137
  - ".gitignore"
138
+ - ".rubocop.yml"
138
139
  - CHANGELOG.md
139
140
  - CODE_OF_CONDUCT.md
140
141
  - Gemfile