Skip to content

Commit

Permalink
Merge pull request #235 from Shopify/alias-conflicts
Browse files Browse the repository at this point in the history
prevent Alias conflicts
  • Loading branch information
sbfaulkner committed Apr 5, 2024
2 parents b6b449b + b82a13d commit 5fdaf0e
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 1 deletion.
3 changes: 3 additions & 0 deletions CHANGELOG.md
@@ -1,5 +1,8 @@
# CHANGELOG

## 7.0.0
- Validate that there are no A/AAAA record conflicts with ALIAS records

## 6.7.2
- Fix ActiveModel::Error usage for validate_records (behaviour change in ActiveModel 7)

Expand Down
2 changes: 1 addition & 1 deletion lib/record_store/version.rb
@@ -1,3 +1,3 @@
module RecordStore
VERSION = '6.7.2'.freeze
VERSION = '7.0.0'.freeze
end
22 changes: 22 additions & 0 deletions lib/record_store/zone.rb
Expand Up @@ -22,6 +22,7 @@ class Zone
validate :validate_can_handle_alias_records
validate :validate_no_duplicate_keys
validate :validate_zone_record_not_shadowed
validate :validate_alias_has_no_conflicts

class << self
def download(name, provider_name, **write_options)
Expand Down Expand Up @@ -265,6 +266,27 @@ def validate_cname_records_dont_point_to_root
end
end

# CNAME conflict is handled by validate_cname_records_for_same_fqdn
ALIAS_CONFLICTS = [
"A",
"AAAA",
]

def validate_alias_has_no_conflicts
alias_records = records.select { |record| record.is_a?(Record::ALIAS) }

alias_records.each do |alias_record|
records.each do |record|
next unless ALIAS_CONFLICTS.include?(record.type)
next unless record.fqdn == alias_record.fqdn

errors.add(:records, "#{record.type} record conflicts with ALIAS:\n" \
"- #{alias_record}\n" \
"- #{record}")
end
end
end

def validate_provider_can_handle_zone_records
record_types = records.map(&:type).to_set
return unless config.valid?
Expand Down
30 changes: 30 additions & 0 deletions test/zone_test.rb
Expand Up @@ -197,6 +197,36 @@ def test_zone_with_cname_records
)
end

def test_zone_with_alias_conflicts
zone = Zone.new(
name: 'example.com',
config: { providers: ['DynECT'], supports_alias: true },
)

zone.records = [
Record::ALIAS.new(fqdn: 'www.example.com.', ttl: 600, alias: 'other.example.com.'),
Record::TXT.new(fqdn: 'www.example.com.', ttl: 600, txtdata: 'example'),
]

assert_predicate(zone, :valid?)

zone.records = [
Record::ALIAS.new(fqdn: 'www.example.com.', ttl: 600, alias: 'other.example.com.'),
Record::A.new(fqdn: 'www.example.com.', ttl: 600, address: '1.2.3.4'),
]

refute_predicate(zone, :valid?)
assert_match(/A record conflicts with ALIAS/, zone.errors[:records].first)

zone.records = [
Record::ALIAS.new(fqdn: 'www.example.com.', ttl: 600, alias: 'other.example.com.'),
Record::AAAA.new(fqdn: 'www.example.com.', ttl: 600, address: '2001:db8:85a3::ea75:1337:beef'),
]

refute_predicate(zone, :valid?)
assert_match(/AAAA record conflicts with ALIAS/, zone.errors[:records].first)
end

def test_filter_records
records = [
Record::CNAME.new(fqdn: 'www.example.com.', ttl: 600, cname: 'real.example.com.'),
Expand Down

0 comments on commit 5fdaf0e

Please sign in to comment.