datadog_backup 3.1.0 → 3.1.1

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: f24893d65b7350e2c22c2f1f89068664f9d4dd932231d292a26ae4b5f0c87a57
4
- data.tar.gz: d7a3a5e175b128a3e11bf523d5fa8fbd9b3c890260a3e14bb74ba8688f0aef06
3
+ metadata.gz: 332899376b51dd8ad98dda7a3528b7a7c80ca8cbbd2c4bbe9c2cb9976a1c7024
4
+ data.tar.gz: 68b89a77b5148006b16388c7a93241ca50fcecb6bc4edc09ab36cf34a80d92e8
5
5
  SHA512:
6
- metadata.gz: bd41dd652e26e9d049d25439c81b29a7be45da046526188bc77e0ffd2e06607e25044d10d78d72a0c35066c4b83919f2bcfb435136f9582240f11fcf035c13d6
7
- data.tar.gz: 256dd9b0eb76878f7966a853a644c39aede938882781f13e5b7577db4e09f97600c57748858a75aebcff0cd0a3ca32e2a4358618bb0481eea5568469bb57abe8
6
+ metadata.gz: ab35b9e6a6152cc22ff3de7714ed60f2bca54c056a510d5726e5d33921a0f54d088195bfd7b992494545ccdfa8350e99e097c19155cfde4f7396049aeaad9650
7
+ data.tar.gz: 4f2f791146658c9a9e4185ef3bda43180a5ef46938dd6b2754aa493bcac9949f19a53f70b972a125ae51ad7b71f6f8c309767d83654e40a4d7d5f4be70e6c39c
@@ -35,7 +35,6 @@ jobs:
35
35
  uses: ruby/setup-ruby@v1
36
36
  with:
37
37
  ruby-version: 2.7
38
- bundler-cache: true
39
38
  - name: Zip
40
39
  run : |
41
40
  zip -r datadog_backup.zip ./*
@@ -44,14 +43,10 @@ jobs:
44
43
  uses: cycjimmy/semantic-release-action@v3
45
44
  env:
46
45
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
46
+ GEM_HOST_API_KEY: ${{ secrets.RUBYGEMS_API_TOKEN }}
47
47
  with:
48
48
  semantic_version: 17
49
49
  extra_plugins: |
50
50
  @semantic-release/changelog@5
51
51
  @semantic-release/git@9
52
- - name: push to rubygems
53
- if: ${{ steps.semantic.output.new_release_published }}
54
- env:
55
- GEM_HOST_API_KEY: ${{ secrets.RUBYGEMS_API_TOKEN }}
56
- run: |
57
- gem push datadog_backup.gem
52
+ semantic-release-rubygem@1
data/.gitignore CHANGED
@@ -120,4 +120,6 @@ backup/
120
120
 
121
121
  .envrc
122
122
 
123
- .vscode
123
+ .vscode
124
+ spec/examples.txt
125
+
data/CHANGELOG.md CHANGED
@@ -1,3 +1,16 @@
1
+ ## [3.1.1](https://github.com/scribd/datadog_backup/compare/v3.1.0...v3.1.1) (2022-09-01)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * catch SystemExit so that rspec can complete ([9eee0e5](https://github.com/scribd/datadog_backup/commit/9eee0e5c5ea857baeafcf3fbc0f1c8f3748b0ca8))
7
+ * specify minimum ruby version in Gemfile ([c7f48f9](https://github.com/scribd/datadog_backup/commit/c7f48f95269a23549e28576434292d4ba1332d59))
8
+
9
+
10
+ ### Reverts
11
+
12
+ * Revert "fix: specify minimum ruby version in Gemfile" ([e934ac2](https://github.com/scribd/datadog_backup/commit/e934ac2611c9bb557a181dd2f6f6b2678287773d))
13
+
1
14
  # [3.1.0](https://github.com/scribd/datadog_backup/compare/v3.0.0...v3.1.0) (2022-08-30)
2
15
 
3
16
 
@@ -2,23 +2,11 @@
2
2
 
3
3
  module DatadogBackup
4
4
  # Dashboards specific overrides for backup and restore.
5
- class Dashboards < Core
5
+ class Dashboards < Resources
6
6
  def all
7
7
  get_all.fetch('dashboards')
8
8
  end
9
9
 
10
- def api_version
11
- 'v1'
12
- end
13
-
14
- def api_resource_name
15
- 'dashboard'
16
- end
17
-
18
- def id_keyname
19
- 'id'
20
- end
21
-
22
10
  def backup
23
11
  LOGGER.info("Starting diffs on #{::DatadogBackup::ThreadPool::TPOOL.max_length} threads")
24
12
  futures = all.map do |dashboard|
@@ -38,5 +26,19 @@ module DatadogBackup
38
26
  super(options)
39
27
  @banlist = %w[modified_at url].freeze
40
28
  end
29
+
30
+ private
31
+
32
+ def api_version
33
+ 'v1'
34
+ end
35
+
36
+ def api_resource_name
37
+ 'dashboard'
38
+ end
39
+
40
+ def id_keyname
41
+ 'id'
42
+ end
41
43
  end
42
44
  end
@@ -7,7 +7,7 @@ require 'deepsort'
7
7
 
8
8
  module DatadogBackup
9
9
  ##
10
- # Meant to be mixed into DatadogBackup::Core
10
+ # Meant to be mixed into DatadogBackup::Resources
11
11
  # Relies on @options[:backup_dir] and @options[:output_format]
12
12
  module LocalFilesystem
13
13
  def all_files
@@ -2,19 +2,11 @@
2
2
 
3
3
  module DatadogBackup
4
4
  # Monitor specific overrides for backup and restore.
5
- class Monitors < Core
5
+ class Monitors < Resources
6
6
  def all
7
7
  get_all
8
8
  end
9
9
 
10
- def api_version
11
- 'v1'
12
- end
13
-
14
- def api_resource_name
15
- 'monitor'
16
- end
17
-
18
10
  def backup
19
11
  all.map do |monitor|
20
12
  id = monitor['id']
@@ -31,5 +23,15 @@ module DatadogBackup
31
23
  super(options)
32
24
  @banlist = %w[overall_state overall_state_modified matching_downtimes modified].freeze
33
25
  end
26
+
27
+ private
28
+
29
+ def api_version
30
+ 'v1'
31
+ end
32
+
33
+ def api_resource_name
34
+ 'monitor'
35
+ end
34
36
  end
35
37
  end
@@ -8,53 +8,16 @@ require 'faraday/retry'
8
8
  module DatadogBackup
9
9
  # The default options for backing up and restores.
10
10
  # This base class is meant to be extended by specific resources, such as Dashboards, Monitors, and so on.
11
- class Core
11
+ class Resources
12
12
  include ::DatadogBackup::LocalFilesystem
13
13
  include ::DatadogBackup::Options
14
14
 
15
- @retry_options = {
15
+ RETRY_OPTIONS = {
16
16
  max: 5,
17
17
  interval: 0.05,
18
18
  interval_randomness: 0.5,
19
19
  backoff_factor: 2
20
- }
21
-
22
- def api_service
23
- @api_service ||= Faraday.new(
24
- url: api_url,
25
- headers: {
26
- 'DD-API-KEY' => ENV.fetch('DD_API_KEY'),
27
- 'DD-APPLICATION-KEY' => ENV.fetch('DD_APP_KEY')
28
- }
29
- ) do |faraday|
30
- faraday.request :json
31
- faraday.request :retry, @retry_options
32
- faraday.response(:logger, LOGGER, { headers: true, bodies: LOGGER.debug?, log_level: :debug }) do |logger|
33
- logger.filter(/(DD-API-KEY:)([^&]+)/, '\1[REDACTED]')
34
- logger.filter(/(DD-APPLICATION-KEY:)([^&]+)/, '\1[REDACTED]')
35
- end
36
- faraday.response :raise_error
37
- faraday.response :json
38
- faraday.adapter Faraday.default_adapter
39
- end
40
- end
41
-
42
- def api_url
43
- ENV.fetch('DD_SITE_URL', 'https://api.datadoghq.com/')
44
- end
45
-
46
- def api_version
47
- raise 'subclass is expected to implement #api_version'
48
- end
49
-
50
- def api_resource_name
51
- raise 'subclass is expected to implement #api_resource_name'
52
- end
53
-
54
- # Some resources have a different key for the id.
55
- def id_keyname
56
- 'id'
57
- end
20
+ }.freeze
58
21
 
59
22
  def backup
60
23
  raise 'subclass is expected to implement #backup'
@@ -166,6 +129,43 @@ module DatadogBackup
166
129
 
167
130
  private
168
131
 
132
+ def api_url
133
+ ENV.fetch('DD_SITE_URL', 'https://api.datadoghq.com/')
134
+ end
135
+
136
+ def api_version
137
+ raise 'subclass is expected to implement #api_version'
138
+ end
139
+
140
+ def api_resource_name
141
+ raise 'subclass is expected to implement #api_resource_name'
142
+ end
143
+
144
+ # Some resources have a different key for the id.
145
+ def id_keyname
146
+ 'id'
147
+ end
148
+
149
+ def api_service
150
+ @api_service ||= Faraday.new(
151
+ url: api_url,
152
+ headers: {
153
+ 'DD-API-KEY' => ENV.fetch('DD_API_KEY'),
154
+ 'DD-APPLICATION-KEY' => ENV.fetch('DD_APP_KEY')
155
+ }
156
+ ) do |faraday|
157
+ faraday.request :json
158
+ faraday.request :retry, RETRY_OPTIONS
159
+ faraday.response(:logger, LOGGER, { headers: true, bodies: LOGGER.debug?, log_level: :debug }) do |logger|
160
+ logger.filter(/(DD-API-KEY:)([^&]+)/, '\1[REDACTED]')
161
+ logger.filter(/(DD-APPLICATION-KEY:)([^&]+)/, '\1[REDACTED]')
162
+ end
163
+ faraday.response :raise_error
164
+ faraday.response :json
165
+ faraday.adapter Faraday.default_adapter
166
+ end
167
+ end
168
+
169
169
  # Create a new resource in Datadog, then move the old file to the new resource's ID
170
170
  def create_newly(file_id, body)
171
171
  new_id = create(body).fetch(id_keyname)
@@ -2,28 +2,11 @@
2
2
 
3
3
  module DatadogBackup
4
4
  # Synthetic specific overrides for backup and restore.
5
- class Synthetics < Core
5
+ class Synthetics < Resources
6
6
  def all
7
7
  get_all.fetch('tests')
8
8
  end
9
9
 
10
- def api_version
11
- 'v1'
12
- end
13
-
14
- def api_resource_name(body = nil)
15
- return 'synthetics/tests' if body.nil?
16
- return 'synthetics/tests' if body['type'].nil?
17
- return 'synthetics/tests/browser' if body['type'].to_s == 'browser'
18
- return 'synthetics/tests/api' if body['type'].to_s == 'api'
19
-
20
- raise "Unknown type #{body['type']}"
21
- end
22
-
23
- def id_keyname
24
- 'public_id'
25
- end
26
-
27
10
  def backup
28
11
  all.map do |synthetic|
29
12
  id = synthetic[id_keyname]
@@ -62,5 +45,24 @@ module DatadogBackup
62
45
  @get_all = nil
63
46
  resbody
64
47
  end
48
+
49
+ private
50
+
51
+ def api_version
52
+ 'v1'
53
+ end
54
+
55
+ def api_resource_name(body = nil)
56
+ return 'synthetics/tests' if body.nil?
57
+ return 'synthetics/tests' if body['type'].nil?
58
+ return 'synthetics/tests/browser' if body['type'].to_s == 'browser'
59
+ return 'synthetics/tests/api' if body['type'].to_s == 'api'
60
+
61
+ raise "Unknown type #{body['type']}"
62
+ end
63
+
64
+ def id_keyname
65
+ 'public_id'
66
+ end
65
67
  end
66
68
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DatadogBackup
4
- # Used by CLI and Dashboards to size thread pool according to available CPU cores.
4
+ # Used by CLI and Dashboards to size thread pool according to available CPU resourcess.
5
5
  module ThreadPool
6
6
  TPOOL = ::Concurrent::ThreadPoolExecutor.new(
7
7
  min_threads: [2, Concurrent.processor_count].max,
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DatadogBackup
4
- VERSION = '3.1.0'
4
+ VERSION = '3.1.1'
5
5
  end
@@ -5,7 +5,7 @@ require 'concurrent'
5
5
  require_relative 'datadog_backup/local_filesystem'
6
6
  require_relative 'datadog_backup/options'
7
7
  require_relative 'datadog_backup/cli'
8
- require_relative 'datadog_backup/core'
8
+ require_relative 'datadog_backup/resources'
9
9
  require_relative 'datadog_backup/dashboards'
10
10
  require_relative 'datadog_backup/monitors'
11
11
  require_relative 'datadog_backup/synthetics'
data/release.config.js CHANGED
@@ -12,6 +12,12 @@ module.exports = {
12
12
  "changelogFile": "CHANGELOG.md"
13
13
  }
14
14
  ],
15
+ [
16
+ "semantic-release-rubygem",
17
+ {
18
+ "gemFileDir": "."
19
+ }
20
+ ],
15
21
  [
16
22
  "@semantic-release/git",
17
23
  {
@@ -29,16 +29,14 @@ describe DatadogBackup::Cli do
29
29
  describe '#backup' do
30
30
  context 'when dashboards are deleted in datadog' do
31
31
  let(:all_dashboards) do
32
- [
33
- 200,
34
- {},
32
+ respond_with200(
35
33
  {
36
34
  'dashboards' => [
37
35
  { 'id' => 'stillthere' },
38
36
  { 'id' => 'alsostillthere' }
39
37
  ]
40
38
  }
41
- ]
39
+ )
42
40
  end
43
41
 
44
42
  before do
@@ -60,8 +58,14 @@ describe DatadogBackup::Cli do
60
58
 
61
59
  describe '#restore' do
62
60
  subject(:restore) { cli.restore }
61
+ let(:stdin) { class_double('STDIN') }
63
62
 
63
+ after(:all) do
64
+ $stdin = STDIN
65
+ end
66
+
64
67
  before do
68
+ $stdin = stdin
65
69
  dashboards.write_file('{"text": "diff"}', "#{tempdir}/dashboards/diffs1.json")
66
70
  allow(dashboards).to receive(:get_by_id).and_return({ 'text' => 'diff2' })
67
71
  allow(dashboards).to receive(:write_file)
@@ -69,7 +73,7 @@ describe DatadogBackup::Cli do
69
73
  end
70
74
 
71
75
  example 'starts interactive restore' do
72
- allow($stdin).to receive(:gets).and_return('q')
76
+ allow(stdin).to receive(:gets).and_return('q')
73
77
 
74
78
  expect { restore }.to(
75
79
  output(/\(r\)estore to Datadog, overwrite local changes and \(d\)ownload, \(s\)kip, or \(q\)uit\?/).to_stdout
@@ -79,7 +83,7 @@ describe DatadogBackup::Cli do
79
83
 
80
84
  context 'when the user chooses to restore' do
81
85
  before do
82
- allow($stdin).to receive(:gets).and_return('r')
86
+ allow(stdin).to receive(:gets).and_return('r')
83
87
  end
84
88
 
85
89
  example 'it restores from disk to server' do
@@ -90,7 +94,7 @@ describe DatadogBackup::Cli do
90
94
 
91
95
  context 'when the user chooses to download' do
92
96
  before do
93
- allow($stdin).to receive(:gets).and_return('d')
97
+ allow(stdin).to receive(:gets).and_return('d')
94
98
  end
95
99
 
96
100
  example 'it writes from server to disk' do
@@ -101,7 +105,7 @@ describe DatadogBackup::Cli do
101
105
 
102
106
  context 'when the user chooses to skip' do
103
107
  before do
104
- allow($stdin).to receive(:gets).and_return('s')
108
+ allow(stdin).to receive(:gets).and_return('s')
105
109
  end
106
110
 
107
111
  example 'it does not write to disk' do
@@ -117,7 +121,7 @@ describe DatadogBackup::Cli do
117
121
 
118
122
  context 'when the user chooses to quit' do
119
123
  before do
120
- allow($stdin).to receive(:gets).and_return('q')
124
+ allow(stdin).to receive(:gets).and_return('q')
121
125
  end
122
126
 
123
127
  example 'it exits' do
@@ -126,11 +130,13 @@ describe DatadogBackup::Cli do
126
130
 
127
131
  example 'it does not write to disk' do
128
132
  restore
133
+ rescue SystemExit
129
134
  expect(dashboards).not_to have_received(:write_file)
130
135
  end
131
136
 
132
137
  example 'it does not update the server' do
133
138
  restore
139
+ rescue SystemExit
134
140
  expect(dashboards).not_to have_received(:update)
135
141
  end
136
142
  end
@@ -2,28 +2,28 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe DatadogBackup::Core do
5
+ describe DatadogBackup::Resources do
6
6
  let(:stubs) { Faraday::Adapter::Test::Stubs.new }
7
7
  let(:api_client_double) { Faraday.new { |f| f.adapter :test, stubs } }
8
8
  let(:tempdir) { Dir.mktmpdir }
9
- let(:core) do
10
- core = described_class.new(
9
+ let(:resources) do
10
+ resources = described_class.new(
11
11
  action: 'backup',
12
12
  backup_dir: tempdir,
13
13
  diff_format: nil,
14
14
  resources: [],
15
15
  output_format: :json
16
16
  )
17
- allow(core).to receive(:api_service).and_return(api_client_double)
18
- return core
17
+ allow(resources).to receive(:api_service).and_return(api_client_double)
18
+ return resources
19
19
  end
20
20
 
21
21
  describe '#diff' do
22
- subject(:diff) { core.diff('diff') }
22
+ subject(:diff) { resources.diff('diff') }
23
23
 
24
24
  before do
25
- allow(core).to receive(:get_by_id).and_return({ 'text' => 'diff1', 'extra' => 'diff1' })
26
- core.write_file('{"text": "diff2", "extra": "diff2"}', "#{tempdir}/core/diff.json")
25
+ allow(resources).to receive(:get_by_id).and_return({ 'text' => 'diff1', 'extra' => 'diff1' })
26
+ resources.write_file('{"text": "diff2", "extra": "diff2"}', "#{tempdir}/resources/diff.json")
27
27
  end
28
28
 
29
29
  it {
@@ -39,34 +39,34 @@ describe DatadogBackup::Core do
39
39
  end
40
40
 
41
41
  describe '#except' do
42
- subject { core.except({ a: :b, b: :c }) }
42
+ subject { resources.except({ a: :b, b: :c }) }
43
43
 
44
44
  it { is_expected.to eq({ a: :b, b: :c }) }
45
45
  end
46
46
 
47
47
  describe '#initialize' do
48
- subject(:mycore) { core }
48
+ subject(:myresources) { resources }
49
49
 
50
50
  it 'makes the subdirectories' do
51
51
  fileutils = class_double(FileUtils).as_stubbed_const
52
52
  allow(fileutils).to receive(:mkdir_p)
53
- mycore
54
- expect(fileutils).to have_received(:mkdir_p).with("#{tempdir}/core")
53
+ myresources
54
+ expect(fileutils).to have_received(:mkdir_p).with("#{tempdir}/resources")
55
55
  end
56
56
  end
57
57
 
58
58
  describe '#myclass' do
59
- subject { core.myclass }
59
+ subject { resources.myclass }
60
60
 
61
- it { is_expected.to eq 'core' }
61
+ it { is_expected.to eq 'resources' }
62
62
  end
63
63
 
64
64
  describe '#create' do
65
- subject(:create) { core.create({ 'a' => 'b' }) }
65
+ subject(:create) { resources.create({ 'a' => 'b' }) }
66
66
 
67
67
  example 'it will post /api/v1/dashboard' do
68
- allow(core).to receive(:api_version).and_return('v1')
69
- allow(core).to receive(:api_resource_name).and_return('dashboard')
68
+ allow(resources).to receive(:api_version).and_return('v1')
69
+ allow(resources).to receive(:api_resource_name).and_return('dashboard')
70
70
  stubs.post('/api/v1/dashboard', { 'a' => 'b' }) { respond_with200({ 'id' => 'whatever-id-abc' }) }
71
71
  create
72
72
  stubs.verify_stubbed_calls
@@ -74,11 +74,11 @@ describe DatadogBackup::Core do
74
74
  end
75
75
 
76
76
  describe '#update' do
77
- subject(:update) { core.update('abc-123-def', { 'a' => 'b' }) }
77
+ subject(:update) { resources.update('abc-123-def', { 'a' => 'b' }) }
78
78
 
79
79
  example 'it puts /api/v1/dashboard' do
80
- allow(core).to receive(:api_version).and_return('v1')
81
- allow(core).to receive(:api_resource_name).and_return('dashboard')
80
+ allow(resources).to receive(:api_version).and_return('v1')
81
+ allow(resources).to receive(:api_resource_name).and_return('dashboard')
82
82
  stubs.put('/api/v1/dashboard/abc-123-def', { 'a' => 'b' }) { respond_with200({ 'id' => 'whatever-id-abc' }) }
83
83
  update
84
84
  stubs.verify_stubbed_calls
@@ -86,8 +86,8 @@ describe DatadogBackup::Core do
86
86
 
87
87
  context 'when the id is not found' do
88
88
  before do
89
- allow(core).to receive(:api_version).and_return('v1')
90
- allow(core).to receive(:api_resource_name).and_return('dashboard')
89
+ allow(resources).to receive(:api_version).and_return('v1')
90
+ allow(resources).to receive(:api_resource_name).and_return('dashboard')
91
91
  stubs.put('/api/v1/dashboard/abc-123-def', { 'a' => 'b' }) { [404, {}, { 'id' => 'whatever-id-abc' }] }
92
92
  end
93
93
 
@@ -99,32 +99,32 @@ describe DatadogBackup::Core do
99
99
 
100
100
  describe '#restore' do
101
101
  before do
102
- allow(core).to receive(:api_version).and_return('api-version-string')
103
- allow(core).to receive(:api_resource_name).and_return('api-resource-name-string')
102
+ allow(resources).to receive(:api_version).and_return('api-version-string')
103
+ allow(resources).to receive(:api_resource_name).and_return('api-resource-name-string')
104
104
  stubs.get('/api/api-version-string/api-resource-name-string/abc-123-def') { respond_with200({ 'test' => 'ok' }) }
105
105
  stubs.get('/api/api-version-string/api-resource-name-string/bad-123-id') do
106
106
  [404, {}, { 'error' => 'blahblah_not_found' }]
107
107
  end
108
- allow(core).to receive(:load_from_file_by_id).and_return({ 'load' => 'ok' })
108
+ allow(resources).to receive(:load_from_file_by_id).and_return({ 'load' => 'ok' })
109
109
  end
110
110
 
111
111
  context 'when id exists' do
112
- subject(:restore) { core.restore('abc-123-def') }
112
+ subject(:restore) { resources.restore('abc-123-def') }
113
113
 
114
114
  example 'it calls out to update' do
115
- allow(core).to receive(:update)
115
+ allow(resources).to receive(:update)
116
116
  restore
117
- expect(core).to have_received(:update).with('abc-123-def', { 'load' => 'ok' })
117
+ expect(resources).to have_received(:update).with('abc-123-def', { 'load' => 'ok' })
118
118
  end
119
119
  end
120
120
 
121
121
  context 'when id does not exist on remote' do
122
- subject(:restore_newly) { core.restore('bad-123-id') }
122
+ subject(:restore_newly) { resources.restore('bad-123-id') }
123
123
 
124
124
  let(:fileutils) { class_double(FileUtils).as_stubbed_const }
125
125
 
126
126
  before do
127
- allow(core).to receive(:load_from_file_by_id).and_return({ 'load' => 'ok' })
127
+ allow(resources).to receive(:load_from_file_by_id).and_return({ 'load' => 'ok' })
128
128
  stubs.put('/api/api-version-string/api-resource-name-string/bad-123-id') do
129
129
  [404, {}, { 'error' => 'id not found' }]
130
130
  end
@@ -132,19 +132,19 @@ describe DatadogBackup::Core do
132
132
  respond_with200({ 'id' => 'my-new-id' })
133
133
  end
134
134
  allow(fileutils).to receive(:rm)
135
- allow(core).to receive(:create).with({ 'load' => 'ok' }).and_return({ 'id' => 'my-new-id' })
136
- allow(core).to receive(:get_and_write_file)
137
- allow(core).to receive(:find_file_by_id).with('bad-123-id').and_return('/path/to/bad-123-id.json')
135
+ allow(resources).to receive(:create).with({ 'load' => 'ok' }).and_return({ 'id' => 'my-new-id' })
136
+ allow(resources).to receive(:get_and_write_file)
137
+ allow(resources).to receive(:find_file_by_id).with('bad-123-id').and_return('/path/to/bad-123-id.json')
138
138
  end
139
139
 
140
140
  example 'it calls out to create' do
141
141
  restore_newly
142
- expect(core).to have_received(:create).with({ 'load' => 'ok' })
142
+ expect(resources).to have_received(:create).with({ 'load' => 'ok' })
143
143
  end
144
144
 
145
145
  example 'it saves the new file' do
146
146
  restore_newly
147
- expect(core).to have_received(:get_and_write_file).with('my-new-id')
147
+ expect(resources).to have_received(:get_and_write_file).with('my-new-id')
148
148
  end
149
149
 
150
150
  example 'it deletes the old file' do
@@ -4,16 +4,16 @@ require 'spec_helper'
4
4
 
5
5
  describe DatadogBackup::LocalFilesystem do
6
6
  let(:tempdir) { Dir.mktmpdir }
7
- let(:core) do
8
- DatadogBackup::Core.new(
7
+ let(:resources) do
8
+ DatadogBackup::Resources.new(
9
9
  action: 'backup',
10
10
  backup_dir: tempdir,
11
11
  resources: [DatadogBackup::Dashboards],
12
12
  output_format: :json
13
13
  )
14
14
  end
15
- let(:core_yaml) do
16
- DatadogBackup::Core.new(
15
+ let(:resources_yaml) do
16
+ DatadogBackup::Resources.new(
17
17
  action: 'backup',
18
18
  backup_dir: tempdir,
19
19
  resources: [],
@@ -22,7 +22,7 @@ describe DatadogBackup::LocalFilesystem do
22
22
  end
23
23
 
24
24
  describe '#all_files' do
25
- subject { core.all_files }
25
+ subject { resources.all_files }
26
26
 
27
27
  before do
28
28
  File.new("#{tempdir}/all_files.json", 'w')
@@ -36,7 +36,7 @@ describe DatadogBackup::LocalFilesystem do
36
36
  end
37
37
 
38
38
  describe '#all_file_ids_for_selected_resources' do
39
- subject { core.all_file_ids_for_selected_resources }
39
+ subject { resources.all_file_ids_for_selected_resources }
40
40
 
41
41
  before do
42
42
  Dir.mkdir("#{tempdir}/dashboards")
@@ -54,28 +54,28 @@ describe DatadogBackup::LocalFilesystem do
54
54
  end
55
55
 
56
56
  describe '#class_from_id' do
57
- subject { core.class_from_id('abc-123-def') }
57
+ subject { resources.class_from_id('abc-123-def') }
58
58
 
59
59
  before do
60
- core.write_file('abc', "#{tempdir}/core/abc-123-def.json")
60
+ resources.write_file('abc', "#{tempdir}/resources/abc-123-def.json")
61
61
  end
62
62
 
63
63
  after do
64
- FileUtils.rm "#{tempdir}/core/abc-123-def.json"
64
+ FileUtils.rm "#{tempdir}/resources/abc-123-def.json"
65
65
  end
66
66
 
67
- it { is_expected.to eq DatadogBackup::Core }
67
+ it { is_expected.to eq DatadogBackup::Resources }
68
68
  end
69
69
 
70
70
  describe '#dump' do
71
71
  context 'when mode is :json' do
72
- subject { core.dump({ a: :b }) }
72
+ subject { resources.dump({ a: :b }) }
73
73
 
74
74
  it { is_expected.to eq(%({\n "a": "b"\n})) }
75
75
  end
76
76
 
77
77
  context 'when mode is :yaml' do
78
- subject { core_yaml.dump({ 'a' => 'b' }) }
78
+ subject { resources_yaml.dump({ 'a' => 'b' }) }
79
79
 
80
80
  it { is_expected.to eq(%(---\na: b\n)) }
81
81
  end
@@ -83,20 +83,20 @@ describe DatadogBackup::LocalFilesystem do
83
83
 
84
84
  describe '#filename' do
85
85
  context 'when mode is :json' do
86
- subject { core.filename('abc-123-def') }
86
+ subject { resources.filename('abc-123-def') }
87
87
 
88
- it { is_expected.to eq("#{tempdir}/core/abc-123-def.json") }
88
+ it { is_expected.to eq("#{tempdir}/resources/abc-123-def.json") }
89
89
  end
90
90
 
91
91
  context 'when mode is :yaml' do
92
- subject { core_yaml.filename('abc-123-def') }
92
+ subject { resources_yaml.filename('abc-123-def') }
93
93
 
94
- it { is_expected.to eq("#{tempdir}/core/abc-123-def.yaml") }
94
+ it { is_expected.to eq("#{tempdir}/resources/abc-123-def.yaml") }
95
95
  end
96
96
  end
97
97
 
98
98
  describe '#file_type' do
99
- subject { core.file_type("#{tempdir}/file_type.json") }
99
+ subject { resources.file_type("#{tempdir}/file_type.json") }
100
100
 
101
101
  before do
102
102
  File.new("#{tempdir}/file_type.json", 'w')
@@ -110,7 +110,7 @@ describe DatadogBackup::LocalFilesystem do
110
110
  end
111
111
 
112
112
  describe '#find_file_by_id' do
113
- subject { core.find_file_by_id('find_file') }
113
+ subject { resources.find_file_by_id('find_file') }
114
114
 
115
115
  before do
116
116
  File.new("#{tempdir}/find_file.json", 'w')
@@ -125,13 +125,13 @@ describe DatadogBackup::LocalFilesystem do
125
125
 
126
126
  describe '#load_from_file' do
127
127
  context 'when mode is :json' do
128
- subject { core.load_from_file(%({\n "a": "b"\n}), :json) }
128
+ subject { resources.load_from_file(%({\n "a": "b"\n}), :json) }
129
129
 
130
130
  it { is_expected.to eq('a' => 'b') }
131
131
  end
132
132
 
133
133
  context 'when mode is :yaml' do
134
- subject { core.load_from_file(%(---\na: b\n), :yaml) }
134
+ subject { resources.load_from_file(%(---\na: b\n), :yaml) }
135
135
 
136
136
  it { is_expected.to eq('a' => 'b') }
137
137
  end
@@ -139,44 +139,44 @@ describe DatadogBackup::LocalFilesystem do
139
139
 
140
140
  describe '#load_from_file_by_id' do
141
141
  context 'when the backup is in json but the mode is :yaml' do
142
- subject { core_yaml.load_from_file_by_id('abc-123-def') }
142
+ subject { resources_yaml.load_from_file_by_id('abc-123-def') }
143
143
 
144
- before { core.write_file(%({"a": "b"}), "#{tempdir}/core/abc-123-def.json") }
144
+ before { resources.write_file(%({"a": "b"}), "#{tempdir}/resources/abc-123-def.json") }
145
145
 
146
- after { FileUtils.rm "#{tempdir}/core/abc-123-def.json" }
146
+ after { FileUtils.rm "#{tempdir}/resources/abc-123-def.json" }
147
147
 
148
148
  it { is_expected.to eq('a' => 'b') }
149
149
  end
150
150
 
151
151
  context 'when the backup is in yaml but the mode is :json' do
152
- subject { core.load_from_file_by_id('abc-123-def') }
152
+ subject { resources.load_from_file_by_id('abc-123-def') }
153
153
 
154
- before { core.write_file(%(---\na: b), "#{tempdir}/core/abc-123-def.yaml") }
154
+ before { resources.write_file(%(---\na: b), "#{tempdir}/resources/abc-123-def.yaml") }
155
155
 
156
- after { FileUtils.rm "#{tempdir}/core/abc-123-def.yaml" }
156
+ after { FileUtils.rm "#{tempdir}/resources/abc-123-def.yaml" }
157
157
 
158
158
  it { is_expected.to eq('a' => 'b') }
159
159
  end
160
160
 
161
161
  context 'with Integer as parameter' do
162
- subject { core.load_from_file_by_id(12_345) }
162
+ subject { resources.load_from_file_by_id(12_345) }
163
163
 
164
- before { core.write_file(%(---\na: b), "#{tempdir}/core/12345.yaml") }
164
+ before { resources.write_file(%(---\na: b), "#{tempdir}/resources/12345.yaml") }
165
165
 
166
- after { FileUtils.rm "#{tempdir}/core/12345.yaml" }
166
+ after { FileUtils.rm "#{tempdir}/resources/12345.yaml" }
167
167
 
168
168
  it { is_expected.to eq('a' => 'b') }
169
169
  end
170
170
  end
171
171
 
172
172
  describe '#write_file' do
173
- subject(:write_file) { core.write_file('abc123', "#{tempdir}/core/abc-123-def.json") }
173
+ subject(:write_file) { resources.write_file('abc123', "#{tempdir}/resources/abc-123-def.json") }
174
174
 
175
175
  let(:file_like_object) { instance_double(File) }
176
176
 
177
177
  it 'writes a file to abc-123-def.json' do
178
178
  allow(File).to receive(:open).and_call_original
179
- allow(File).to receive(:open).with("#{tempdir}/core/abc-123-def.json", 'w').and_return(file_like_object)
179
+ allow(File).to receive(:open).with("#{tempdir}/resources/abc-123-def.json", 'w').and_return(file_like_object)
180
180
  allow(file_like_object).to receive(:write)
181
181
  allow(file_like_object).to receive(:close)
182
182
 
@@ -136,7 +136,7 @@ describe DatadogBackup::Synthetics do
136
136
  end
137
137
  end
138
138
 
139
- describe '#diff' do # TODO: migrate to core_spec.rb, since #diff is not defined here.
139
+ describe '#diff' do # TODO: migrate to resources_spec.rb, since #diff is not defined here.
140
140
  subject { synthetics.diff('abc-123-def') }
141
141
 
142
142
  before do
data/spec/spec_helper.rb CHANGED
@@ -15,16 +15,62 @@ SPEC_ROOT = __dir__
15
15
  WORK_ROOT = File.expand_path(File.join(SPEC_ROOT, '..'))
16
16
 
17
17
  RSpec.configure do |config|
18
+ # rspec-expectations config goes here. You can use an alternate
19
+ # assertion/expectation library such as wrong or the stdlib/minitest
20
+ # assertions if you prefer.
18
21
  config.expect_with :rspec do |expectations|
22
+ # This option will default to `true` in RSpec 4. It makes the `description`
23
+ # and `failure_message` of custom matchers include text for helper methods
24
+ # defined using `chain`, e.g.:
25
+ # be_bigger_than(2).and_smaller_than(4).description
26
+ # # => "be bigger than 2 and smaller than 4"
27
+ # ...rather than:
28
+ # # => "be bigger than 2"
19
29
  expectations.include_chain_clauses_in_custom_matcher_descriptions = true
20
30
  end
31
+
32
+ # rspec-mocks config goes here. You can use an alternate test double
33
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
21
34
  config.mock_with :rspec do |mocks|
35
+ # Prevents you from mocking or stubbing a method that does not exist on
36
+ # a real object. This is generally recommended, and will default to
37
+ # `true` in RSpec 4.
22
38
  mocks.verify_partial_doubles = true
23
39
  end
24
40
 
25
- config.filter_run :focus
26
- config.run_all_when_everything_filtered = true
41
+ # This option will default to `:apply_to_host_groups` in RSpec 4 (and will
42
+ # have no way to turn it off -- the option exists only for backwards
43
+ # compatibility in RSpec 3). It causes shared context metadata to be
44
+ # inherited by the metadata hash of host groups and examples, rather than
45
+ # triggering implicit auto-inclusion in groups with matching metadata.
46
+ config.shared_context_metadata_behavior = :apply_to_host_groups
47
+
48
+ # The settings below are suggested to provide a good initial experience
49
+ # with RSpec, but feel free to customize to your heart's content.
50
+ # This allows you to limit a spec run to individual examples or groups
51
+ # you care about by tagging them with `:focus` metadata. When nothing
52
+ # is tagged with `:focus`, all examples get run. RSpec also provides
53
+ # aliases for `it`, `describe`, and `context` that include `:focus`
54
+ # metadata: `fit`, `fdescribe` and `fcontext`, respectively.
55
+ config.filter_run_when_matching :focus
56
+
57
+ # Allows RSpec to persist some state between runs in order to support
58
+ # the `--only-failures` and `--next-failure` CLI options. We recommend
59
+ # you configure your source control system to ignore this file.
60
+ config.example_status_persistence_file_path = 'spec/examples.txt'
61
+
62
+ # Limits the available syntax to the non-monkey patched syntax that is
63
+ # recommended. For more details, see:
64
+ # https://relishapp.com/rspec/rspec-core/docs/configuration/zero-monkey-patching-mode
65
+ config.disable_monkey_patching!
27
66
 
67
+ # This setting enables warnings. It's recommended, but in some cases may
68
+ # be too noisy due to issues in dependencies.
69
+ config.warnings = true
70
+
71
+ # Many RSpec users commonly either run the entire suite or an individual
72
+ # file, and it's useful to allow more verbose output when running an
73
+ # individual spec file.
28
74
  if config.files_to_run.one?
29
75
  # Use the documentation formatter for detailed output,
30
76
  # unless a formatter has already been configured
@@ -32,9 +78,25 @@ RSpec.configure do |config|
32
78
  config.default_formatter = 'doc'
33
79
  end
34
80
 
35
- config.example_status_persistence_file_path = File.join(SPEC_ROOT, 'helpers', 'failures.txt')
81
+ # Print the 10 slowest examples and example groups at the
82
+ # end of the spec run, to help surface which specs are running
83
+ # particularly slow.
84
+ config.profile_examples = 10
85
+
86
+ # Run specs in random order to surface order dependencies. If you find an
87
+ # order dependency and want to debug it, you can fix the order by providing
88
+ # the seed, which is printed after each run.
89
+ # --seed 1234
90
+ config.order = :random
36
91
 
92
+ # Seed global randomization in this process using the `--seed` CLI option.
93
+ # Setting this allows you to use `--seed` to deterministically reproduce
94
+ # test failures related to randomization by passing the same `--seed` value
95
+ # as the one that triggered the failure.
37
96
  Kernel.srand config.seed
97
+
98
+ # Make RSpec available throughout the rspec unit test suite
99
+ config.expose_dsl_globally = true
38
100
  end
39
101
 
40
102
  def respond_with200(body)
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: 3.1.0
4
+ version: 3.1.1
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: 2022-08-30 00:00:00.000000000 Z
12
+ date: 2022-09-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: amazing_print
@@ -210,7 +210,6 @@ files:
210
210
  - CHANGELOG.md
211
211
  - CODE_OF_CONDUCT.md
212
212
  - Gemfile
213
- - Gemfile.lock
214
213
  - Guardfile
215
214
  - LICENSE
216
215
  - README.md
@@ -224,12 +223,12 @@ files:
224
223
  - images/demo.yml
225
224
  - lib/datadog_backup.rb
226
225
  - lib/datadog_backup/cli.rb
227
- - lib/datadog_backup/core.rb
228
226
  - lib/datadog_backup/dashboards.rb
229
227
  - lib/datadog_backup/deprecations.rb
230
228
  - lib/datadog_backup/local_filesystem.rb
231
229
  - lib/datadog_backup/monitors.rb
232
230
  - lib/datadog_backup/options.rb
231
+ - lib/datadog_backup/resources.rb
233
232
  - lib/datadog_backup/synthetics.rb
234
233
  - lib/datadog_backup/thread_pool.rb
235
234
  - lib/datadog_backup/version.rb
data/Gemfile.lock DELETED
@@ -1,118 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- datadog_backup (3.0.0)
5
- amazing_print
6
- concurrent-ruby
7
- deepsort
8
- diffy
9
- faraday
10
- faraday-retry
11
-
12
- GEM
13
- remote: https://rubygems.org/
14
- specs:
15
- amazing_print (1.4.0)
16
- ast (2.4.2)
17
- byebug (11.1.3)
18
- coderay (1.1.3)
19
- concurrent-ruby (1.1.10)
20
- deepsort (0.4.5)
21
- diff-lcs (1.5.0)
22
- diffy (3.4.2)
23
- faraday (2.5.2)
24
- faraday-net_http (>= 2.0, < 3.1)
25
- ruby2_keywords (>= 0.0.4)
26
- faraday-net_http (3.0.0)
27
- faraday-retry (2.0.0)
28
- faraday (~> 2.0)
29
- ffi (1.15.5)
30
- formatador (1.1.0)
31
- guard (2.18.0)
32
- formatador (>= 0.2.4)
33
- listen (>= 2.7, < 4.0)
34
- lumberjack (>= 1.0.12, < 2.0)
35
- nenv (~> 0.1)
36
- notiffany (~> 0.0)
37
- pry (>= 0.13.0)
38
- shellany (~> 0.0)
39
- thor (>= 0.18.1)
40
- guard-compat (1.2.1)
41
- guard-rspec (4.7.3)
42
- guard (~> 2.1)
43
- guard-compat (~> 1.1)
44
- rspec (>= 2.99.0, < 4.0)
45
- json (2.6.2)
46
- listen (3.7.1)
47
- rb-fsevent (~> 0.10, >= 0.10.3)
48
- rb-inotify (~> 0.9, >= 0.9.10)
49
- lumberjack (1.2.8)
50
- method_source (1.0.0)
51
- nenv (0.3.0)
52
- notiffany (0.1.3)
53
- nenv (~> 0.1)
54
- shellany (~> 0.0)
55
- parallel (1.22.1)
56
- parser (3.1.2.1)
57
- ast (~> 2.4.1)
58
- pry (0.14.1)
59
- coderay (~> 1.1)
60
- method_source (~> 1.0)
61
- pry-byebug (3.10.1)
62
- byebug (~> 11.0)
63
- pry (>= 0.13, < 0.15)
64
- rainbow (3.1.1)
65
- rb-fsevent (0.11.2)
66
- rb-inotify (0.10.1)
67
- ffi (~> 1.0)
68
- regexp_parser (2.5.0)
69
- rexml (3.2.5)
70
- rspec (3.11.0)
71
- rspec-core (~> 3.11.0)
72
- rspec-expectations (~> 3.11.0)
73
- rspec-mocks (~> 3.11.0)
74
- rspec-core (3.11.0)
75
- rspec-support (~> 3.11.0)
76
- rspec-expectations (3.11.0)
77
- diff-lcs (>= 1.2.0, < 2.0)
78
- rspec-support (~> 3.11.0)
79
- rspec-mocks (3.11.1)
80
- diff-lcs (>= 1.2.0, < 2.0)
81
- rspec-support (~> 3.11.0)
82
- rspec-support (3.11.0)
83
- rubocop (1.35.1)
84
- json (~> 2.3)
85
- parallel (~> 1.10)
86
- parser (>= 3.1.2.1)
87
- rainbow (>= 2.2.2, < 4.0)
88
- regexp_parser (>= 1.8, < 3.0)
89
- rexml (>= 3.2.5, < 4.0)
90
- rubocop-ast (>= 1.20.1, < 2.0)
91
- ruby-progressbar (~> 1.7)
92
- unicode-display_width (>= 1.4.0, < 3.0)
93
- rubocop-ast (1.21.0)
94
- parser (>= 3.1.1.0)
95
- rubocop-rspec (2.12.1)
96
- rubocop (~> 1.31)
97
- ruby-progressbar (1.11.0)
98
- ruby2_keywords (0.0.5)
99
- shellany (0.0.1)
100
- thor (1.2.1)
101
- unicode-display_width (2.2.0)
102
-
103
- PLATFORMS
104
- ruby
105
- x86_64-linux
106
-
107
- DEPENDENCIES
108
- bundler
109
- datadog_backup!
110
- guard-rspec
111
- pry
112
- pry-byebug
113
- rspec
114
- rubocop
115
- rubocop-rspec
116
-
117
- BUNDLED WITH
118
- 2.3.20