internetee-registry/db/migrate/20161227193500_update_generate_zone_file_function.rb
2016-12-27 21:50:59 +02:00

128 lines
4.7 KiB
Ruby

class UpdateGenerateZoneFileFunction < ActiveRecord::Migration
def up
execute <<-SQL
CREATE OR REPLACE FUNCTION generate_zonefile(i_origin character varying) RETURNS text
LANGUAGE plpgsql
AS $_$
DECLARE
zone_header text := concat('$ORIGIN ', i_origin, '.');
serial_num varchar;
include_filter varchar := '';
exclude_filter varchar := '';
tmp_var text;
ret text;
BEGIN
-- define filters
include_filter = '%.' || i_origin;
-- for %.%.%
IF i_origin ~ '\.' THEN
exclude_filter := '';
-- for %.%
ELSE
exclude_filter := '%.%.' || i_origin;
END IF;
SELECT ROUND(extract(epoch from now() at time zone 'utc')) INTO serial_num;
-- zonefile header
SELECT concat(
format('%-10s', '$ORIGIN .'), chr(10),
format('%-10s', '$TTL'), zf.ttl, chr(10), chr(10),
format('%-10s', i_origin || '.'), 'IN SOA ', zf.master_nameserver, '. ', zf.email, '. (', chr(10),
format('%-17s', ''), format('%-12s', serial_num), '; serial number', chr(10),
format('%-17s', ''), format('%-12s', zf.refresh), '; refresh, seconds', chr(10),
format('%-17s', ''), format('%-12s', zf.retry), '; retry, seconds', chr(10),
format('%-17s', ''), format('%-12s', zf.expire), '; expire, seconds', chr(10),
format('%-17s', ''), format('%-12s', zf.minimum_ttl), '; minimum TTL, seconds', chr(10),
format('%-17s', ''), ')'
) FROM zonefile_settings zf WHERE i_origin = zf.origin INTO tmp_var;
ret = concat(tmp_var, chr(10), chr(10));
-- origin ns records
SELECT ns_records FROM zonefile_settings zf WHERE i_origin = zf.origin INTO tmp_var;
ret := concat(ret, '; Zone NS Records', chr(10), tmp_var, chr(10));
-- ns records
SELECT array_to_string(
array(
SELECT concat(d.name_puny, '. IN NS ', ns.hostname, '.')
FROM domains d
JOIN nameservers ns ON ns.domain_id = d.id
WHERE d.name LIKE include_filter AND d.name NOT LIKE exclude_filter
AND NOT ('{serverHold,clientHold,inactive}' && d.statuses)
ORDER BY d.name
),
chr(10)
) INTO tmp_var;
ret := concat(ret, tmp_var, chr(10), chr(10));
-- origin a glue records
SELECT a_records FROM zonefile_settings zf WHERE i_origin = zf.origin INTO tmp_var;
ret := concat(ret, '; Zone A Records', chr(10), tmp_var, chr(10));
-- a glue records for other nameservers
SELECT array_to_string(
array(
SELECT concat(ns.hostname, '. IN A ', unnest(ns.ipv4))
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 LIKE '%.' || d.name
AND d.name <> i_origin
AND ns.ipv4 IS NOT NULL AND ns.ipv4 <> '{}'
AND NOT ('{serverHold,clientHold,inactive}' && d.statuses)
), chr(10)
) INTO tmp_var;
ret := concat(ret, tmp_var, chr(10), chr(10));
-- origin aaaa glue records
SELECT a4_records FROM zonefile_settings zf WHERE i_origin = zf.origin INTO tmp_var;
ret := concat(ret, '; Zone AAAA Records', chr(10), tmp_var, chr(10));
-- aaaa glue records for other nameservers
SELECT array_to_string(
array(
SELECT concat(ns.hostname, '. IN AAAA ', unnest(ns.ipv6))
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 LIKE '%.' || d.name
AND d.name <> i_origin
AND ns.ipv6 IS NOT NULL AND ns.ipv6 <> '{}'
AND NOT ('{serverHold,clientHold,inactive}' && d.statuses)
), chr(10)
) INTO tmp_var;
ret := concat(ret, tmp_var, chr(10), chr(10));
-- ds records
SELECT array_to_string(
array(
SELECT concat(
d.name_puny, '. 3600 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 include_filter AND d.name NOT LIKE exclude_filter AND dk.flags = 257
AND NOT ('{serverHold,clientHold,inactive}' && d.statuses)
),
chr(10)
) INTO tmp_var;
ret := concat(ret, '; Zone DS Records', chr(10), tmp_var, chr(10));
RETURN ret;
END;
$_$;
SQL
end
def down
raise ActiveRecord::IrreversibleMigration
end
end