91 lines
3.9 KiB
SQL
91 lines
3.9 KiB
SQL
-- This file control sum
|
||
SET vars.csum TO :'csum';
|
||
-- This zone copy hostname
|
||
SET vars.ns TO :'NSERVER';
|
||
|
||
DO $$
|
||
-- Наполнение
|
||
|
||
DECLARE
|
||
v_domain text; -- domain name
|
||
v_domain_id integer; -- internal domain id
|
||
v_ns_admin text := 'hostmaster.example.ru'; -- master DNS admin email
|
||
v_soa text; -- zone SOA
|
||
v_prefixes cidr[] := ARRAY[
|
||
'10.0.0.0/8', -- Private-Use Networks
|
||
'100.64.0.0/10', -- CG-NAT
|
||
'127.0.0.0/8', -- Loopback
|
||
'172.16.0.0/12', -- LLA
|
||
'169.254.0.0/16', -- Private-Use Networks
|
||
'192.0.0.0/24', -- IETF Protocol Assignments
|
||
'192.0.2.0/24', -- TEST-NET-1
|
||
'192.88.99.0/24', -- 6to4 Relay Anycast
|
||
'192.168.0.0/16', -- Private-Use Networks
|
||
'198.18.0.0/15', -- Network Interconnect Device Benchmark Testing
|
||
'198.51.100.0/24', -- TEST-NET-2
|
||
'203.0.113.0/24' -- TEST-NET-3
|
||
];
|
||
v_prefixes24 cidr[];
|
||
v_prefix cidr;
|
||
v_arr text[];
|
||
|
||
BEGIN
|
||
-- пересобираем список префиксов по /24
|
||
-- ToDo: префиксы выходящие за границы /8 =< prefix < /24 пропускать
|
||
FOREACH v_prefix IN ARRAY v_prefixes LOOP
|
||
-- получили размерность
|
||
FOR i IN 0 .. 2^(24 - masklen(v_prefix))-1 LOOP
|
||
-- добавили каждую /24
|
||
v_prefixes24 := ARRAY_APPEND(v_prefixes24, set_masklen(v_prefix + 256 * i, 24));
|
||
-- RAISE NOTICE '% %: %', v_prefix, i, set_masklen(v_prefix + 256 * i, 24);
|
||
END LOOP;
|
||
END LOOP;
|
||
|
||
FOREACH v_prefix IN ARRAY v_prefixes24 LOOP
|
||
-- собираем имя зоны
|
||
v_domain := concat_ws('.', -- собираем полностью итоговый v_domain в формате $oct3.$oct2.$oct1.in-addr.arpa
|
||
array_to_string( -- результат превращаем в текст
|
||
array_reverse( -- разворачиваем массив в обратном направлении для in-addr.arpa
|
||
trim_array( -- отрезаем от массива последний октет с маской, так как для /24 в in-addr.arpa надо 3 октета
|
||
string_to_array(v_prefix::text, '.'), -- v_prefix переводим в text и разбираем в массив через '.'
|
||
1
|
||
)
|
||
),'.'
|
||
),
|
||
'in-addr.arpa'
|
||
);
|
||
|
||
SELECT INTO v_domain_id id FROM domains WHERE name = v_domain;
|
||
IF NOT FOUND THEN
|
||
-- зона отсутствует, будем генерить зону по умолчанию
|
||
RAISE NOTICE 'Stub generator for prefix:% zone:%', v_prefix, v_domain;
|
||
ELSE
|
||
-- зона уже создана, пропустить stub-функционал
|
||
RAISE NOTICE 'zone:% already exists, skip stub generation', v_domain;
|
||
CONTINUE;
|
||
END IF;
|
||
|
||
/*
|
||
чексуммы у зоны нет, поэтому достаточно будет первого запуска по
|
||
файлу со спецификой зоны, чтобы затереть зону-заглушку
|
||
получаем/создаём домен ID
|
||
*/
|
||
v_domain_id := domain_id(v_domain);
|
||
|
||
-- собираем SOA
|
||
v_soa := soa_mk(v_domain_id, v_ns_admin);
|
||
|
||
-- в принципе если мы здесь, то предполагается, что зоны такой не существовало
|
||
-- и записей, соответственно, нет. но тем не менее
|
||
DELETE FROM records WHERE domain_id = v_domain_id;
|
||
|
||
-- генерим зону по умолчанию
|
||
INSERT INTO records (domain_id, name, ttl, type, prio, content) VALUES
|
||
(v_domain_id, v_domain, 10800, 'SOA', 0, v_soa)
|
||
, (v_domain_id, v_domain, 10800, 'NS', 0, 'ns1.example.ru')
|
||
, (v_domain_id, v_domain, 10800, 'NS', 0, 'ns2.example.ru')
|
||
;
|
||
END LOOP;
|
||
END;
|
||
$$;
|