add: ACME domain, .env generator; minor code refactoring
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,2 +1,3 @@
|
|||||||
.env
|
.env
|
||||||
|
.env.*
|
||||||
*.done
|
*.done
|
||||||
|
|||||||
90
Makefile
90
Makefile
@@ -1,3 +1,5 @@
|
|||||||
|
# app custom Makefile
|
||||||
|
|
||||||
SHELL = /bin/sh
|
SHELL = /bin/sh
|
||||||
CFG = .env
|
CFG = .env
|
||||||
|
|
||||||
@@ -6,30 +8,28 @@ OBJECTS = $(SOURCES:.sql=.done)
|
|||||||
OBJECTSDIRECT = $(SOURCES:.sql=.direct)
|
OBJECTSDIRECT = $(SOURCES:.sql=.direct)
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# шаблон файла .env
|
# app custom config
|
||||||
|
# comments prefixed with '#- ' will be copied to $(CFG).sample
|
||||||
|
|
||||||
define CONFIG_DEF
|
#- Postgresql container name (access via docker)
|
||||||
# dcape-dns config file, generated by make $(CFG)
|
PG_CONTAINER ?= dcape_db_1
|
||||||
|
|
||||||
# Postgresql container name (access via docker)
|
#- PowerDNS DB user name
|
||||||
PG_CONTAINER=dcape_db_1
|
PGUSER ?= pdns
|
||||||
|
|
||||||
# PowerDNS DB user name
|
#- PowerDNS DB name
|
||||||
PGUSER=pdns
|
PGDATABASE ?= pdns
|
||||||
|
|
||||||
# PowerDNS DB name
|
#- Used ONLY for direct DB access without docker (update-direct)
|
||||||
PGDATABASE=pdns
|
PGPASSWORD ?=
|
||||||
|
|
||||||
# Used ONLY for direct DB access without docker (start-direct)
|
#- ACME zone suffix
|
||||||
PGPASSWORD=
|
ACME_DOMAIN ?=
|
||||||
|
|
||||||
endef
|
|
||||||
export CONFIG_DEF
|
|
||||||
|
|
||||||
all: help
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
all: help
|
||||||
|
|
||||||
-include $(CFG)
|
-include $(CFG)
|
||||||
export
|
export
|
||||||
|
|
||||||
@@ -38,41 +38,69 @@ export
|
|||||||
|
|
||||||
start-hook: update
|
start-hook: update
|
||||||
|
|
||||||
start-direct: update-direct
|
|
||||||
|
|
||||||
stop:
|
stop:
|
||||||
|
|
||||||
$(CFG): $(CFG).sample
|
|
||||||
@[ -f $@ ] || cp $< $@
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
## Usage
|
||||||
|
#:
|
||||||
|
|
||||||
|
## Load updated zone files via running PG container
|
||||||
update: $(OBJECTS)
|
update: $(OBJECTS)
|
||||||
|
|
||||||
%.done: %.sql
|
%.done: %.sql
|
||||||
@echo "*** $< ***"
|
@echo "*** $< ***"
|
||||||
@csum=$$(md5sum $< | sed 's/ .*//') ; \
|
@csum=$$(md5sum $< | sed 's/ .*//') ; \
|
||||||
cat $< | docker exec -i $$PG_CONTAINER psql -U $$PGUSER -d $$PGDATABASE -vcsum=$$csum > $@
|
cat $< | docker exec -i $$PG_CONTAINER psql -U $$PGUSER -d $$PGDATABASE -vcsum=$$csum -vACME_DOMAIN=$(ACME_DOMAIN) > $@
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
## Load updated zone files via psql connection
|
||||||
update-direct: $(CFG) $(OBJECTSDIRECT)
|
update-direct: $(CFG) $(OBJECTSDIRECT)
|
||||||
|
|
||||||
%.direct: %.sql
|
%.direct: %.sql
|
||||||
@echo "*** $< ***"
|
@echo "*** $< ***"
|
||||||
@source $(CFG) && cat $< | PGPASSWORD=$$PGPASSWORD psql -h localhost -U $$PGUSER > $@
|
@source $(CFG) && cat $< | PGPASSWORD=$$PGPASSWORD psql -h localhost -U $$PGUSER > $@
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
## Run psql via running PG container
|
||||||
|
|
||||||
psql:
|
psql:
|
||||||
@docker exec -it $$PG_CONTAINER psql -U $$PGUSER $$PGDATABASE
|
@docker exec -it $$PG_CONTAINER psql -U $$PGUSER $$PGDATABASE
|
||||||
|
|
||||||
clean:
|
# ------------------------------------------------------------------------------
|
||||||
rm -rf *.done
|
## Other
|
||||||
|
#:
|
||||||
|
|
||||||
$(CFG).sample:
|
# This code generates $(CFG).sample from Makefile vars with previous comment line(s)
|
||||||
@echo "*** $@ ***"
|
# See https://gist.github.com/LeKovr/2697fe02504d7c081b0bf79427c93db6
|
||||||
@[ -f $@ ] || echo "$$CONFIG_DEF" > $@
|
|
||||||
|
# Internal: generate config sample data
|
||||||
|
.env.temp.mk:
|
||||||
|
@echo "define CFVAR" > $@
|
||||||
|
@grep -A 1 -h "^#- " $(MAKEFILE_LIST) | grep -vE "^--" \
|
||||||
|
| sed -E 's/^([^\n ]+)\ *\??=([^\n]*)$$/\1=$$(\1)\n/ ; s/^(#)-/\1/' >> $@
|
||||||
|
@echo "endef" >> $@
|
||||||
|
|
||||||
|
ifneq ($(findstring $(MAKECMDGOALS),config $(CFG).sample),)
|
||||||
|
include .env.temp.mk
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Internal: generate config sample
|
||||||
|
$(CFG).sample: .env.temp.mk
|
||||||
|
@echo "# dcape-dns config file, generated by 'make config'\n" > $@
|
||||||
|
@echo "$$CFVAR" >> $@
|
||||||
|
@rm -f $<
|
||||||
|
|
||||||
## generate sample config
|
## generate sample config
|
||||||
config: $(CFG).sample
|
config: $(CFG).sample
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
## Remove .done files
|
||||||
|
clean:
|
||||||
|
rm -rf *.done
|
||||||
|
|
||||||
|
# This code handles group header and target comment with one or two lines only
|
||||||
|
## list Makefile targets
|
||||||
|
## (this is default target)
|
||||||
|
help:
|
||||||
|
@grep -A 1 -h "^## " $(MAKEFILE_LIST) \
|
||||||
|
| sed -E 's/^--$$// ; /./{H;$$!d} ; x ; s/^\n## ([^\n]+)\n(## (.+)\n)*(.+):(.*)$$/" " "\4" "\1" "\3"/' \
|
||||||
|
| sed -E 's/^" " "#" "(.+)" "(.*)"$$/"" "" "" ""\n"\1 \2" "" "" ""/' \
|
||||||
|
| xargs printf "%s\033[36m%-15s\033[0m %s %s\n"
|
||||||
|
|||||||
9
_lib.sql
9
_lib.sql
@@ -1,5 +1,10 @@
|
|||||||
/*
|
/*
|
||||||
Вспомогательные функции
|
Вспомогательные функции
|
||||||
|
|
||||||
|
* FUNCTION soa_upd(a_old TEXT) RETURNS TEXT
|
||||||
|
* FUNCTION domain_id(a_name TEXT, a_type TEXT DEFAULT 'NATIVE') RETURNS INTEGER
|
||||||
|
* PROCEDURE acme_insert(a_domain_id INT, a_name TEXT, a_ip TEXT, a_ttl INT)
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION soa_upd(a_old TEXT) RETURNS TEXT AS $_$
|
CREATE OR REPLACE FUNCTION soa_upd(a_old TEXT) RETURNS TEXT AS $_$
|
||||||
@@ -53,7 +58,7 @@ BEGIN
|
|||||||
END
|
END
|
||||||
$_$ LANGUAGE plpgsql;
|
$_$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
CREATE OR REPLACE PROCEDURE acme_insert(a_domain_id INT, a_name TEXT, a_ip TEXT, a_ttl INT) LANGUAGE plpgsql AS $_$
|
CREATE OR REPLACE PROCEDURE acme_insert(a_domain_id INT, a_name TEXT, a_ip TEXT, a_ttl INT) AS $_$
|
||||||
/*
|
/*
|
||||||
Добавление в зону для заданного a_ip записей для передачи ему контроля над зоной a_name.
|
Добавление в зону для заданного a_ip записей для передачи ему контроля над зоной a_name.
|
||||||
Это используется в DNS-01 challenge ACME
|
Это используется в DNS-01 challenge ACME
|
||||||
@@ -70,4 +75,4 @@ BEGIN
|
|||||||
FROM acme
|
FROM acme
|
||||||
;
|
;
|
||||||
END;
|
END;
|
||||||
$_$;
|
$_$ LANGUAGE plpgsql;
|
||||||
|
|||||||
60
acme.sql.sample
Normal file
60
acme.sql.sample
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
Zone setup for DNS-01 ACME challenge
|
||||||
|
|
||||||
|
This code executed once per domain.
|
||||||
|
Future changes makes traefik via PowerDNS API
|
||||||
|
*/
|
||||||
|
|
||||||
|
-- This var must be set in psql args
|
||||||
|
SET vars.domain TO :'ACME_DOMAIN';
|
||||||
|
|
||||||
|
DO $_$
|
||||||
|
DECLARE
|
||||||
|
v_domain text := 'acme-' || current_setting('vars.domain'); -- domain name
|
||||||
|
v_ns text := 'ns.' || current_setting('vars.domain'); -- master DNS host
|
||||||
|
v_ns_admin text := 'admin.'|| current_setting('vars.domain'); -- master DNS admin email
|
||||||
|
|
||||||
|
v_refresh int := 10800;
|
||||||
|
v_retry int := 3600;
|
||||||
|
v_expire int := 604800;
|
||||||
|
v_ttl int := 1800;
|
||||||
|
|
||||||
|
v_domain_id integer; -- internal domain id
|
||||||
|
v_stamp text; -- zone timestamp
|
||||||
|
v_stamp_old text; -- previous zone SOA timestamp
|
||||||
|
v_soa text; -- zone SOA
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
IF v_domain = 'acme-' THEN
|
||||||
|
RAISE NOTICE 'ACME_DOMAIN is not set. Skipping acme zone setup';
|
||||||
|
RETURN;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
RAISE NOTICE 'Setup acme zone % for nameserver %',v_domain,v_ns;
|
||||||
|
|
||||||
|
SELECT INTO v_domain_id id FROM domains WHERE name = v_domain;
|
||||||
|
IF FOUND THEN
|
||||||
|
-- no any changes needed after creation
|
||||||
|
RAISE NOTICE 'Zone already exists. Skipping';
|
||||||
|
RETURN;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
INSERT INTO domains (name, type) VALUES
|
||||||
|
(v_domain, 'NATIVE')
|
||||||
|
RETURNING id INTO v_domain_id
|
||||||
|
;
|
||||||
|
|
||||||
|
INSERT INTO domainmetadata(domain_id, kind, content) VALUES
|
||||||
|
(v_domain_id, 'SOA-EDIT-API', 'INCREASE')
|
||||||
|
;
|
||||||
|
|
||||||
|
v_stamp := soa_upd();
|
||||||
|
v_soa := concat_ws(' ', v_ns, v_ns_admin, v_stamp, v_refresh, v_retry, v_expire, v_ttl);
|
||||||
|
|
||||||
|
INSERT INTO records (domain_id, name, ttl, type, prio, content) VALUES
|
||||||
|
(v_domain_id, v_domain, 60, 'SOA', 0, v_soa)
|
||||||
|
, (v_domain_id, v_domain, 1800, 'NS', 0, v_ns)
|
||||||
|
;
|
||||||
|
END;
|
||||||
|
$_$;
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
DO $$
|
/*
|
||||||
|
Complete PowerDNS zone records
|
||||||
-- Reload PowerDNS zone data
|
*/
|
||||||
|
|
||||||
|
DO $_$
|
||||||
DECLARE
|
DECLARE
|
||||||
v_domain text := 'dev.lan'; -- domain name
|
v_domain text := 'dev.lan'; -- domain name
|
||||||
v_ip text := '127.0.0.1'; -- base ip
|
v_ip text := '127.0.0.1'; -- base ip
|
||||||
@@ -13,6 +14,11 @@ DECLARE
|
|||||||
v_stamp_old text; -- previous zone SOA timestamp
|
v_stamp_old text; -- previous zone SOA timestamp
|
||||||
v_soa text; -- zone SOA
|
v_soa text; -- zone SOA
|
||||||
|
|
||||||
|
v_refresh int := 10800;
|
||||||
|
v_retry int := 3600;
|
||||||
|
v_expire int := 604800;
|
||||||
|
v_ttl int := 1800;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
refresh -- time lag until the slave again asks the master for a current version of the zone file
|
refresh -- time lag until the slave again asks the master for a current version of the zone file
|
||||||
retry -- Should this request go unanswered, the “Retry” field regulates when a new attempt is to be carried out (< refresh)
|
retry -- Should this request go unanswered, the “Retry” field regulates when a new attempt is to be carried out (< refresh)
|
||||||
@@ -22,11 +28,6 @@ DECLARE
|
|||||||
Each value in seconds
|
Each value in seconds
|
||||||
*/
|
*/
|
||||||
|
|
||||||
v_refresh int := 10800;
|
|
||||||
v_retry int := 3600;
|
|
||||||
v_expire int := 604800;
|
|
||||||
v_ttl int := 1800;
|
|
||||||
|
|
||||||
BEGIN
|
BEGIN
|
||||||
v_domain_id := domain_id(v_domain);
|
v_domain_id := domain_id(v_domain);
|
||||||
|
|
||||||
@@ -52,4 +53,4 @@ BEGIN
|
|||||||
CALL acme_insert(v_domain_id, 'front.' || v_domain, v_ip1, v_ttl);
|
CALL acme_insert(v_domain_id, 'front.' || v_domain, v_ip1, v_ttl);
|
||||||
|
|
||||||
END;
|
END;
|
||||||
$$;
|
$_$;
|
||||||
|
|||||||
Reference in New Issue
Block a user