datadog_backup 0.11.0 → 1.0.0.alpha.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 +4 -4
- data/CHANGELOG.md +13 -0
- data/bin/datadog_backup +2 -1
- data/lib/datadog_backup/cli.rb +2 -2
- data/lib/datadog_backup/core.rb +28 -3
- data/lib/datadog_backup/monitors.rb +1 -1
- data/lib/datadog_backup/version.rb +1 -1
- data/spec/datadog_backup/cli_spec.rb +6 -3
- data/spec/datadog_backup/core_spec.rb +81 -4
- data/spec/datadog_backup/dashboards_spec.rb +5 -3
- data/spec/datadog_backup/monitors_spec.rb +4 -2
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5db8a5e804f30996a50247c24352e3fc1075971d141e37a2093987c510e9c9f1
|
4
|
+
data.tar.gz: 41c6f43d1c15c7e789aabe5a5b9bd34d45e5f5712d4ada557fb32edaeac4dd11
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f34c936e1a48773a4e0d600cfb23414c07b7197d7e72f9e1f7c3e1efd27c6b25b2ec9ab8643228b6b6d055f1b9c83762cf62e743418708ca8a02046405f256f7
|
7
|
+
data.tar.gz: e3f2a91bf80a2ea6c265766b55e07b01ac885a002a4be41f3f6dc7dc9574bdd394a158c1258887814b387290915f9843dc5a07759dc74d5c9d5c491c155b4ffe
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
# [1.0.0-alpha.1](https://github.com/scribd/datadog_backup/compare/v0.11.0...v1.0.0-alpha.1) (2021-01-17)
|
2
|
+
|
3
|
+
|
4
|
+
### Features
|
5
|
+
|
6
|
+
* If resource doesn't exist in Datadog, the resource is recreated. ([95d9699](https://github.com/scribd/datadog_backup/commit/95d9699e3fe6a6ecae0d6690dce225680f1d6a8a))
|
7
|
+
|
8
|
+
|
9
|
+
### BREAKING CHANGES
|
10
|
+
|
11
|
+
* `datadog-backup` used to exit with an error if a resource
|
12
|
+
wasn't found in Datadog.
|
13
|
+
|
1
14
|
# [0.11.0](https://github.com/scribd/datadog_backup/compare/v0.10.3...v0.11.0) (2021-01-12)
|
2
15
|
|
3
16
|
|
data/bin/datadog_backup
CHANGED
@@ -55,7 +55,8 @@ def prereqs
|
|
55
55
|
opts.on('--dashboards-only') do
|
56
56
|
@options[:resources] = [DatadogBackup::Dashboards]
|
57
57
|
end
|
58
|
-
opts.on('--json',
|
58
|
+
opts.on('--json',
|
59
|
+
'format backups as JSON instead of YAML. Does not impact `diffs` nor `restore`, but do not mix formats in the same backup-dir.') do
|
59
60
|
@options[:output_format] = :json
|
60
61
|
end
|
61
62
|
opts.on('--no-color', 'removes colored output from diff format') do
|
data/lib/datadog_backup/cli.rb
CHANGED
@@ -109,7 +109,7 @@ module DatadogBackup
|
|
109
109
|
next unless diff
|
110
110
|
|
111
111
|
if @options[:force_restore]
|
112
|
-
definitive_resource_instance(id).
|
112
|
+
definitive_resource_instance(id).restore(id)
|
113
113
|
else
|
114
114
|
puts '--------------------------------------------------------------------------------'
|
115
115
|
puts format_diff_output([id, diff])
|
@@ -120,7 +120,7 @@ module DatadogBackup
|
|
120
120
|
exit
|
121
121
|
when 'r'
|
122
122
|
puts "Restoring #{id} to Datadog."
|
123
|
-
definitive_resource_instance(id).
|
123
|
+
definitive_resource_instance(id).restore(id)
|
124
124
|
when 'd'
|
125
125
|
puts "Downloading #{id} from Datadog."
|
126
126
|
definitive_resource_instance(id).get_and_write_file(id)
|
data/lib/datadog_backup/core.rb
CHANGED
@@ -73,12 +73,38 @@ module DatadogBackup
|
|
73
73
|
self.class.to_s.split(':').last.downcase
|
74
74
|
end
|
75
75
|
|
76
|
+
# Calls out to Datadog and checks for a '200' response
|
77
|
+
def create(body)
|
78
|
+
result = with_200 do
|
79
|
+
api_service.request(Net::HTTP::Post, "/api/#{api_version}/#{api_resource_name}", nil, body, true)
|
80
|
+
end
|
81
|
+
logger.warn 'Successfully created in datadog.'
|
82
|
+
result
|
83
|
+
end
|
84
|
+
|
76
85
|
# Calls out to Datadog and checks for a '200' response
|
77
86
|
def update(id, body)
|
78
|
-
with_200 do
|
87
|
+
result = with_200 do
|
79
88
|
api_service.request(Net::HTTP::Put, "/api/#{api_version}/#{api_resource_name}/#{id}", nil, body, true)
|
80
89
|
end
|
81
90
|
logger.warn 'Successfully restored to datadog.'
|
91
|
+
result
|
92
|
+
end
|
93
|
+
|
94
|
+
def restore(id)
|
95
|
+
body = load_from_file_by_id(id)
|
96
|
+
begin
|
97
|
+
update(id, body)
|
98
|
+
rescue RuntimeError => e
|
99
|
+
if e.message.include?('Request failed with error ["404"')
|
100
|
+
new_id = create(body).fetch('id')
|
101
|
+
|
102
|
+
get_and_write_file(new_id)
|
103
|
+
FileUtils.rm(find_file_by_id(id))
|
104
|
+
else
|
105
|
+
raise e.message
|
106
|
+
end
|
107
|
+
end
|
82
108
|
end
|
83
109
|
|
84
110
|
def with_200
|
@@ -94,9 +120,8 @@ module DatadogBackup
|
|
94
120
|
sleep(0.1 * retries**5) # 0.1, 3.2, 24.3, 102.4 seconds per retry
|
95
121
|
retry
|
96
122
|
else
|
97
|
-
raise "
|
123
|
+
raise "Net::OpenTimeout: #{e.message}"
|
98
124
|
end
|
99
125
|
end
|
100
|
-
|
101
126
|
end
|
102
127
|
end
|
@@ -45,9 +45,12 @@ describe DatadogBackup::Cli do
|
|
45
45
|
dashboards.write_file('{"text": "diff"}', "#{tempdir}/dashboards/deleted.json")
|
46
46
|
|
47
47
|
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,
|
49
|
-
|
50
|
-
allow(api_service_double).to receive(:request).with(Net::HTTP::Get,
|
48
|
+
allow(api_service_double).to receive(:request).with(Net::HTTP::Get, '/api/v1/dashboard', nil, nil,
|
49
|
+
false).and_return(all_boards)
|
50
|
+
allow(api_service_double).to receive(:request).with(Net::HTTP::Get, '/api/v1/dashboard/stillthere', nil, nil,
|
51
|
+
false).and_return(['200', {}])
|
52
|
+
allow(api_service_double).to receive(:request).with(Net::HTTP::Get, '/api/v1/dashboard/alsostillthere', nil,
|
53
|
+
nil, false).and_return(['200', {}])
|
51
54
|
end
|
52
55
|
|
53
56
|
it 'deletes the file locally as well' do
|
@@ -26,13 +26,13 @@ describe DatadogBackup::Core do
|
|
26
26
|
|
27
27
|
describe '#with_200' do
|
28
28
|
context 'with 200' do
|
29
|
-
subject { core.with_200 {['200', { foo: :bar }]} }
|
29
|
+
subject { core.with_200 { ['200', { foo: :bar }] } }
|
30
30
|
|
31
31
|
it { is_expected.to eq({ foo: :bar }) }
|
32
32
|
end
|
33
33
|
|
34
34
|
context 'with not 200' do
|
35
|
-
subject { core.with_200 {['400',
|
35
|
+
subject { core.with_200 { ['400', 'Error message'] } }
|
36
36
|
|
37
37
|
it 'raises an error' do
|
38
38
|
expect { subject }.to raise_error(RuntimeError)
|
@@ -76,15 +76,92 @@ describe DatadogBackup::Core do
|
|
76
76
|
it { is_expected.to eq 'core' }
|
77
77
|
end
|
78
78
|
|
79
|
+
describe '#create' do
|
80
|
+
subject { core.create({ 'a' => 'b' }) }
|
81
|
+
example 'it calls Dogapi::APIService.request' do
|
82
|
+
stub_const('Dogapi::APIService::API_VERSION', 'v1')
|
83
|
+
allow(core).to receive(:api_service).and_return(api_service_double)
|
84
|
+
allow(core).to receive(:api_version).and_return('v1')
|
85
|
+
allow(core).to receive(:api_resource_name).and_return('dashboard')
|
86
|
+
expect(api_service_double).to receive(:request).with(Net::HTTP::Post, '/api/v1/dashboard', nil, { 'a' => 'b' },
|
87
|
+
true).and_return(['200', { 'id' => 'whatever-id-abc' }])
|
88
|
+
subject
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
79
92
|
describe '#update' do
|
80
|
-
subject { core.update('abc-123-def', '
|
93
|
+
subject { core.update('abc-123-def', { 'a' => 'b' }) }
|
81
94
|
example 'it calls Dogapi::APIService.request' do
|
82
95
|
stub_const('Dogapi::APIService::API_VERSION', 'v1')
|
83
96
|
allow(core).to receive(:api_service).and_return(api_service_double)
|
84
97
|
allow(core).to receive(:api_version).and_return('v1')
|
85
98
|
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,
|
99
|
+
expect(api_service_double).to receive(:request).with(Net::HTTP::Put, '/api/v1/dashboard/abc-123-def', nil,
|
100
|
+
{ 'a' => 'b' }, true).and_return(['200',
|
101
|
+
{ 'id' => 'whataver-man-thats-like-your-opinion' }])
|
87
102
|
subject
|
88
103
|
end
|
89
104
|
end
|
105
|
+
|
106
|
+
describe '#restore' do
|
107
|
+
before(:each) do
|
108
|
+
allow(core).to receive(:api_service).and_return(api_service_double)
|
109
|
+
allow(core).to receive(:api_version).and_return('api-version-string')
|
110
|
+
allow(core).to receive(:api_resource_name).and_return('api-resource-name-string')
|
111
|
+
allow(api_service_double).to receive(:request).with(
|
112
|
+
Net::HTTP::Get,
|
113
|
+
'/api/api-version-string/api-resource-name-string/abc-123-def',
|
114
|
+
nil,
|
115
|
+
nil,
|
116
|
+
false
|
117
|
+
).and_return(['200', { test: :ok }])
|
118
|
+
allow(api_service_double).to receive(:request).with(
|
119
|
+
Net::HTTP::Get,
|
120
|
+
'/api/api-version-string/api-resource-name-string/bad-123-id',
|
121
|
+
nil,
|
122
|
+
nil,
|
123
|
+
false
|
124
|
+
).and_return(['404', { error: :blahblah_not_found }])
|
125
|
+
allow(core).to receive(:load_from_file_by_id).and_return({ 'load' => 'ok' })
|
126
|
+
end
|
127
|
+
|
128
|
+
context 'when id exists' do
|
129
|
+
subject { core.restore('abc-123-def') }
|
130
|
+
example 'it calls out to update' do
|
131
|
+
expect(core).to receive(:update).with('abc-123-def', { 'load' => 'ok' })
|
132
|
+
subject
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
context 'when id does not exist' do
|
137
|
+
before(:each) do
|
138
|
+
allow(api_service_double).to receive(:request).with(
|
139
|
+
Net::HTTP::Put,
|
140
|
+
'/api/api-version-string/api-resource-name-string/bad-123-id',
|
141
|
+
nil, { 'load' => 'ok' },
|
142
|
+
true
|
143
|
+
).and_return(
|
144
|
+
['404', { 'Error' => 'my not found' }]
|
145
|
+
)
|
146
|
+
allow(api_service_double).to receive(:request).with(
|
147
|
+
Net::HTTP::Post,
|
148
|
+
'/api/api-version-string/api-resource-name-string',
|
149
|
+
nil,
|
150
|
+
{ 'load' => 'ok' },
|
151
|
+
true
|
152
|
+
).and_return(
|
153
|
+
['200', { 'id' => 'my-new-id' }]
|
154
|
+
)
|
155
|
+
end
|
156
|
+
|
157
|
+
subject { core.restore('bad-123-id') }
|
158
|
+
example 'it calls out to create then saves the new file and deletes the new file' do
|
159
|
+
expect(core).to receive(:create).with({ 'load' => 'ok' }).and_return({ 'id' => 'my-new-id' })
|
160
|
+
expect(core).to receive(:get_and_write_file).with('my-new-id')
|
161
|
+
allow(core).to receive(:find_file_by_id).with('bad-123-id').and_return('/path/to/bad-123-id.json')
|
162
|
+
expect(FileUtils).to receive(:rm).with('/path/to/bad-123-id.json')
|
163
|
+
subject
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
90
167
|
end
|
@@ -61,8 +61,10 @@ describe DatadogBackup::Dashboards do
|
|
61
61
|
end
|
62
62
|
before(:example) do
|
63
63
|
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,
|
65
|
-
|
64
|
+
allow(api_service_double).to receive(:request).with(Net::HTTP::Get, '/api/v1/dashboard', nil, nil,
|
65
|
+
false).and_return(all_boards)
|
66
|
+
allow(api_service_double).to receive(:request).with(Net::HTTP::Get, '/api/v1/dashboard/abc-123-def', nil, nil,
|
67
|
+
false).and_return(example_dashboard)
|
66
68
|
end
|
67
69
|
|
68
70
|
describe '#backup' do
|
@@ -100,7 +102,7 @@ describe DatadogBackup::Dashboards do
|
|
100
102
|
-title: example dashboard
|
101
103
|
+a: b
|
102
104
|
EOF
|
103
|
-
|
105
|
+
)
|
104
106
|
end
|
105
107
|
end
|
106
108
|
|
@@ -51,8 +51,10 @@ describe DatadogBackup::Monitors do
|
|
51
51
|
|
52
52
|
before(:example) 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,
|
55
|
-
|
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
|
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.
|
4
|
+
version: 1.0.0.alpha.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: 2021-01-
|
12
|
+
date: 2021-01-17 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: amazing_print
|
@@ -183,9 +183,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
183
183
|
version: '0'
|
184
184
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
185
185
|
requirements:
|
186
|
-
- - "
|
186
|
+
- - ">"
|
187
187
|
- !ruby/object:Gem::Version
|
188
|
-
version:
|
188
|
+
version: 1.3.1
|
189
189
|
requirements: []
|
190
190
|
rubygems_version: 3.1.4
|
191
191
|
signing_key:
|