Page Menu
Home
GRNET
Search
Configure Global Search
Log In
Files
F461586
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Sun, May 18, 3:15 AM
Size
5 KB
Mime Type
text/x-diff
Expires
Tue, May 20, 3:15 AM (1 d, 11 h)
Engine
blob
Format
Raw Data
Handle
219998
Attached To
rWEBDNS WebDNS (edet4)
View Options
diff --git a/app/models/domain.rb b/app/models/domain.rb
index deafa86..0fd518f 100644
--- a/app/models/domain.rb
+++ b/app/models/domain.rb
@@ -1,110 +1,124 @@
class Domain < ActiveRecord::Base
+ class NotAChild < StandardError; end
self.inheritance_column = :nx
# List all supported domain types.
def self.domain_types
[
'NATIVE',
'MASTER',
'SLAVE',
]
end
# List domain types that can be created.
def self.allowed_domain_types
domain_types - WebDNS.settings[:prohibit_domain_types]
end
belongs_to :group
has_many :records
# BUG in bump_serial_trigger
has_one :soa, -> { unscope(where: :type) }, class_name: SOA
validates :group_id, presence: true
validates :name, uniqueness: true, presence: true
validates :type, presence: true, inclusion: { in: domain_types }
validates :master, presence: true, ipv4: true, if: :slave?
after_create :generate_soa
after_create :generate_ns
attr_writer :serial_strategy
# Get the zone's serial strategy.
#
# Returns one of the supported serial strategies.
def serial_strategy
@serial_strategy ||= WebDNS.settings[:serial_strategy]
end
# Returns true if this a reverse zone.
def reverse?
name.end_with?('.in-addr.arpa') || name.end_with?('.ip6.arpa')
end
# Returns true if this a ENUM zone.
def enum?
name.end_with?('.e164.arpa')
end
# Returns true if this is a slave zone.
def slave?
type == 'SLAVE'
end
# Compute subnet for reverse records
def subnet
return if not reverse?
if name.end_with?('.in-addr.arpa')
subnet_v4
elsif name.end_with?('.ip6.arpa')
subnet_v6
end
end
+ def self.replace_ds(parent, child, records)
+ parent = find_by_name!(parent)
+ fail NotAChild if not child.end_with?(parent.name)
+
+ existing = parent.records.where(name: child, type: 'DS')
+ recs = records.map { |rec| DS.new(domain: parent, name: child, content: rec) }
+
+ ActiveRecord::Base.transaction do
+ existing.destroy_all
+ recs.map(&:save!)
+ end
+ end
+
private
def subnet_v4
# get ip octets (remove .in-addr.arpa)
octets = name.split('.')[0...-2].reverse
return if octets.any? { |_| false }
mask = 8 * octets.size
octets += [0, 0, 0, 0]
ip = IPAddr.new octets[0, 4].join('.')
[ip, mask].join('/')
end
def subnet_v6
nibbles = name.split('.')[0...-2].reverse
return if nibbles.any? { |_| false }
mask = 4 * nibbles.size
nibbles += [0] * 32
ip = IPAddr.new nibbles[0, 32].in_groups_of(4).map(&:join).join(':')
[ip, mask].join('/')
end
# Hooks
def generate_soa
soa_record = SOA.new(domain: self)
soa_record.save!
end
def generate_ns
return if slave?
return if WebDNS.settings[:default_ns].empty?
WebDNS.settings[:default_ns].each { |ns|
Record.find_or_create_by!(domain: self, type: 'NS', name: '', content: ns)
}
end
end
diff --git a/test/models/domain_test.rb b/test/models/domain_test.rb
index 44852e2..6479a74 100644
--- a/test/models/domain_test.rb
+++ b/test/models/domain_test.rb
@@ -1,87 +1,116 @@
require 'test_helper'
class DomainTest < ActiveSupport::TestCase
def setup
@domain = build(:domain)
end
test 'automatic SOA creation' do
@domain.save!
@domain.reload
assert_not_nil @domain.soa
end
test 'increment serial on new record' do
@domain.save!
soa = @domain.soa
assert_serial_update soa do
www = A.new(name: 'www', domain: @domain, content: '1.2.3.4')
www.save!
end
end
test 'increment serial on record update' do
@domain.save!
www = A.new(name: 'www', domain: @domain, content: '1.2.3.4')
www.save!
soa = @domain.soa.reload
assert_serial_update soa do
www.content = '1.2.3.5'
www.save!
end
end
test 'automatic NS creation' do
@domain.save!
@domain.reload
assert_equal WebDNS.settings[:default_ns].sort,
@domain.records.where(type: 'NS').pluck(:content).sort
end
test 'increment serial on record destroy' do
@domain.save!
www = A.new(name: 'www', domain: @domain, content: '1.2.3.4')
www.save!
soa = @domain.soa.reload
assert_serial_update soa do
www.destroy!
end
end
class SlaveDomainTest < ActiveSupport::TestCase
def setup
@domain = build(:slave)
end
test 'saves' do
@domain.save
assert_empty @domain.errors
end
test 'automatic SOA creation' do
@domain.save!
@domain.reload
assert_not_nil @domain.soa
assert_equal 1, @domain.soa.serial
end
test 'validates master' do
@domain.master = 'not-an-ip'
@domain.save
assert_not_empty @domain.errors['master']
end
test 'no records are allowed for users' do
@domain.save!
rec = build(:a, domain_id: @domain.id)
assert_not rec.valid?
assert_not_empty rec.errors[:type]
end
end
+
+ class DsDomainTest < ActiveSupport::TestCase
+ def setup
+ @domain = create(:domain)
+ @ds = [
+ '31406 8 1 189968811e6eba862dd6c209f75623d8d9ed9142',
+ '31406 8 2 f78cf3344f72137235098ecbbd08947c2c9001c7f6a085a17f518b5d8f6b916d',
+ ]
+ @child = "dnssec.#{@domain.name}"
+ @extra = DS.create(domain: @domain, name: @child, content: 'other')
+ end
+
+ test 'add ds records' do
+ Domain.replace_ds(@domain.name, @child, @ds)
+ @extra.save! # Should be deleted
+
+ assert_equal @ds.size, DS.where(name: "dnssec.#{@domain.name}").count
+ @ds.each { |ds|
+ assert_equal 1, DS.where(name: "dnssec.#{@domain.name}", content: ds).count
+ }
+ end
+
+ test 'check if child is a valid subdomain' do
+ assert_raise Domain::NotAChild do
+ Domain.replace_ds(@domain.name, 'dnssec.example.net', @ds)
+ end
+ end
+
+ end
end
Event Timeline
Log In to Comment