diff --git a/app/controllers/records_controller.rb b/app/controllers/records_controller.rb index 63a26d3..7518e20 100644 --- a/app/controllers/records_controller.rb +++ b/app/controllers/records_controller.rb @@ -19,7 +19,7 @@ class RecordsController < ApplicationController respond_to :html, :xml, :json active_scaffold :record do |conf| - conf.sti_children = [:SOA, :NS, :MX, :A, :CNAME, :TXT, :AAAA] + conf.sti_children = [:SOA, :NS, :MX, :A, :CNAME, :TXT, :AAAA, :SRV] conf.columns = [:name, :type, :content, :ttl, :prio, :change_date, :authentication_token] conf.columns[:change_date].list_ui = :timestamp conf.columns[:ttl].options = {:i18n_number => {:delimiter => ''}} diff --git a/app/controllers/srvs_controller.rb b/app/controllers/srvs_controller.rb new file mode 100644 index 0000000..87ad798 --- /dev/null +++ b/app/controllers/srvs_controller.rb @@ -0,0 +1,42 @@ +class SrvsController < ApplicationController + active_scaffold :srv do |conf| + conf.columns = [:name, :type, :content, :weight, :port, :host, :ttl, :prio, :change_date, :authentication_token] + conf.columns = [:name, :type, :content, :ttl, :prio, :change_date, :authentication_token] + conf.create.columns = [:weight, :host, :port, :ttl, :prio] + conf.update.columns = [:weight, :host, :port, :ttl, :prio] + conf.columns[:content].description = 'Ex. "_http._tcp.example.com"' + conf.columns[:change_date].list_ui = :timestamp + conf.columns[:ttl].options = {:i18n_number => {:delimiter => ''}} + conf.actions.exclude :show + end + before_filter :ensure_nested_under_domain + + protected + + def do_new + super + @record.prio ||= 0 + end + + # override to use :mx_records instead of :records assoc + def beginning_of_chain + if nested? && nested.association && nested.association.collection? && nested.association.name == :records + nested.parent_scope.srv_records + else + super + end + end + + # override, we make our own sti logic + def new_model + model = beginning_of_chain.new + model.name = nested_parent_record.name + model + end + + # override to close create form after success + def render_parent? + nested_singular_association? # || params[:parent_sti] + end + +end diff --git a/app/helpers/srvs_helper.rb b/app/helpers/srvs_helper.rb new file mode 100644 index 0000000..049646f --- /dev/null +++ b/app/helpers/srvs_helper.rb @@ -0,0 +1,2 @@ +module SrvsHelper +end \ No newline at end of file diff --git a/app/models/record.rb b/app/models/record.rb index c696818..ab7f30c 100644 --- a/app/models/record.rb +++ b/app/models/record.rb @@ -3,7 +3,7 @@ class Record < ActiveRecord::Base belongs_to :user, :inverse_of => :records cattr_reader :types - @@types = %w(SOA NS A MX TXT CNAME AAAA) + @@types = %w(SOA NS A MX TXT CNAME AAAA SRV) validates :domain, :name, :presence => true validates :type, :inclusion => {:in => @@types, :message => "Unknown record type"} diff --git a/app/models/srv.rb b/app/models/srv.rb new file mode 100644 index 0000000..b83a1ae --- /dev/null +++ b/app/models/srv.rb @@ -0,0 +1,51 @@ +# = Services Record (SRV) +# +# Defines services available in the zone, for example, ldap, http etc.. +# +# @see http://www.ietf.org/rfc/rfc2872.txt +# @see http://www.zytrax.com/books/dns/ch8/srv.html +class SRV < Record + validates :name, :hostname => {:allow_underscore => true, :allow_wildcard_hostname => true} + validates :content, :format => /^\d+ \d+ [A-Za-z0-9\-_.]+$/ + # RFC 2872 + validates :prio, :presence => true, :numericality => { + :greater_than_or_equal_to => 0, + :less_than_or_equal_to => 65535, + :only_integer => true + } + validates :weight, :presence => true, :numericality => { + :greater_than_or_equal_to => 0, + :less_than_or_equal_to => 65535, + :only_integer => true + } + validates :port, :presence => true, :numericality => { + :greater_than_or_equal_to => 0, + :less_than_or_equal_to => 65535, + :only_integer => true + } + validates :host, :presence => true, :hostname => { + :allow_underscore => true, + :allow_wildcard_hostname => true + } + + attr_accessor :weight, :port, :host + + before_validation :assemble_content + after_initialize :disassemble_content + + def supports_priority?; true end + + protected + + def assemble_content + self.content = "#{@weight} #{@port} #{@host}".strip + end + + # Update our convenience accessors when the object has changed + def disassemble_content + @weight, @port, @host = content.split(/\s+/) unless content.blank? + end + +end + +Srv = SRV diff --git a/app/views/pages/fragments/_features.html.erb b/app/views/pages/fragments/_features.html.erb index 217c56a..4156fd1 100644 --- a/app/views/pages/fragments/_features.html.erb +++ b/app/views/pages/fragments/_features.html.erb @@ -3,7 +3,7 @@
SOA, NS, A, CNAME, TXT (more coming soon)
+SOA, NS, A, CNAME, AAAA, MX, TXT, SRV (more coming soon)
Yes, you certainly can.
diff --git a/config/locales/en.yml b/config/locales/en.yml index e97ae61..3d6bc75 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -5,8 +5,8 @@ en: errors: action_not_allowed: "Action not allowed" messages: - ipv4: "must be a valid IPV4" - ipv6: "must be a valid IPV6" + ipv4: "must be a valid IPv4" + ipv6: "must be a valid IPv6" activerecord: models: soa: "SOA Record" @@ -16,6 +16,7 @@ en: a: "A Record" aaaa: "AAAA Record" txt: "TXT Record" + srv: "SRV Record" attributes: domain: ip: "IP" diff --git a/config/routes.rb b/config/routes.rb index f565ca4..a369373 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -46,6 +46,10 @@ Entrydns::Application.routes.draw do as_routes end + resources :srvs do + as_routes + end + get '/dashboard', :to => 'dashboard#index', :as => :dashboard resources :pages, :only => :show diff --git a/spec/controllers/srvs_controller_spec.rb b/spec/controllers/srvs_controller_spec.rb new file mode 100644 index 0000000..b830048 --- /dev/null +++ b/spec/controllers/srvs_controller_spec.rb @@ -0,0 +1,157 @@ +require 'spec_helper' + +# This spec was generated by rspec-rails when you ran the scaffold generator. +# It demonstrates how one might use RSpec to specify the controller code that +# was generated by Rails when you ran the scaffold generator. +# +# It assumes that the implementation code is generated by the rails scaffold +# generator. If you are using any extension libraries to generate different +# controller code, this generated spec may or may not pass. +# +# It only uses APIs available in rails and/or rspec-rails. There are a number +# of tools you can use to make these specs even more expressive, but we're +# sticking to rails and rspec-rails APIs to keep things simple and stable. +# +# Compared to earlier versions of this generator, there is very limited use of +# stubs and message expectations in this spec. Stubs are only used when there +# is no simpler way to get a handle on the object needed for the example. +# Message expectations are only used when there is no simpler way to specify +# that an instance is receiving a specific message. + +describe SrvsController do + + # This should return the minimal set of attributes required to create a valid + # Srv. As you add validations to Srv, be sure to + # update the return value of this method accordingly. + def valid_attributes + {} + end + + describe "GET index" do + it "assigns all srvs as @srvs" do + srv = Srv.create! valid_attributes + get :index + assigns(:srvs).should eq([srv]) + end + end + + describe "GET show" do + it "assigns the requested srv as @srv" do + srv = Srv.create! valid_attributes + get :show, :id => srv.id.to_s + assigns(:srv).should eq(srv) + end + end + + describe "GET new" do + it "assigns a new srv as @srv" do + get :new + assigns(:srv).should be_a_new(Srv) + end + end + + describe "GET edit" do + it "assigns the requested srv as @srv" do + srv = Srv.create! valid_attributes + get :edit, :id => srv.id.to_s + assigns(:srv).should eq(srv) + end + end + + describe "POST create" do + describe "with valid params" do + it "creates a new Srv" do + expect { + post :create, :srv => valid_attributes + }.to change(Srv, :count).by(1) + end + + it "assigns a newly created srv as @srv" do + post :create, :srv => valid_attributes + assigns(:srv).should be_a(Srv) + assigns(:srv).should be_persisted + end + + it "redirects to the created srv" do + post :create, :srv => valid_attributes + response.should redirect_to(Srv.last) + end + end + + describe "with invalid params" do + it "assigns a newly created but unsaved srv as @srv" do + # Trigger the behavior that occurs when invalid params are submitted + Srv.any_instance.stub(:save).and_return(false) + post :create, :srv => {} + assigns(:srv).should be_a_new(Srv) + end + + it "re-renders the 'new' template" do + # Trigger the behavior that occurs when invalid params are submitted + Srv.any_instance.stub(:save).and_return(false) + post :create, :srv => {} + response.should render_template("new") + end + end + end + + describe "PUT update" do + describe "with valid params" do + it "updates the requested srv" do + srv = Srv.create! valid_attributes + # Assuming there are no other srvs in the database, this + # specifies that the Srv created on the previous line + # receives the :update_attributes message with whatever params are + # submitted in the request. + Srv.any_instance.should_receive(:update_attributes).with({'these' => 'params'}) + put :update, :id => srv.id, :srv => {'these' => 'params'} + end + + it "assigns the requested srv as @srv" do + srv = Srv.create! valid_attributes + put :update, :id => srv.id, :srv => valid_attributes + assigns(:srv).should eq(srv) + end + + it "redirects to the srv" do + srv = Srv.create! valid_attributes + put :update, :id => srv.id, :srv => valid_attributes + response.should redirect_to(srv) + end + end + + describe "with invalid params" do + it "assigns the srv as @srv" do + srv = Srv.create! valid_attributes + # Trigger the behavior that occurs when invalid params are submitted + Srv.any_instance.stub(:save).and_return(false) + put :update, :id => srv.id.to_s, :srv => {} + assigns(:srv).should eq(srv) + end + + it "re-renders the 'edit' template" do + srv = Srv.create! valid_attributes + # Trigger the behavior that occurs when invalid params are submitted + Srv.any_instance.stub(:save).and_return(false) + put :update, :id => srv.id.to_s, :srv => {} + response.should render_template("edit") + end + end + end + + describe "DELETE destroy" do + it "destroys the requested srv" do + srv = Srv.create! valid_attributes + expect { + delete :destroy, :id => srv.id.to_s + }.to change(Srv, :count).by(-1) + end + + it "redirects to the srvs list" do + srv = Srv.create! valid_attributes + delete :destroy, :id => srv.id.to_s + response.should redirect_to(srvs_url) + end + end + +end diff --git a/spec/helpers/srvs_helper_spec.rb b/spec/helpers/srvs_helper_spec.rb new file mode 100644 index 0000000..1d83d47 --- /dev/null +++ b/spec/helpers/srvs_helper_spec.rb @@ -0,0 +1,15 @@ +require 'spec_helper' + +# Specs in this file have access to a helper object that includes +# the SrvsHelper. For example: +# +# describe SrvsHelper do +# describe "string concat" do +# it "concats two strings with spaces" do +# helper.concat_strings("this","that").should == "this that" +# end +# end +# end +describe SrvsHelper do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/requests/srvs_spec.rb b/spec/requests/srvs_spec.rb new file mode 100644 index 0000000..04f08c5 --- /dev/null +++ b/spec/requests/srvs_spec.rb @@ -0,0 +1,11 @@ +require 'spec_helper' + +describe "Srvs" do + describe "GET /srvs" do + it "works! (now write some real specs)" do + # Run the generator again with the --webrat flag if you want to use webrat methods/matchers + get srvs_path + response.status.should be(200) + end + end +end diff --git a/spec/routing/srvs_routing_spec.rb b/spec/routing/srvs_routing_spec.rb new file mode 100644 index 0000000..e7b796a --- /dev/null +++ b/spec/routing/srvs_routing_spec.rb @@ -0,0 +1,35 @@ +require "spec_helper" + +describe SrvsController do + describe "routing" do + + it "routes to #index" do + get("/srvs").should route_to("srvs#index") + end + + it "routes to #new" do + get("/srvs/new").should route_to("srvs#new") + end + + it "routes to #show" do + get("/srvs/1").should route_to("srvs#show", :id => "1") + end + + it "routes to #edit" do + get("/srvs/1/edit").should route_to("srvs#edit", :id => "1") + end + + it "routes to #create" do + post("/srvs").should route_to("srvs#create") + end + + it "routes to #update" do + put("/srvs/1").should route_to("srvs#update", :id => "1") + end + + it "routes to #destroy" do + delete("/srvs/1").should route_to("srvs#destroy", :id => "1") + end + + end +end diff --git a/spec/views/srvs/edit.html.erb_spec.rb b/spec/views/srvs/edit.html.erb_spec.rb new file mode 100644 index 0000000..f1d4e3f --- /dev/null +++ b/spec/views/srvs/edit.html.erb_spec.rb @@ -0,0 +1,15 @@ +require 'spec_helper' + +describe "srvs/edit.html.erb" do + before(:each) do + @srv = assign(:srv, stub_model(Srv)) + end + + it "renders the edit srv form" do + render + + # Run the generator again with the --webrat flag if you want to use webrat matchers + assert_select "form", :action => srvs_path(@srv), :method => "post" do + end + end +end diff --git a/spec/views/srvs/index.html.erb_spec.rb b/spec/views/srvs/index.html.erb_spec.rb new file mode 100644 index 0000000..68ccddf --- /dev/null +++ b/spec/views/srvs/index.html.erb_spec.rb @@ -0,0 +1,14 @@ +require 'spec_helper' + +describe "srvs/index.html.erb" do + before(:each) do + assign(:srvs, [ + stub_model(Srv), + stub_model(Srv) + ]) + end + + it "renders a list of srvs" do + render + end +end diff --git a/spec/views/srvs/new.html.erb_spec.rb b/spec/views/srvs/new.html.erb_spec.rb new file mode 100644 index 0000000..7cd61bc --- /dev/null +++ b/spec/views/srvs/new.html.erb_spec.rb @@ -0,0 +1,15 @@ +require 'spec_helper' + +describe "srvs/new.html.erb" do + before(:each) do + assign(:srv, stub_model(Srv).as_new_record) + end + + it "renders new srv form" do + render + + # Run the generator again with the --webrat flag if you want to use webrat matchers + assert_select "form", :action => srvs_path, :method => "post" do + end + end +end diff --git a/spec/views/srvs/show.html.erb_spec.rb b/spec/views/srvs/show.html.erb_spec.rb new file mode 100644 index 0000000..ed03d06 --- /dev/null +++ b/spec/views/srvs/show.html.erb_spec.rb @@ -0,0 +1,11 @@ +require 'spec_helper' + +describe "srvs/show.html.erb" do + before(:each) do + @srv = assign(:srv, stub_model(Srv)) + end + + it "renders attributes in" do + render + end +end