datadog_backup 2.0.0 → 3.0.0.alpha.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DatadogBackup
4
- VERSION = '2.0.0'
4
+ VERSION = '3.0.0.alpha.1'
5
5
  end
@@ -2,17 +2,21 @@
2
2
 
3
3
  require 'concurrent'
4
4
 
5
- require 'dogapi'
5
+ require 'pry' #TODO: remove this
6
+ require 'pry-byebug' #TODO: remove this
6
7
 
7
8
  require_relative 'datadog_backup/local_filesystem'
8
9
  require_relative 'datadog_backup/options'
9
-
10
10
  require_relative 'datadog_backup/cli'
11
11
  require_relative 'datadog_backup/core'
12
12
  require_relative 'datadog_backup/dashboards'
13
13
  require_relative 'datadog_backup/monitors'
14
14
  require_relative 'datadog_backup/thread_pool'
15
15
  require_relative 'datadog_backup/version'
16
+ require_relative 'datadog_backup/deprecations'
17
+ DatadogBackup::Deprecations.check
18
+
16
19
 
17
20
  module DatadogBackup
18
21
  end
22
+
data/release.config.js CHANGED
@@ -18,7 +18,8 @@ module.exports = {
18
18
  "@semantic-release/git",
19
19
  {
20
20
  "assets": [
21
- "CHANGELOG.md"
21
+ "CHANGELOG.md",
22
+ "lib/datadog_backup/version.rb"
22
23
  ],
23
24
  "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
24
25
  }
@@ -3,64 +3,35 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  describe DatadogBackup::Cli do
6
- let(:api_service_double) { double(Dogapi::APIService) }
7
- let(:client_double) { double }
6
+ let(:stubs) { Faraday::Adapter::Test::Stubs.new }
7
+ let(:api_client_double) { Faraday.new { |f| f.adapter :test, stubs } }
8
8
  let(:tempdir) { Dir.mktmpdir }
9
9
  let(:options) do
10
10
  {
11
11
  action: 'backup',
12
12
  backup_dir: tempdir,
13
- client: client_double,
14
- datadog_api_key: 1,
15
- datadog_app_key: 1,
16
13
  diff_format: nil,
17
- logger: Logger.new('/dev/null'),
18
14
  output_format: :json,
19
15
  resources: [DatadogBackup::Dashboards]
20
16
  }
21
17
  end
22
18
  let(:cli) { described_class.new(options) }
23
- let(:dashboards) { DatadogBackup::Dashboards.new(options) }
19
+ let(:dashboards) do
20
+ dashboards = DatadogBackup::Dashboards.new(options)
21
+ allow(dashboards).to receive(:api_service).and_return(api_client_double)
22
+ return dashboards
23
+ end
24
24
 
25
25
  before do
26
26
  allow(cli).to receive(:resource_instances).and_return([dashboards])
27
27
  end
28
28
 
29
- describe '#initialize_client' do
30
- subject { described_class.new({ datadog_api_key: 1, datadog_app_key: 1 }).initialize_client }
31
-
32
- it { is_expected.to be_a(Dogapi::Client) }
33
-
34
- context 'when the environment variable DATADOG_HOST is set to a custom host like https://api.datadoghq.eu' do
35
- before do
36
- stub_const('ENV', 'DATADOG_HOST' => 'https://api.datadoghq.eu')
37
- end
38
-
39
- describe 'then #datadog_host is https://api.datadoghq.eu' do
40
- subject { described_class.new({ datadog_api_key: 1, datadog_app_key: 1 }).initialize_client.datadog_host }
41
-
42
- it { is_expected.to eq('https://api.datadoghq.eu') }
43
- end
44
- end
45
-
46
- context 'when the environment variable DATADOG_HOST is not set' do
47
- before do
48
- stub_const('ENV', {})
49
- end
50
-
51
- describe 'then #datadog_host is https://api.datadoghq.eu' do
52
- subject { described_class.new({ datadog_api_key: 1, datadog_app_key: 1 }).initialize_client.datadog_host }
53
-
54
- it { is_expected.to eq('https://api.datadoghq.com') }
55
- end
56
- end
57
- end
58
-
59
29
  describe '#backup' do
60
30
  context 'when dashboards are deleted in datadog' do
61
- let(:all_boards) do
31
+ let(:all_dashboards) do
62
32
  [
63
- '200',
33
+ 200,
34
+ {},
64
35
  {
65
36
  'dashboards' => [
66
37
  { 'id' => 'stillthere' },
@@ -75,22 +46,9 @@ describe DatadogBackup::Cli do
75
46
  dashboards.write_file('{"text": "diff"}', "#{tempdir}/dashboards/alsostillthere.json")
76
47
  dashboards.write_file('{"text": "diff"}', "#{tempdir}/dashboards/deleted.json")
77
48
 
78
- allow(client_double).to receive(:instance_variable_get).with(:@dashboard_service).and_return(api_service_double)
79
- allow(api_service_double).to receive(:request).with(Net::HTTP::Get,
80
- '/api/v1/dashboard',
81
- nil,
82
- nil,
83
- false).and_return(all_boards)
84
- allow(api_service_double).to receive(:request).with(Net::HTTP::Get,
85
- '/api/v1/dashboard/stillthere',
86
- nil,
87
- nil,
88
- false).and_return(['200', {}])
89
- allow(api_service_double).to receive(:request).with(Net::HTTP::Get,
90
- '/api/v1/dashboard/alsostillthere',
91
- nil,
92
- nil,
93
- false).and_return(['200', {}])
49
+ stubs.get('/api/v1/dashboard') { all_dashboards }
50
+ stubs.get('/api/v1/dashboard/stillthere') {[200, {}, {}]}
51
+ stubs.get('/api/v1/dashboard/alsostillthere') {[200, {}, {}]}
94
52
  end
95
53
 
96
54
  it 'deletes the file locally as well' do
@@ -108,7 +66,6 @@ describe DatadogBackup::Cli do
108
66
  dashboards.write_file('{"text": "diff"}', "#{tempdir}/dashboards/diffs2.json")
109
67
  dashboards.write_file('{"text": "diff"}', "#{tempdir}/dashboards/diffs3.json")
110
68
  allow(dashboards).to receive(:get_by_id).and_return({ 'text' => 'diff2' })
111
- allow(cli).to receive(:initialize_client).and_return(client_double)
112
69
  end
113
70
 
114
71
  it {
@@ -126,7 +83,6 @@ describe DatadogBackup::Cli do
126
83
  before do
127
84
  dashboards.write_file('{"text": "diff"}', "#{tempdir}/dashboards/diffs1.json")
128
85
  allow(dashboards).to receive(:get_by_id).and_return({ 'text' => 'diff2' })
129
- allow(cli).to receive(:initialize_client).and_return(client_double)
130
86
  end
131
87
 
132
88
  example 'starts interactive restore' do
@@ -3,43 +3,23 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  describe DatadogBackup::Core do
6
- let(:api_service_double) { double(Dogapi::APIService) }
7
- let(:client_double) { double }
6
+ let(:stubs) { Faraday::Adapter::Test::Stubs.new }
7
+ let(:api_client_double) { Faraday.new { |f| f.adapter :test, stubs } }
8
8
  let(:tempdir) { Dir.mktmpdir }
9
9
  let(:core) do
10
- described_class.new(
10
+ core = described_class.new(
11
11
  action: 'backup',
12
- api_service: api_service_double,
13
- client: client_double,
14
12
  backup_dir: tempdir,
15
13
  diff_format: nil,
16
14
  resources: [],
17
- output_format: :json,
18
- logger: Logger.new('/dev/null')
15
+ output_format: :json
19
16
  )
17
+ allow(core).to receive(:api_service).and_return(api_client_double)
18
+ return core
20
19
  end
21
20
 
22
- describe '#client' do
23
- subject { core.client }
24
21
 
25
- it { is_expected.to eq client_double }
26
- end
27
-
28
- describe '#with_200' do
29
- context 'with 200' do
30
- subject { core.with_200 { ['200', { foo: :bar }] } }
31
-
32
- it { is_expected.to eq({ foo: :bar }) }
33
- end
34
22
 
35
- context 'with not 200' do
36
- subject { core.with_200 { ['400', 'Error message'] } }
37
-
38
- it 'raises an error' do
39
- expect { subject }.to raise_error(RuntimeError)
40
- end
41
- end
42
- end
43
23
 
44
24
  describe '#diff' do
45
25
  subject { core.diff('diff') }
@@ -84,52 +64,44 @@ describe DatadogBackup::Core do
84
64
  describe '#create' do
85
65
  subject { core.create({ 'a' => 'b' }) }
86
66
 
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)
67
+ example 'it will post /api/v1/dashboard' do
90
68
  allow(core).to receive(:api_version).and_return('v1')
91
69
  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' }])
70
+ stubs.post('/api/v1/dashboard', {'a' => 'b'}) {[200, {}, {'id' => 'whatever-id-abc' }]}
97
71
  subject
72
+ stubs.verify_stubbed_calls
98
73
  end
99
74
  end
100
75
 
101
76
  describe '#update' do
102
77
  subject { core.update('abc-123-def', { 'a' => 'b' }) }
103
78
 
104
- example 'it calls Dogapi::APIService.request' do
105
- stub_const('Dogapi::APIService::API_VERSION', 'v1')
106
- allow(core).to receive(:api_service).and_return(api_service_double)
79
+ example 'it puts /api/v1/dashboard' do
107
80
  allow(core).to receive(:api_version).and_return('v1')
108
81
  allow(core).to receive(:api_resource_name).and_return('dashboard')
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' }])
82
+ stubs.put('/api/v1/dashboard/abc-123-def', {'a' => 'b'}) {[200, {}, {'id' => 'whatever-id-abc' }]}
114
83
  subject
84
+ stubs.verify_stubbed_calls
85
+ end
86
+
87
+ context 'when the id is not found' do
88
+ before do
89
+ allow(core).to receive(:api_version).and_return('v1')
90
+ allow(core).to receive(:api_resource_name).and_return('dashboard')
91
+ stubs.put('/api/v1/dashboard/abc-123-def', {'a' => 'b'}) {[404, {}, {'id' => 'whatever-id-abc' }]}
92
+ end
93
+ it 'raises an error' do
94
+ expect { subject }.to raise_error(RuntimeError, 'update failed with error 404')
95
+ end
115
96
  end
116
97
  end
117
98
 
118
99
  describe '#restore' do
119
100
  before do
120
- allow(core).to receive(:api_service).and_return(api_service_double)
121
101
  allow(core).to receive(:api_version).and_return('api-version-string')
122
102
  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 }])
103
+ stubs.get('/api/api-version-string/api-resource-name-string/abc-123-def') {[200, {}, {'test' => 'ok' }]}
104
+ stubs.get('/api/api-version-string/api-resource-name-string/bad-123-id') {[404, {}, {'error' => 'blahblah_not_found' }]}
133
105
  allow(core).to receive(:load_from_file_by_id).and_return({ 'load' => 'ok' })
134
106
  end
135
107
 
@@ -142,19 +114,13 @@ describe DatadogBackup::Core do
142
114
  end
143
115
  end
144
116
 
145
- context 'when id does not exist' do
117
+ context 'when id does not exist on remote' do
146
118
  subject { core.restore('bad-123-id') }
147
119
 
148
120
  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' }])
121
+ allow(core).to receive(:load_from_file_by_id).and_return({ 'load' => 'ok' })
122
+ stubs.put('/api/api-version-string/api-resource-name-string/bad-123-id') {[404, {}, {'error' => 'id not found' }]}
123
+ stubs.post('/api/api-version-string/api-resource-name-string', {'load' => 'ok'}) {[200, {}, {'id' => 'my-new-id' }]}
158
124
  end
159
125
 
160
126
  example 'it calls out to create then saves the new file and deletes the new file' do
@@ -3,18 +3,18 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  describe DatadogBackup::Dashboards do
6
- let(:api_service_double) { double(Dogapi::APIService) }
7
- let(:client_double) { double }
6
+ let(:stubs) { Faraday::Adapter::Test::Stubs.new }
7
+ let(:api_client_double) { Faraday.new { |f| f.adapter :test, stubs } }
8
8
  let(:tempdir) { Dir.mktmpdir }
9
9
  let(:dashboards) do
10
- described_class.new(
10
+ dashboards = described_class.new(
11
11
  action: 'backup',
12
- client: client_double,
13
12
  backup_dir: tempdir,
14
13
  output_format: :json,
15
- resources: [],
16
- logger: Logger.new('/dev/null')
14
+ resources: []
17
15
  )
16
+ allow(dashboards).to receive(:api_service).and_return(api_client_double)
17
+ return dashboards
18
18
  end
19
19
  let(:dashboard_description) do
20
20
  {
@@ -23,9 +23,10 @@ describe DatadogBackup::Dashboards do
23
23
  'title' => 'foo'
24
24
  }
25
25
  end
26
- let(:all_boards) do
26
+ let(:all_dashboards) do
27
27
  [
28
- '200',
28
+ 200,
29
+ {},
29
30
  {
30
31
  'dashboards' => [
31
32
  dashboard_description
@@ -35,7 +36,8 @@ describe DatadogBackup::Dashboards do
35
36
  end
36
37
  let(:example_dashboard) do
37
38
  [
38
- '200',
39
+ 200,
40
+ {},
39
41
  board_abc_123_def
40
42
  ]
41
43
  end
@@ -61,11 +63,8 @@ describe DatadogBackup::Dashboards do
61
63
  end
62
64
 
63
65
  before do
64
- allow(client_double).to receive(:instance_variable_get).with(:@dashboard_service).and_return(api_service_double)
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
+ stubs.get('/api/v1/dashboard') { all_dashboards }
67
+ stubs.get('/api/v1/dashboard/abc-123-def') { example_dashboard }
69
68
  end
70
69
 
71
70
  describe '#backup' do
@@ -81,8 +80,8 @@ describe DatadogBackup::Dashboards do
81
80
  end
82
81
  end
83
82
 
84
- describe '#all_boards' do
85
- subject { dashboards.all_boards }
83
+ describe '#all_dashboards' do
84
+ subject { dashboards.all_dashboards }
86
85
 
87
86
  it { is_expected.to eq [dashboard_description] }
88
87
  end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe DatadogBackup::Deprecations do
6
+ let(:logger) { double }
7
+
8
+ before do
9
+ stub_const('LOGGER', logger)
10
+ allow(logger).to receive(:warn)
11
+ end
12
+
13
+ %w[2.4.10 2.5.9 2.6.8].each do |ruby_version|
14
+ describe "#check#{ruby_version}" do
15
+ subject { described_class.check }
16
+
17
+ it 'does warn' do
18
+ stub_const('RUBY_VERSION', ruby_version)
19
+ expect(logger).to receive(:warn).with(/ruby-#{ruby_version} is deprecated./)
20
+ subject
21
+ end
22
+ end
23
+ end
24
+
25
+ %w[2.7.4 3.0.4 3.1.2 3.2.0-preview1].each do |ruby_version|
26
+ describe "#check#{ruby_version}" do
27
+ subject { described_class.check }
28
+
29
+ it 'does not warn' do
30
+ stub_const('RUBY_VERSION', ruby_version)
31
+ expect(logger).to_not receive(:warn).with(/ruby-#{ruby_version} is deprecated./)
32
+ subject
33
+ end
34
+ end
35
+ end
36
+ end
@@ -3,26 +3,21 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  describe DatadogBackup::LocalFilesystem do
6
- let(:client_double) { double }
7
6
  let(:tempdir) { Dir.mktmpdir }
8
7
  let(:core) do
9
8
  DatadogBackup::Core.new(
10
9
  action: 'backup',
11
- client: client_double,
12
10
  backup_dir: tempdir,
13
11
  resources: [DatadogBackup::Dashboards],
14
- output_format: :json,
15
- logger: Logger.new('/dev/null')
12
+ output_format: :json
16
13
  )
17
14
  end
18
15
  let(:core_yaml) do
19
16
  DatadogBackup::Core.new(
20
17
  action: 'backup',
21
- client: client_double,
22
18
  backup_dir: tempdir,
23
19
  resources: [],
24
- output_format: :yaml,
25
- logger: Logger.new('/dev/null')
20
+ output_format: :yaml
26
21
  )
27
22
  end
28
23
 
@@ -3,19 +3,20 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  describe DatadogBackup::Monitors do
6
- let(:api_service_double) { double(Dogapi::APIService) }
7
- let(:client_double) { double }
6
+ let(:stubs) { Faraday::Adapter::Test::Stubs.new }
7
+ let(:api_client_double) { Faraday.new { |f| f.adapter :test, stubs } }
8
8
  let(:tempdir) { Dir.mktmpdir }
9
9
  let(:monitors) do
10
- described_class.new(
10
+ monitors = described_class.new(
11
11
  action: 'backup',
12
- client: client_double,
13
12
  backup_dir: tempdir,
14
13
  output_format: :json,
15
- resources: [],
16
- logger: Logger.new('/dev/null')
14
+ resources: []
17
15
  )
16
+ allow(monitors).to receive(:api_service).and_return(api_client_double)
17
+ return monitors
18
18
  end
19
+
19
20
  let(:monitor_description) do
20
21
  {
21
22
  'query' => 'bar',
@@ -36,7 +37,8 @@ describe DatadogBackup::Monitors do
36
37
  end
37
38
  let(:all_monitors) do
38
39
  [
39
- '200',
40
+ 200,
41
+ {},
40
42
  [
41
43
  monitor_description
42
44
  ]
@@ -44,17 +46,15 @@ describe DatadogBackup::Monitors do
44
46
  end
45
47
  let(:example_monitor) do
46
48
  [
47
- '200',
49
+ 200,
50
+ {},
48
51
  monitor_description
49
52
  ]
50
53
  end
51
54
 
52
55
  before do
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,
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
+ stubs.get('/api/v1/monitor') { all_monitors }
57
+ stubs.get('/api/v1/dashboard/123455') { example_monitor }
58
58
  end
59
59
 
60
60
  describe '#all_monitors' do
@@ -79,9 +79,10 @@ describe DatadogBackup::Monitors do
79
79
  describe '#diff and #except' do
80
80
  example 'it ignores `overall_state` and `overall_state_modified`' do
81
81
  monitors.write_file(monitors.dump(monitor_description), monitors.filename(123_455))
82
- allow(api_service_double).to receive(:request).and_return(
82
+ stubs.get('/api/v1/dashboard/123455') {
83
83
  [
84
- '200',
84
+ 200,
85
+ {},
85
86
  [
86
87
  {
87
88
  'query' => 'bar',
@@ -93,7 +94,7 @@ describe DatadogBackup::Monitors do
93
94
  }
94
95
  ]
95
96
  ]
96
- )
97
+ }
97
98
 
98
99
  expect(monitors.diff(123_455)).to eq ''
99
100
 
@@ -17,13 +17,13 @@ describe 'bin/datadog_backup' do
17
17
  i.close
18
18
  end
19
19
 
20
- Timeout.timeout(2.0) do
20
+ Timeout.timeout(4.0) do
21
21
  oe.each do |v|
22
22
  output += v
23
23
  end
24
24
  end
25
25
  rescue Timeout::Error
26
- LOGGER.warn "Timing out #{t.inspect} after 2 second"
26
+ LOGGER.error "Timing out #{t.inspect} after 4 second"
27
27
  Process.kill(15, pid)
28
28
  ensure
29
29
  status = t.value
@@ -32,8 +32,8 @@ describe 'bin/datadog_backup' do
32
32
  end
33
33
 
34
34
  required_vars = %w[
35
- DATADOG_API_KEY
36
- DATADOG_APP_KEY
35
+ DD_API_KEY
36
+ DD_APP_KEY
37
37
  ]
38
38
 
39
39
  env = {}
@@ -52,7 +52,7 @@ describe 'bin/datadog_backup' do
52
52
  it 'supplies help' do
53
53
  stub_const('ENV', env)
54
54
  out_err, status = run_bin('--help')
55
- expect(out_err).to match(/Usage: DATADOG_API_KEY=/)
55
+ expect(out_err).to match(/Usage: DD_API_KEY=/)
56
56
  expect(status).to be_success
57
57
  end
58
58
  end
data/spec/spec_helper.rb CHANGED
@@ -2,16 +2,17 @@
2
2
 
3
3
  $LOAD_PATH.unshift(File.expand_path('../lib', File.dirname(__FILE__)))
4
4
 
5
- require 'datadog_backup'
6
5
  require 'logger'
7
- require 'tmpdir'
8
- require 'dogapi'
9
-
10
6
  $stdout.sync = $stderr.sync = true
11
- LOGGER = Logger.new($stderr) unless defined?(LOGGER)
12
- LOGGER.level = Logger::INFO
7
+ LOGGER = Logger.new($stderr)
8
+ LOGGER.level = Logger::ERROR
13
9
  $stdout = File.new('/dev/null', 'w+')
14
10
 
11
+ require 'tmpdir'
12
+ require 'datadog_backup'
13
+
14
+
15
+
15
16
  SPEC_ROOT = __dir__
16
17
  WORK_ROOT = File.expand_path(File.join(SPEC_ROOT, '..'))
17
18