datadog_backup 2.0.2 → 3.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/.github/workflows/rspec_and_release.yml +1 -1
- data/CHANGELOG.md +15 -0
- data/Gemfile.lock +23 -12
- data/README.md +21 -9
- data/bin/datadog_backup +10 -12
- 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 +2 -1
- 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 +54 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 75f5659461aa4a52626f34a4094174cc899e600695e512c9a8f9b613741cda54
|
4
|
+
data.tar.gz: fc74c95bdbadf48eebb12d27648f365c3e83dfe43f51df5e5f3b41e095b6162f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a199e84cdee10ad8bfd0274dda29cdf67b540451748a8a096eafa166ff5f8063bed16dc93318063fefe085f015c85dbc6f93af202af991776f2ef5219e0e3a59
|
7
|
+
data.tar.gz: be2034d46ec881f89338a2c54880a6f39fd1946288e352a68bd1fcc8338b43066574650d373d9401a35203c95897775dc26773abbd17ba4b597b268fb6396622
|
@@ -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
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
# [3.0.0-alpha.1](https://github.com/scribd/datadog_backup/compare/v2.0.2...v3.0.0-alpha.1) (2022-08-24)
|
2
|
+
|
3
|
+
|
4
|
+
* feat!: release 3.0 ([d09d9e6](https://github.com/scribd/datadog_backup/commit/d09d9e6c845edb35c49cbb19ec6b35878304a078))
|
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
|
+
|
1
16
|
## [2.0.2](https://github.com/scribd/datadog_backup/compare/v2.0.1...v2.0.2) (2022-08-11)
|
2
17
|
|
3
18
|
|
data/Gemfile.lock
CHANGED
@@ -1,25 +1,31 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
datadog_backup (2.0.
|
5
|
-
amazing_print
|
6
|
-
concurrent-ruby
|
7
|
-
deepsort
|
8
|
-
diffy
|
9
|
-
|
4
|
+
datadog_backup (2.0.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
|

|
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,10 +79,9 @@ 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
|
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,9 @@ defaults = {
|
|
90
83
|
force_restore: false
|
91
84
|
}
|
92
85
|
|
86
|
+
begin
|
93
87
|
DatadogBackup::Cli.new(prereqs(defaults)).run!
|
88
|
+
rescue => e
|
89
|
+
require 'pry'
|
90
|
+
binding.pry
|
91
|
+
end
|
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
@@ -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.alpha.1
|
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-24 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
61
|
- !ruby/object:Gem::Version
|
62
|
-
version:
|
62
|
+
version: '0'
|
63
63
|
type: :runtime
|
64
64
|
prerelease: false
|
65
65
|
version_requirements: !ruby/object:Gem::Requirement
|
66
66
|
requirements:
|
67
|
-
- - "
|
67
|
+
- - ">="
|
68
68
|
- !ruby/object:Gem::Version
|
69
|
-
version:
|
69
|
+
version: '0'
|
70
70
|
- !ruby/object:Gem::Dependency
|
71
|
-
name:
|
71
|
+
name: faraday
|
72
72
|
requirement: !ruby/object:Gem::Requirement
|
73
73
|
requirements:
|
74
|
-
- - "
|
74
|
+
- - ">="
|
75
75
|
- !ruby/object:Gem::Version
|
76
|
-
version:
|
76
|
+
version: '0'
|
77
77
|
type: :runtime
|
78
78
|
prerelease: false
|
79
79
|
version_requirements: !ruby/object:Gem::Requirement
|
80
80
|
requirements:
|
81
|
-
- - "
|
81
|
+
- - ">="
|
82
82
|
- !ruby/object:Gem::Version
|
83
|
-
version:
|
83
|
+
version: '0'
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: faraday-retry
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
type: :runtime
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::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,12 +254,12 @@ 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
|
+
- - ">"
|
233
261
|
- !ruby/object:Gem::Version
|
234
|
-
version:
|
262
|
+
version: 1.3.1
|
235
263
|
requirements: []
|
236
264
|
rubygems_version: 3.1.6
|
237
265
|
signing_key:
|