Page MenuHomeGRNET

No OneTemporary

File Metadata

Created
Wed, Nov 19, 7:25 AM
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