-- 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; $$;