diff --git a/app/controllers/admin/zonefiles_controller.rb b/app/controllers/admin/zonefiles_controller.rb index 811df5627..1eb88687f 100644 --- a/app/controllers/admin/zonefiles_controller.rb +++ b/app/controllers/admin/zonefiles_controller.rb @@ -2,7 +2,20 @@ class Admin::ZonefilesController < ApplicationController # TODO: Refactor this # rubocop:disable Metrics/MethodLength def index - @zonefile = ActiveRecord::Base.connection.execute("select generate_zonefile('ee')")[0]['generate_zonefile'] - send_data @zonefile, filename: 'zonefile-1000.txt' + + end + + def create + if ZonefileSetting.pluck(:origin).include?(params[:origin]) + + @zonefile = ActiveRecord::Base.connection.execute( + "select generate_zonefile('#{params[:origin]}')" + )[0]['generate_zonefile'] + + send_data @zonefile, filename: "#{params[:origin]}.txt" + else + flash[:alert] = 'Origin not supported' + redirect_to :back + end end end diff --git a/app/models/cached_nameserver.rb b/app/models/cached_nameserver.rb new file mode 100644 index 000000000..d465edf83 --- /dev/null +++ b/app/models/cached_nameserver.rb @@ -0,0 +1,2 @@ +class CachedNameserver < ActiveRecord::Base +end diff --git a/app/models/nameserver.rb b/app/models/nameserver.rb index 65373034d..8e1b1d186 100644 --- a/app/models/nameserver.rb +++ b/app/models/nameserver.rb @@ -10,6 +10,10 @@ class Nameserver < ActiveRecord::Base validates :ipv6, format: { with: /(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))/, allow_blank: true } # rubocop: enable Metrics/LineLength + # caching + after_commit :clear_cache + after_commit :create_cache, on: [:create, :update] + # archiving has_paper_trail class_name: 'NameserverVersion' after_destroy :domain_version @@ -52,6 +56,16 @@ class Nameserver < ActiveRecord::Base domain.create_version if domain end + def create_cache + CachedNameserver.create(snapshot) + rescue ActiveRecord::RecordNotUnique + logger.info('Nameserver already exists in cache; not caching') + end + + def clear_cache + CachedNameserver.find_by(snapshot).try(:delete) + end + def to_s hostname end diff --git a/app/views/admin/zonefile_settings/index.haml b/app/views/admin/zonefile_settings/index.haml index 6e3a7ae17..48411be88 100644 --- a/app/views/admin/zonefile_settings/index.haml +++ b/app/views/admin/zonefile_settings/index.haml @@ -17,4 +17,4 @@ %tr %td= link_to(x, edit_admin_zonefile_setting_path(x)) %td - = link_to(t('generate_zonefile'), admin_zonefiles_path, class: 'btn btn-xs btn-primary') + = link_to(t('generate_zonefile'), admin_zonefiles_path(origin: x.origin), method: 'post', class: 'btn btn-xs btn-primary') diff --git a/db/migrate/20141120140837_add_ee_domain_objects.rb b/db/migrate/20141120140837_add_ee_domain_objects.rb index af1a63325..fb7d296cc 100644 --- a/db/migrate/20141120140837_add_ee_domain_objects.rb +++ b/db/migrate/20141120140837_add_ee_domain_objects.rb @@ -1,14 +1,14 @@ class AddEeDomainObjects < ActiveRecord::Migration # rubocop:disable Metrics/MethodLength def up - r = Registrar.create( + r = Registrar.create!( name: 'EIS', reg_no: '123321', address: 'Tallinn', country: Country.estonia ) - c = Contact.create( + c = Contact.create!( name: 'EIS', phone: '+372.123321', email: 'info@testing.ee', @@ -21,14 +21,14 @@ class AddEeDomainObjects < ActiveRecord::Migration registrar: r ) - EppUser.create( + EppUser.create!( registrar: r, username: 'testeis', password: 'testeis', active: true ) - Domain.create( + Domain.create!( name: 'ee', valid_to: Date.new(9999, 1, 1), period: 1, @@ -46,17 +46,23 @@ class AddEeDomainObjects < ActiveRecord::Migration registrar: r ) - pri = Domain.new( + Domain.create!( name: 'pri.ee', valid_to: Date.new(9999, 1, 1), period: 1, period_unit: 'y', owner_contact: c, + nameservers: [ + Nameserver.create(hostname: 'ns.tld.ee', ipv4: '195.43.87.10'), + Nameserver.create(hostname: 'b.tld.ee', ipv4: '194.146.106.110', ipv6: '2001:67c:1010:28::53'), + Nameserver.create(hostname: 'e.tld.ee', ipv4: '204.61.216.36', ipv6: '2001:678:94:53::53'), + Nameserver.create(hostname: 'ee.aso.ee', ipv4: '213.184.51.122', ipv6: '2a02:88:0:21::2'), + Nameserver.create(hostname: 'ns.ut.ee', ipv4: '193.40.5.99', ipv6: ''), + Nameserver.create(hostname: 'sunic.sunet.se', ipv4: '195.80.103.202') + ], admin_contacts: [c], registrar: r ) - - pri.save(validate: false) end # rubocop:enable Metrics/MethodLength diff --git a/db/migrate/20141121093125_add_zonefile_procedure.rb b/db/migrate/20141121093125_add_zonefile_procedure.rb index 1eb53d50d..59d5f3e2e 100644 --- a/db/migrate/20141121093125_add_zonefile_procedure.rb +++ b/db/migrate/20141121093125_add_zonefile_procedure.rb @@ -17,11 +17,11 @@ class AddZonefileProcedure < ActiveRecord::Migration include_filter = '%' || i_origin; -- for %.%.% - IF i_origin ~ '\.' THEN + IF i_origin ~ '\\.' THEN exclude_filter := ''; -- for %.% ELSE - exclude_filter = '%.%.' || i_origin; + exclude_filter := '%.%.' || i_origin; END IF; -- zonefile header @@ -36,14 +36,14 @@ class AddZonefileProcedure < ActiveRecord::Migration format('%-17s', ''), format('%-12s', zf.minimum_ttl), '; minimum TTL, seconds', chr(10), format('%-17s', ''), ')' ) FROM zonefile_settings zf WHERE i_origin = zf.origin INTO zone_header; - RAISE NOTICE '%', include_filter; + -- ns records SELECT array_to_string( array( SELECT concat(d.name, '. IN NS ', ns.hostname, '.') FROM domains d JOIN nameservers ns ON ns.domain_id = d.id - WHERE d.name LIKE include_filter + WHERE d.name LIKE include_filter AND d.name NOT LIKE exclude_filter ORDER BY CASE d.name WHEN i_origin THEN 1 @@ -52,17 +52,25 @@ class AddZonefileProcedure < ActiveRecord::Migration chr(10) ) INTO ns_records; + -- use caching + + /*SELECT concat(cns.hostname, '. IN A ', cns.ipv4, '.') FROM cached_nameservers cns WHERE EXISTS ( + SELECT 1 + FROM nameservers ns + JOIN domains d ON d.id = ns.domain_id + WHERE d.name LIKE include_filter AND d.name NOT LIKE exclude_filter + AND ns.hostname = cns.hostname AND ns.ipv4 = cns.ipv4 AND ns.ipv6 = cns.ipv6 + AND ns.ipv4 IS NOT NULL AND ns.ipv4 <> '' + );*/ + -- a records SELECT array_to_string( array( SELECT concat(ns.hostname, '. IN A ', ns.ipv4, '.') FROM domains d JOIN nameservers ns ON ns.domain_id = d.id - WHERE d.name LIKE '%' || i_origin AND ns.ipv4 IS NOT NULL AND ns.ipv4 <> '' - ORDER BY - CASE d.name - WHEN i_origin THEN 1 - END + WHERE d.name LIKE include_filter AND d.name NOT LIKE exclude_filter + AND ns.ipv4 IS NOT NULL AND ns.ipv4 <> '' ), chr(10) ) INTO a_records; @@ -73,11 +81,8 @@ class AddZonefileProcedure < ActiveRecord::Migration SELECT concat(ns.hostname, '. IN AAAA ', ns.ipv6, '.') FROM domains d JOIN nameservers ns ON ns.domain_id = d.id - WHERE d.name LIKE '%' || i_origin AND ns.ipv6 IS NOT NULL AND ns.ipv6 <> '' - ORDER BY - CASE d.name - WHEN i_origin THEN 1 - END + WHERE d.name LIKE include_filter AND d.name NOT LIKE exclude_filter + AND ns.ipv6 IS NOT NULL AND ns.ipv6 <> '' ), chr(10) ) INTO a4_records; @@ -86,16 +91,12 @@ class AddZonefileProcedure < ActiveRecord::Migration SELECT array_to_string( array( SELECT concat( - d.name, '. 86400 IN ', dk.ds_key_tag, ' ', + d.name, '. 86400 IN DS ', dk.ds_key_tag, ' ', dk.ds_alg, ' ', dk.ds_digest_type, ' ', dk.ds_digest ) FROM domains d JOIN dnskeys dk ON dk.domain_id = d.id - WHERE d.name LIKE '%' || i_origin - ORDER BY - CASE d.name - WHEN i_origin THEN 1 - END + WHERE d.name LIKE include_filter AND d.name NOT LIKE exclude_filter ), chr(10) ) INTO ds_records; diff --git a/db/migrate/20141125111414_create_nameservers_cache.rb b/db/migrate/20141125111414_create_nameservers_cache.rb new file mode 100644 index 000000000..db56cd767 --- /dev/null +++ b/db/migrate/20141125111414_create_nameservers_cache.rb @@ -0,0 +1,16 @@ +class CreateNameserversCache < ActiveRecord::Migration + def change + create_table :cached_nameservers, id: false do |t| + t.string :hostname + t.string :ipv4 + t.string :ipv6 + end + add_index :cached_nameservers, [:hostname, :ipv4, :ipv6], unique: true + + execute <<-SQL + INSERT INTO cached_nameservers ( + SELECT ns.hostname, ns.ipv4, ns.ipv6 FROM nameservers ns GROUP BY ns.hostname, ns.ipv4, ns.ipv6 + ); + SQL + end +end diff --git a/db/schema.rb b/db/schema.rb index 295d7b948..ec3684f36 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20141114130737) do +ActiveRecord::Schema.define(version: 20141125111414) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -39,6 +39,14 @@ ActiveRecord::Schema.define(version: 20141114130737) do t.string "street3" end + create_table "cached_nameservers", id: false, force: true do |t| + t.string "hostname" + t.string "ipv4" + t.string "ipv6" + end + + add_index "cached_nameservers", ["hostname", "ipv4", "ipv6"], name: "index_cached_nameservers_on_hostname_and_ipv4_and_ipv6", unique: true, using: :btree + create_table "contact_disclosures", force: true do |t| t.integer "contact_id" t.boolean "int_name", default: false @@ -335,4 +343,17 @@ ActiveRecord::Schema.define(version: 20141114130737) do add_index "versions", ["item_type", "item_id"], name: "index_versions_on_item_type_and_item_id", using: :btree + create_table "zonefile_settings", force: true do |t| + t.string "origin" + t.integer "ttl" + t.integer "refresh" + t.integer "retry" + t.integer "expire" + t.integer "minimum_ttl" + t.string "email" + t.string "master_nameserver" + t.datetime "created_at" + t.datetime "updated_at" + end + end