Page Menu
Home
GRNET
Search
Configure Global Search
Log In
Files
F1300044
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
Wed, Nov 19, 7:25 AM
Size
3 KB
Mime Type
text/x-diff
Expires
Fri, Nov 21, 7:25 AM (1 d, 3 h)
Engine
blob
Format
Raw Data
Handle
294778
Attached To
rWEBDNS WebDNS (edet4)
View Options
diff --git a/app/models/ptr.rb b/app/models/ptr.rb
new file mode 100644
index 0000000..daa4351
--- /dev/null
+++ b/app/models/ptr.rb
@@ -0,0 +1,4 @@
+class PTR < Record
+ validates :content, presence: true, hostname: true
+end
+
diff --git a/app/models/record.rb b/app/models/record.rb
index 46b6829..bf96011 100644
--- a/app/models/record.rb
+++ b/app/models/record.rb
@@ -1,58 +1,71 @@
+require 'ipaddr'
+
class Record < ActiveRecord::Base
belongs_to :domain
def self.record_types
[
'SOA', 'NS', 'CNAME',
'A', 'AAAA',
'MX',
'TXT', 'SPF', 'SRV', 'SSHFP',
'PTR',
]
end
validates :name, presence: true
validates :type, inclusion: { in: record_types }
+ before_validation :guess_reverse_name
before_validation :set_name
after_save :update_zone_serial
after_destroy :update_zone_serial
def short
return '' if name == domain.name
return '' if name.blank?
File.basename(name, ".#{domain.name}")
end
def supports_prio?
false
end
# Create record specific urls for all record types
#
# Overrides default rails STI
def self.model_name
return super if self == Record
Record.model_name
end
private
# Hooks
+ def guess_reverse_name
+ return if not type == 'PTR'
+ return if not domain.reverse?
+ return if name.blank?
+
+ reverse = IPAddr.new(name).reverse
+ self.name = reverse if reverse.end_with?(domain.name)
+ rescue IPAddr::InvalidAddressError # rubycop:disable HandleExceptions
+ end
+
# Powerdns expects full domain names
def set_name
self.name = domain.name if name.blank?
self.name = "#{name}.#{domain.name}" if not name.end_with?(domain.name)
end
def update_zone_serial
# SOA records handle serial themselves
return true if type == 'SOA'
domain.soa.bump_serial!
end
end
diff --git a/test/factories/ptr.rb b/test/factories/ptr.rb
new file mode 100644
index 0000000..1b63cdc
--- /dev/null
+++ b/test/factories/ptr.rb
@@ -0,0 +1,23 @@
+FactoryGirl.define do
+ sequence(:byte) { |n| (n % 256).to_s }
+ sequence(:nibble) { |n| (n % 16).to_s(16) }
+
+ factory :v4_ptr, class: 'PTR' do
+ domain factory: :v4_arpa_domain
+ name { generate(:byte) }
+ content { generate(:domain) }
+ end
+
+ factory :v6_ptr, class: 'PTR' do
+ domain factory: :v6_arpa_domain
+ name {
+ all_nibbles = '0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa'.split('.').size
+ domain_nibbles = domain.name.split('.').size
+ missing = []
+ (all_nibbles - domain_nibbles).times { missing << generate(:nibble) }
+
+ missing.join('.')
+ }
+ content { generate(:domain) }
+ end
+end
diff --git a/test/models/ptr_test.rb b/test/models/ptr_test.rb
new file mode 100644
index 0000000..7ba80e9
--- /dev/null
+++ b/test/models/ptr_test.rb
@@ -0,0 +1,42 @@
+require 'test_helper'
+
+class PTRTest < ActiveSupport::TestCase
+ class V4PTRTest < ActiveSupport::TestCase
+ setup do
+ @record = build(:v4_ptr)
+ end
+
+ test 'save' do
+ @record.save
+
+ assert_empty @record.errors
+ end
+
+ test 'guess record' do
+ @record.name = '192.0.2.1'
+ assert @record.save
+
+ assert_equal '1.2.0.192.in-addr.arpa', @record.name
+ end
+ end
+
+ class V6PTRTest < ActiveSupport::TestCase
+ setup do
+ @record = build(:v6_ptr)
+ end
+
+ test 'save' do
+ @record.save
+ assert_empty @record.errors
+ end
+
+ test 'guess record' do
+ @record.name = '2001:db8::2'
+ assert @record.save
+
+ assert_equal '2.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa',
+ @record.name
+ end
+ end
+
+end
Event Timeline
Log In to Comment