record_store 6.3.1 → 6.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f6875c27f0cf86510b733a58f668d44560eeb40e7c8b6c9438183fee175bc514
4
- data.tar.gz: 3599cc9903a5afe46d544f8aeef349961fdc2d95011973325bbdcc75972c56c5
3
+ metadata.gz: 729d72dfcdc31837d583ed7701c8c9a20a344ff1a15c16e0473b6bec160eaa4a
4
+ data.tar.gz: 77287fe899cd38ac839f62925daae1e416a69ddf3dab895c1f8c5f61eef5777b
5
5
  SHA512:
6
- metadata.gz: 9a6def9342919457cc71fdda4691c92310450dfc28a476eee6d353b73798b8d1b612b4775982704b0c44b2e657149a02f0e96330796b03d591619ad5930509ae
7
- data.tar.gz: 42183ae0ecd31e27a2d40977ecdda6cb51c0368ff24ac3a2de4411ab016809c5551ee3faeb50eb53503be059ece4bc41889e6c73d3e1f0ab53e7ab9290563628
6
+ metadata.gz: 2facb09ae40af90a3f7b83700b00251b3ba29415a1c0c91ab09f9be36136591ad338d63685bb60e12b5779a1645242f5aa4a3f458436f91ea604235f11b78a68
7
+ data.tar.gz: 5f77c86a04dcc27385358fb8039b2c2e717b12e086e726c7d08915db284866e95b2038529675a1516ea0114ca2b53785bcd9331b05f75b93e187a7f87d1918a9
@@ -195,6 +195,7 @@ Style/FrozenStringLiteralComment:
195
195
  SupportedStyles:
196
196
  - always
197
197
  - never
198
+ SafeAutoCorrect: true
198
199
 
199
200
  Style/GlobalVars:
200
201
  AllowedVariables: []
@@ -264,7 +265,7 @@ Style/MethodCallWithArgsParentheses:
264
265
  - raise
265
266
  - puts
266
267
  Exclude:
267
- - Gemfile
268
+ - '**/Gemfile'
268
269
 
269
270
  Style/MethodDefParentheses:
270
271
  EnforcedStyle: require_parentheses
@@ -577,6 +578,7 @@ Layout/BlockEndNewline:
577
578
 
578
579
  Style/CaseEquality:
579
580
  Enabled: true
581
+ AllowOnConstant: true
580
582
 
581
583
  Style/CharacterLiteral:
582
584
  Enabled: true
@@ -659,6 +661,9 @@ Style/IfWithSemicolon:
659
661
  Style/IdenticalConditionalBranches:
660
662
  Enabled: true
661
663
 
664
+ Layout/IndentationStyle:
665
+ Enabled: true
666
+
662
667
  Style/InfiniteLoop:
663
668
  Enabled: true
664
669
 
@@ -803,9 +808,6 @@ Layout/SpaceInsideRangeLiteral:
803
808
  Style/SymbolLiteral:
804
809
  Enabled: true
805
810
 
806
- Layout/IndentationStyle:
807
- Enabled: true
808
-
809
811
  Layout/TrailingWhitespace:
810
812
  Enabled: true
811
813
 
@@ -834,7 +836,7 @@ Style/ZeroLengthPredicate:
834
836
  Enabled: true
835
837
 
836
838
  Layout/HeredocIndentation:
837
- EnforcedStyle: squiggly
839
+ Enabled: true
838
840
 
839
841
  Lint/AmbiguousOperator:
840
842
  Enabled: true
@@ -1015,3 +1017,6 @@ Style/ModuleFunction:
1015
1017
 
1016
1018
  Lint/OrderedMagicComments:
1017
1019
  Enabled: true
1020
+
1021
+ Lint/DeprecatedOpenSSLConstant:
1022
+ Enabled: true
@@ -1,5 +1,13 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 6.4.0
4
+
5
+ Add support for injecting implicit records into a zone based on a pre-configured template. Brief overview of template keys:
6
+
7
+ - `each_record`: the template will generate all `injected_records` in the template for each Record in the Zone that matches criteria listed here.
8
+ - `conflict_with`: if any Record in the Zone matches the criteria listed here, the template will avoid injecting any of its generated implicit records into the zone
9
+ - `injected_records`: the implicit records that will be generated by the template for every Zone Record that matches the `each_record` criteria
10
+
3
11
  ## 6.3.1
4
12
  - Improve resiliency in the face of temporary provider outages [BUGFIX]
5
13
 
data/README.md CHANGED
@@ -116,6 +116,13 @@ When running `bin/record-store apply`, a `Changeset` is generated by comparing t
116
116
 
117
117
  Record store attempts to parallelize some of the bulk zone fetching operations. It does so by spawning multiple threads (default: 10). This value can be configured by setting the RECORD_STORE_MAX_THREADS environment variable to a positive integer value.
118
118
 
119
+
120
+ ### Templates
121
+
122
+ Record Store supports injecting implicit records into a zone based on templates. Each `Zone` can have a list of `Zone::Config::ImplicitRecordTemplate` in its `Zone::Config` that can define their own criteria for which records they use for generating implicit template records, which records conflict with the template-generated records, and what the template-generated records look like. These records are injected at the time of `Zone` initialization within `Zone#build_records`.
123
+
124
+ Templates can help reduce zone file bloat where instead of defining many generic literals within the zone file for a given criteria zone record, these generic records can be implicitly injected into the `Zone` at the time of initialization based on information provided within the template.
125
+
119
126
  ----
120
127
 
121
128
  # Development
@@ -6,6 +6,7 @@ require 'record_store'
6
6
 
7
7
  RecordStore.zones_path = File.expand_path('../../dev/zones', __FILE__)
8
8
  RecordStore.config_path = File.expand_path('../../dev/config.yml', __FILE__)
9
+ RecordStore.implicit_records_templates_path = File.expand_path('../../dev/templates/implicit_records', __FILE__)
9
10
 
10
11
  require 'pry'
11
12
  binding.pry(RecordStore) # rubocop:disable Lint/Debugger
@@ -28,6 +28,7 @@ require 'record_store/zone/yaml_definitions'
28
28
  require 'record_store/zone'
29
29
  require 'record_store/zone/config'
30
30
  require 'record_store/zone/config/ignore_pattern'
31
+ require 'record_store/zone/config/implicit_record_template'
31
32
  require 'record_store/changeset'
32
33
  require 'record_store/provider'
33
34
  require 'record_store/provider/dynect'
@@ -59,6 +60,13 @@ module RecordStore
59
60
  @config_path ||= File.expand_path('config.yml', Dir.pwd)
60
61
  end
61
62
 
63
+ def implicit_records_templates_path
64
+ @implicit_records_templates_path ||= Pathname.new(
65
+ File.expand_path(config.fetch('implicit_records_templates_path'),
66
+ File.dirname(config_path)),
67
+ ).realpath.to_s
68
+ end
69
+
62
70
  def config_path=(config_path)
63
71
  @config = @zones_path = @secrets_path = nil
64
72
  @config_path = config_path
@@ -1,3 +1,3 @@
1
1
  module RecordStore
2
- VERSION = '6.3.1'.freeze
2
+ VERSION = '6.4.0'.freeze
3
3
  end
@@ -189,7 +189,13 @@ module RecordStore
189
189
  end
190
190
 
191
191
  def build_records(records)
192
- records.map { |record| Record.build_from_yaml_definition(record) }
192
+ all_records = records.map { |record| Record.build_from_yaml_definition(record) }
193
+
194
+ config.implicit_record_templates.each do |template|
195
+ all_records.push(*template.generate_records_to_inject(current_records: all_records))
196
+ end
197
+
198
+ all_records
193
199
  end
194
200
 
195
201
  def validate_records
@@ -3,15 +3,17 @@ module RecordStore
3
3
  class Config
4
4
  include ActiveModel::Validations
5
5
 
6
- attr_reader :ignore_patterns, :providers, :supports_alias
6
+ attr_reader :ignore_patterns, :providers, :supports_alias, :implicit_record_templates
7
7
 
8
8
  validate :validate_zone_config
9
9
 
10
- def initialize(ignore_patterns: [], providers: nil, supports_alias: nil)
10
+ def initialize(ignore_patterns: [], providers: nil, supports_alias: nil, implicit_record_templates: [])
11
11
  @ignore_patterns = ignore_patterns.map do |ignore_pattern|
12
12
  Zone::Config::IgnorePattern.new(ignore_pattern)
13
13
  end
14
-
14
+ @implicit_record_templates = implicit_record_templates.map do |filename|
15
+ Zone::Config::ImplicitRecordTemplate.from_file(filename: filename)
16
+ end
15
17
  @providers = providers
16
18
  @supports_alias = supports_alias
17
19
  end
@@ -0,0 +1,94 @@
1
+ # frozen_string_literal: true
2
+ module RecordStore
3
+ class Zone
4
+ class Config
5
+ class TemplateContext
6
+ def self.build(record:, current_records:)
7
+ new(record: record, current_records: current_records)
8
+ end
9
+
10
+ def initialize(record:, current_records:)
11
+ @record = record
12
+ @current_records = current_records
13
+ end
14
+
15
+ def fetch_binding
16
+ binding
17
+ end
18
+
19
+ private
20
+
21
+ attr_reader :record, :current_records
22
+ end
23
+
24
+ class ImplicitRecordTemplate
25
+ class << self
26
+ def from_file(filename:)
27
+ filepath = template_filepath_for(filename: filename)
28
+ template_file = File.read(filepath)
29
+ filters_for_records_to_template = YAML.load(template_file).deep_symbolize_keys[:each_record]
30
+
31
+ new(template: ERB.new(template_file), filters_for_records_to_template: filters_for_records_to_template)
32
+ end
33
+
34
+ private
35
+
36
+ def template_filepath_for(filename:)
37
+ "#{RecordStore.implicit_records_templates_path}/#{filename}"
38
+ end
39
+ end
40
+
41
+ def initialize(template:, filters_for_records_to_template:)
42
+ @template = template
43
+ @filters_for_records_to_template = filters_for_records_to_template
44
+ end
45
+
46
+ def generate_records_to_inject(current_records:)
47
+ current_records
48
+ .select { |record| should_template?(record: record) }
49
+ .map { |record| template_record_for(record: record, current_records: current_records) }
50
+ .each_with_object([]) do |template_records, records_to_inject|
51
+ next unless should_inject?(
52
+ template_records: template_records,
53
+ current_records: current_records + records_to_inject
54
+ )
55
+
56
+ records_to_inject.push(
57
+ *template_records.fetch(:injected_records, []).map { |r_yml| Record.build_from_yaml_definition(r_yml) }
58
+ )
59
+ end
60
+ end
61
+
62
+ private
63
+
64
+ attr_reader :template, :filters_for_records_to_template
65
+
66
+ def should_inject?(template_records:, current_records:)
67
+ current_records.none? do |record|
68
+ template_records[:conflict_with].any? do |filter|
69
+ record_match?(record: record, filter: filter)
70
+ end
71
+ end
72
+ end
73
+
74
+ def should_template?(record:)
75
+ filters_for_records_to_template.any? { |filter| record_match?(record: record, filter: filter) }
76
+ end
77
+
78
+ def record_match?(record:, filter:)
79
+ filter.all? do |key, value|
80
+ record.public_send(key) == value
81
+ end
82
+ end
83
+
84
+ def template_record_for(record:, current_records:)
85
+ context = TemplateContext.build(record: record, current_records: current_records)
86
+
87
+ YAML.load(
88
+ template.result(context.fetch_binding)
89
+ ).deep_symbolize_keys
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
@@ -48,6 +48,6 @@ Gem::Specification.new do |spec|
48
48
  spec.add_development_dependency 'vcr'
49
49
  spec.add_development_dependency 'pry'
50
50
  spec.add_development_dependency 'webmock'
51
- spec.add_development_dependency 'rubocop', '0.89.1'
51
+ spec.add_development_dependency 'rubocop', '~> 1.0.0'
52
52
  spec.add_development_dependency 'minitest-focus'
53
53
  end
@@ -1,2 +1,3 @@
1
1
  zones_path: zones/
2
2
  secrets_path: secrets.json
3
+ implicit_records_templates_path: templates/implicit_records/
@@ -0,0 +1,13 @@
1
+ each_record:
2
+ - type: A
3
+ fqdn: abc.123.com.
4
+ - type: TXT
5
+ conflict_with:
6
+ - type: TXT
7
+ fqdn: <%= record.fqdn %>.more.domain.com.
8
+ injected_records:
9
+ - type: CNAME
10
+ ttl: 3600
11
+ fqdn: <%= record.fqdn %>.added.information.com
12
+ cname: <%= record.fqdn %>.more.added.information.com.
13
+
@@ -5,6 +5,8 @@ dynect.example.com:
5
5
  ignore_patterns:
6
6
  - type: NS
7
7
  fqdn: dynect.example.com.
8
+ implicit_record_templates:
9
+ - implicit_example.yml.erb
8
10
  records:
9
11
  - type: A
10
12
  fqdn: a-record.dynect.example.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.3.1
4
+ version: 6.4.0
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-10-09 00:00:00.000000000 Z
12
+ date: 2020-12-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: thor
@@ -301,16 +301,16 @@ dependencies:
301
301
  name: rubocop
302
302
  requirement: !ruby/object:Gem::Requirement
303
303
  requirements:
304
- - - '='
304
+ - - "~>"
305
305
  - !ruby/object:Gem::Version
306
- version: 0.89.1
306
+ version: 1.0.0
307
307
  type: :development
308
308
  prerelease: false
309
309
  version_requirements: !ruby/object:Gem::Requirement
310
310
  requirements:
311
- - - '='
311
+ - - "~>"
312
312
  - !ruby/object:Gem::Version
313
- version: 0.89.1
313
+ version: 1.0.0
314
314
  - !ruby/object:Gem::Dependency
315
315
  name: minitest-focus
316
316
  requirement: !ruby/object:Gem::Requirement
@@ -380,6 +380,7 @@ files:
380
380
  - lib/record_store/zone.rb
381
381
  - lib/record_store/zone/config.rb
382
382
  - lib/record_store/zone/config/ignore_pattern.rb
383
+ - lib/record_store/zone/config/implicit_record_template.rb
383
384
  - lib/record_store/zone/yaml_definitions.rb
384
385
  - record_store.gemspec
385
386
  - shipit.rubygems.yml
@@ -389,6 +390,7 @@ files:
389
390
  - template/bin/test
390
391
  - template/config.yml
391
392
  - template/secrets.json
393
+ - template/templates/implicit_records/implicit_example.yml.erb
392
394
  - template/zones/dnsimple.example.com.yml
393
395
  - template/zones/dnsimple.example.com/A__a-record.yml
394
396
  - template/zones/dnsimple.example.com/TXT__marco.yml