datadog_backup 2.0.2 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/rspec_and_release.yml +1 -2
- data/CHANGELOG.md +41 -0
- data/Gemfile.lock +23 -12
- data/README.md +22 -10
- data/bin/datadog_backup +6 -13
- data/datadog_backup.gemspec +9 -6
- data/example/.github/workflows/backup.yml +2 -2
- data/lib/datadog_backup/cli.rb +0 -8
- data/lib/datadog_backup/core.rb +54 -37
- data/lib/datadog_backup/dashboards.rb +5 -9
- data/lib/datadog_backup/monitors.rb +0 -5
- data/lib/datadog_backup/options.rb +0 -12
- data/lib/datadog_backup/version.rb +1 -1
- data/lib/datadog_backup.rb +0 -2
- data/release.config.js +5 -0
- data/spec/datadog_backup/cli_spec.rb +13 -56
- data/spec/datadog_backup/core_spec.rb +28 -61
- data/spec/datadog_backup/dashboards_spec.rb +14 -14
- data/spec/datadog_backup/local_filesystem_spec.rb +0 -3
- data/spec/datadog_backup/monitors_spec.rb +16 -14
- data/spec/datadog_backup_bin_spec.rb +5 -5
- data/spec/spec_helper.rb +2 -3
- metadata +52 -24
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0eec1a1c9c37c415e69f59bccdc5fb28cfc2260b4cf40941c283a588c89727e8
|
4
|
+
data.tar.gz: 202db8cd658b13977d8c9e1dc3248e8bf33411aeeb4102e669f9a572c92dce39
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 48d83c230a6ee5a17957e5c5da124911529e28a230170c3556105639025497d79e8528555cbf8e37b00abc70256399addbaabc1d8101dd367574d248557826af
|
7
|
+
data.tar.gz: 9bcb707a074415be48f1f687f29e524ebcbfbbe60ca85dd7c56a95e3a6d0bcec7606da3504045b716b012c03c3c2a4a16d3808f1150e3e2dfd3a0101d29b7d41
|
@@ -12,7 +12,7 @@ jobs:
|
|
12
12
|
matrix:
|
13
13
|
os: [ubuntu-latest, macos-latest]
|
14
14
|
# Due to https://github.com/actions/runner/issues/849, we have to use quotes for '3.0'
|
15
|
-
ruby: [2.
|
15
|
+
ruby: [2.7, '3.0', '3.1']
|
16
16
|
runs-on: ${{ matrix.os }}
|
17
17
|
steps:
|
18
18
|
- uses: actions/checkout@v3
|
@@ -25,7 +25,6 @@ jobs:
|
|
25
25
|
run: |
|
26
26
|
bundle exec rspec --format documentation --require spec_helper
|
27
27
|
release:
|
28
|
-
if: github.event_name == 'push'
|
29
28
|
needs: rspec
|
30
29
|
runs-on: ubuntu-latest
|
31
30
|
env:
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,44 @@
|
|
1
|
+
# [3.0.0](https://github.com/scribd/datadog_backup/compare/v2.0.2...v3.0.0) (2022-08-25)
|
2
|
+
|
3
|
+
|
4
|
+
* feat!: release 3.0 (#136) ([3d23b03](https://github.com/scribd/datadog_backup/commit/3d23b03668e888886f394de2fa4884aa1e3ca287)), closes [#136](https://github.com/scribd/datadog_backup/issues/136)
|
5
|
+
|
6
|
+
|
7
|
+
### BREAKING CHANGES
|
8
|
+
|
9
|
+
* DATADOG_API_KEY and DATADOG_APP_KEY are no longer the environment variables used to authenticate to Datadog. Instead, set the environment variables DD_API_KEY and DD_APP_KEY.
|
10
|
+
* ruby 2.6 is no longer supported. Please upgrade to ruby 2.7 or higher.
|
11
|
+
* The options `--ssh` and `--ssshh` are no longer supported. Instead, please use `--quiet` to supress logging. `--debug` remains supported.
|
12
|
+
* The environment variable `DATADOG_HOST` is no longer supported. Instead, please use `DD_SITE_URL`.
|
13
|
+
|
14
|
+
refactor: The legacy [dogapi-rb ](https://github.com/DataDog/dogapi-rb) gem is replaced with [faraday](https://lostisland.github.io/faraday/). The [official client library](https://github.com/DataDog/datadog-api-client-ruby) was considered, but was not adopted as I had a hard time grok-ing it.
|
15
|
+
|
16
|
+
* chore: permit logging from tests, but only error+
|
17
|
+
|
18
|
+
Co-authored-by: semantic-release-bot <semantic-release-bot@martynus.net>
|
19
|
+
|
20
|
+
# [3.0.0-alpha.2](https://github.com/scribd/datadog_backup/compare/v3.0.0-alpha.1...v3.0.0-alpha.2) (2022-08-25)
|
21
|
+
|
22
|
+
|
23
|
+
### Bug Fixes
|
24
|
+
|
25
|
+
* remove development pry ([611d0a6](https://github.com/scribd/datadog_backup/commit/611d0a6dd5899b0046fc00233cf679834b275089))
|
26
|
+
|
27
|
+
# [3.0.0-alpha.1](https://github.com/scribd/datadog_backup/compare/v2.0.2...v3.0.0-alpha.1) (2022-08-24)
|
28
|
+
|
29
|
+
|
30
|
+
* feat!: release 3.0 ([d09d9e6](https://github.com/scribd/datadog_backup/commit/d09d9e6c845edb35c49cbb19ec6b35878304a078))
|
31
|
+
|
32
|
+
|
33
|
+
### BREAKING CHANGES
|
34
|
+
|
35
|
+
* DATADOG_API_KEY and DATADOG_APP_KEY are no longer the environment variables used to authenticate to Datadog. Instead, set the environment variables DD_API_KEY and DD_APP_KEY.
|
36
|
+
* ruby 2.6 is no longer supported. Please upgrade to ruby 2.7 or higher.
|
37
|
+
* The options `--ssh` and `--ssshh` are no longer supported. Instead, please use `--quiet` to supress logging. `--debug` remains supported.
|
38
|
+
* The environment variable `DATADOG_HOST` is no longer supported. Instead, please use `DD_SITE_URL`.
|
39
|
+
|
40
|
+
refactor: The legacy [dogapi-rb ](https://github.com/DataDog/dogapi-rb) gem is replaced with [faraday](https://lostisland.github.io/faraday/). The [official client library](https://github.com/DataDog/datadog-api-client-ruby) was considered, but was not adopted as I had a hard time grok-ing it.
|
41
|
+
|
1
42
|
## [2.0.2](https://github.com/scribd/datadog_backup/compare/v2.0.1...v2.0.2) (2022-08-11)
|
2
43
|
|
3
44
|
|
data/Gemfile.lock
CHANGED
@@ -1,25 +1,31 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
datadog_backup (
|
5
|
-
amazing_print
|
6
|
-
concurrent-ruby
|
7
|
-
deepsort
|
8
|
-
diffy
|
9
|
-
|
4
|
+
datadog_backup (3.0.0.alpha.2)
|
5
|
+
amazing_print
|
6
|
+
concurrent-ruby
|
7
|
+
deepsort
|
8
|
+
diffy
|
9
|
+
faraday
|
10
|
+
faraday-retry
|
10
11
|
|
11
12
|
GEM
|
12
13
|
remote: https://rubygems.org/
|
13
14
|
specs:
|
14
15
|
amazing_print (1.4.0)
|
15
16
|
ast (2.4.2)
|
17
|
+
byebug (11.1.3)
|
16
18
|
coderay (1.1.3)
|
17
19
|
concurrent-ruby (1.1.10)
|
18
20
|
deepsort (0.4.5)
|
19
21
|
diff-lcs (1.5.0)
|
20
22
|
diffy (3.4.2)
|
21
|
-
|
22
|
-
|
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)
|
23
29
|
ffi (1.15.5)
|
24
30
|
formatador (1.1.0)
|
25
31
|
guard (2.18.0)
|
@@ -42,7 +48,6 @@ GEM
|
|
42
48
|
rb-inotify (~> 0.9, >= 0.9.10)
|
43
49
|
lumberjack (1.2.8)
|
44
50
|
method_source (1.0.0)
|
45
|
-
multi_json (1.15.0)
|
46
51
|
nenv (0.3.0)
|
47
52
|
notiffany (0.1.3)
|
48
53
|
nenv (~> 0.1)
|
@@ -53,6 +58,9 @@ GEM
|
|
53
58
|
pry (0.14.1)
|
54
59
|
coderay (~> 1.1)
|
55
60
|
method_source (~> 1.0)
|
61
|
+
pry-byebug (3.10.1)
|
62
|
+
byebug (~> 11.0)
|
63
|
+
pry (>= 0.13, < 0.15)
|
56
64
|
rainbow (3.1.1)
|
57
65
|
rb-fsevent (0.11.1)
|
58
66
|
rb-inotify (0.10.1)
|
@@ -72,14 +80,14 @@ GEM
|
|
72
80
|
diff-lcs (>= 1.2.0, < 2.0)
|
73
81
|
rspec-support (~> 3.11.0)
|
74
82
|
rspec-support (3.11.0)
|
75
|
-
rubocop (1.
|
83
|
+
rubocop (1.35.1)
|
76
84
|
json (~> 2.3)
|
77
85
|
parallel (~> 1.10)
|
78
86
|
parser (>= 3.1.2.1)
|
79
87
|
rainbow (>= 2.2.2, < 4.0)
|
80
88
|
regexp_parser (>= 1.8, < 3.0)
|
81
89
|
rexml (>= 3.2.5, < 4.0)
|
82
|
-
rubocop-ast (>= 1.20.
|
90
|
+
rubocop-ast (>= 1.20.1, < 2.0)
|
83
91
|
ruby-progressbar (~> 1.7)
|
84
92
|
unicode-display_width (>= 1.4.0, < 3.0)
|
85
93
|
rubocop-ast (1.21.0)
|
@@ -87,21 +95,24 @@ GEM
|
|
87
95
|
rubocop-rspec (2.12.1)
|
88
96
|
rubocop (~> 1.31)
|
89
97
|
ruby-progressbar (1.11.0)
|
98
|
+
ruby2_keywords (0.0.5)
|
90
99
|
shellany (0.0.1)
|
91
100
|
thor (1.2.1)
|
92
101
|
unicode-display_width (2.2.0)
|
93
102
|
|
94
103
|
PLATFORMS
|
95
104
|
ruby
|
105
|
+
x86_64-linux
|
96
106
|
|
97
107
|
DEPENDENCIES
|
98
108
|
bundler
|
99
109
|
datadog_backup!
|
100
110
|
guard-rspec
|
101
111
|
pry
|
112
|
+
pry-byebug
|
102
113
|
rspec
|
103
114
|
rubocop
|
104
115
|
rubocop-rspec
|
105
116
|
|
106
117
|
BUNDLED WITH
|
107
|
-
2.3.
|
118
|
+
2.3.20
|
data/README.md
CHANGED
@@ -11,6 +11,20 @@ Currently supports
|
|
11
11
|
|
12
12
|
Additional features may be built out over time.
|
13
13
|
|
14
|
+
# v3 Migration
|
15
|
+
|
16
|
+
## Breaking Changes
|
17
|
+
v3 is a backwards incompatible change.
|
18
|
+
|
19
|
+
- [] DATADOG_API_KEY and DATADOG_APP_KEY are no longer the environment variables used to authenticate to Datadog. Instead, set the environment variables DD_API_KEY and DD_APP_KEY.
|
20
|
+
- [ ] ruby 2.6 is no longer supported. Please upgrade to ruby 2.7 or higher.
|
21
|
+
- [ ] The options `--ssh` and `--ssshh` are no longer supported. Instead, please use `--quiet` to supress logging. `--debug` remains supported.
|
22
|
+
- [ ] The environment variable `DATADOG_HOST` is no longer supported. Instead, please use `DD_SITE_URL`.
|
23
|
+
|
24
|
+
## Misc
|
25
|
+
- [ ] The legacy [dogapi-rb ](https://github.com/DataDog/dogapi-rb) gem is replaced with [faraday](https://lostisland.github.io/faraday/). The [official client library](https://github.com/DataDog/datadog-api-client-ruby) was considered, but was not adopted as I had a hard time grok-ing it.
|
26
|
+
|
27
|
+
|
14
28
|
## Installation
|
15
29
|
|
16
30
|
```
|
@@ -22,13 +36,13 @@ gem install datadog_backup
|
|
22
36
|
![demo](images/demo.gif)
|
23
37
|
|
24
38
|
```
|
25
|
-
|
39
|
+
DD_API_KEY=example123 DD_APP_KEY=example123 datadog_backup <backup|diffs|restore> [--backup-dir /path/to/backups] [--debug] [--monitors-only] [--dashboards-only] [--diff-format color|html|html_simple] [--no-color] [--json]
|
26
40
|
```
|
27
41
|
|
28
42
|
```
|
29
43
|
gem install datadog_backup
|
30
|
-
export
|
31
|
-
export
|
44
|
+
export DD_API_KEY=abc123
|
45
|
+
export DD_APP_KEY=abc123
|
32
46
|
|
33
47
|
# Perform backup to `./backup/` using YAML encoding
|
34
48
|
datadog_backup backup
|
@@ -49,8 +63,7 @@ Supply the following parameters in order to customize datadog_backup:
|
|
49
63
|
parameter | description | default
|
50
64
|
---------------------|-------------------------------------------------------------------------------------------------------------------------------|--------------------------
|
51
65
|
--debug | log debug and above | info
|
52
|
-
--
|
53
|
-
--shhh | log errors and above | info
|
66
|
+
--quiet | only show errors and above | info
|
54
67
|
--backup-dir PATH | path to the directory to backup to or restore from | `./backup/`
|
55
68
|
--monitors-only | only backup monitors | backup monitors and dashboards
|
56
69
|
--dashboards-only | only backup dashboards | backup monitors and dashboards
|
@@ -66,15 +79,14 @@ The following environment variables can be set in order to further customize dat
|
|
66
79
|
|
67
80
|
environment variable | description | default
|
68
81
|
---------------------|--------------------------------------------------------------------------------|--------------------------
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
dd_proxy_https | Same as `http_proxy` | none
|
82
|
+
DD_SITE_URL | Describe the API endpoint to connect to (https://api.datadoghq.eu for example) | https://api.datadoghq.com
|
83
|
+
DD_API_KEY | The API key for the Datadog account | none
|
84
|
+
DD_API_KEY | The Application key for the Datadog account | none
|
73
85
|
|
74
86
|
|
75
87
|
### Usage in a Github repo
|
76
88
|
|
77
|
-
See [example/](https://github.com/scribd/datadog_backup/tree/
|
89
|
+
See [example/](https://github.com/scribd/datadog_backup/tree/main/example) for an example implementation as a repo that backs up your Datadog dashboards hourly.
|
78
90
|
|
79
91
|
# Development
|
80
92
|
|
data/bin/datadog_backup
CHANGED
@@ -10,7 +10,6 @@ LOGGER = Logger.new($stderr) unless defined?(LOGGER)
|
|
10
10
|
LOGGER.level = Logger::INFO
|
11
11
|
|
12
12
|
require 'datadog_backup'
|
13
|
-
require 'dogapi'
|
14
13
|
|
15
14
|
|
16
15
|
def fatal(message)
|
@@ -19,9 +18,8 @@ def fatal(message)
|
|
19
18
|
end
|
20
19
|
|
21
20
|
def options_valid?(options)
|
22
|
-
%w[backup diffs restore].include?(options[:action])
|
23
|
-
|
24
|
-
options[:datadog_app_key]
|
21
|
+
%w[backup diffs restore].include?(options[:action])
|
22
|
+
%w[DD_API_KEY DD_APP_KEY].all? { |key| ENV[key] }
|
25
23
|
end
|
26
24
|
|
27
25
|
def prereqs(defaults)
|
@@ -30,7 +28,7 @@ def prereqs(defaults)
|
|
30
28
|
result = defaults.dup
|
31
29
|
|
32
30
|
options = OptionParser.new do |opts|
|
33
|
-
opts.banner = "Usage:
|
31
|
+
opts.banner = "Usage: DD_API_KEY=abc123 DD_APP_KEY=abc123 #{File.basename($PROGRAM_NAME)} <backup|diffs|restore>"
|
34
32
|
opts.separator ''
|
35
33
|
opts.on_tail('-h', '--help', 'Show this message') do
|
36
34
|
puts opts
|
@@ -39,10 +37,7 @@ def prereqs(defaults)
|
|
39
37
|
opts.on('--debug', 'log debug and above') do
|
40
38
|
LOGGER.level = Logger::DEBUG
|
41
39
|
end
|
42
|
-
opts.on('--
|
43
|
-
LOGGER.level = Logger::WARN
|
44
|
-
end
|
45
|
-
opts.on('--shhh', 'log errors and above') do
|
40
|
+
opts.on('--quiet', 'log errors and above') do
|
46
41
|
LOGGER.level = Logger::ERROR
|
47
42
|
end
|
48
43
|
opts.on('--backup-dir PATH', '`backup` by default') do |path|
|
@@ -73,7 +68,7 @@ def prereqs(defaults)
|
|
73
68
|
options.parse!
|
74
69
|
|
75
70
|
result[:action] = ARGV.first
|
76
|
-
fatal(options) unless options_valid?(result)
|
71
|
+
fatal(options.banner) unless options_valid?(result)
|
77
72
|
result
|
78
73
|
end
|
79
74
|
|
@@ -81,8 +76,6 @@ end
|
|
81
76
|
# Default parameters
|
82
77
|
defaults = {
|
83
78
|
action: nil,
|
84
|
-
datadog_api_key: ENV.fetch('DATADOG_API_KEY', nil),
|
85
|
-
datadog_app_key: ENV.fetch('DATADOG_APP_KEY', nil),
|
86
79
|
backup_dir: File.join(ENV.fetch('PWD'), 'backup'),
|
87
80
|
diff_format: :color,
|
88
81
|
resources: [DatadogBackup::Dashboards, DatadogBackup::Monitors],
|
@@ -90,4 +83,4 @@ defaults = {
|
|
90
83
|
force_restore: false
|
91
84
|
}
|
92
85
|
|
93
|
-
DatadogBackup::Cli.new(prereqs(defaults)).run!
|
86
|
+
DatadogBackup::Cli.new(prereqs(defaults)).run!
|
data/datadog_backup.gemspec
CHANGED
@@ -19,16 +19,19 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.test_files = spec.files.grep(%r{^spec/})
|
20
20
|
spec.require_paths = ['lib']
|
21
21
|
|
22
|
-
spec.required_ruby_version = ['>= 2.
|
22
|
+
spec.required_ruby_version = ['>= 2.7']
|
23
|
+
|
24
|
+
spec.add_dependency 'amazing_print'
|
25
|
+
spec.add_dependency 'concurrent-ruby'
|
26
|
+
spec.add_dependency 'deepsort'
|
27
|
+
spec.add_dependency 'diffy'
|
28
|
+
spec.add_dependency 'faraday'
|
29
|
+
spec.add_dependency 'faraday-retry'
|
23
30
|
|
24
|
-
spec.add_dependency 'amazing_print', '~> 1.4.0'
|
25
|
-
spec.add_dependency 'concurrent-ruby', '~> 1.1.10'
|
26
|
-
spec.add_dependency 'deepsort', '~> 0.4.5'
|
27
|
-
spec.add_dependency 'diffy', '~> 3.4.2'
|
28
|
-
spec.add_dependency 'dogapi', '~> 1.45.0'
|
29
31
|
|
30
32
|
spec.add_development_dependency 'bundler'
|
31
33
|
spec.add_development_dependency 'pry'
|
34
|
+
spec.add_development_dependency 'pry-byebug'
|
32
35
|
spec.add_development_dependency 'guard-rspec'
|
33
36
|
spec.add_development_dependency 'rspec'
|
34
37
|
spec.add_development_dependency 'rubocop'
|
@@ -17,8 +17,8 @@ jobs:
|
|
17
17
|
ruby-version: 2.7.1
|
18
18
|
- name: perform backup
|
19
19
|
env:
|
20
|
-
|
21
|
-
|
20
|
+
DD_API_KEY: ${{ secrets.DD_API_KEY }}
|
21
|
+
DD_APP_KEY: ${{ secrets.DD_APP_KEY }}
|
22
22
|
run: |
|
23
23
|
gem install --no-document bundler
|
24
24
|
bundle install --jobs 4 --retry 3
|
data/lib/datadog_backup/cli.rb
CHANGED
@@ -28,13 +28,6 @@ module DatadogBackup
|
|
28
28
|
any_resource_instance.all_files
|
29
29
|
end
|
30
30
|
|
31
|
-
def initialize_client
|
32
|
-
@options[:client] ||= Dogapi::Client.new(
|
33
|
-
datadog_api_key,
|
34
|
-
datadog_app_key
|
35
|
-
)
|
36
|
-
end
|
37
|
-
|
38
31
|
def definitive_resource_instance(id)
|
39
32
|
matching_resource_instance(any_resource_instance.class_from_id(id))
|
40
33
|
end
|
@@ -86,7 +79,6 @@ module DatadogBackup
|
|
86
79
|
|
87
80
|
def initialize(options)
|
88
81
|
@options = options
|
89
|
-
initialize_client
|
90
82
|
end
|
91
83
|
|
92
84
|
def matching_resource_instance(klass)
|
data/lib/datadog_backup/core.rb
CHANGED
@@ -2,14 +2,45 @@
|
|
2
2
|
|
3
3
|
require 'diffy'
|
4
4
|
require 'deepsort'
|
5
|
+
require 'faraday'
|
6
|
+
require 'faraday/retry'
|
7
|
+
|
8
|
+
|
5
9
|
|
6
10
|
module DatadogBackup
|
7
11
|
class Core
|
8
12
|
include ::DatadogBackup::LocalFilesystem
|
9
13
|
include ::DatadogBackup::Options
|
10
14
|
|
15
|
+
@@retry_options = {
|
16
|
+
max: 5,
|
17
|
+
interval: 0.05,
|
18
|
+
interval_randomness: 0.5,
|
19
|
+
backoff_factor: 2
|
20
|
+
}
|
21
|
+
|
11
22
|
def api_service
|
12
|
-
|
23
|
+
conn ||= 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/")
|
13
44
|
end
|
14
45
|
|
15
46
|
def api_version
|
@@ -44,19 +75,17 @@ module DatadogBackup
|
|
44
75
|
end
|
45
76
|
|
46
77
|
def get(id)
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
return {} if e.message.include?('Request failed with error ["404"')
|
52
|
-
|
53
|
-
raise e.message
|
78
|
+
params = {}
|
79
|
+
headers = {}
|
80
|
+
response = api_service.get("/api/#{api_version}/#{api_resource_name}/#{id}", params, headers)
|
81
|
+
body_with_2xx(response)
|
54
82
|
end
|
55
83
|
|
56
84
|
def get_all
|
57
|
-
|
58
|
-
|
59
|
-
|
85
|
+
params = {}
|
86
|
+
headers = {}
|
87
|
+
response = api_service.get("/api/#{api_version}/#{api_resource_name}", params, headers)
|
88
|
+
body_with_2xx(response)
|
60
89
|
end
|
61
90
|
|
62
91
|
def get_and_write_file(id)
|
@@ -79,20 +108,20 @@ module DatadogBackup
|
|
79
108
|
|
80
109
|
# Calls out to Datadog and checks for a '200' response
|
81
110
|
def create(body)
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
LOGGER.warn
|
86
|
-
|
111
|
+
headers = {}
|
112
|
+
response = api_service.post("/api/#{api_version}/#{api_resource_name}", body, headers)
|
113
|
+
body = body_with_2xx(response)
|
114
|
+
LOGGER.warn "Successfully created #{body.fetch('id')} in datadog."
|
115
|
+
body
|
87
116
|
end
|
88
117
|
|
89
118
|
# Calls out to Datadog and checks for a '200' response
|
90
119
|
def update(id, body)
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
LOGGER.warn 'Successfully restored to datadog.'
|
95
|
-
|
120
|
+
headers = {}
|
121
|
+
response = api_service.put("/api/#{api_version}/#{api_resource_name}/#{id}", body, headers)
|
122
|
+
body = body_with_2xx(response)
|
123
|
+
LOGGER.warn 'Successfully restored #{id} to datadog.'
|
124
|
+
body
|
96
125
|
end
|
97
126
|
|
98
127
|
def restore(id)
|
@@ -100,7 +129,7 @@ module DatadogBackup
|
|
100
129
|
begin
|
101
130
|
update(id, body)
|
102
131
|
rescue RuntimeError => e
|
103
|
-
if e.message.include?('
|
132
|
+
if e.message.include?('update failed with error 404')
|
104
133
|
new_id = create(body).fetch('id')
|
105
134
|
|
106
135
|
FileUtils.rm(find_file_by_id(id))
|
@@ -111,21 +140,9 @@ module DatadogBackup
|
|
111
140
|
end
|
112
141
|
end
|
113
142
|
|
114
|
-
def
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
response = yield
|
119
|
-
raise "Request failed with error #{response}" unless response[0] == '200'
|
120
|
-
|
121
|
-
response[1]
|
122
|
-
rescue ::Net::OpenTimeout => e
|
123
|
-
if (retries += 1) <= max_retries
|
124
|
-
sleep(0.1 * retries**5) # 0.1, 3.2, 24.3, 102.4 seconds per retry
|
125
|
-
retry
|
126
|
-
else
|
127
|
-
raise "Net::OpenTimeout: #{e.message}"
|
128
|
-
end
|
143
|
+
def body_with_2xx(response)
|
144
|
+
raise "#{caller_locations(1,1)[0].label} failed with error #{response.status}" unless response.status.to_s =~ /^2/
|
145
|
+
response.body
|
129
146
|
end
|
130
147
|
end
|
131
148
|
end
|
@@ -2,14 +2,6 @@
|
|
2
2
|
|
3
3
|
module DatadogBackup
|
4
4
|
class Dashboards < Core
|
5
|
-
def all_boards
|
6
|
-
get_all.fetch('dashboards')
|
7
|
-
end
|
8
|
-
|
9
|
-
def api_service
|
10
|
-
# The underlying class from Dogapi that talks to datadog
|
11
|
-
client.instance_variable_get(:@dashboard_service)
|
12
|
-
end
|
13
5
|
|
14
6
|
def api_version
|
15
7
|
'v1'
|
@@ -22,7 +14,7 @@ module DatadogBackup
|
|
22
14
|
def backup
|
23
15
|
LOGGER.info("Starting diffs on #{::DatadogBackup::ThreadPool::TPOOL.max_length} threads")
|
24
16
|
|
25
|
-
futures =
|
17
|
+
futures = all_dashboards.map do |board|
|
26
18
|
Concurrent::Promises.future_on(::DatadogBackup::ThreadPool::TPOOL, board) do |board|
|
27
19
|
id = board['id']
|
28
20
|
get_and_write_file(id)
|
@@ -35,6 +27,10 @@ module DatadogBackup
|
|
35
27
|
Concurrent::Promises.zip(*futures).value!
|
36
28
|
end
|
37
29
|
|
30
|
+
def all_dashboards
|
31
|
+
get_all.fetch('dashboards')
|
32
|
+
end
|
33
|
+
|
38
34
|
def initialize(options)
|
39
35
|
super(options)
|
40
36
|
@banlist = %w[modified_at url].freeze
|
@@ -10,22 +10,10 @@ module DatadogBackup
|
|
10
10
|
@options[:backup_dir]
|
11
11
|
end
|
12
12
|
|
13
|
-
def client
|
14
|
-
@options[:client]
|
15
|
-
end
|
16
|
-
|
17
13
|
def concurrency_limit
|
18
14
|
@options[:concurrency_limit] | 2
|
19
15
|
end
|
20
16
|
|
21
|
-
def datadog_api_key
|
22
|
-
@options[:datadog_api_key]
|
23
|
-
end
|
24
|
-
|
25
|
-
def datadog_app_key
|
26
|
-
@options[:datadog_app_key]
|
27
|
-
end
|
28
|
-
|
29
17
|
def diff_format
|
30
18
|
@options[:diff_format]
|
31
19
|
end
|
data/lib/datadog_backup.rb
CHANGED
data/release.config.js
CHANGED
@@ -3,63 +3,35 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
describe DatadogBackup::Cli do
|
6
|
-
let(:
|
7
|
-
let(:
|
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
14
|
output_format: :json,
|
18
15
|
resources: [DatadogBackup::Dashboards]
|
19
16
|
}
|
20
17
|
end
|
21
18
|
let(:cli) { described_class.new(options) }
|
22
|
-
let(:dashboards)
|
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
|
23
24
|
|
24
25
|
before do
|
25
26
|
allow(cli).to receive(:resource_instances).and_return([dashboards])
|
26
27
|
end
|
27
28
|
|
28
|
-
describe '#initialize_client' do
|
29
|
-
subject { described_class.new({ datadog_api_key: 1, datadog_app_key: 1 }).initialize_client }
|
30
|
-
|
31
|
-
it { is_expected.to be_a(Dogapi::Client) }
|
32
|
-
|
33
|
-
context 'when the environment variable DATADOG_HOST is set to a custom host like https://api.datadoghq.eu' do
|
34
|
-
before do
|
35
|
-
stub_const('ENV', 'DATADOG_HOST' => 'https://api.datadoghq.eu')
|
36
|
-
end
|
37
|
-
|
38
|
-
describe 'then #datadog_host is https://api.datadoghq.eu' do
|
39
|
-
subject { described_class.new({ datadog_api_key: 1, datadog_app_key: 1 }).initialize_client.datadog_host }
|
40
|
-
|
41
|
-
it { is_expected.to eq('https://api.datadoghq.eu') }
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
context 'when the environment variable DATADOG_HOST is not set' do
|
46
|
-
before do
|
47
|
-
stub_const('ENV', {})
|
48
|
-
end
|
49
|
-
|
50
|
-
describe 'then #datadog_host is https://api.datadoghq.eu' do
|
51
|
-
subject { described_class.new({ datadog_api_key: 1, datadog_app_key: 1 }).initialize_client.datadog_host }
|
52
|
-
|
53
|
-
it { is_expected.to eq('https://api.datadoghq.com') }
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
29
|
describe '#backup' do
|
59
30
|
context 'when dashboards are deleted in datadog' do
|
60
|
-
let(:
|
31
|
+
let(:all_dashboards) do
|
61
32
|
[
|
62
|
-
|
33
|
+
200,
|
34
|
+
{},
|
63
35
|
{
|
64
36
|
'dashboards' => [
|
65
37
|
{ 'id' => 'stillthere' },
|
@@ -74,22 +46,9 @@ describe DatadogBackup::Cli do
|
|
74
46
|
dashboards.write_file('{"text": "diff"}', "#{tempdir}/dashboards/alsostillthere.json")
|
75
47
|
dashboards.write_file('{"text": "diff"}', "#{tempdir}/dashboards/deleted.json")
|
76
48
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
nil,
|
81
|
-
nil,
|
82
|
-
false).and_return(all_boards)
|
83
|
-
allow(api_service_double).to receive(:request).with(Net::HTTP::Get,
|
84
|
-
'/api/v1/dashboard/stillthere',
|
85
|
-
nil,
|
86
|
-
nil,
|
87
|
-
false).and_return(['200', {}])
|
88
|
-
allow(api_service_double).to receive(:request).with(Net::HTTP::Get,
|
89
|
-
'/api/v1/dashboard/alsostillthere',
|
90
|
-
nil,
|
91
|
-
nil,
|
92
|
-
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, {}, {}]}
|
93
52
|
end
|
94
53
|
|
95
54
|
it 'deletes the file locally as well' do
|
@@ -107,7 +66,6 @@ describe DatadogBackup::Cli do
|
|
107
66
|
dashboards.write_file('{"text": "diff"}', "#{tempdir}/dashboards/diffs2.json")
|
108
67
|
dashboards.write_file('{"text": "diff"}', "#{tempdir}/dashboards/diffs3.json")
|
109
68
|
allow(dashboards).to receive(:get_by_id).and_return({ 'text' => 'diff2' })
|
110
|
-
allow(cli).to receive(:initialize_client).and_return(client_double)
|
111
69
|
end
|
112
70
|
|
113
71
|
it {
|
@@ -125,7 +83,6 @@ describe DatadogBackup::Cli do
|
|
125
83
|
before do
|
126
84
|
dashboards.write_file('{"text": "diff"}', "#{tempdir}/dashboards/diffs1.json")
|
127
85
|
allow(dashboards).to receive(:get_by_id).and_return({ 'text' => 'diff2' })
|
128
|
-
allow(cli).to receive(:initialize_client).and_return(client_double)
|
129
86
|
end
|
130
87
|
|
131
88
|
example 'starts interactive restore' do
|
@@ -3,42 +3,23 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
describe DatadogBackup::Core do
|
6
|
-
let(:
|
7
|
-
let(:
|
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
15
|
output_format: :json
|
18
16
|
)
|
17
|
+
allow(core).to receive(:api_service).and_return(api_client_double)
|
18
|
+
return core
|
19
19
|
end
|
20
20
|
|
21
|
-
describe '#client' do
|
22
|
-
subject { core.client }
|
23
21
|
|
24
|
-
it { is_expected.to eq client_double }
|
25
|
-
end
|
26
|
-
|
27
|
-
describe '#with_200' do
|
28
|
-
context 'with 200' do
|
29
|
-
subject { core.with_200 { ['200', { foo: :bar }] } }
|
30
|
-
|
31
|
-
it { is_expected.to eq({ foo: :bar }) }
|
32
|
-
end
|
33
22
|
|
34
|
-
context 'with not 200' do
|
35
|
-
subject { core.with_200 { ['400', 'Error message'] } }
|
36
|
-
|
37
|
-
it 'raises an error' do
|
38
|
-
expect { subject }.to raise_error(RuntimeError)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
23
|
|
43
24
|
describe '#diff' do
|
44
25
|
subject { core.diff('diff') }
|
@@ -83,52 +64,44 @@ describe DatadogBackup::Core do
|
|
83
64
|
describe '#create' do
|
84
65
|
subject { core.create({ 'a' => 'b' }) }
|
85
66
|
|
86
|
-
example 'it
|
87
|
-
stub_const('Dogapi::APIService::API_VERSION', 'v1')
|
88
|
-
allow(core).to receive(:api_service).and_return(api_service_double)
|
67
|
+
example 'it will post /api/v1/dashboard' do
|
89
68
|
allow(core).to receive(:api_version).and_return('v1')
|
90
69
|
allow(core).to receive(:api_resource_name).and_return('dashboard')
|
91
|
-
|
92
|
-
'/api/v1/dashboard',
|
93
|
-
nil,
|
94
|
-
{ 'a' => 'b' },
|
95
|
-
true).and_return(['200', { 'id' => 'whatever-id-abc' }])
|
70
|
+
stubs.post('/api/v1/dashboard', {'a' => 'b'}) {[200, {}, {'id' => 'whatever-id-abc' }]}
|
96
71
|
subject
|
72
|
+
stubs.verify_stubbed_calls
|
97
73
|
end
|
98
74
|
end
|
99
75
|
|
100
76
|
describe '#update' do
|
101
77
|
subject { core.update('abc-123-def', { 'a' => 'b' }) }
|
102
78
|
|
103
|
-
example 'it
|
104
|
-
stub_const('Dogapi::APIService::API_VERSION', 'v1')
|
105
|
-
allow(core).to receive(:api_service).and_return(api_service_double)
|
79
|
+
example 'it puts /api/v1/dashboard' do
|
106
80
|
allow(core).to receive(:api_version).and_return('v1')
|
107
81
|
allow(core).to receive(:api_resource_name).and_return('dashboard')
|
108
|
-
|
109
|
-
'/api/v1/dashboard/abc-123-def',
|
110
|
-
nil,
|
111
|
-
{ 'a' => 'b' },
|
112
|
-
true).and_return(['200', { 'id' => 'whatever-id-abc' }])
|
82
|
+
stubs.put('/api/v1/dashboard/abc-123-def', {'a' => 'b'}) {[200, {}, {'id' => 'whatever-id-abc' }]}
|
113
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
|
114
96
|
end
|
115
97
|
end
|
116
98
|
|
117
99
|
describe '#restore' do
|
118
100
|
before do
|
119
|
-
allow(core).to receive(:api_service).and_return(api_service_double)
|
120
101
|
allow(core).to receive(:api_version).and_return('api-version-string')
|
121
102
|
allow(core).to receive(:api_resource_name).and_return('api-resource-name-string')
|
122
|
-
|
123
|
-
|
124
|
-
nil,
|
125
|
-
nil,
|
126
|
-
false).and_return(['200', { test: :ok }])
|
127
|
-
allow(api_service_double).to receive(:request).with(Net::HTTP::Get,
|
128
|
-
'/api/api-version-string/api-resource-name-string/bad-123-id',
|
129
|
-
nil,
|
130
|
-
nil,
|
131
|
-
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' }]}
|
132
105
|
allow(core).to receive(:load_from_file_by_id).and_return({ 'load' => 'ok' })
|
133
106
|
end
|
134
107
|
|
@@ -141,19 +114,13 @@ describe DatadogBackup::Core do
|
|
141
114
|
end
|
142
115
|
end
|
143
116
|
|
144
|
-
context 'when id does not exist' do
|
117
|
+
context 'when id does not exist on remote' do
|
145
118
|
subject { core.restore('bad-123-id') }
|
146
119
|
|
147
120
|
before do
|
148
|
-
allow(
|
149
|
-
|
150
|
-
|
151
|
-
true).and_return(['404', { 'Error' => 'my not found' }])
|
152
|
-
allow(api_service_double).to receive(:request).with(Net::HTTP::Post,
|
153
|
-
'/api/api-version-string/api-resource-name-string',
|
154
|
-
nil,
|
155
|
-
{ 'load' => 'ok' },
|
156
|
-
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' }]}
|
157
124
|
end
|
158
125
|
|
159
126
|
example 'it calls out to create then saves the new file and deletes the new file' do
|
@@ -3,17 +3,18 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
describe DatadogBackup::Dashboards do
|
6
|
-
let(:
|
7
|
-
let(:
|
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
14
|
resources: []
|
16
15
|
)
|
16
|
+
allow(dashboards).to receive(:api_service).and_return(api_client_double)
|
17
|
+
return dashboards
|
17
18
|
end
|
18
19
|
let(:dashboard_description) do
|
19
20
|
{
|
@@ -22,9 +23,10 @@ describe DatadogBackup::Dashboards do
|
|
22
23
|
'title' => 'foo'
|
23
24
|
}
|
24
25
|
end
|
25
|
-
let(:
|
26
|
+
let(:all_dashboards) do
|
26
27
|
[
|
27
|
-
|
28
|
+
200,
|
29
|
+
{},
|
28
30
|
{
|
29
31
|
'dashboards' => [
|
30
32
|
dashboard_description
|
@@ -34,7 +36,8 @@ describe DatadogBackup::Dashboards do
|
|
34
36
|
end
|
35
37
|
let(:example_dashboard) do
|
36
38
|
[
|
37
|
-
|
39
|
+
200,
|
40
|
+
{},
|
38
41
|
board_abc_123_def
|
39
42
|
]
|
40
43
|
end
|
@@ -60,11 +63,8 @@ describe DatadogBackup::Dashboards do
|
|
60
63
|
end
|
61
64
|
|
62
65
|
before do
|
63
|
-
|
64
|
-
|
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
|
+
stubs.get('/api/v1/dashboard') { all_dashboards }
|
67
|
+
stubs.get('/api/v1/dashboard/abc-123-def') { example_dashboard }
|
68
68
|
end
|
69
69
|
|
70
70
|
describe '#backup' do
|
@@ -80,8 +80,8 @@ describe DatadogBackup::Dashboards do
|
|
80
80
|
end
|
81
81
|
end
|
82
82
|
|
83
|
-
describe '#
|
84
|
-
subject { dashboards.
|
83
|
+
describe '#all_dashboards' do
|
84
|
+
subject { dashboards.all_dashboards }
|
85
85
|
|
86
86
|
it { is_expected.to eq [dashboard_description] }
|
87
87
|
end
|
@@ -3,12 +3,10 @@
|
|
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
12
|
output_format: :json
|
@@ -17,7 +15,6 @@ describe DatadogBackup::LocalFilesystem do
|
|
17
15
|
let(:core_yaml) do
|
18
16
|
DatadogBackup::Core.new(
|
19
17
|
action: 'backup',
|
20
|
-
client: client_double,
|
21
18
|
backup_dir: tempdir,
|
22
19
|
resources: [],
|
23
20
|
output_format: :yaml
|
@@ -3,18 +3,20 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
describe DatadogBackup::Monitors do
|
6
|
-
let(:
|
7
|
-
let(:
|
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
14
|
resources: []
|
16
15
|
)
|
16
|
+
allow(monitors).to receive(:api_service).and_return(api_client_double)
|
17
|
+
return monitors
|
17
18
|
end
|
19
|
+
|
18
20
|
let(:monitor_description) do
|
19
21
|
{
|
20
22
|
'query' => 'bar',
|
@@ -35,7 +37,8 @@ describe DatadogBackup::Monitors do
|
|
35
37
|
end
|
36
38
|
let(:all_monitors) do
|
37
39
|
[
|
38
|
-
|
40
|
+
200,
|
41
|
+
{},
|
39
42
|
[
|
40
43
|
monitor_description
|
41
44
|
]
|
@@ -43,17 +46,15 @@ describe DatadogBackup::Monitors do
|
|
43
46
|
end
|
44
47
|
let(:example_monitor) do
|
45
48
|
[
|
46
|
-
|
49
|
+
200,
|
50
|
+
{},
|
47
51
|
monitor_description
|
48
52
|
]
|
49
53
|
end
|
50
54
|
|
51
55
|
before do
|
52
|
-
|
53
|
-
|
54
|
-
false).and_return(all_monitors)
|
55
|
-
allow(api_service_double).to receive(:request).with(Net::HTTP::Get, '/api/v1/dashboard/123455', nil, nil,
|
56
|
-
false).and_return(example_monitor)
|
56
|
+
stubs.get('/api/v1/monitor') { all_monitors }
|
57
|
+
stubs.get('/api/v1/dashboard/123455') { example_monitor }
|
57
58
|
end
|
58
59
|
|
59
60
|
describe '#all_monitors' do
|
@@ -78,9 +79,10 @@ describe DatadogBackup::Monitors do
|
|
78
79
|
describe '#diff and #except' do
|
79
80
|
example 'it ignores `overall_state` and `overall_state_modified`' do
|
80
81
|
monitors.write_file(monitors.dump(monitor_description), monitors.filename(123_455))
|
81
|
-
|
82
|
+
stubs.get('/api/v1/dashboard/123455') {
|
82
83
|
[
|
83
|
-
|
84
|
+
200,
|
85
|
+
{},
|
84
86
|
[
|
85
87
|
{
|
86
88
|
'query' => 'bar',
|
@@ -92,7 +94,7 @@ describe DatadogBackup::Monitors do
|
|
92
94
|
}
|
93
95
|
]
|
94
96
|
]
|
95
|
-
|
97
|
+
}
|
96
98
|
|
97
99
|
expect(monitors.diff(123_455)).to eq ''
|
98
100
|
|
@@ -17,13 +17,13 @@ describe 'bin/datadog_backup' do
|
|
17
17
|
i.close
|
18
18
|
end
|
19
19
|
|
20
|
-
Timeout.timeout(
|
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.
|
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
|
-
|
36
|
-
|
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:
|
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
@@ -4,12 +4,11 @@ $LOAD_PATH.unshift(File.expand_path('../lib', File.dirname(__FILE__)))
|
|
4
4
|
|
5
5
|
require 'logger'
|
6
6
|
$stdout.sync = $stderr.sync = true
|
7
|
-
LOGGER = Logger.new(
|
8
|
-
LOGGER.level = Logger::
|
7
|
+
LOGGER = Logger.new($stderr)
|
8
|
+
LOGGER.level = Logger::ERROR
|
9
9
|
$stdout = File.new('/dev/null', 'w+')
|
10
10
|
|
11
11
|
require 'tmpdir'
|
12
|
-
require 'dogapi'
|
13
12
|
require 'datadog_backup'
|
14
13
|
|
15
14
|
|
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:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kamran Farhadi
|
@@ -9,78 +9,92 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2022-08-
|
12
|
+
date: 2022-08-25 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: amazing_print
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
|
-
- - "
|
18
|
+
- - ">="
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version:
|
20
|
+
version: '0'
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
|
-
- - "
|
25
|
+
- - ">="
|
26
26
|
- !ruby/object:Gem::Version
|
27
|
-
version:
|
27
|
+
version: '0'
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: concurrent-ruby
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
31
31
|
requirements:
|
32
|
-
- - "
|
32
|
+
- - ">="
|
33
33
|
- !ruby/object:Gem::Version
|
34
|
-
version:
|
34
|
+
version: '0'
|
35
35
|
type: :runtime
|
36
36
|
prerelease: false
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
|
-
- - "
|
39
|
+
- - ">="
|
40
40
|
- !ruby/object:Gem::Version
|
41
|
-
version:
|
41
|
+
version: '0'
|
42
42
|
- !ruby/object:Gem::Dependency
|
43
43
|
name: deepsort
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
45
45
|
requirements:
|
46
|
-
- - "
|
46
|
+
- - ">="
|
47
47
|
- !ruby/object:Gem::Version
|
48
|
-
version: 0
|
48
|
+
version: '0'
|
49
49
|
type: :runtime
|
50
50
|
prerelease: false
|
51
51
|
version_requirements: !ruby/object:Gem::Requirement
|
52
52
|
requirements:
|
53
|
-
- - "
|
53
|
+
- - ">="
|
54
54
|
- !ruby/object:Gem::Version
|
55
|
-
version: 0
|
55
|
+
version: '0'
|
56
56
|
- !ruby/object:Gem::Dependency
|
57
57
|
name: diffy
|
58
58
|
requirement: !ruby/object:Gem::Requirement
|
59
59
|
requirements:
|
60
|
-
- - "
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
type: :runtime
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: faraday
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
61
75
|
- !ruby/object:Gem::Version
|
62
|
-
version:
|
76
|
+
version: '0'
|
63
77
|
type: :runtime
|
64
78
|
prerelease: false
|
65
79
|
version_requirements: !ruby/object:Gem::Requirement
|
66
80
|
requirements:
|
67
|
-
- - "
|
81
|
+
- - ">="
|
68
82
|
- !ruby/object:Gem::Version
|
69
|
-
version:
|
83
|
+
version: '0'
|
70
84
|
- !ruby/object:Gem::Dependency
|
71
|
-
name:
|
85
|
+
name: faraday-retry
|
72
86
|
requirement: !ruby/object:Gem::Requirement
|
73
87
|
requirements:
|
74
|
-
- - "
|
88
|
+
- - ">="
|
75
89
|
- !ruby/object:Gem::Version
|
76
|
-
version:
|
90
|
+
version: '0'
|
77
91
|
type: :runtime
|
78
92
|
prerelease: false
|
79
93
|
version_requirements: !ruby/object:Gem::Requirement
|
80
94
|
requirements:
|
81
|
-
- - "
|
95
|
+
- - ">="
|
82
96
|
- !ruby/object:Gem::Version
|
83
|
-
version:
|
97
|
+
version: '0'
|
84
98
|
- !ruby/object:Gem::Dependency
|
85
99
|
name: bundler
|
86
100
|
requirement: !ruby/object:Gem::Requirement
|
@@ -109,6 +123,20 @@ dependencies:
|
|
109
123
|
- - ">="
|
110
124
|
- !ruby/object:Gem::Version
|
111
125
|
version: '0'
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: pry-byebug
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
requirements:
|
130
|
+
- - ">="
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: '0'
|
133
|
+
type: :development
|
134
|
+
prerelease: false
|
135
|
+
version_requirements: !ruby/object:Gem::Requirement
|
136
|
+
requirements:
|
137
|
+
- - ">="
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: '0'
|
112
140
|
- !ruby/object:Gem::Dependency
|
113
141
|
name: guard-rspec
|
114
142
|
requirement: !ruby/object:Gem::Requirement
|
@@ -226,7 +254,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
226
254
|
requirements:
|
227
255
|
- - ">="
|
228
256
|
- !ruby/object:Gem::Version
|
229
|
-
version: '2.
|
257
|
+
version: '2.7'
|
230
258
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
231
259
|
requirements:
|
232
260
|
- - ">="
|