datadog_backup 3.2.1 → 4.0.0

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: 2e3e8528c064d05b09bd31080a7bcab7c77fcca8dde46949cf8c62a7702f2af1
4
- data.tar.gz: 24c57007224fcf546b5a886e4b9f2a78f76b2a63fd2c64067ae2454192919848
3
+ metadata.gz: 48b1dae9a4913fddefcca2facdd992cec33d541de98f1cdb95db1435c908e0c8
4
+ data.tar.gz: ced45888346071657d3f7e43a123fcd30c70add2eefad3f59f60a80efcce502b
5
5
  SHA512:
6
- metadata.gz: d5180a6ba1f92f5db842e88d337878eacd0bafe114fbbb8752153b85f7c47f682be3bdd529b694294cc5523fe4c94274a7ee78d15fc4798b327598fb7710303b
7
- data.tar.gz: f4ccccd735136f06f92cc71f1df0176e5fa626fd36f5e60f4bc88ef93f9fcf31f8d840c523e1e70f08195faf8d32e8522fea3665e9b6f1efe280cf8b214331a9
6
+ metadata.gz: 3a48ffe5dcb9f78b2609b6e229f3a012fd5b0674280851dfc13385ab46ddacd387acb957089d57eb8f0095f90cb8ee0a3557a67bbf984eae5db896c37920e439
7
+ data.tar.gz: 6c7b23395d06767197a3a2ab7d5bb273a71ed15721da680a2f723f99551cd13b471d98035b5b1e6e5802dec4e798170b3c69e79e0b807959493922e8c5706f35
@@ -12,10 +12,10 @@ 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.7, '3.0', '3.1']
15
+ ruby: ['3.0', '3.1', '3.2']
16
16
  runs-on: ${{ matrix.os }}
17
17
  steps:
18
- - uses: actions/checkout@v3
18
+ - uses: actions/checkout@v4
19
19
  - name: Set up Ruby
20
20
  uses: ruby/setup-ruby@v1
21
21
  with:
@@ -30,7 +30,7 @@ jobs:
30
30
  env:
31
31
  BUNDLE_DEPLOYMENT: true
32
32
  steps:
33
- - uses: actions/checkout@v3
33
+ - uses: actions/checkout@v4
34
34
  - name: Set up Ruby
35
35
  uses: ruby/setup-ruby@v1
36
36
  with:
@@ -40,7 +40,7 @@ jobs:
40
40
  zip -r datadog_backup.zip ./*
41
41
  - name: Semantic Release
42
42
  id: semantic
43
- uses: cycjimmy/semantic-release-action@v3
43
+ uses: cycjimmy/semantic-release-action@v4
44
44
  env:
45
45
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
46
46
  GEM_HOST_API_KEY: ${{ secrets.RUBYGEMS_API_TOKEN }}
@@ -10,7 +10,7 @@ jobs:
10
10
  runs-on: ubuntu-20.04
11
11
  steps:
12
12
  - name: Validate PR Title
13
- uses: amannn/action-semantic-pull-request@v5.0.2
13
+ uses: amannn/action-semantic-pull-request@v5.4.0
14
14
  env:
15
15
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
16
16
  with:
data/CHANGELOG.md CHANGED
@@ -1,3 +1,22 @@
1
+ # [4.0.0](https://github.com/scribd/datadog_backup/compare/v3.3.0...v4.0.0) (2024-04-30)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * Deprecate Ruby 3.0 and Drop support for Ruby 2.7 ([#163](https://github.com/scribd/datadog_backup/issues/163)) ([3d81d65](https://github.com/scribd/datadog_backup/commit/3d81d652bfb35f06b61dfb679c4d9e0d3567efcb))
7
+
8
+
9
+ ### BREAKING CHANGES
10
+
11
+ * ruby 2.7 is no longer supported. Please upgrade to ruby 3.0 or higher.
12
+
13
+ # [3.3.0](https://github.com/scribd/datadog_backup/compare/v3.2.1...v3.3.0) (2023-08-17)
14
+
15
+
16
+ ### Features
17
+
18
+ * backup SLOs ([#155](https://github.com/scribd/datadog_backup/issues/155)) ([6cca6e7](https://github.com/scribd/datadog_backup/commit/6cca6e7567895673e94c7de80022c821553698ee)), closes [#1](https://github.com/scribd/datadog_backup/issues/1)
19
+
1
20
  ## [3.2.1](https://github.com/scribd/datadog_backup/compare/v3.2.0...v3.2.1) (2023-02-11)
2
21
 
3
22
 
data/README.md CHANGED
@@ -17,7 +17,7 @@ Additional features may be built out over time.
17
17
  v3 is a backwards incompatible change.
18
18
 
19
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.
20
+ - [ ] ruby 2.7 is no longer supported. Please upgrade to ruby 3.0 or higher.
21
21
  - [ ] The options `--ssh` and `--ssshh` are no longer supported. Instead, please use `--quiet` to supress logging. `--debug` remains supported.
22
22
  - [ ] The environment variable `DATADOG_HOST` is no longer supported. Instead, please use `DD_SITE_URL`.
23
23
 
data/bin/datadog_backup CHANGED
@@ -48,6 +48,9 @@ def prereqs(defaults) # rubocop:disable Metrics/AbcSize
48
48
  opts.on('--dashboards-only') do
49
49
  result[:resources] = [DatadogBackup::Dashboards]
50
50
  end
51
+ opts.on('--slos-only') do
52
+ result[:resources] = [DatadogBackup::SLOs]
53
+ end
51
54
  opts.on('--synthetics-only') do
52
55
  result[:resources] = [DatadogBackup::Synthetics]
53
56
  end
@@ -83,7 +86,7 @@ defaults = {
83
86
  action: nil,
84
87
  backup_dir: File.join(ENV.fetch('PWD'), 'backup'),
85
88
  diff_format: :color,
86
- resources: [DatadogBackup::Dashboards, DatadogBackup::Monitors, DatadogBackup::Synthetics],
89
+ resources: [DatadogBackup::Dashboards, DatadogBackup::Monitors, DatadogBackup::SLOs, DatadogBackup::Synthetics],
87
90
  output_format: :yaml,
88
91
  force_restore: false,
89
92
  disable_array_sort: false
@@ -19,7 +19,7 @@ Gem::Specification.new do |spec|
19
19
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
20
20
  spec.require_paths = ['lib']
21
21
 
22
- spec.required_ruby_version = '>= 2.7'
22
+ spec.required_ruby_version = '>= 3.0'
23
23
 
24
24
  spec.add_dependency 'amazing_print'
25
25
  spec.add_dependency 'concurrent-ruby'
@@ -10,11 +10,11 @@ jobs:
10
10
  runs-on: ubuntu-latest
11
11
 
12
12
  steps:
13
- - uses: actions/checkout@v2
14
- - name: Set up Ruby 2.7.1
13
+ - uses: actions/checkout@v4
14
+ - name: Set up Ruby 3.1
15
15
  uses: ruby/setup-ruby@v1
16
16
  with:
17
- ruby-version: 2.7.1
17
+ ruby-version: 3.1
18
18
  - name: perform backup
19
19
  env:
20
20
  DD_API_KEY: ${{ secrets.DD_API_KEY }}
@@ -24,7 +24,7 @@ jobs:
24
24
  bundle install --jobs 4 --retry 3
25
25
  bundle exec datadog_backup backup
26
26
  - name: commit changes
27
- uses: stefanzweifel/git-auto-commit-action@v4
27
+ uses: stefanzweifel/git-auto-commit-action@v5
28
28
  with:
29
29
  commit_message: "Changes as of run: ${{ github.run_id }}"
30
30
  file_pattern: backup/
@@ -4,7 +4,7 @@ module DatadogBackup
4
4
  # Notify the user if they are using deprecated features.
5
5
  module Deprecations
6
6
  def self.check
7
- LOGGER.warn "ruby-#{RUBY_VERSION} is deprecated. Ruby 2.7 or higher will be required to use this gem after datadog_backup@v3" if RUBY_VERSION < '2.7'
7
+ LOGGER.warn "ruby-#{RUBY_VERSION} is deprecated. Ruby 3.1 or higher will be required to use this gem after datadog_backup@v3" if RUBY_VERSION < '3.1'
8
8
  end
9
9
  end
10
10
  end
@@ -16,7 +16,9 @@ module DatadogBackup
16
16
  max: 5,
17
17
  interval: 0.05,
18
18
  interval_randomness: 0.5,
19
- backoff_factor: 2
19
+ backoff_factor: 2,
20
+ rate_limit_reset_header: 'x-ratelimit-reset',
21
+ exceptions: [Faraday::TooManyRequestsError] + Faraday::Retry::Middleware::DEFAULT_EXCEPTIONS
20
22
  }.freeze
21
23
 
22
24
  def backup
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DatadogBackup
4
+ # SLO specific overrides for backup and restore.
5
+ class SLOs < Resources
6
+ def all
7
+ get_all
8
+ end
9
+
10
+ def backup
11
+ LOGGER.info("Starting diffs on #{::DatadogBackup::ThreadPool::TPOOL.max_length} threads")
12
+ futures = all.map do |slo|
13
+ Concurrent::Promises.future_on(::DatadogBackup::ThreadPool::TPOOL, slo) do |board|
14
+ id = board[id_keyname]
15
+ get_and_write_file(id)
16
+ end
17
+ end
18
+
19
+ watcher = ::DatadogBackup::ThreadPool.watcher
20
+ watcher.join if watcher.status
21
+
22
+ Concurrent::Promises.zip(*futures).value!
23
+ end
24
+
25
+ def get_by_id(id)
26
+ begin
27
+ slo = except(get(id))
28
+ rescue Faraday::ResourceNotFound => e
29
+ slo = {}
30
+ end
31
+ except(slo)
32
+ end
33
+
34
+ def initialize(options)
35
+ super(options)
36
+ @banlist = %w[modified_at url].freeze
37
+ end
38
+
39
+ # Return the Faraday body from a response with a 2xx status code, otherwise raise an error
40
+ def body_with_2xx(response)
41
+ unless response.status.to_s =~ /^2/
42
+ raise "#{caller_locations(1,
43
+ 1)[0].label} failed with error #{response.status}"
44
+ end
45
+
46
+ response.body.fetch('data')
47
+ end
48
+
49
+ private
50
+
51
+ def api_version
52
+ 'v1'
53
+ end
54
+
55
+ def api_resource_name
56
+ 'slo'
57
+ end
58
+
59
+ def id_keyname
60
+ 'id'
61
+ end
62
+ end
63
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DatadogBackup
4
- VERSION = '3.2.1'
4
+ VERSION = '4.0.0'
5
5
  end
@@ -8,6 +8,7 @@ require_relative 'datadog_backup/cli'
8
8
  require_relative 'datadog_backup/resources'
9
9
  require_relative 'datadog_backup/dashboards'
10
10
  require_relative 'datadog_backup/monitors'
11
+ require_relative 'datadog_backup/slos'
11
12
  require_relative 'datadog_backup/synthetics'
12
13
  require_relative 'datadog_backup/thread_pool'
13
14
  require_relative 'datadog_backup/version'
@@ -12,7 +12,7 @@ describe DatadogBackup::Deprecations do
12
12
  allow(logger).to receive(:warn)
13
13
  end
14
14
 
15
- %w[2.4.10 2.5.9 2.6.8].each do |ruby_version|
15
+ %w[2.5.9 2.6.8 2.7 3.0.4].each do |ruby_version|
16
16
  describe "#check#{ruby_version}" do
17
17
  it 'does warn' do
18
18
  stub_const('RUBY_VERSION', ruby_version)
@@ -22,7 +22,7 @@ describe DatadogBackup::Deprecations do
22
22
  end
23
23
  end
24
24
 
25
- %w[2.7.4 3.0.4 3.1.2 3.2.0-preview1].each do |ruby_version|
25
+ %w[3.1.2 3.2.0-preview1].each do |ruby_version|
26
26
  describe "#check#{ruby_version}" do
27
27
  it 'does not warn' do
28
28
  stub_const('RUBY_VERSION', ruby_version)
@@ -0,0 +1,207 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe DatadogBackup::SLOs do
6
+ let(:stubs) { Faraday::Adapter::Test::Stubs.new }
7
+ let(:api_client_double) { Faraday.new { |f| f.adapter :test, stubs } }
8
+ let(:tempdir) { Dir.mktmpdir }
9
+ let(:slos) do
10
+ slos = described_class.new(
11
+ action: 'backup',
12
+ backup_dir: tempdir,
13
+ output_format: :json,
14
+ resources: []
15
+ )
16
+ allow(slos).to receive(:api_service).and_return(api_client_double)
17
+ return slos
18
+ end
19
+ let(:fetched_slos) do
20
+ {
21
+ "data"=>[
22
+ {"id"=>"abc-123", "name"=>"CI Stability", "tags"=>["kind:availability", "team:my_team"], "monitor_tags"=>[], "thresholds"=>[{"timeframe"=>"7d", "target"=>98.0, "target_display"=>"98."}, {"timeframe"=>"30d", "target"=>98.0, "target_display"=>"98."}, {"timeframe"=>"90d", "target"=>98.0, "target_display"=>"98."}], "type"=>"metric", "type_id"=>1, "description"=>"something helpful", "timeframe"=>"30d", "target_threshold"=>98.0, "query"=>{"denominator"=>"sum:metric.ci_things{*}.as_count()", "numerator"=>"sum:metric.ci_things{*}.as_count()-sum:metric.ci_things{infra_failure}.as_count()"}, "creator"=>{"name"=>"Thelma Patterson", "handle"=>"thelma.patterson@example.com", "email"=>"thelma.patterson@example.com"}, "created_at"=>1571335531, "modified_at"=>1687844157},
23
+ {"id"=>"sbc-124", "name"=>"A Latency SLO", "tags"=>["team:my_team", "kind:latency"], "monitor_tags"=>[], "thresholds"=>[{"timeframe"=>"7d", "target"=>95.0, "target_display"=>"95."}, {"timeframe"=>"30d", "target"=>95.0, "target_display"=>"95."}, {"timeframe"=>"90d", "target"=>95.0, "target_display"=>"95."}], "type"=>"monitor", "type_id"=>0, "description"=>"", "timeframe"=>"30d", "target_threshold"=>95.0, "monitor_ids"=>[13158755], "creator"=>{"name"=>"Louise Montague", "handle"=>"louise.montague@example.com", "email"=>"louise.montague@example.com"}, "created_at"=>1573162531, "modified_at"=>1685819875}
24
+ ],
25
+ "errors"=>[],
26
+ "metadata"=>{"page"=>{"total_count"=>359, "total_filtered_count"=>359}}
27
+ }
28
+ end
29
+ let(:slo_abc_123) do
30
+ {
31
+ "id" => "abc-123",
32
+ "name" => "CI Stability",
33
+ "tags" => [
34
+ "kind:availability",
35
+ "team:my_team",
36
+ ],
37
+ "monitor_tags" => [],
38
+ "thresholds" => [
39
+ {
40
+ "timeframe" => "7d",
41
+ "target" => 98.0,
42
+ "target_display" => "98."
43
+ },
44
+ {
45
+ "timeframe" => "30d",
46
+ "target" => 98.0,
47
+ "target_display" => "98."
48
+ },
49
+ {
50
+ "timeframe" => "90d",
51
+ "target" => 98.0,
52
+ "target_display" => "98."
53
+ }
54
+ ],
55
+ "type" => "metric",
56
+ "type_id" => 1,
57
+ "description" => "something helpful",
58
+ "timeframe" => "30d",
59
+ "target_threshold" => 98.0,
60
+ "query" => {
61
+ "denominator" => "sum:metric.ci_things{*}.as_count()",
62
+ "numerator" => "sum:metric.ci_things{*}.as_count()-sum:metric.ci_things{infra_failure}.as_count()"
63
+ },
64
+ "creator" => {
65
+ "name" => "Thelma Patterson",
66
+ "handle" => "thelma.patterson@example.com",
67
+ "email" => "thelma.patterson@example.com"
68
+ },
69
+ "created_at" => 1571335531,
70
+ "modified_at" => 1687844157
71
+ }
72
+ end
73
+ let(:slo_sbc_124) do
74
+ {
75
+ "id" => "sbc-124",
76
+ "name" => "A Latency SLO",
77
+ "tags" => [
78
+ "kind:latency",
79
+ "team:my_team",
80
+ ],
81
+ "monitor_tags" => [],
82
+ "thresholds" => [
83
+ {
84
+ "timeframe" => "7d",
85
+ "target" => 98.0,
86
+ "target_display" => "98."
87
+ },
88
+ {
89
+ "timeframe" => "30d",
90
+ "target" => 98.0,
91
+ "target_display" => "98."
92
+ },
93
+ {
94
+ "timeframe" => "90d",
95
+ "target" => 98.0,
96
+ "target_display" => "98."
97
+ }
98
+ ],
99
+ "type" => "monitor",
100
+ "type_id"=>0,
101
+ "description"=>"",
102
+ "timeframe"=>"30d",
103
+ "target_threshold"=>95.0,
104
+ "monitor_ids"=>[ 13158755 ],
105
+ "creator"=>{
106
+ "name"=>"Louise Montague",
107
+ "handle"=>"louise.montague@example.com",
108
+ "email"=>"louise.montague@example.com"
109
+ },
110
+ "created_at"=>1573162531,
111
+ "modified_at"=>1685819875
112
+ }
113
+ end
114
+ let(:slo_abc_123_response) do
115
+ { "data" => slo_abc_123, "errors" => [] }
116
+ end
117
+ let(:slo_sbc_124_response) do
118
+ { "data" => slo_sbc_124, "errors" => [] }
119
+ end
120
+ let(:all_slos) { respond_with200(fetched_slos) }
121
+ let(:example_slo1) { respond_with200(slo_abc_123_response) }
122
+ let(:example_slo2) { respond_with200(slo_sbc_124_response) }
123
+
124
+ before do
125
+ stubs.get('/api/v1/slo') { all_slos }
126
+ stubs.get('/api/v1/slo/abc-123') { example_slo1 }
127
+ stubs.get('/api/v1/slo/sbc-124') { example_slo2 }
128
+ end
129
+
130
+ describe '#backup' do
131
+ subject { slos.backup }
132
+
133
+ it 'is expected to create two files' do
134
+ file1 = instance_double(File)
135
+ allow(File).to receive(:open).with(slos.filename('abc-123'), 'w').and_return(file1)
136
+ allow(file1).to receive(:write)
137
+ allow(file1).to receive(:close)
138
+
139
+ file2 = instance_double(File)
140
+ allow(File).to receive(:open).with(slos.filename('sbc-124'), 'w').and_return(file2)
141
+ allow(file2).to receive(:write)
142
+ allow(file2).to receive(:close)
143
+
144
+ slos.backup
145
+ expect(file1).to have_received(:write).with(::JSON.pretty_generate(slo_abc_123.deep_sort))
146
+ expect(file2).to have_received(:write).with(::JSON.pretty_generate(slo_sbc_124.deep_sort))
147
+ end
148
+ end
149
+
150
+ describe '#filename' do
151
+ subject { slos.filename('abc-123') }
152
+
153
+ it { is_expected.to eq("#{tempdir}/slos/abc-123.json") }
154
+ end
155
+
156
+ describe '#get_by_id' do
157
+ subject { slos.get_by_id('abc-123') }
158
+
159
+ it { is_expected.to eq slo_abc_123 }
160
+ end
161
+
162
+ describe '#diff' do
163
+ it 'calls the api only once' do
164
+ slos.write_file('{"a":"b"}', slos.filename('abc-123'))
165
+ expect(slos.diff('abc-123')).to eq(<<~EODASH
166
+ ---
167
+ -created_at: 1571335531
168
+ -creator:
169
+ - email: thelma.patterson@example.com
170
+ - handle: thelma.patterson@example.com
171
+ - name: Thelma Patterson
172
+ -description: something helpful
173
+ -id: abc-123
174
+ -monitor_tags: []
175
+ -name: CI Stability
176
+ -query:
177
+ - denominator: sum:metric.ci_things{*}.as_count()
178
+ - numerator: sum:metric.ci_things{*}.as_count()-sum:metric.ci_things{infra_failure}.as_count()
179
+ -tags:
180
+ -- kind:availability
181
+ -- team:my_team
182
+ -target_threshold: 98.0
183
+ -thresholds:
184
+ -- target: 98.0
185
+ - target_display: '98.'
186
+ - timeframe: 30d
187
+ -- target: 98.0
188
+ - target_display: '98.'
189
+ - timeframe: 7d
190
+ -- target: 98.0
191
+ - target_display: '98.'
192
+ - timeframe: 90d
193
+ -timeframe: 30d
194
+ -type: metric
195
+ -type_id: 1
196
+ +a: b
197
+ EODASH
198
+ .chomp)
199
+ end
200
+ end
201
+
202
+ describe '#except' do
203
+ subject { slos.except({ :a => :b, 'modified_at' => :c, 'url' => :d }) }
204
+
205
+ it { is_expected.to eq({ a: :b }) }
206
+ end
207
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: datadog_backup
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.1
4
+ version: 4.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kamran Farhadi
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2023-02-11 00:00:00.000000000 Z
12
+ date: 2024-04-30 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: amazing_print
@@ -229,6 +229,7 @@ files:
229
229
  - lib/datadog_backup/monitors.rb
230
230
  - lib/datadog_backup/options.rb
231
231
  - lib/datadog_backup/resources.rb
232
+ - lib/datadog_backup/slos.rb
232
233
  - lib/datadog_backup/synthetics.rb
233
234
  - lib/datadog_backup/thread_pool.rb
234
235
  - lib/datadog_backup/version.rb
@@ -239,6 +240,7 @@ files:
239
240
  - spec/datadog_backup/deprecations_spec.rb
240
241
  - spec/datadog_backup/local_filesystem_spec.rb
241
242
  - spec/datadog_backup/monitors_spec.rb
243
+ - spec/datadog_backup/slos_spec.rb
242
244
  - spec/datadog_backup/synthetics_spec.rb
243
245
  - spec/datadog_backup_bin_spec.rb
244
246
  - spec/spec_helper.rb
@@ -255,7 +257,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
255
257
  requirements:
256
258
  - - ">="
257
259
  - !ruby/object:Gem::Version
258
- version: '2.7'
260
+ version: '3.0'
259
261
  required_rubygems_version: !ruby/object:Gem::Requirement
260
262
  requirements:
261
263
  - - ">="