mirror of
https://github.com/internetee/registry.git
synced 2025-07-02 01:03:35 +02:00
Merge branch 'master' of github.com:internetee/registry
This commit is contained in:
commit
c64fa8c132
10 changed files with 215 additions and 11 deletions
|
@ -1,5 +1,5 @@
|
|||
class Admin::DomainsController < AdminController
|
||||
before_action :set_domain, only: [:show, :edit, :update]
|
||||
before_action :set_domain, only: [:show, :edit, :update, :zonefile]
|
||||
|
||||
def index
|
||||
@q = Domain.includes(:registrar, :owner_contact).search(params[:q])
|
||||
|
@ -27,6 +27,11 @@ class Admin::DomainsController < AdminController
|
|||
end
|
||||
end
|
||||
|
||||
def zonefile
|
||||
@zonefile = @domain.generate_zonefile
|
||||
# send_data @zonefile, filename: 'bla.txt'
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_domain
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
class AdminController < ApplicationController
|
||||
before_action :verify_admin
|
||||
# before_action :verify_admin
|
||||
|
||||
def verify_admin
|
||||
redirect_to client_root_path unless current_user.try(:admin?)
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
class ClientController < ApplicationController
|
||||
helper_method :current_registrar
|
||||
|
||||
def current_registrar
|
||||
return Registrar.find(session[:current_user_registrar_id]) if current_user.admin?
|
||||
current_user.registrar
|
||||
end
|
||||
end
|
|
@ -298,6 +298,35 @@ class Domain < ActiveRecord::Base
|
|||
end
|
||||
end
|
||||
|
||||
def generate_zonefile
|
||||
zf = Zonefile.new
|
||||
zf.ttl = '3600'
|
||||
zf.origin = "#{name}."
|
||||
ns = nameservers.first
|
||||
zf.soa[:primary_ns] = "#{ns.hostname}."
|
||||
zf.soa[:email] = 'hostmaster.internet.ee'
|
||||
zf.soa[:origin] = "#{name}."
|
||||
zf.soa[:refresh] = '10800'
|
||||
zf.soa[:retry] = '3600'
|
||||
zf.soa[:expire] = '604800'
|
||||
zf.soa[:minimumTTL] = '3600'
|
||||
|
||||
nameservers.each do |x|
|
||||
zf.ns << { name: "#{name}.", class: 'IN', host: "#{x.hostname}." }
|
||||
end
|
||||
|
||||
dnskeys.each do |x|
|
||||
zf.ds << { name: "#{name}.", ttl: '86400', class: 'IN', key_tag: x.ds_key_tag, algorithm: x.ds_alg,
|
||||
digest_type: x.ds_digest_type, digest: x.ds_digest }
|
||||
|
||||
zf.dnskey << { name: "#{name}.", ttl: '86400', class: 'IN', flag: x.flags,
|
||||
protocol: x.protocol, algorithm: x.alg, public_key: x.public_key }
|
||||
end
|
||||
|
||||
zf.new_serial
|
||||
zf.generate
|
||||
end
|
||||
|
||||
class << self
|
||||
def convert_period_to_time(period, unit)
|
||||
return period.to_i.days if unit == 'd'
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
.col-sm-6
|
||||
%h2.text-right.text-center-xs
|
||||
= link_to(t('shared.edit_statuses'), edit_admin_domain_path(@domain), class: 'btn btn-primary')
|
||||
= link_to(t('generate_zonefile'), zonefile_admin_domain_path(@domain), class: 'btn btn-primary')
|
||||
|
||||
%hr
|
||||
.row
|
||||
|
|
12
app/views/admin/domains/zonefile.haml
Normal file
12
app/views/admin/domains/zonefile.haml
Normal file
|
@ -0,0 +1,12 @@
|
|||
.row
|
||||
.col-sm-6
|
||||
%h2.text-center-xs
|
||||
= "#{t('zonefile')}"
|
||||
.col-sm-6
|
||||
%h2.text-right.text-center-xs
|
||||
= link_to(t('shared.back_to_domain'), admin_domain_path(@domain), class: 'btn btn-default')
|
||||
%hr
|
||||
.row
|
||||
.col-md-12
|
||||
= preserve do
|
||||
%pre= @zonefile
|
|
@ -27,6 +27,8 @@ module Registry
|
|||
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
|
||||
# config.i18n.default_locale = :de
|
||||
|
||||
config.autoload_paths += %W(#{config.root}/lib)
|
||||
|
||||
config.generators do |g|
|
||||
g.stylesheets false
|
||||
g.javascripts false
|
||||
|
|
|
@ -423,3 +423,5 @@ en:
|
|||
transfer_requested: 'Transfer requested.'
|
||||
message_was_not_found: 'Message was not found'
|
||||
host_obj_is_not_allowed: 'hostObj object is not allowed'
|
||||
generate_zonefile: 'Generate zonefile'
|
||||
zonefile: 'Zonefile'
|
||||
|
|
|
@ -7,7 +7,11 @@ Rails.application.routes.draw do
|
|||
|
||||
## ADMIN ROUTES
|
||||
namespace(:admin) do
|
||||
resources :domains
|
||||
resources :domains do
|
||||
member do
|
||||
get 'zonefile'
|
||||
end
|
||||
end
|
||||
resources :settings
|
||||
resources :registrars do
|
||||
collection do
|
||||
|
|
157
lib/zonefile.rb
Normal file
157
lib/zonefile.rb
Normal file
|
@ -0,0 +1,157 @@
|
|||
class Zonefile
|
||||
RECORDS = [:mx, :a, :a4, :ns, :cname, :txt, :ptr, :srv, :soa, :ds,
|
||||
:dnskey, :rrsig, :nsec, :nsec3, :nsec3param, :tlsa, :naptr]
|
||||
|
||||
attr_accessor(*RECORDS, :ttl, :origin)
|
||||
|
||||
def initialize(obj = {})
|
||||
RECORDS.each do |x|
|
||||
if x == :soa
|
||||
send("#{x}=", {})
|
||||
else
|
||||
send("#{x}=", [])
|
||||
end
|
||||
end
|
||||
|
||||
obj.each do |k, v|
|
||||
send("#{k}=", v)
|
||||
end
|
||||
end
|
||||
|
||||
def new_serial
|
||||
base = sprintf('%04d%02d%02d', Time.now.year, Time.now.month, Time.now.day)
|
||||
|
||||
if soa[:serial]
|
||||
if base == soa[:serial].first(8)
|
||||
sequence = soa[:serial].last(2).to_i + 1
|
||||
soa[:serial] = "#{base}#{sprintf('%02d', sequence)}"
|
||||
return soa[:serial]
|
||||
end
|
||||
end
|
||||
|
||||
soa[:serial] = soa[:serial] = "#{base}00"
|
||||
end
|
||||
|
||||
# rubocop:disable Metrics/MethodLength
|
||||
# rubocop: disable Metrics/PerceivedComplexity
|
||||
# rubocop: disable Metrics/CyclomaticComplexity
|
||||
def generate
|
||||
out = <<-eos
|
||||
$ORIGIN #{origin} ; designates the start of this zone file in the namespace
|
||||
$TTL #{ttl} ; default expiration time of all resource records without their own TTL value
|
||||
|
||||
#{soa[:origin]} #{soa[:ttl]} IN SOA #{soa[:primary_ns]} #{soa[:email]} (
|
||||
#{sprintf('%-13s', soa[:serial])}; serial number
|
||||
#{sprintf('%-13s', soa[:refresh])}; refresh, seconds
|
||||
#{sprintf('%-13s', soa[:retry])}; retry, seconds
|
||||
#{sprintf('%-13s', soa[:expire])}; expire, seconds
|
||||
#{sprintf('%-13s', soa[:minimumTTL])}; minimum TTL, seconds
|
||||
)
|
||||
eos
|
||||
|
||||
ns.each do |ns|
|
||||
out << "#{ns[:name]} #{ns[:ttl]} #{ns[:class]} NS #{ns[:host]}\n"
|
||||
end
|
||||
|
||||
out << "\n; Zone MX Records\n" unless mx.empty?
|
||||
|
||||
mx.each do |mx|
|
||||
out << "#{mx[:name]} #{mx[:ttl]} #{mx[:class]} MX #{mx[:pri]} #{mx[:host]}\n"
|
||||
end
|
||||
|
||||
out << "\n; Zone A Records\n" unless a.empty?
|
||||
|
||||
a.each do |a|
|
||||
out << "#{a[:name]} #{a[:ttl]} #{a[:class]} A #{a[:host]}\n"
|
||||
end
|
||||
|
||||
out << "\n; Zone CNAME Records\n" unless cname.empty?
|
||||
|
||||
cname.each do |cn|
|
||||
out << "#{cn[:name]} #{cn[:ttl]} #{cn[:class]} CNAME #{cn[:host]}\n"
|
||||
end
|
||||
|
||||
out << "\n; Zone AAAA Records\n" unless a4.empty?
|
||||
|
||||
a4.each do |a4|
|
||||
out << "#{a4[:name]} #{a4[:ttl]} #{a4[:class]} AAAA #{a4[:host]}\n"
|
||||
end
|
||||
|
||||
out << "\n; Zone TXT Records\n" unless txt.empty?
|
||||
|
||||
txt.each do |tx|
|
||||
out << "#{tx[:name]} #{tx[:ttl]} #{tx[:class]} TXT #{tx[:text]}\n"
|
||||
end
|
||||
|
||||
out << "\n; Zone SRV Records\n" unless srv.empty?
|
||||
|
||||
srv.each do |srv|
|
||||
out << "#{srv[:name]} #{srv[:ttl]} #{srv[:class]} SRV #{srv[:pri]} "\
|
||||
"#{srv[:weight]} #{srv[:port]} #{srv[:host]}\n"
|
||||
end
|
||||
|
||||
out << "\n; Zone PTR Records\n" unless ptr.empty?
|
||||
|
||||
ptr.each do |ptr|
|
||||
out << "#{ptr[:name]} #{ptr[:ttl]} #{ptr[:class]} PTR #{ptr[:host]}\n"
|
||||
end
|
||||
|
||||
out << "\n; Zone DS Records\n" unless ds.empty?
|
||||
|
||||
ds.each do |ds|
|
||||
out << "#{ds[:name]} #{ds[:ttl]} #{ds[:class]} DS #{ds[:key_tag]} #{ds[:algorithm]} "\
|
||||
"#{ds[:digest_type]} #{ds[:digest]}\n"
|
||||
end
|
||||
|
||||
out << "\n; Zone NSEC Records\n" unless self.ds.empty?
|
||||
|
||||
nsec.each do |nsec|
|
||||
out << "#{nsec[:name]} #{nsec[:ttl]} #{nsec[:class]} NSEC #{nsec[:next]} #{nsec[:types]}\n"
|
||||
end
|
||||
|
||||
out << "\n; Zone NSEC3 Records\n" unless self.ds.empty?
|
||||
|
||||
nsec3.each do |nsec3|
|
||||
out << "#{nsec3[:name]} #{nsec3[:ttl]} #{nsec3[:class]} NSEC3 #{nsec3[:algorithm]} "\
|
||||
"#{nsec3[:flags]} #{nsec3[:iterations]} #{nsec3[:salt]} #{nsec3[:next]} #{nsec3[:types]}\n"
|
||||
end
|
||||
|
||||
out << "\n; Zone NSEC3PARAM Records\n" unless self.ds.empty?
|
||||
|
||||
nsec3param.each do |nsec3param|
|
||||
out << "#{nsec3param[:name]} #{nsec3param[:ttl]} #{nsec3param[:class]} NSEC3PARAM "\
|
||||
"#{nsec3param[:algorithm]} #{nsec3param[:flags]} #{nsec3param[:iterations]} #{nsec3param[:salt]}\n"
|
||||
end
|
||||
|
||||
out << "\n; Zone DNSKEY Records\n" unless self.ds.empty?
|
||||
|
||||
dnskey.each do |dnskey|
|
||||
out << "#{dnskey[:name]} #{dnskey[:ttl]} #{dnskey[:class]} DNSKEY #{dnskey[:flag]} "\
|
||||
"#{dnskey[:protocol]} #{dnskey[:algorithm]} #{dnskey[:public_key]}\n"
|
||||
end
|
||||
|
||||
out << "\n; Zone RRSIG Records\n" unless self.ds.empty?
|
||||
|
||||
rrsig.each do |rrsig|
|
||||
out << "#{rrsig[:name]} #{rrsig[:ttl]} #{rrsig[:class]} RRSIG #{rrsig[:type_covered]} "\
|
||||
"#{rrsig[:algorithm]} #{rrsig[:labels]} #{rrsig[:original_ttl]} #{rrsig[:expiration]} "\
|
||||
"#{rrsig[:inception]} #{rrsig[:key_tag]} #{rrsig[:signer]} #{rrsig[:signature]}\n"
|
||||
end
|
||||
|
||||
out << "\n; Zone TLSA Records\n" unless tlsa.empty?
|
||||
|
||||
tlsa.each do |tlsa|
|
||||
out << "#{tlsa[:name]} #{tlsa[:ttl]} #{tlsa[:class]} TLSA #{tlsa[:certificate_usage]} "\
|
||||
"#{tlsa[:selector]} #{tlsa[:matching_type]} #{tlsa[:data]}\n"
|
||||
end
|
||||
|
||||
out << "\n; Zone NAPTR Records\n" unless self.ds.empty?
|
||||
|
||||
naptr.each do |naptr|
|
||||
out << "#{naptr[:name]} #{naptr[:ttl]} #{naptr[:class]} NAPTR #{naptr[:order]} "\
|
||||
"#{naptr[:preference]} #{naptr[:flags]} #{naptr[:service]} #{naptr[:regexp]} #{naptr[:replacement]}\n"
|
||||
end
|
||||
|
||||
out
|
||||
end
|
||||
end
|
Loading…
Add table
Add a link
Reference in a new issue