datadog_backup 2.0.2 → 3.0.0.alpha.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 985fb90b7482b78cf13ce586048eba798002d79aa0a00aa1475f2c9030fe5585
4
- data.tar.gz: 34e55a0a46912ac13a06cf022f63e97474d576b28377b38695bae14606871388
3
+ metadata.gz: 75f5659461aa4a52626f34a4094174cc899e600695e512c9a8f9b613741cda54
4
+ data.tar.gz: fc74c95bdbadf48eebb12d27648f365c3e83dfe43f51df5e5f3b41e095b6162f
5
5
  SHA512:
6
- metadata.gz: 5783ab3fc1be9f27f99c9039f7ea3a1b0b3c5eae72278cdf99c2b954242c93dcf932bace845adaa825ed4481a4a6f39fe502ae2fedbb9a24973eed5b1b576f6c
7
- data.tar.gz: 293c615e05587b9adf6af65e719e5ff3f8ab9f1441625904248c644a5b3ddaaad51cd5c265f8e99b784fbac6ba86fa41e71e5739a95049bedcc77d84dc575d53
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.6, 2.7, '3.0', '3.1']
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.1)
5
- amazing_print (~> 1.4.0)
6
- concurrent-ruby (~> 1.1.10)
7
- deepsort (~> 0.4.5)
8
- diffy (~> 3.4.2)
9
- dogapi (~> 1.45.0)
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
- dogapi (1.45.0)
22
- multi_json
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.34.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.0, < 2.0)
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.19
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
- DATADOG_API_KEY=example123 DATADOG_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]
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 DATADOG_API_KEY=abc123
31
- export DATADOG_APP_KEY=abc123
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
- --shh | log warnings and above | info
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
- DATADOG_HOST | Describe the API endpoint to connect to (https://api.datadoghq.eu for example) | https://api.datadoghq.com
70
- http_proxy | Instruct Dogapi to connect via a differnt proxy address | none
71
- https_proxy | Same as `http_proxy` | none
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
- options[:datadog_api_key] &&
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: DATADOG_API_KEY=abc123 DATADOG_APP_KEY=abc123 #{File.basename($PROGRAM_NAME)} <backup|diffs|restore>"
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('--shh', 'log warnings and above') do
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
@@ -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.6']
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
- DATADOG_API_KEY: ${{ secrets.DATADOG_API_KEY }}
21
- DATADOG_APP_KEY: ${{ secrets.DATADOG_APP_KEY }}
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
@@ -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)
@@ -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
- raise 'subclass is expected to implement #api_service'
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
- with_200 do
48
- api_service.request(Net::HTTP::Get, "/api/#{api_version}/#{api_resource_name}/#{id}", nil, nil, false)
49
- end
50
- rescue RuntimeError => e
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
- with_200 do
58
- api_service.request(Net::HTTP::Get, "/api/#{api_version}/#{api_resource_name}", nil, nil, false)
59
- end
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
- result = with_200 do
83
- api_service.request(Net::HTTP::Post, "/api/#{api_version}/#{api_resource_name}", nil, body, true)
84
- end
85
- LOGGER.warn 'Successfully created in datadog.'
86
- result
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
- result = with_200 do
92
- api_service.request(Net::HTTP::Put, "/api/#{api_version}/#{api_resource_name}/#{id}", nil, body, true)
93
- end
94
- LOGGER.warn 'Successfully restored to datadog.'
95
- result
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?('Request failed with error ["404"')
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 with_200
115
- max_retries = 6
116
- retries ||= 0
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 = all_boards.map do |board|
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
@@ -6,11 +6,6 @@ module DatadogBackup
6
6
  @all_monitors ||= get_all
7
7
  end
8
8
 
9
- def api_service
10
- # The underlying class from Dogapi that talks to datadog
11
- client.instance_variable_get(:@monitor_svc)
12
- end
13
-
14
9
  def api_version
15
10
  'v1'
16
11
  end
@@ -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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DatadogBackup
4
- VERSION = '2.0.2'
4
+ VERSION = '3.0.0.alpha.1'
5
5
  end
@@ -2,7 +2,8 @@
2
2
 
3
3
  require 'concurrent'
4
4
 
5
- require 'dogapi'
5
+ require 'pry' #TODO: remove this
6
+ require 'pry-byebug' #TODO: remove this
6
7
 
7
8
  require_relative 'datadog_backup/local_filesystem'
8
9
  require_relative 'datadog_backup/options'
@@ -3,63 +3,35 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  describe DatadogBackup::Cli do
6
- let(:api_service_double) { double(Dogapi::APIService) }
7
- let(:client_double) { double }
6
+ let(:stubs) { Faraday::Adapter::Test::Stubs.new }
7
+ let(:api_client_double) { Faraday.new { |f| f.adapter :test, stubs } }
8
8
  let(:tempdir) { Dir.mktmpdir }
9
9
  let(:options) do
10
10
  {
11
11
  action: 'backup',
12
12
  backup_dir: tempdir,
13
- client: client_double,
14
- datadog_api_key: 1,
15
- datadog_app_key: 1,
16
13
  diff_format: nil,
17
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) { DatadogBackup::Dashboards.new(options) }
19
+ let(:dashboards) do
20
+ dashboards = DatadogBackup::Dashboards.new(options)
21
+ allow(dashboards).to receive(:api_service).and_return(api_client_double)
22
+ return dashboards
23
+ end
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(:all_boards) do
31
+ let(:all_dashboards) do
61
32
  [
62
- '200',
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
- allow(client_double).to receive(:instance_variable_get).with(:@dashboard_service).and_return(api_service_double)
78
- allow(api_service_double).to receive(:request).with(Net::HTTP::Get,
79
- '/api/v1/dashboard',
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(:api_service_double) { double(Dogapi::APIService) }
7
- let(:client_double) { double }
6
+ let(:stubs) { Faraday::Adapter::Test::Stubs.new }
7
+ let(:api_client_double) { Faraday.new { |f| f.adapter :test, stubs } }
8
8
  let(:tempdir) { Dir.mktmpdir }
9
9
  let(:core) do
10
- described_class.new(
10
+ core = described_class.new(
11
11
  action: 'backup',
12
- api_service: api_service_double,
13
- client: client_double,
14
12
  backup_dir: tempdir,
15
13
  diff_format: nil,
16
14
  resources: [],
17
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 calls Dogapi::APIService.request' do
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
- expect(api_service_double).to receive(:request).with(Net::HTTP::Post,
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 calls Dogapi::APIService.request' do
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
- expect(api_service_double).to receive(:request).with(Net::HTTP::Put,
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
- allow(api_service_double).to receive(:request).with(Net::HTTP::Get,
123
- '/api/api-version-string/api-resource-name-string/abc-123-def',
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(api_service_double).to receive(:request).with(Net::HTTP::Put,
149
- '/api/api-version-string/api-resource-name-string/bad-123-id',
150
- nil, { 'load' => 'ok' },
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(:api_service_double) { double(Dogapi::APIService) }
7
- let(:client_double) { double }
6
+ let(:stubs) { Faraday::Adapter::Test::Stubs.new }
7
+ let(:api_client_double) { Faraday.new { |f| f.adapter :test, stubs } }
8
8
  let(:tempdir) { Dir.mktmpdir }
9
9
  let(:dashboards) do
10
- described_class.new(
10
+ dashboards = described_class.new(
11
11
  action: 'backup',
12
- client: client_double,
13
12
  backup_dir: tempdir,
14
13
  output_format: :json,
15
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(:all_boards) do
26
+ let(:all_dashboards) do
26
27
  [
27
- '200',
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
- '200',
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
- 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, '/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
+ 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 '#all_boards' do
84
- subject { dashboards.all_boards }
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(:api_service_double) { double(Dogapi::APIService) }
7
- let(:client_double) { double }
6
+ let(:stubs) { Faraday::Adapter::Test::Stubs.new }
7
+ let(:api_client_double) { Faraday.new { |f| f.adapter :test, stubs } }
8
8
  let(:tempdir) { Dir.mktmpdir }
9
9
  let(:monitors) do
10
- described_class.new(
10
+ monitors = described_class.new(
11
11
  action: 'backup',
12
- client: client_double,
13
12
  backup_dir: tempdir,
14
13
  output_format: :json,
15
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
- '200',
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
- '200',
49
+ 200,
50
+ {},
47
51
  monitor_description
48
52
  ]
49
53
  end
50
54
 
51
55
  before do
52
- allow(client_double).to receive(:instance_variable_get).with(:@monitor_svc).and_return(api_service_double)
53
- allow(api_service_double).to receive(:request).with(Net::HTTP::Get, '/api/v1/monitor', nil, nil,
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
- allow(api_service_double).to receive(:request).and_return(
82
+ stubs.get('/api/v1/dashboard/123455') {
82
83
  [
83
- '200',
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(2.0) do
20
+ Timeout.timeout(4.0) do
21
21
  oe.each do |v|
22
22
  output += v
23
23
  end
24
24
  end
25
25
  rescue Timeout::Error
26
- LOGGER.warn "Timing out #{t.inspect} after 2 second"
26
+ LOGGER.error "Timing out #{t.inspect} after 4 second"
27
27
  Process.kill(15, pid)
28
28
  ensure
29
29
  status = t.value
@@ -32,8 +32,8 @@ describe 'bin/datadog_backup' do
32
32
  end
33
33
 
34
34
  required_vars = %w[
35
- DATADOG_API_KEY
36
- DATADOG_APP_KEY
35
+ DD_API_KEY
36
+ DD_APP_KEY
37
37
  ]
38
38
 
39
39
  env = {}
@@ -52,7 +52,7 @@ describe 'bin/datadog_backup' do
52
52
  it 'supplies help' do
53
53
  stub_const('ENV', env)
54
54
  out_err, status = run_bin('--help')
55
- expect(out_err).to match(/Usage: DATADOG_API_KEY=/)
55
+ expect(out_err).to match(/Usage: DD_API_KEY=/)
56
56
  expect(status).to be_success
57
57
  end
58
58
  end
data/spec/spec_helper.rb CHANGED
@@ -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('/dev/null')
8
- LOGGER.level = Logger::INFO
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: 2.0.2
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-11 00:00:00.000000000 Z
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: 1.4.0
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: 1.4.0
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: 1.1.10
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: 1.1.10
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.4.5
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.4.5
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: 3.4.2
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: 3.4.2
69
+ version: '0'
70
70
  - !ruby/object:Gem::Dependency
71
- name: dogapi
71
+ name: faraday
72
72
  requirement: !ruby/object:Gem::Requirement
73
73
  requirements:
74
- - - "~>"
74
+ - - ">="
75
75
  - !ruby/object:Gem::Version
76
- version: 1.45.0
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: 1.45.0
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.6'
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: '0'
262
+ version: 1.3.1
235
263
  requirements: []
236
264
  rubygems_version: 3.1.6
237
265
  signing_key: