record_store 6.1.2 → 6.2.0
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/lib/record_store/provider.rb +12 -7
- data/lib/record_store/provider/dnsimple.rb +4 -0
- data/lib/record_store/provider/dnsimple/patch_api_header.rb +3 -3
- data/lib/record_store/provider/ns1/patch_api_header.rb +3 -3
- data/lib/record_store/provider/provider_utils/waiter.rb +41 -0
- data/lib/record_store/record.rb +4 -0
- data/lib/record_store/version.rb +1 -1
- data/lib/record_store/zone.rb +23 -0
- data/lib/record_store/zone/config.rb +4 -0
- metadata +2 -2
- data/lib/record_store/provider/provider_utils/rate_limit.rb +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7c401c0dafc01955edd90912d793cdd0f27bd698df86f18ed4132e3ae0a8d1bc
|
4
|
+
data.tar.gz: 261f5a6a0c768d417e247746fe95955393075c643322fb7a5c701d39edef218d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7160e11eec16c8ecea7fa7cf02ae7437a5093ec58f6f932a7e9e63feb85413ff5d9c28e0a90f8960ff76a94dd0bc7992e0712a0a6f40a2158062755079a16bac
|
7
|
+
data.tar.gz: 7d81f1268810c177bd785b8ab5610175d2e9b7f20db743d12996df2ab6f145c522a354a1f7e94e86e91b90c7a44b1b63bcbe1a92a1e93e0f1f5eefb13d76a659
|
@@ -52,6 +52,10 @@ module RecordStore
|
|
52
52
|
false
|
53
53
|
end
|
54
54
|
|
55
|
+
def empty_non_terminal_over_wildcard?
|
56
|
+
true
|
57
|
+
end
|
58
|
+
|
55
59
|
def build_zone(zone_name:, config:)
|
56
60
|
zone = Zone.new(name: zone_name)
|
57
61
|
zone.records = retrieve_current_records(zone: zone_name)
|
@@ -136,6 +140,13 @@ module RecordStore
|
|
136
140
|
backoff_multiplier: 2,
|
137
141
|
max_backoff: 10
|
138
142
|
)
|
143
|
+
waiter = BackoffWaiter.new(
|
144
|
+
"Waiting to retry after a connection reset",
|
145
|
+
initial_delay: delay,
|
146
|
+
multiplier: backoff_multiplier,
|
147
|
+
max_delay: max_backoff,
|
148
|
+
)
|
149
|
+
|
139
150
|
loop do
|
140
151
|
begin
|
141
152
|
return yield
|
@@ -148,16 +159,10 @@ module RecordStore
|
|
148
159
|
raise if max_conn_resets <= 0
|
149
160
|
max_conn_resets -= 1
|
150
161
|
|
151
|
-
|
152
|
-
backoff_sleep(delay)
|
153
|
-
delay = [delay * backoff_multiplier, max_backoff].min
|
162
|
+
waiter.wait
|
154
163
|
end
|
155
164
|
end
|
156
165
|
end
|
157
|
-
|
158
|
-
def backoff_sleep(delay)
|
159
|
-
sleep(delay)
|
160
|
-
end
|
161
166
|
end
|
162
167
|
end
|
163
168
|
end
|
@@ -12,6 +12,10 @@ module RecordStore
|
|
12
12
|
true
|
13
13
|
end
|
14
14
|
|
15
|
+
def empty_non_terminal_over_wildcard?
|
16
|
+
false
|
17
|
+
end
|
18
|
+
|
15
19
|
# returns an array of Record objects that match the records which exist in the provider
|
16
20
|
def retrieve_current_records(zone:, stdout: $stdout)
|
17
21
|
retry_on_connection_errors do
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require_relative '../provider_utils/
|
1
|
+
require_relative '../provider_utils/waiter'
|
2
2
|
|
3
3
|
# Patch Dnsimple client method which retrieves headers for API rate limit dynamically
|
4
4
|
module Dnsimple
|
@@ -26,8 +26,8 @@ module Dnsimple
|
|
26
26
|
rate_limit_periods = rate_limit_remaining + 1
|
27
27
|
sleep_time = rate_limit_reset_in / rate_limit_periods.to_f
|
28
28
|
|
29
|
-
rate_limit =
|
30
|
-
rate_limit.
|
29
|
+
rate_limit = RateLimitWaiter.new('DNSimple')
|
30
|
+
rate_limit.wait(sleep_time)
|
31
31
|
end
|
32
32
|
end
|
33
33
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'net/http'
|
2
|
-
require_relative '../provider_utils/
|
2
|
+
require_relative '../provider_utils/waiter'
|
3
3
|
|
4
4
|
# Patch the method which retrieves headers for API rate limit dynamically
|
5
5
|
module NS1::Transport
|
@@ -14,8 +14,8 @@ module NS1::Transport
|
|
14
14
|
sleep_time = response_hash[X_RATELIMIT_PERIOD].first.to_i /
|
15
15
|
[1, response_hash[X_RATELIMIT_REMAINING].first.to_i].max.to_f
|
16
16
|
|
17
|
-
rate_limit =
|
18
|
-
rate_limit.
|
17
|
+
rate_limit = RateLimitWaiter.new('NS1')
|
18
|
+
rate_limit.wait(sleep_time)
|
19
19
|
end
|
20
20
|
|
21
21
|
body = JSON.parse(response.body)
|
@@ -0,0 +1,41 @@
|
|
1
|
+
class Waiter
|
2
|
+
def initialize(message = nil)
|
3
|
+
@message = message || 'Waiting'
|
4
|
+
end
|
5
|
+
|
6
|
+
attr_accessor :message
|
7
|
+
|
8
|
+
def wait(sleep_time)
|
9
|
+
while sleep_time > 0
|
10
|
+
wait_time = [10, sleep_time].min
|
11
|
+
puts "#{message} (#{sleep_time}s left)" if wait_time > 1
|
12
|
+
sleep(wait_time)
|
13
|
+
sleep_time -= wait_time
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class RateLimitWaiter < Waiter
|
19
|
+
def initialize(provider)
|
20
|
+
super("Waiting on #{provider} rate-limit")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class BackoffWaiter < Waiter
|
25
|
+
def initialize(message, initial_delay:, multiplier:, max_delay: nil)
|
26
|
+
super(message)
|
27
|
+
|
28
|
+
@initial_delay = @current_delay = initial_delay
|
29
|
+
@multiplier = multiplier
|
30
|
+
@max_delay = max_delay
|
31
|
+
end
|
32
|
+
|
33
|
+
def reset
|
34
|
+
@current_delay = @initial_delay
|
35
|
+
end
|
36
|
+
|
37
|
+
def wait
|
38
|
+
super(@current_delay)
|
39
|
+
@current_delay = [@current_delay * @multiplier, @max_delay].compact.min
|
40
|
+
end
|
41
|
+
end
|
data/lib/record_store/record.rb
CHANGED
data/lib/record_store/version.rb
CHANGED
data/lib/record_store/zone.rb
CHANGED
@@ -18,6 +18,7 @@ module RecordStore
|
|
18
18
|
validate :validate_cname_records_dont_point_to_root
|
19
19
|
validate :validate_same_ttl_for_records_sharing_fqdn_and_type
|
20
20
|
validate :validate_provider_can_handle_zone_records
|
21
|
+
validate :validate_no_empty_non_terminal
|
21
22
|
validate :validate_can_handle_alias_records
|
22
23
|
|
23
24
|
class << self
|
@@ -258,6 +259,28 @@ module RecordStore
|
|
258
259
|
end
|
259
260
|
end
|
260
261
|
|
262
|
+
def validate_no_empty_non_terminal
|
263
|
+
return unless config.empty_non_terminal_over_wildcard?
|
264
|
+
|
265
|
+
wildcards = records.select(&:wildcard?).map(&:fqdn).uniq
|
266
|
+
wildcards.each do |wildcard|
|
267
|
+
suffix = wildcard[1..-1]
|
268
|
+
|
269
|
+
terminal_records = records.map(&:fqdn)
|
270
|
+
.select { |record| record.match?(/^([a-zA-Z0-9-_]+\.[a-zA-Z0-9-_])#{Regexp.escape(suffix)}$/) }
|
271
|
+
next unless terminal_records.any?
|
272
|
+
|
273
|
+
intermediate_records = records.map(&:fqdn)
|
274
|
+
.select { |record| record.match?(/^([a-zA-Z0-9-_]+)#{Regexp.escape(suffix)}$/) }
|
275
|
+
terminal_records.each do |terminal_record|
|
276
|
+
non_terminal = terminal_record.partition('.').last
|
277
|
+
errors.add(:records, "found empty non-terminal #{non_terminal} "\
|
278
|
+
"(caused by existing records #{wildcard} and #{terminal_record})")\
|
279
|
+
unless intermediate_records.include?(non_terminal)
|
280
|
+
end
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
261
284
|
def validate_can_handle_alias_records
|
262
285
|
return unless records.any? { |record| record.is_a?(Record::ALIAS) }
|
263
286
|
return if config.supports_alias?
|
@@ -24,6 +24,10 @@ module RecordStore
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
+
def empty_non_terminal_over_wildcard?
|
28
|
+
valid_providers? && providers.any? { |provider| Provider.const_get(provider).empty_non_terminal_over_wildcard? }
|
29
|
+
end
|
30
|
+
|
27
31
|
def to_hash
|
28
32
|
config_hash = {
|
29
33
|
providers: providers,
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: record_store
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.
|
4
|
+
version: 6.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Willem van Bergen
|
@@ -362,7 +362,7 @@ files:
|
|
362
362
|
- lib/record_store/provider/ns1/client.rb
|
363
363
|
- lib/record_store/provider/ns1/patch_api_header.rb
|
364
364
|
- lib/record_store/provider/oracle_cloud_dns.rb
|
365
|
-
- lib/record_store/provider/provider_utils/
|
365
|
+
- lib/record_store/provider/provider_utils/waiter.rb
|
366
366
|
- lib/record_store/record.rb
|
367
367
|
- lib/record_store/record/a.rb
|
368
368
|
- lib/record_store/record/aaaa.rb
|
@@ -1,14 +0,0 @@
|
|
1
|
-
class RateLimit
|
2
|
-
def initialize(provider)
|
3
|
-
@provider = provider
|
4
|
-
end
|
5
|
-
|
6
|
-
def sleep_for(sleep_time)
|
7
|
-
while sleep_time > 0
|
8
|
-
wait = [10, sleep_time].min
|
9
|
-
puts "Waiting on #{@provider} rate-limit" if wait > 1
|
10
|
-
sleep(wait)
|
11
|
-
sleep_time -= wait
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|