Page Menu
Home
GRNET
Search
Configure Global Search
Log In
Files
F461704
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, 4:36 PM
Size
6 KB
Mime Type
text/x-diff
Expires
Tue, May 20, 4:36 PM (1 d, 14 h)
Engine
blob
Format
Raw Data
Handle
220413
Attached To
rWEBDNS WebDNS (edet4)
View Options
diff --git a/app/models/domain.rb b/app/models/domain.rb
index ca828fb..2fdf4c6 100644
--- a/app/models/domain.rb
+++ b/app/models/domain.rb
@@ -1,28 +1,33 @@
class Domain < ActiveRecord::Base
self.inheritance_column = :nx
def self.domain_types
[
'NATIVE',
'MASTER',
'SLAVE',
]
end
has_many :records
has_one :soa, class_name: SOA
validates :name, uniqueness: true, presence: true
validates :type, presence: true, inclusion: { in: domain_types }
after_create :generate_soa
+ attr_writer :serial_strategy
+ def serial_strategy
+ @serial_strategy ||= WebDNS.settings[:serial_strategy]
+ end
+
private
# Hooks
def generate_soa
soa_record = SOA.new(domain: self)
soa_record.save
end
end
diff --git a/app/models/soa.rb b/app/models/soa.rb
index 8cf823d..bac20ac 100644
--- a/app/models/soa.rb
+++ b/app/models/soa.rb
@@ -1,73 +1,77 @@
class SOA < Record
validates :domain_id, uniqueness: true
validates_numericality_of :serial, :refresh, :retry, :expire
validates_presence_of :contact
SOA_DEFAULTS = WebDNS.settings[:soa_defaults]
SOA_FIELDS = SOA_DEFAULTS.keys
SOA_FIELDS.each { |soa_entry|
attr_accessor soa_entry
}
# Handle SOA Fields
after_initialize :set_soa_fields
# Load soa fields on reload
def reload_with_soa_fields(*args)
reload_without_soa_fields(*args).tap {
set_soa_fields
}
end
alias_method_chain :reload, :soa_fields
before_validation :set_content
before_validation :update_serial, on: :update
def bump_serial!
with_lock {
reload
- self.serial += 1
+ generate_serial
save!
}
end
def serial_changed?
return false if not self.content_changed?
serial_index = SOA_FIELDS.index(:serial)
old, new = content_change.map { |c|
(c || '').split(/\s+/)[serial_index]
}
old != new
end
private
+ def generate_serial
+ self.serial = domain.serial_strategy.generate_serial(serial)
+ end
+
# Callbacks
def set_soa_fields
content_values = (content || '').split(/\s+/)
SOA_DEFAULTS.each { |field, default_value|
val = content_values.shift || default_value
val = Integer(val) if default_value.is_a?(Integer)
send("#{field}=", val)
}
end
def set_content
self.content = SOA_FIELDS.map { |field| send(field) }.join(' ')
end
def update_serial
# Don't update if nothing has changed
return if not self.content_changed?
# Don't updade if serial is already changed
return if self.serial_changed?
- self.serial += 1
+ generate_serial
set_content
end
end
diff --git a/config/initializers/00_settings.rb b/config/initializers/00_settings.rb
index 991c443..88695d4 100644
--- a/config/initializers/00_settings.rb
+++ b/config/initializers/00_settings.rb
@@ -1,12 +1,13 @@
WebDNS = Base
WebDNS.settings[:soa_defaults] = {
primary_ns: 'ns.example.com',
contact: 'domainmaster@example.com',
serial: 1,
refresh: 10_800,
retry: 3600,
expire: 604_800,
nx: 3600
}
+WebDNS.settings[:serial_strategy] = Strategies::Date
diff --git a/lib/strategies/date.rb b/lib/strategies/date.rb
new file mode 100644
index 0000000..ed4e145
--- /dev/null
+++ b/lib/strategies/date.rb
@@ -0,0 +1,19 @@
+module Strategies
+ module Date
+ module_function
+
+ def generate_serial(current_serial)
+ # Optimization for the case that current_serial is a lot larger
+ # than the generated serial
+ new = [
+ Time.now.strftime('%Y%m%d00').to_i,
+ current_serial
+ ].max
+
+ # Increment until we find a spot
+ new += 1 while new <= current_serial
+
+ new
+ end
+ end
+end
diff --git a/lib/strategies/incremental.rb b/lib/strategies/incremental.rb
new file mode 100644
index 0000000..75a4772
--- /dev/null
+++ b/lib/strategies/incremental.rb
@@ -0,0 +1,9 @@
+module Strategies
+ module Incremental
+ module_function
+
+ def generate_serial(current_serial)
+ current_serial + 1
+ end
+ end
+end
diff --git a/test/factories/domain.rb b/test/factories/domain.rb
index f216127..6ff5abf 100644
--- a/test/factories/domain.rb
+++ b/test/factories/domain.rb
@@ -1,7 +1,14 @@
FactoryGirl.define do
sequence(:domain) { |n| "example#{n}.com" }
factory :domain do
name { generate(:domain) }
+ serial_strategy Strategies::Date
+ type 'NATIVE'
+ end
+
+ factory :date_domain, class: Domain do
+ name { generate(:domain) }
+ serial_strategy Strategies::Date
type 'NATIVE'
end
end
diff --git a/test/models/soa_test.rb b/test/models/soa_test.rb
index 3ad4cfa..a96a30f 100644
--- a/test/models/soa_test.rb
+++ b/test/models/soa_test.rb
@@ -1,25 +1,60 @@
require 'test_helper'
class SOATest < ActiveSupport::TestCase
def setup
domain = create(:domain)
@record = domain.soa
end
test 'bump_serial!' do
@record.save!
assert_serial_update @record do
@record.bump_serial!
end
end
test 'updating attributes bumps serial' do
@record.save!
assert_serial_update @record do
@record.contact = 'admin@example.com'
@record.save!
end
end
+
+ class DateSerialTests < ActiveSupport::TestCase
+ setup do
+ domain = create(:date_domain)
+ @record = domain.soa
+ end
+
+ test 'last bump of the day' do
+ assert_equal Strategies::Date, @record.domain.serial_strategy
+
+ freeze_time do
+ last_for_day = Time.now.strftime('%Y%m%d99').to_i
+ @record.serial = last_for_day
+ @record.save!
+
+ assert_serial_update @record do
+ @record.bump_serial!
+ end
+ end
+ end
+
+ test 'existing serial points to a future date' do
+ assert_equal Strategies::Date, @record.domain.serial_strategy
+
+ freeze_time do
+ future_day = (Time.now + 1.week).strftime('%Y%m%d00').to_i
+ @record.serial = future_day
+ @record.save!
+
+ assert_serial_update @record do
+ @record.bump_serial!
+ end
+ end
+ end
+ end
end
Event Timeline
Log In to Comment