record_store 6.4.0 → 6.5.2

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: 729d72dfcdc31837d583ed7701c8c9a20a344ff1a15c16e0473b6bec160eaa4a
4
- data.tar.gz: 77287fe899cd38ac839f62925daae1e416a69ddf3dab895c1f8c5f61eef5777b
3
+ metadata.gz: 444fc56b77f3f4a4142af2094365fea4bd2ac0a2a89d2f42574067c48f13a4e6
4
+ data.tar.gz: 6d4bb6928c710a6d247be321e05b91ca929ac44d9ec15a2c99967e1f0a994d09
5
5
  SHA512:
6
- metadata.gz: 2facb09ae40af90a3f7b83700b00251b3ba29415a1c0c91ab09f9be36136591ad338d63685bb60e12b5779a1645242f5aa4a3f458436f91ea604235f11b78a68
7
- data.tar.gz: 5f77c86a04dcc27385358fb8039b2c2e717b12e086e726c7d08915db284866e95b2038529675a1516ea0114ca2b53785bcd9331b05f75b93e187a7f87d1918a9
6
+ metadata.gz: bf23882c66cfca5065bc4fb3308f39e5e441d085f2891297c254b9ff8f4af0b4b73a8a04cf806ad861f4cd6b075b429c20e74c73e5e6e0047a19b7b59ff4548f
7
+ data.tar.gz: 187c5f2c80fc0dfeb6baa3583ed2fadf1dac26ac0e3d344fd3cb7ce6b378cda27cfaa382250db0da79f5cf9514cfd40a27d74f5fda41cfa266cb4f4388b5bec2
@@ -0,0 +1,28 @@
1
+ name: CI
2
+
3
+ on: [push, pull_request]
4
+
5
+ env:
6
+ SRB_SKIP_GEM_RBIS: true
7
+
8
+ jobs:
9
+ build:
10
+ runs-on: ubuntu-latest
11
+ strategy:
12
+ fail-fast: false
13
+ matrix:
14
+ ruby: [ 2.7.1 ]
15
+ name: Test Ruby ${{ matrix.ruby }}
16
+ steps:
17
+ - uses: actions/checkout@v2
18
+ - name: Set up Ruby
19
+ uses: ruby/setup-ruby@v1
20
+ with:
21
+ ruby-version: ${{ matrix.ruby }}
22
+ bundler-cache: true
23
+ - name: rubocop
24
+ run: bin/rubocop --version && bin/rubocop
25
+ - name: setup
26
+ run: bin/setup
27
+ - name: test
28
+ run: bundle exec rake test
data/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 6.5.2
4
+ - Ensure filters for implicit_records, `except_record` and `conflict_with`, are truly optional [BUGFIX]
5
+
6
+ ## 6.5.1
7
+
8
+ Add support for a new parameter in the implicit records templates:
9
+
10
+ - `except_record`: the template will *NOT* generate the `injected_records` for records matching `except_record`, even if they matched `each_record`.
11
+
12
+ 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
13
+ 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
14
+ `each_record` fields.
15
+
16
+ ## 6.5.0
17
+
18
+ ...
19
+
3
20
  ## 6.4.0
4
21
 
5
22
  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.4.0'.freeze
2
+ VERSION = '6.5.2'.freeze
3
3
  end
@@ -20,6 +20,7 @@ module RecordStore
20
20
  validate :validate_provider_can_handle_zone_records
21
21
  validate :validate_no_empty_non_terminal
22
22
  validate :validate_can_handle_alias_records
23
+ validate :validate_no_duplicate_keys
23
24
 
24
25
  class << self
25
26
  def download(name, provider_name, **write_options)
@@ -70,10 +71,11 @@ module RecordStore
70
71
  end
71
72
  end
72
73
 
73
- def initialize(name:, records: [], config: {})
74
+ def initialize(name:, records: [], config: {}, abstract_syntax_trees: {})
74
75
  @name = Record.ensure_ends_with_dot(name)
75
76
  @config = RecordStore::Zone::Config.new(config.deep_symbolize_keys)
76
77
  @records = build_records(records)
78
+ @abstract_syntax_trees = abstract_syntax_trees
77
79
  end
78
80
 
79
81
  def build_changesets(all: false)
@@ -191,7 +193,7 @@ module RecordStore
191
193
  def build_records(records)
192
194
  all_records = records.map { |record| Record.build_from_yaml_definition(record) }
193
195
 
194
- config.implicit_record_templates.each do |template|
196
+ config.implicit_records_templates.each do |template|
195
197
  all_records.push(*template.generate_records_to_inject(current_records: all_records))
196
198
  end
197
199
 
@@ -307,5 +309,34 @@ module RecordStore
307
309
 
308
310
  errors.add(:records, "ALIAS record should be defined on the root of the zone: #{alias_record}")
309
311
  end
312
+
313
+ def validate_no_duplicate_keys
314
+ @abstract_syntax_trees.each do |filename, ast|
315
+ validate_no_duplicate_keys_in_node(filename, ast)
316
+ end
317
+ end
318
+
319
+ def validate_no_duplicate_keys_in_node(filename, node)
320
+ if node.mapping?
321
+ keys = node
322
+ .children
323
+ .each_slice(2)
324
+ .map(&:first)
325
+ .map(&:value)
326
+ .sort
327
+ dup_keys = keys
328
+ .find_all { |k| keys.count(k) > 1 }
329
+ .uniq
330
+ unless dup_keys.empty?
331
+ location = "#{File.basename(filename)}:#{node.start_line}"
332
+ description = "multiple definitions for keys #{dup_keys}"
333
+ errors.add(:records, "#{location}: #{description}")
334
+ end
335
+ end
336
+
337
+ node.children&.each do |child|
338
+ validate_no_duplicate_keys_in_node(filename, child)
339
+ end
340
+ end
310
341
  end
311
342
  end
@@ -3,15 +3,15 @@ module RecordStore
3
3
  class Config
4
4
  include ActiveModel::Validations
5
5
 
6
- attr_reader :ignore_patterns, :providers, :supports_alias, :implicit_record_templates
6
+ attr_reader :ignore_patterns, :providers, :supports_alias, :implicit_records_templates
7
7
 
8
8
  validate :validate_zone_config
9
9
 
10
- def initialize(ignore_patterns: [], providers: nil, supports_alias: nil, implicit_record_templates: [])
10
+ def initialize(ignore_patterns: [], providers: nil, supports_alias: nil, implicit_records_templates: [])
11
11
  @ignore_patterns = ignore_patterns.map do |ignore_pattern|
12
12
  Zone::Config::IgnorePattern.new(ignore_pattern)
13
13
  end
14
- @implicit_record_templates = implicit_record_templates.map do |filename|
14
+ @implicit_records_templates = implicit_records_templates.map do |filename|
15
15
  Zone::Config::ImplicitRecordTemplate.from_file(filename: filename)
16
16
  end
17
17
  @providers = providers
@@ -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
 
@@ -66,7 +66,10 @@ module RecordStore
66
66
  Dir["#{dir}/#{name}/*__*.yml"].each do |record_file|
67
67
  definition['records'] += load_yml_record_definitions(name, record_file)
68
68
  end
69
- Zone.new(name: name, records: definition['records'], config: definition['config'])
69
+
70
+ asts = { filename => Psych.parse_file(filename) }
71
+
72
+ Zone.new(name: name, records: definition['records'], config: definition['config'], abstract_syntax_trees: asts)
70
73
  end
71
74
 
72
75
  def load_yml_record_definitions(name, record_file)
@@ -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.
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.0
4
+ version: 6.5.2
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: 2020-12-02 00:00:00.000000000 Z
12
+ date: 2021-08-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: thor
@@ -335,6 +335,7 @@ executables:
335
335
  extensions: []
336
336
  extra_rdoc_files: []
337
337
  files:
338
+ - ".github/workflows/ci.yml"
338
339
  - ".gitignore"
339
340
  - ".rubocop-https---shopify-github-io-ruby-style-guide-rubocop-yml"
340
341
  - ".rubocop.yml"
@@ -416,7 +417,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
416
417
  - !ruby/object:Gem::Version
417
418
  version: '0'
418
419
  requirements: []
419
- rubygems_version: 3.0.3
420
+ rubygems_version: 3.2.20
420
421
  signing_key:
421
422
  specification_version: 4
422
423
  summary: Manage DNS using git