record_store 6.5.0 → 6.5.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7f5d50f38de714c7b8d6d316070fc9d6bca5ac4d40751629c3c565866178d628
4
- data.tar.gz: 14e3171ad53e5903404fcda9404bbfa109ec63db0c9253d8f3f7df76ee0e0ff1
3
+ metadata.gz: 16f9a10f5929ea735a99f35ec95365468ae74f1ca96b895ab66f77b22092cef2
4
+ data.tar.gz: cfa31577b7ed26208894fb03f2635ba1111d45bccd95a187553b4ce9750f9c98
5
5
  SHA512:
6
- metadata.gz: ac87302ec7f2d9e1afcbac7af6ef340a7a6fdd7d503a2f941fb7e7f021a46eb3a2b071841a152b264ba1956c50aa45141853a3bfdda4e8101a5e226ddec595ac
7
- data.tar.gz: 17fdee4d8ca5b4e9692e6a3718cdbb143e076890b2752a9dd4516c110835edbd73208056c8be8bfc5d18b926d97050d33300a04c29639d77cdc1429b2caf41cc
6
+ metadata.gz: d27fedbd2fe747f57fb595660fbd2f57aba841449db6d5c2ce571aa30f41c6a8cb8453960f336be1535e0b70fee532e317a89c320688eb55506ba247de19cf4a
7
+ data.tar.gz: 0dbb66a9617e4b7cb9a79f0e531e63984c63acf9d461cef32778317545d839ae83836a0ab02d36226e43a3ffaa865847c0c8a6e91f2af68a3d18c1346faed053
data/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 6.5.4
4
+ - Updates config path structure for build pipeline
5
+
6
+ ## 6.5.3
7
+ - Adds check for detecting shadowed records, used when a record being added to a zone in record-store will have no effect because it is shadowed by another record.
8
+
9
+ ## 6.5.2
10
+ - Ensure filters for implicit_records, `except_record` and `conflict_with`, are truly optional [BUGFIX]
11
+
12
+ ## 6.5.1
13
+
14
+ Add support for a new parameter in the implicit records templates:
15
+
16
+ - `except_record`: the template will *NOT* generate the `injected_records` for records matching `except_record`, even if they matched `each_record`.
17
+
18
+ Also added support for regular expressions in the matching, using the already available `!ruby/regexp` text in a YAML value. The object loaded from the YAML
19
+ will be of `Regexp` type, and will thus be used to _match_ the value, instead of being identical only. This is supported in both `except_record` and
20
+ `each_record` fields.
21
+
22
+ ## 6.5.0
23
+
24
+ ...
25
+
3
26
  ## 6.4.0
4
27
 
5
28
  Add support for injecting implicit records into a zone based on a pre-configured template. Brief overview of template keys:
@@ -1,3 +1,3 @@
1
1
  module RecordStore
2
- VERSION = '6.5.0'.freeze
2
+ VERSION = '6.5.4'.freeze
3
3
  end
@@ -26,9 +26,14 @@ module RecordStore
26
26
  def from_file(filename:)
27
27
  filepath = template_filepath_for(filename: filename)
28
28
  template_file = File.read(filepath)
29
- filters_for_records_to_template = YAML.load(template_file).deep_symbolize_keys[:each_record]
30
29
 
31
- new(template: ERB.new(template_file), filters_for_records_to_template: filters_for_records_to_template)
30
+ template_file_yaml = YAML.load(template_file).deep_symbolize_keys
31
+ filters_for_records_to_template = template_file_yaml[:each_record]
32
+ filters_for_records_to_exclude = template_file_yaml[:except_record] || []
33
+
34
+ new(template: ERB.new(template_file),
35
+ filters_for_records_to_template: filters_for_records_to_template,
36
+ filters_for_records_to_exclude: filters_for_records_to_exclude)
32
37
  end
33
38
 
34
39
  private
@@ -38,9 +43,10 @@ module RecordStore
38
43
  end
39
44
  end
40
45
 
41
- def initialize(template:, filters_for_records_to_template:)
46
+ def initialize(template:, filters_for_records_to_template:, filters_for_records_to_exclude:)
42
47
  @template = template
43
48
  @filters_for_records_to_template = filters_for_records_to_template
49
+ @filters_for_records_to_exclude = filters_for_records_to_exclude
44
50
  end
45
51
 
46
52
  def generate_records_to_inject(current_records:)
@@ -61,23 +67,29 @@ module RecordStore
61
67
 
62
68
  private
63
69
 
64
- attr_reader :template, :filters_for_records_to_template
70
+ attr_reader :template, :filters_for_records_to_template, :filters_for_records_to_exclude
65
71
 
66
72
  def should_inject?(template_records:, current_records:)
73
+ conflict_with = template_records[:conflict_with] || []
67
74
  current_records.none? do |record|
68
- template_records[:conflict_with].any? do |filter|
75
+ conflict_with.any? do |filter|
69
76
  record_match?(record: record, filter: filter)
70
77
  end
71
78
  end
72
79
  end
73
80
 
74
81
  def should_template?(record:)
75
- filters_for_records_to_template.any? { |filter| record_match?(record: record, filter: filter) }
82
+ filters_for_records_to_template.any? { |filter| record_match?(record: record, filter: filter) } && \
83
+ filters_for_records_to_exclude.none? { |filter| record_match?(record: record, filter: filter) }
76
84
  end
77
85
 
78
86
  def record_match?(record:, filter:)
79
87
  filter.all? do |key, value|
80
- record.public_send(key) == value
88
+ if value.is_a?(Regexp)
89
+ value.match(record.public_send(key))
90
+ else
91
+ record.public_send(key) == value
92
+ end
81
93
  end
82
94
  end
83
95
 
@@ -21,6 +21,7 @@ module RecordStore
21
21
  validate :validate_no_empty_non_terminal
22
22
  validate :validate_can_handle_alias_records
23
23
  validate :validate_no_duplicate_keys
24
+ validate :validate_zone_record_not_shadowed
24
25
 
25
26
  class << self
26
27
  def download(name, provider_name, **write_options)
@@ -62,7 +63,12 @@ module RecordStore
62
63
  current_zone = nil
63
64
  while zones.any?
64
65
  mutex.synchronize { current_zone = zones.shift }
65
- mutex.synchronize { modified_zones << current_zone } unless current_zone.unchanged?
66
+ break if current_zone.nil? # account for the race between `zones.any?` and `zones.shift`
67
+
68
+ # `unchanged?` is deliberately outside locked context since it's a bit CPU/time heavy
69
+ unless current_zone.unchanged?
70
+ mutex.synchronize { modified_zones << current_zone }
71
+ end
66
72
  end
67
73
  end
68
74
  end.each(&:join)
@@ -272,6 +278,26 @@ module RecordStore
272
278
  end
273
279
  end
274
280
 
281
+ def validate_zone_record_not_shadowed
282
+ nameserver_fqdns = records
283
+ .select { |record| record.is_a?(Record::NS) && name != record.fqdn }
284
+ .map { |record| record.fqdn.delete_suffix(".") }
285
+ .uniq
286
+
287
+ nameserver_fqdns.each do |ns_record|
288
+ selected_records = records.reject do |record|
289
+ record.is_a?(Record::NS) && \
290
+ record.fqdn.delete_suffix(".") == ns_record
291
+ end
292
+ selected_records.each do |record|
293
+ normalized_record = record.fqdn.delete_suffix(".")
294
+ next unless normalized_record.end_with?(".#{ns_record}") || normalized_record == ns_record
295
+ errors.add(:records, "Record #{record.fqdn} #{record.type} in Zone #{name} " \
296
+ "is shadowed by #{ns_record} and will be ignored")
297
+ end
298
+ end
299
+ end
300
+
275
301
  def validate_no_empty_non_terminal
276
302
  return unless config.empty_non_terminal_over_wildcard?
277
303
 
data/lib/record_store.rb CHANGED
@@ -44,6 +44,7 @@ module RecordStore
44
44
  class << self
45
45
  attr_writer :secrets_path
46
46
  attr_writer :zones_path
47
+ attr_writer :implicit_records_templates_path
47
48
 
48
49
  def secrets_path
49
50
  @secrets_path ||= File.expand_path(config.fetch('secrets_path'), File.dirname(config_path))
@@ -2,6 +2,8 @@ each_record:
2
2
  - type: A
3
3
  fqdn: abc.123.com.
4
4
  - type: TXT
5
+ except_record:
6
+ - fqdn: !ruby/regexp /^_/
5
7
  conflict_with:
6
8
  - type: TXT
7
9
  fqdn: <%= record.fqdn %>.more.domain.com.
@@ -5,7 +5,7 @@ dynect.example.com:
5
5
  ignore_patterns:
6
6
  - type: NS
7
7
  fqdn: dynect.example.com.
8
- implicit_record_templates:
8
+ implicit_records_templates:
9
9
  - implicit_example.yml.erb
10
10
  records:
11
11
  - type: A
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.5.0
4
+ version: 6.5.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Willem van Bergen
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2021-06-04 00:00:00.000000000 Z
12
+ date: 2021-09-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: thor
@@ -417,7 +417,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
417
417
  - !ruby/object:Gem::Version
418
418
  version: '0'
419
419
  requirements: []
420
- rubygems_version: 3.2.17
420
+ rubygems_version: 3.2.20
421
421
  signing_key:
422
422
  specification_version: 4
423
423
  summary: Manage DNS using git