From 87ceaa90b19abd053659e758328b405966922f55 Mon Sep 17 00:00:00 2001 From: Kenneth Kalmer Date: Sun, 6 Jul 2008 20:23:47 +0200 Subject: [PATCH] New zone creation only loads valid zone templates [#24 state:resolved] Added new finder extensions to ZoneTemplate ([#24]) --- app/controllers/zones_controller.rb | 2 +- app/models/zone_template.rb | 29 ++++++++++++++++++++++- spec/controllers/zones_controller_spec.rb | 1 + spec/fixtures/record_templates.yml | 25 ++++++++++++++----- spec/fixtures/zone_templates.yml | 5 ++++ spec/models/zone_template_spec.rb | 18 ++++++++++++++ 6 files changed, 72 insertions(+), 8 deletions(-) diff --git a/app/controllers/zones_controller.rb b/app/controllers/zones_controller.rb index a54e009..cc1508c 100644 --- a/app/controllers/zones_controller.rb +++ b/app/controllers/zones_controller.rb @@ -17,7 +17,7 @@ def show def new @zone = Zone.new - @zone_templates = ZoneTemplate.find( :all ) + @zone_templates = ZoneTemplate.find( :all, :require_soa => true ) end def create diff --git a/app/models/zone_template.rb b/app/models/zone_template.rb index b8e3caf..45f82ba 100644 --- a/app/models/zone_template.rb +++ b/app/models/zone_template.rb @@ -6,7 +6,28 @@ class ZoneTemplate < ActiveRecord::Base validates_uniqueness_of :name validates_presence_of :ttl - # Build a new zone using +self+ as a template. +zone+ should be valid zone + class << self + + # Custom find that takes one additional parameter, :require_soa (bool), for + # restricting the returned resultset to only instances that #has_soa? + def find_with_validations( *args ) + options = args.extract_options! + valid_soa = options.delete( :require_soa ) || false + + # find as per usual + records = find_without_validations( *args << options ) + + if valid_soa + records.delete_if { |z| !z.has_soa? } + end + + records # give back + end + alias_method_chain :find, :validations + + end + + # Build a new zone using +self+ as a template. +zone+ should be valid zone # name. This method will throw exceptions as it encounters errors, and will # use a transaction to complete the operation def build( zone_name ) @@ -39,4 +60,10 @@ def build( zone_name ) zone end + + # If the template has an SOA record, it can be used for building zones + def has_soa? + record_templates.count( :conditions => "record_type LIKE 'SOA'" ) == 1 + end + end diff --git a/spec/controllers/zones_controller_spec.rb b/spec/controllers/zones_controller_spec.rb index b737680..56b8abb 100644 --- a/spec/controllers/zones_controller_spec.rb +++ b/spec/controllers/zones_controller_spec.rb @@ -37,6 +37,7 @@ response.should render_template('zones/new') assigns[:zone].should be_a_kind_of( Zone ) assigns[:zone_templates].should_not be_empty + assigns[:zone_templates].size.should be(2) end it "should not save a partial form" do diff --git a/spec/fixtures/record_templates.yml b/spec/fixtures/record_templates.yml index c92fcf7..3b8a466 100644 --- a/spec/fixtures/record_templates.yml +++ b/spec/fixtures/record_templates.yml @@ -17,40 +17,53 @@ east_coast_ns_ns1: record_type: NS host: @ data: ns1.%ZONE%. -example_com_ns_ns2: +east_coast_ns_ns2: zone_template: east_coast_dc ttl: 86400 record_type: NS host: @ data: ns2.%ZONE%. -example_com_a_ns1: +east_coast_a_ns1: zone_template: east_coast_dc ttl: 86400 record_type: A host: ns1 data: 10.0.0.1 -example_com_a_ns2: +east_coast_a_ns2: zone_template: east_coast_dc ttl: 86400 record_type: A host: ns2 data: 10.0.0.2 -example_com_a: +east_coast_a: zone_template: east_coast_dc ttl: 86400 record_type: A host: @ data: 10.0.0.3 -example_com_mx: +east_coast_mx: zone_template: east_coast_dc ttl: 86400 record_type: MX host: @ priority: 10 data: mail -example_com_a_mail: +east_coast_a_mail: zone_template: east_coast_dc ttl: 86400 record_type: A host: mail data: 10.0.0.4 + +# This template only has an SOA record +west_coast_soa: + zone_template: west_coast_dc + ttl: 86400 + record_type: SOA + host: @ + primary_ns: ns1.%ZONE%. + contact: ewest-coast.example.com + refresh: 10800 + retry: 7200 + expire: 604800 + minimum: 10800 diff --git a/spec/fixtures/zone_templates.yml b/spec/fixtures/zone_templates.yml index b0e943a..ea87523 100644 --- a/spec/fixtures/zone_templates.yml +++ b/spec/fixtures/zone_templates.yml @@ -7,3 +7,8 @@ east_coast_dc: west_coast_dc: name: West Coast Data Center ttl: 86400 + +# Has no SOA records, so should never be used in zone creation +partially_complete: + name: Partially Complete + ttl: 43200 diff --git a/spec/models/zone_template_spec.rb b/spec/models/zone_template_spec.rb index fe804c0..e7c4876 100644 --- a/spec/models/zone_template_spec.rb +++ b/spec/models/zone_template_spec.rb @@ -42,6 +42,12 @@ zone.should be_a_kind_of( Zone ) zone.should be_valid end + + it "should have a sense of validity" do + @zone_template.has_soa?.should be_true + + zone_templates( :partially_complete ).has_soa?.should_not be_true + end end describe ZoneTemplate, "when used to build a zone" do @@ -75,4 +81,16 @@ ns.each { |r| r.should be_a_kind_of( NS ) } end +end + +describe ZoneTemplate, "and finders" do + fixtures :all + + it "should be able to return all templates" do + ZoneTemplate.find(:all).size.should be( ZoneTemplate.count ) + end + + it "should respect required validations" do + ZoneTemplate.find(:all, :require_soa => true).size.should be( 2 ) + end end \ No newline at end of file