record_store 6.1.2 → 6.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|