You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

85 lines
2.6 KiB

# See #SOA
# = Start of Authority Record
# Defined in RFC 1035. The SOA defines global parameters for the zone (domain).
# There is only one SOA record allowed in a zone file.
#
# Obtained from http://www.zytrax.com/books/dns/ch8/soa.html
#
class SOA < Record
validates :domain_id, :presence => true, :uniqueness => true # one SOA per domain
validates :name, :presence => true, :hostname => true
validate :name_equals_dmain_name?
validates :content, :presence => true
validates :primary_ns, :presence => true
CONTACT_FORMAT = /\A[a-zA-Z0-9\-\.]+@[a-zA-Z0-9-]+\.[a-zA-Z.]{2,6}\z/
validates :contact, :format => {:with => CONTACT_FORMAT}
validates :serial, :presence => true, :numericality => {:allow_blank => true, :greater_than_or_equal_to => 0}
before_validation :assemble_content
before_update :update_serial
after_initialize :disassemble_content
before_validation do
self.primary_ns ||= domain.ns_records.first.content
end
# This allows us to have these convenience attributes act like any other
# column in terms of validations
attr_accessor :primary_ns, :contact, :serial
# Treat contact specially
# replacing the first period with an @ if no @'s are present
def contact=(email)
email.sub!('.', '@') if email.present? && email.index('@').nil?
@contact = email
end
# Hook into #reload
def reload_with_content
reload_without_content
disassemble_content
end
alias_method_chain :reload, :content
# Updates the serial number to the next logical one. Format of the generated
# serial is YYYYMMDDNN, where NN is the number of the change for the day.
# 01 for the first change, 02 the seconds, etc...
#
# If the serial number is 0, we opt for PowerDNS's automatic serial number
# generation, that gets triggered by updating the change_date
def update_serial
return if self.content_changed?
date_serial = Time.now.strftime( "%Y%m%d00" ).to_i
@serial = (@serial.nil? || date_serial > @serial) ? date_serial : @serial + 1
end
# Same as #update_serial and saves the record
def update_serial!
update_serial
save
end
def to_label; "#{primary_ns} #{contact}" end
private
def assemble_content
self.content = "#{@primary_ns} #{@contact} #{@serial}".strip
end
# Update our convenience accessors when the object has changed
def disassemble_content
@primary_ns, @contact, @serial = content.split(/\s+/) unless content.blank?
@serial = @serial.to_i unless @serial.nil?
update_serial if @serial.nil? || @serial.zero?
end
def name_equals_dmain_name?
unless name == domain.name
errors.add :name, "must be equal to domain's name"
end
end
end
Soa = SOA